diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs index 7b28689912e5..5f7e6782fdd2 100644 --- a/crates/hir-ty/src/lower.rs +++ b/crates/hir-ty/src/lower.rs @@ -932,7 +932,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { bound: &'b TypeBound, self_ty: Ty<'db>, ignore_bindings: bool, - ) -> impl Iterator, GenericPredicateSource)> + use<'b, 'a, 'db> { + ) -> impl Iterator, GenericPredicateSource)> + use<'db> { let interner = self.interner; let meta_sized = self.lang_items.MetaSized; let pointee_sized = self.lang_items.PointeeSized; @@ -1030,7 +1030,17 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { for b in bounds { let db = self.db; - self.lower_type_bound(b, dummy_self_ty, false).for_each(|(b, _)| { + match b { + TypeBound::Path(_, TraitBoundModifier::None) => { + // `dyn Trait<'a>` is an existential predicate that introduces a binder. + self.with_shifted_in(&[], |ctx| { + ctx.lower_type_bound(b, dummy_self_ty, false) + }) + .0 + } + _ => self.lower_type_bound(b, dummy_self_ty, false), + } + .for_each(|(b, _)| { match b.kind().skip_binder() { rustc_type_ir::ClauseKind::Trait(t) => { let id = t.def_id(); diff --git a/crates/hir-ty/src/tests/regression.rs b/crates/hir-ty/src/tests/regression.rs index bdf087c34134..6260722dd0f3 100644 --- a/crates/hir-ty/src/tests/regression.rs +++ b/crates/hir-ty/src/tests/regression.rs @@ -3138,3 +3138,13 @@ fn main() { "#, ); } + +#[test] +fn dyn_trait_binder_inside_fn_ptr() { + check_no_mismatches( + r#" +trait Trait<'a> {} +fn f<'a>(_: fn() -> &'a dyn Trait<'a>) {} + "#, + ); +}