Substitute universe params in a universe level. Fails with `UnivParamOutOfRange { idx, bound }` if an interior `Param(idx)` references beyond `us.len()`. In a well-typed kernel run, every call site supplies `us` whose length matches the arity of the enclosing constant (validated by `infer` at the Const gate), so this error never fires on well-formed input. It exists to turn any internal invariant
(
&mut self,
u: &KUniv<M>,
us: &[KUniv<M>],
)
| 777 | cache.insert(key, interned.clone()); |
| 778 | Ok(interned) |
| 779 | } |
| 780 | |
| 781 | /// Substitute universe params in a universe level. |
| 782 | /// |
| 783 | /// Fails with `UnivParamOutOfRange { idx, bound }` if an interior |
| 784 | /// `Param(idx)` references beyond `us.len()`. In a well-typed kernel |
| 785 | /// run, every call site supplies `us` whose length matches the |
| 786 | /// arity of the enclosing constant (validated by `infer` at the Const |
| 787 | /// gate), so this error never fires on well-formed input. It exists |
| 788 | /// to turn any internal invariant slip into a loud failure instead of |
| 789 | /// a silent orphan `Param` propagating downstream. |
| 790 | pub fn subst_univ( |
| 791 | &mut self, |
| 792 | u: &KUniv<M>, |
| 793 | us: &[KUniv<M>], |
| 794 | ) -> Result<KUniv<M>, TcError<M>> { |
| 795 | match u.data() { |
| 796 | UnivData::Zero(_) => Ok(u.clone()), |
| 797 | UnivData::Param(i, _, _) => { |
| 798 | match usize::try_from(*i).ok().and_then(|i| us.get(i)) { |
| 799 | Some(v) => Ok(v.clone()), |
| 800 | None => { |
| 801 | Err(TcError::UnivParamOutOfRange { idx: *i, bound: us.len() }) |
| 802 | }, |
| 803 | } |
| 804 | }, |
| 805 | UnivData::Succ(inner, _) => { |
| 806 | let inner2 = self.subst_univ(inner, us)?; |
| 807 | Ok(KUniv::succ(inner2)) |
| 808 | }, |
| 809 | UnivData::Max(a, b, _) => { |
| 810 | let a2 = self.subst_univ(a, us)?; |
| 811 | let b2 = self.subst_univ(b, us)?; |
| 812 | Ok(KUniv::max(a2, b2)) |