diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 827317fcebb..daf379ef879 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs @@ -124,7 +124,7 @@ pub fn wrap_empty(value: T) -> Self where T: TypeWalk, { - Binders::empty(&Interner, value.shift_bound_vars(DebruijnIndex::ONE)) + Binders::empty(&Interner, value.shifted_in_from(DebruijnIndex::ONE)) } } @@ -209,7 +209,8 @@ pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig { params_and_return: fn_ptr .substs .clone() - .shift_bound_vars_out(DebruijnIndex::ONE) + .shifted_out_to(DebruijnIndex::ONE) + .expect("unexpected lifetime vars in fn ptr") .interned() .iter() .map(|arg| arg.assert_ty_ref(&Interner).clone()) diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs index 66e72c814fc..48c26f471f1 100644 --- a/crates/hir_ty/src/lower.rs +++ b/crates/hir_ty/src/lower.rs @@ -483,7 +483,7 @@ fn select_associated_type(&self, res: Option, segment: PathSegment<'_>) }; // We need to shift in the bound vars, since // associated_type_shorthand_candidates does not do that - let substs = substs.shift_bound_vars(self.in_binders); + let substs = substs.shifted_in_from(self.in_binders); // FIXME handle type parameters on the segment return Some( TyKind::Alias(AliasTy::Projection(ProjectionTy { @@ -831,20 +831,20 @@ pub fn associated_type_shorthand_candidates( }; match res { - // FIXME: how to correctly handle higher-ranked bounds here? TypeNs::SelfType(impl_id) => search( - db.impl_trait(impl_id)? - .into_value_and_skipped_binders() - .0 - .shift_bound_vars_out(DebruijnIndex::ONE), + // we're _in_ the impl -- the binders get added back later. Correct, + // but it would be nice to make this more explicit + db.impl_trait(impl_id)?.into_value_and_skipped_binders().0, ), TypeNs::GenericParam(param_id) => { let predicates = db.generic_predicates_for_param(param_id); let res = predicates.iter().find_map(|pred| match pred.skip_binders().skip_binders() { // FIXME: how to correctly handle higher-ranked bounds here? - WhereClause::Implemented(tr) => { - search(tr.clone().shift_bound_vars_out(DebruijnIndex::ONE)) - } + WhereClause::Implemented(tr) => search( + tr.clone() + .shifted_out_to(DebruijnIndex::ONE) + .expect("FIXME unexpected higher-ranked trait bound"), + ), _ => None, }); if let res @ Some(_) = res { diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs index 9db2b0c2f99..c3b148cab7c 100644 --- a/crates/hir_ty/src/traits/chalk/mapping.rs +++ b/crates/hir_ty/src/traits/chalk/mapping.rs @@ -531,7 +531,7 @@ pub(super) fn generic_predicate_to_inline_bound( ) -> Option>> { // An InlineBound is like a GenericPredicate, except the self type is left out. // We don't have a special type for this, but Chalk does. - let self_ty_shifted_in = self_ty.clone().shift_bound_vars(DebruijnIndex::ONE); + let self_ty_shifted_in = self_ty.clone().shifted_in_from(DebruijnIndex::ONE); let (pred, binders) = pred.as_ref().into_value_and_skipped_binders(); match pred { WhereClause::Implemented(trait_ref) => { diff --git a/crates/hir_ty/src/utils.rs b/crates/hir_ty/src/utils.rs index c7786a19923..d11708299d2 100644 --- a/crates/hir_ty/src/utils.rs +++ b/crates/hir_ty/src/utils.rs @@ -66,9 +66,11 @@ fn direct_super_trait_refs(db: &dyn HirDatabase, trait_ref: &TraitRef) -> Vec { - Some(tr.clone().shift_bound_vars_out(DebruijnIndex::ONE)) - } + WhereClause::Implemented(tr) => Some( + tr.clone() + .shifted_out_to(DebruijnIndex::ONE) + .expect("FIXME unexpected higher-ranked trait bound"), + ), _ => None, }) }) @@ -103,6 +105,8 @@ pub(super) fn all_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec` and `Trait: OtherTrait` we'll get /// `Self: OtherTrait`. pub(super) fn all_super_trait_refs(db: &dyn HirDatabase, trait_ref: TraitRef) -> Vec { + // FIXME: replace by Chalk's `super_traits`, maybe make this a query + // we need to take care a bit here to avoid infinite loops in case of cycles // (i.e. if we have `trait A: B; trait B: A;`) let mut result = vec![trait_ref]; diff --git a/crates/hir_ty/src/walk.rs b/crates/hir_ty/src/walk.rs index b1e22da0af6..b85e6ab4d26 100644 --- a/crates/hir_ty/src/walk.rs +++ b/crates/hir_ty/src/walk.rs @@ -82,7 +82,7 @@ fn subst_bound_vars_at_depth(mut self, substs: &Substitution, depth: DebruijnInd *ty = substs.interned()[bound.index] .assert_ty_ref(&Interner) .clone() - .shift_bound_vars(binders); + .shifted_in_from(binders); } } }, @@ -92,7 +92,7 @@ fn subst_bound_vars_at_depth(mut self, substs: &Substitution, depth: DebruijnInd } /// Shifts up debruijn indices of `TyKind::Bound` vars by `n`. - fn shift_bound_vars(self, n: DebruijnIndex) -> Self + fn shifted_in_from(self, n: DebruijnIndex) -> Self where Self: Sized, { @@ -108,20 +108,22 @@ fn shift_bound_vars(self, n: DebruijnIndex) -> Self } /// Shifts debruijn indices of `TyKind::Bound` vars out (down) by `n`. - fn shift_bound_vars_out(self, n: DebruijnIndex) -> Self + fn shifted_out_to(self, n: DebruijnIndex) -> Option where Self: Sized + std::fmt::Debug, { - self.fold_binders( - &mut |ty, binders| match ty.kind(&Interner) { - TyKind::BoundVar(bound) if bound.debruijn >= binders => { - TyKind::BoundVar(bound.shifted_out_to(n).unwrap_or(bound.clone())) - .intern(&Interner) + Some(self.fold_binders( + &mut |ty, binders| { + match ty.kind(&Interner) { + TyKind::BoundVar(bound) if bound.debruijn >= binders => { + TyKind::BoundVar(bound.shifted_out_to(n).unwrap_or(bound.clone())) + .intern(&Interner) + } + _ => ty, } - _ => ty, }, DebruijnIndex::INNERMOST, - ) + )) } }