about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2025-07-13 16:23:20 +0000
committerMichael Goulet <michael@errs.io>2025-07-13 16:31:59 +0000
commit549a5d8b2843cff903a872ffa682f34d74bb341a (patch)
tree2b0e107274fc8d636b955ba520546db95afc5a42 /compiler
parentef726a4cef26710fb190d9a179f7be62be16e95c (diff)
Dont collect assoc ty item bounds from trait where clause for host effect predicates
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_hir_analysis/src/collect/item_bounds.rs56
1 files changed, 34 insertions, 22 deletions
diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
index e51ef46afb7..7e3fb5448f6 100644
--- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
+++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
@@ -38,12 +38,13 @@ fn associated_type_bounds<'tcx>(
         let icx = ItemCtxt::new(tcx, assoc_item_def_id);
         let mut bounds = Vec::new();
         icx.lowerer().lower_bounds(item_ty, hir_bounds, &mut bounds, ty::List::empty(), filter);
-        // Implicit bounds are added to associated types unless a `?Trait` bound is found
+
         match filter {
             PredicateFilter::All
             | PredicateFilter::SelfOnly
             | PredicateFilter::SelfTraitThatDefines(_)
             | PredicateFilter::SelfAndAssociatedTypeBounds => {
+                // Implicit bounds are added to associated types unless a `?Trait` bound is found.
                 icx.lowerer().add_sizedness_bounds(
                     &mut bounds,
                     item_ty,
@@ -53,37 +54,48 @@ fn associated_type_bounds<'tcx>(
                     span,
                 );
                 icx.lowerer().add_default_traits(&mut bounds, item_ty, hir_bounds, None, span);
+
+                // Also collect `where Self::Assoc: Trait` from the parent trait's where clauses.
+                let trait_def_id = tcx.local_parent(assoc_item_def_id);
+                let trait_predicates = tcx.trait_explicit_predicates_and_bounds(trait_def_id);
+
+                let item_trait_ref =
+                    ty::TraitRef::identity(tcx, tcx.parent(assoc_item_def_id.to_def_id()));
+                bounds.extend(trait_predicates.predicates.iter().copied().filter_map(
+                    |(clause, span)| {
+                        remap_gat_vars_and_recurse_into_nested_projections(
+                            tcx,
+                            filter,
+                            item_trait_ref,
+                            assoc_item_def_id,
+                            span,
+                            clause,
+                        )
+                    },
+                ));
             }
             // `ConstIfConst` is only interested in `[const]` bounds.
-            PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {}
+            PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {
+                // FIXME(const_trait_impl): We *could* uplift the
+                // `where Self::Assoc: [const] Trait` bounds from the parent trait
+                // here too, but we'd need to split `const_conditions` into two
+                // queries (like we do for `trait_explicit_predicates_and_bounds`)
+                // since we need to also filter the predicates *out* of the const
+                // conditions or they lead to cycles in the trait solver when
+                // utilizing these bounds. For now, let's do nothing.
+            }
         }
 
-        let trait_def_id = tcx.local_parent(assoc_item_def_id);
-        let trait_predicates = tcx.trait_explicit_predicates_and_bounds(trait_def_id);
-
-        let item_trait_ref = ty::TraitRef::identity(tcx, tcx.parent(assoc_item_def_id.to_def_id()));
-        let bounds_from_parent =
-            trait_predicates.predicates.iter().copied().filter_map(|(clause, span)| {
-                remap_gat_vars_and_recurse_into_nested_projections(
-                    tcx,
-                    filter,
-                    item_trait_ref,
-                    assoc_item_def_id,
-                    span,
-                    clause,
-                )
-            });
-
-        let all_bounds = tcx.arena.alloc_from_iter(bounds.into_iter().chain(bounds_from_parent));
+        let bounds = tcx.arena.alloc_from_iter(bounds);
         debug!(
             "associated_type_bounds({}) = {:?}",
             tcx.def_path_str(assoc_item_def_id.to_def_id()),
-            all_bounds
+            bounds
         );
 
-        assert_only_contains_predicates_from(filter, all_bounds, item_ty);
+        assert_only_contains_predicates_from(filter, bounds, item_ty);
 
-        all_bounds
+        bounds
     })
 }