Skip to content

Commit 7ea7435

Browse files
authored
Rollup merge of #143895 - compiler-errors:trait-wc-item-bound-host-eff, r=oli-obk
Dont collect assoc ty item bounds from trait where clause for host effect predicates For background, we uplift `where Self::Assoc: Trait` bounds in a trait's where clauses into *item bounds* on `type Assoc;`. This is because before we *had* syntactical item bounds, users would express their item bounds like so. Let's opt out of doing this same behavior for `HostEffect` predicates like `where Self::Assoc: [const] Trait`. I left a comment in the code: ```rust // 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. ``` As an aside, this was an ICE that was only triggerable when building libraries and not binaries because we never were calling `tcx.ensure_ok().explicit_implied_const_bounds(def_id);` on associated types like we should have been. I adjusted the calls to `ensure_ok` to make sure this happens, so we catch bugs like this in the future more easily. As another aside, I fixed the bound uplifting logic for *always const* predicates, since those act like normal clauses and have no notion of conditional constness. r? ```@oli-obk``` ```@fee1-dead``` or anyone really Fixes #133275
2 parents 36a362b + 8daf98b commit 7ea7435

File tree

6 files changed

+73
-54
lines changed

6 files changed

+73
-54
lines changed

compiler/rustc_hir_analysis/src/check/check.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -889,8 +889,6 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
889889
tcx.ensure_ok().predicates_of(def_id);
890890
tcx.ensure_ok().explicit_item_bounds(def_id);
891891
tcx.ensure_ok().explicit_item_self_bounds(def_id);
892-
tcx.ensure_ok().item_bounds(def_id);
893-
tcx.ensure_ok().item_self_bounds(def_id);
894892
if tcx.is_conditionally_const(def_id) {
895893
tcx.ensure_ok().explicit_implied_const_bounds(def_id);
896894
tcx.ensure_ok().const_conditions(def_id);
@@ -1044,8 +1042,12 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
10441042
let has_type = match assoc_item.container {
10451043
ty::AssocItemContainer::Impl => true,
10461044
ty::AssocItemContainer::Trait => {
1047-
tcx.ensure_ok().item_bounds(def_id);
1048-
tcx.ensure_ok().item_self_bounds(def_id);
1045+
tcx.ensure_ok().explicit_item_bounds(def_id);
1046+
tcx.ensure_ok().explicit_item_self_bounds(def_id);
1047+
if tcx.is_conditionally_const(def_id) {
1048+
tcx.ensure_ok().explicit_implied_const_bounds(def_id);
1049+
tcx.ensure_ok().const_conditions(def_id);
1050+
}
10491051
res = res.and(check_trait_item(tcx, def_id));
10501052
assoc_item.defaultness(tcx).has_value()
10511053
}

compiler/rustc_hir_analysis/src/collect/item_bounds.rs

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,13 @@ fn associated_type_bounds<'tcx>(
3838
let icx = ItemCtxt::new(tcx, assoc_item_def_id);
3939
let mut bounds = Vec::new();
4040
icx.lowerer().lower_bounds(item_ty, hir_bounds, &mut bounds, ty::List::empty(), filter);
41-
// Implicit bounds are added to associated types unless a `?Trait` bound is found
41+
4242
match filter {
4343
PredicateFilter::All
4444
| PredicateFilter::SelfOnly
4545
| PredicateFilter::SelfTraitThatDefines(_)
4646
| PredicateFilter::SelfAndAssociatedTypeBounds => {
47+
// Implicit bounds are added to associated types unless a `?Trait` bound is found.
4748
icx.lowerer().add_sizedness_bounds(
4849
&mut bounds,
4950
item_ty,
@@ -53,37 +54,48 @@ fn associated_type_bounds<'tcx>(
5354
span,
5455
);
5556
icx.lowerer().add_default_traits(&mut bounds, item_ty, hir_bounds, None, span);
57+
58+
// Also collect `where Self::Assoc: Trait` from the parent trait's where clauses.
59+
let trait_def_id = tcx.local_parent(assoc_item_def_id);
60+
let trait_predicates = tcx.trait_explicit_predicates_and_bounds(trait_def_id);
61+
62+
let item_trait_ref =
63+
ty::TraitRef::identity(tcx, tcx.parent(assoc_item_def_id.to_def_id()));
64+
bounds.extend(trait_predicates.predicates.iter().copied().filter_map(
65+
|(clause, span)| {
66+
remap_gat_vars_and_recurse_into_nested_projections(
67+
tcx,
68+
filter,
69+
item_trait_ref,
70+
assoc_item_def_id,
71+
span,
72+
clause,
73+
)
74+
},
75+
));
5676
}
5777
// `ConstIfConst` is only interested in `[const]` bounds.
58-
PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {}
78+
PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {
79+
// FIXME(const_trait_impl): We *could* uplift the
80+
// `where Self::Assoc: [const] Trait` bounds from the parent trait
81+
// here too, but we'd need to split `const_conditions` into two
82+
// queries (like we do for `trait_explicit_predicates_and_bounds`)
83+
// since we need to also filter the predicates *out* of the const
84+
// conditions or they lead to cycles in the trait solver when
85+
// utilizing these bounds. For now, let's do nothing.
86+
}
5987
}
6088

61-
let trait_def_id = tcx.local_parent(assoc_item_def_id);
62-
let trait_predicates = tcx.trait_explicit_predicates_and_bounds(trait_def_id);
63-
64-
let item_trait_ref = ty::TraitRef::identity(tcx, tcx.parent(assoc_item_def_id.to_def_id()));
65-
let bounds_from_parent =
66-
trait_predicates.predicates.iter().copied().filter_map(|(clause, span)| {
67-
remap_gat_vars_and_recurse_into_nested_projections(
68-
tcx,
69-
filter,
70-
item_trait_ref,
71-
assoc_item_def_id,
72-
span,
73-
clause,
74-
)
75-
});
76-
77-
let all_bounds = tcx.arena.alloc_from_iter(bounds.into_iter().chain(bounds_from_parent));
89+
let bounds = tcx.arena.alloc_from_iter(bounds);
7890
debug!(
7991
"associated_type_bounds({}) = {:?}",
8092
tcx.def_path_str(assoc_item_def_id.to_def_id()),
81-
all_bounds
93+
bounds
8294
);
8395

84-
assert_only_contains_predicates_from(filter, all_bounds, item_ty);
96+
assert_only_contains_predicates_from(filter, bounds, item_ty);
8597

86-
all_bounds
98+
bounds
8799
})
88100
}
89101

