Skip to content

Dont collect assoc ty item bounds from trait where clause for host effect predicates #143895

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -889,8 +889,6 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
tcx.ensure_ok().predicates_of(def_id);
tcx.ensure_ok().explicit_item_bounds(def_id);
tcx.ensure_ok().explicit_item_self_bounds(def_id);
tcx.ensure_ok().item_bounds(def_id);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to ensure these queries, since they're just computed from the explicit ones we're ensuring above.

tcx.ensure_ok().item_self_bounds(def_id);
if tcx.is_conditionally_const(def_id) {
tcx.ensure_ok().explicit_implied_const_bounds(def_id);
tcx.ensure_ok().const_conditions(def_id);
Expand Down Expand Up @@ -1042,8 +1040,12 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
let has_type = match assoc_item.container {
ty::AssocItemContainer::Impl => true,
ty::AssocItemContainer::Trait => {
tcx.ensure_ok().item_bounds(def_id);
tcx.ensure_ok().item_self_bounds(def_id);
tcx.ensure_ok().explicit_item_bounds(def_id);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensuring the explicit flavor of the item bounds queries, and also making sure to ensure the const ones too.

tcx.ensure_ok().explicit_item_self_bounds(def_id);
if tcx.is_conditionally_const(def_id) {
tcx.ensure_ok().explicit_implied_const_bounds(def_id);
tcx.ensure_ok().const_conditions(def_id);
}
res = res.and(check_trait_item(tcx, def_id));
assoc_item.defaultness(tcx).has_value()
}
Expand Down
57 changes: 35 additions & 22 deletions compiler/rustc_hir_analysis/src/collect/item_bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
})
}

Expand Down Expand Up @@ -112,6 +124,7 @@ fn remap_gat_vars_and_recurse_into_nested_projections<'tcx>(
ty::ClauseKind::Trait(tr) => tr.self_ty(),
ty::ClauseKind::Projection(proj) => proj.projection_term.self_ty(),
ty::ClauseKind::TypeOutlives(outlives) => outlives.0,
ty::ClauseKind::HostEffect(host) => host.self_ty(),
_ => return None,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems like a good candidate for an exhaustive match

};

Expand Down
13 changes: 0 additions & 13 deletions tests/crashes/133275-1.rs

This file was deleted.

15 changes: 0 additions & 15 deletions tests/crashes/133275-2.rs

This file was deleted.

13 changes: 13 additions & 0 deletions tests/ui/traits/const-traits/const-assoc-bound-in-trait-wc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//@ check-pass

#![feature(const_clone)]
#![feature(const_trait_impl)]

#[const_trait]
trait A where Self::Target: [const] Clone {
type Target;
}

const fn foo<T>() where T: [const] A {}

fn main() {}
19 changes: 19 additions & 0 deletions tests/ui/traits/const-traits/imply-always-const.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//@ check-pass

#![feature(const_trait_impl)]

#[const_trait]
trait A where Self::Assoc: const B {
type Assoc;
}

#[const_trait]
trait B {}

fn needs_b<T: const B>() {}

fn test<T: A>() {
needs_b::<T::Assoc>();
}

fn main() {}
Loading