@@ -534,25 +534,23 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
534534 match where_predicate {
535535 WherePredicate :: ForLifetime { target, bound, .. }
536536 | WherePredicate :: TypeBound { target, bound } => {
537- if let PredicateFilter :: SelfTrait = predicate_filter {
538- let target_type = & self . store [ * target] ;
539- let self_type = ' is_self: {
540- if let TypeRef :: Path ( path) = target_type
541- && path. is_self_type ( )
542- {
543- break ' is_self true ;
544- }
545- if let TypeRef :: TypeParam ( param) = target_type
546- && generics[ param. local_id ( ) ] . is_trait_self ( )
547- {
548- break ' is_self true ;
549- }
550- false
551- } ;
552- if !self_type {
553- return Either :: Left ( Either :: Left ( iter:: empty ( ) ) ) ;
554- }
537+ let is_self_ty = |ty_ref : TypeRefId | match & self . store [ ty_ref] {
538+ TypeRef :: Path ( path) => path. is_self_type ( ) ,
539+ TypeRef :: TypeParam ( param) => generics[ param. local_id ( ) ] . is_trait_self ( ) ,
540+ _ => false ,
541+ } ;
542+
543+ let should_lower = match predicate_filter {
544+ PredicateFilter :: SelfOnly => is_self_ty ( * target) ,
545+ PredicateFilter :: SelfAndAssociatedTypeBounds => {
546+ is_self_ty ( * target) || matches ! ( & self . store[ * target] , TypeRef :: Path ( path) if path. type_anchor( ) . is_some_and( is_self_ty) )
547+ } ,
548+ PredicateFilter :: All => true ,
549+ } ;
550+ if !should_lower {
551+ return Either :: Left ( Either :: Left ( iter:: empty ( ) ) ) ;
555552 }
553+
556554 let self_ty = self . lower_ty ( * target) ;
557555 Either :: Left ( Either :: Right ( self . lower_type_bound ( bound, self_ty, ignore_bindings) ) )
558556 }
@@ -1236,7 +1234,8 @@ impl<'db> ops::Deref for GenericPredicates<'db> {
12361234
12371235#[ derive( Copy , Clone , Debug ) ]
12381236pub ( crate ) enum PredicateFilter {
1239- SelfTrait ,
1237+ SelfOnly ,
1238+ SelfAndAssociatedTypeBounds ,
12401239 All ,
12411240}
12421241
@@ -1265,6 +1264,21 @@ pub(crate) fn generic_predicates_without_parent_with_diagnostics_query<'db>(
12651264 generic_predicates_filtered_by ( db, def, PredicateFilter :: All , |d| d == def)
12661265}
12671266
1267+ pub ( crate ) fn explicit_super_predicates_of_query < ' db > (
1268+ db : & ' db dyn HirDatabase ,
1269+ def : GenericDefId ,
1270+ ) -> GenericPredicates < ' db > {
1271+ generic_predicates_filtered_by ( db, def, PredicateFilter :: SelfOnly , |_| true ) . 0
1272+ }
1273+
1274+ pub ( crate ) fn explicit_implied_predicates_of_query < ' db > (
1275+ db : & ' db dyn HirDatabase ,
1276+ def : GenericDefId ,
1277+ ) -> GenericPredicates < ' db > {
1278+ generic_predicates_filtered_by ( db, def, PredicateFilter :: SelfAndAssociatedTypeBounds , |_| true )
1279+ . 0
1280+ }
1281+
12681282/// Resolve the where clause(s) of an item with generics,
12691283/// with a given filter
12701284#[ tracing:: instrument( skip( db, filter) , ret) ]
@@ -1310,8 +1324,12 @@ where
13101324
13111325 let explicitly_unsized_tys = ctx. unsized_types ;
13121326
1313- let sized_trait = LangItem :: Sized . resolve_trait ( db, resolver. krate ( ) ) ;
1314- if let Some ( sized_trait) = sized_trait {
1327+ // We don't insert extra `: Sized` bounds if we are collecting predicates only for `Self`
1328+ if !matches ! (
1329+ predicate_filter,
1330+ PredicateFilter :: SelfOnly | PredicateFilter :: SelfAndAssociatedTypeBounds
1331+ ) && let Some ( sized_trait) = LangItem :: Sized . resolve_trait ( db, resolver. krate ( ) )
1332+ {
13151333 let ( mut generics, mut def_id) =
13161334 ( crate :: next_solver:: generics:: generics ( db, def. into ( ) ) , def) ;
13171335 loop {
@@ -1358,6 +1376,9 @@ where
13581376 }
13591377 }
13601378
1379+ // FIXME: rustc gathers more predicates by recursing through resulting trait predicates.
1380+ // See https://github.com/rust-lang/rust/blob/76c5ed2847cdb26ef2822a3a165d710f6b772217/compiler/rustc_hir_analysis/src/collect/predicates_of.rs#L689-L715
1381+
13611382 (
13621383 GenericPredicates ( predicates. is_empty ( ) . not ( ) . then ( || predicates. into ( ) ) ) ,
13631384 create_diagnostics ( ctx. diagnostics ) ,
@@ -1724,7 +1745,7 @@ fn named_associated_type_shorthand_candidates<'db, R>(
17241745 for pred in generic_predicates_filtered_by (
17251746 db,
17261747 GenericDefId :: TraitId ( trait_def_id) ,
1727- PredicateFilter :: SelfTrait ,
1748+ PredicateFilter :: SelfOnly ,
17281749 // We are likely in the midst of lowering generic predicates of `def`.
17291750 // So, if we allow `pred == def` we might fall into an infinite recursion.
17301751 // Actually, we have already checked for the case `pred == def` above as we started
0 commit comments