@@ -112,6 +124,7 @@ fn remap_gat_vars_and_recurse_into_nested_projections<'tcx>(
112124
ty::ClauseKind::Trait(tr) => tr.self_ty(),
113125
ty::ClauseKind::Projection(proj) => proj.projection_term.self_ty(),
114126
ty::ClauseKind::TypeOutlives(outlives) => outlives.0,
127+
ty::ClauseKind::HostEffect(host) => host.self_ty(),
115128
_ => return None,
116129
};
117130

tests/crashes/133275-1.rs

Lines changed: 0 additions & 13 deletions
This file was deleted.

tests/crashes/133275-2.rs

Lines changed: 0 additions & 15 deletions
This file was deleted.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//@ check-pass
2+
3+
#![feature(const_clone)]
4+
#![feature(const_trait_impl)]
5+
6+
#[const_trait]
7+
trait A where Self::Target: [const] Clone {
8+
type Target;
9+
}
10+
11+
const fn foo<T>() where T: [const] A {}
12+
13+
fn main() {}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//@ check-pass
2+
3+
#![feature(const_trait_impl)]
4+
5+
#[const_trait]
6+
trait A where Self::Assoc: const B {
7+
type Assoc;
8+
}
9+
10+
#[const_trait]
11+
trait B {}
12+
13+
fn needs_b<T: const B>() {}
14+
15+
fn test<T: A>() {
16+
needs_b::<T::Assoc>();
17+
}
18+
19+
fn main() {}

0 commit comments

Comments
 (0)