Skip to content

Commit 2e9a6da

Browse files
committed
Auto merge of rust-lang#129532 - compiler-errors:remove-predicate-queries, r=<try>
Remove predicate queries Removes: * `predicates_defined_on` - Not necessary. Literally unused. * `trait_explicit_predicates_and_bounds` - Not necessary technically. The side-effect of this is that we now don't remove `where Self::Assoc: Bound` item bounds from the where clauses of traits. This may require more trait solving to be done, but should be fine. Let's see what the fallout of this is. r? `@ghost`
2 parents 748c548 + 8ca62f0 commit 2e9a6da

9 files changed

+105
-138
lines changed

compiler/rustc_hir_analysis/src/collect.rs

-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ pub fn provide(providers: &mut Providers) {
7575
explicit_implied_predicates_of: predicates_of::explicit_implied_predicates_of,
7676
explicit_supertraits_containing_assoc_item:
7777
predicates_of::explicit_supertraits_containing_assoc_item,
78-
trait_explicit_predicates_and_bounds: predicates_of::trait_explicit_predicates_and_bounds,
7978
type_param_predicates: predicates_of::type_param_predicates,
8079
trait_def,
8180
adt_def,

compiler/rustc_hir_analysis/src/collect/item_bounds.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ fn associated_type_bounds<'tcx>(
3838
icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span);
3939

4040
let trait_def_id = tcx.local_parent(assoc_item_def_id);
41-
let trait_predicates = tcx.trait_explicit_predicates_and_bounds(trait_def_id);
41+
let trait_predicates = tcx.predicates_of(trait_def_id);
4242

4343
let bounds_from_parent = trait_predicates.predicates.iter().copied().filter(|(pred, _)| {
4444
match pred.kind().skip_binder() {

compiler/rustc_hir_analysis/src/collect/predicates_of.rs

+48-107
Original file line numberDiff line numberDiff line change
@@ -459,122 +459,63 @@ fn const_evaluatable_predicates_of(
459459
collector.preds
460460
}
461461

462-
pub(super) fn trait_explicit_predicates_and_bounds(
463-
tcx: TyCtxt<'_>,
464-
def_id: LocalDefId,
465-
) -> ty::GenericPredicates<'_> {
466-
assert_eq!(tcx.def_kind(def_id), DefKind::Trait);
467-
gather_explicit_predicates_of(tcx, def_id)
468-
}
469-
470462
pub(super) fn explicit_predicates_of<'tcx>(
471463
tcx: TyCtxt<'tcx>,
472464
def_id: LocalDefId,
473465
) -> ty::GenericPredicates<'tcx> {
474466
let def_kind = tcx.def_kind(def_id);
475-
if let DefKind::Trait = def_kind {
476-
// Remove bounds on associated types from the predicates, they will be
477-
// returned by `explicit_item_bounds`.
478-
let predicates_and_bounds = tcx.trait_explicit_predicates_and_bounds(def_id);
479-
let trait_identity_args = ty::GenericArgs::identity_for_item(tcx, def_id);
480-
481-
let is_assoc_item_ty = |ty: Ty<'tcx>| {
482-
// For a predicate from a where clause to become a bound on an
483-
// associated type:
484-
// * It must use the identity args of the item.
485-
// * We're in the scope of the trait, so we can't name any
486-
// parameters of the GAT. That means that all we need to
487-
// check are that the args of the projection are the
488-
// identity args of the trait.
489-
// * It must be an associated type for this trait (*not* a
490-
// supertrait).
491-
if let ty::Alias(ty::Projection, projection) = ty.kind() {
492-
projection.args == trait_identity_args
493-
// FIXME(return_type_notation): This check should be more robust
494-
&& !tcx.is_impl_trait_in_trait(projection.def_id)
495-
&& tcx.associated_item(projection.def_id).container_id(tcx)
496-
== def_id.to_def_id()
497-
} else {
498-
false
499-
}
500-
};
501-
502-
let predicates: Vec<_> = predicates_and_bounds
467+
if matches!(def_kind, DefKind::AnonConst)
468+
&& tcx.features().generic_const_exprs
469+
&& let Some(defaulted_param_def_id) =
470+
tcx.hir().opt_const_param_default_param_def_id(tcx.local_def_id_to_hir_id(def_id))
471+
{
472+
// In `generics_of` we set the generics' parent to be our parent's parent which means that
473+
// we lose out on the predicates of our actual parent if we dont return those predicates here.
474+
// (See comment in `generics_of` for more information on why the parent shenanigans is necessary)
475+
//
476+
// struct Foo<T, const N: usize = { <T as Trait>::ASSOC }>(T) where T: Trait;
477+
// ^^^ ^^^^^^^^^^^^^^^^^^^^^^^ the def id we are calling
478+
// ^^^ explicit_predicates_of on
479+
// parent item we dont have set as the
480+
// parent of generics returned by `generics_of`
481+
//
482+
// In the above code we want the anon const to have predicates in its param env for `T: Trait`
483+
// and we would be calling `explicit_predicates_of(Foo)` here
484+
let parent_def_id = tcx.local_parent(def_id);
485+
let parent_preds = tcx.explicit_predicates_of(parent_def_id);
486+
487+
// If we dont filter out `ConstArgHasType` predicates then every single defaulted const parameter
488+
// will ICE because of #106994. FIXME(generic_const_exprs): remove this when a more general solution
489+
// to #106994 is implemented.
490+
let filtered_predicates = parent_preds
503491
.predicates
504-
.iter()
505-
.copied()
506-
.filter(|(pred, _)| match pred.kind().skip_binder() {
507-
ty::ClauseKind::Trait(tr) => !is_assoc_item_ty(tr.self_ty()),
508-
ty::ClauseKind::Projection(proj) => {
509-
!is_assoc_item_ty(proj.projection_term.self_ty())
510-
}
511-
ty::ClauseKind::TypeOutlives(outlives) => !is_assoc_item_ty(outlives.0),
512-
_ => true,
513-
})
514-
.collect();
515-
if predicates.len() == predicates_and_bounds.predicates.len() {
516-
predicates_and_bounds
517-
} else {
518-
ty::GenericPredicates {
519-
parent: predicates_and_bounds.parent,
520-
predicates: tcx.arena.alloc_slice(&predicates),
521-
effects_min_tys: predicates_and_bounds.effects_min_tys,
522-
}
523-
}
524-
} else {
525-
if matches!(def_kind, DefKind::AnonConst)
526-
&& tcx.features().generic_const_exprs
527-
&& let Some(defaulted_param_def_id) =
528-
tcx.hir().opt_const_param_default_param_def_id(tcx.local_def_id_to_hir_id(def_id))
529-
{
530-
// In `generics_of` we set the generics' parent to be our parent's parent which means that
531-
// we lose out on the predicates of our actual parent if we dont return those predicates here.
532-
// (See comment in `generics_of` for more information on why the parent shenanigans is necessary)
533-
//
534-
// struct Foo<T, const N: usize = { <T as Trait>::ASSOC }>(T) where T: Trait;
535-
// ^^^ ^^^^^^^^^^^^^^^^^^^^^^^ the def id we are calling
536-
// ^^^ explicit_predicates_of on
537-
// parent item we dont have set as the
538-
// parent of generics returned by `generics_of`
539-
//
540-
// In the above code we want the anon const to have predicates in its param env for `T: Trait`
541-
// and we would be calling `explicit_predicates_of(Foo)` here
542-
let parent_def_id = tcx.local_parent(def_id);
543-
let parent_preds = tcx.explicit_predicates_of(parent_def_id);
544-
545-
// If we dont filter out `ConstArgHasType` predicates then every single defaulted const parameter
546-
// will ICE because of #106994. FIXME(generic_const_exprs): remove this when a more general solution
547-
// to #106994 is implemented.
548-
let filtered_predicates = parent_preds
549-
.predicates
550-
.into_iter()
551-
.filter(|(pred, _)| {
552-
if let ty::ClauseKind::ConstArgHasType(ct, _) = pred.kind().skip_binder() {
553-
match ct.kind() {
554-
ty::ConstKind::Param(param_const) => {
555-
let defaulted_param_idx = tcx
556-
.generics_of(parent_def_id)
557-
.param_def_id_to_index[&defaulted_param_def_id.to_def_id()];
558-
param_const.index < defaulted_param_idx
559-
}
560-
_ => bug!(
561-
"`ConstArgHasType` in `predicates_of`\
562-
that isn't a `Param` const"
563-
),
492+
.into_iter()
493+
.filter(|(pred, _)| {
494+
if let ty::ClauseKind::ConstArgHasType(ct, _) = pred.kind().skip_binder() {
495+
match ct.kind() {
496+
ty::ConstKind::Param(param_const) => {
497+
let defaulted_param_idx = tcx
498+
.generics_of(parent_def_id)
499+
.param_def_id_to_index[&defaulted_param_def_id.to_def_id()];
500+
param_const.index < defaulted_param_idx
564501
}
565-
} else {
566-
true
502+
_ => bug!(
503+
"`ConstArgHasType` in `predicates_of`\
504+
that isn't a `Param` const"
505+
),
567506
}
568-
})
569-
.cloned();
570-
return GenericPredicates {
571-
parent: parent_preds.parent,
572-
predicates: { tcx.arena.alloc_from_iter(filtered_predicates) },
573-
effects_min_tys: parent_preds.effects_min_tys,
574-
};
575-
}
576-
gather_explicit_predicates_of(tcx, def_id)
507+
} else {
508+
true
509+
}
510+
})
511+
.cloned();
512+
return GenericPredicates {
513+
parent: parent_preds.parent,
514+
predicates: { tcx.arena.alloc_from_iter(filtered_predicates) },
515+
effects_min_tys: parent_preds.effects_min_tys,
516+
};
577517
}
518+
gather_explicit_predicates_of(tcx, def_id)
578519
}
579520

580521
/// Ensures that the super-predicates of the trait with a `DefId`

compiler/rustc_middle/src/query/mod.rs

-18
Original file line numberDiff line numberDiff line change
@@ -608,24 +608,6 @@ rustc_queries! {
608608
desc { "getting wasm import module map" }
609609
}
610610

611-
/// Returns everything that looks like a predicate written explicitly
612-
/// by the user on a trait item.
613-
///
614-
/// Traits are unusual, because predicates on associated types are
615-
/// converted into bounds on that type for backwards compatibility:
616-
///
617-
/// trait X where Self::U: Copy { type U; }
618-
///
619-
/// becomes
620-
///
621-
/// trait X { type U: Copy; }
622-
///
623-
/// `explicit_predicates_of` and `explicit_item_bounds` will then take
624-
/// the appropriate subsets of the predicates here.
625-
query trait_explicit_predicates_and_bounds(key: LocalDefId) -> ty::GenericPredicates<'tcx> {
626-
desc { |tcx| "computing explicit predicates of trait `{}`", tcx.def_path_str(key) }
627-
}
628-
629611
/// Returns the predicates written explicitly by the user.
630612
///
631613
/// You should probably use `predicates_of` unless you're looking for

tests/ui/associated-types/point-at-type-on-obligation-failure-2.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ trait Foo {
55
}
66

77
impl Foo for () {
8-
type Assoc = bool; //~ ERROR the trait bound `bool: Bar` is not satisfied
8+
type Assoc = bool;
9+
//~^ ERROR the trait bound `bool: Bar` is not satisfied
910
}
1011

1112
trait Baz
@@ -16,7 +17,9 @@ where
1617
}
1718

1819
impl Baz for () {
19-
type Assoc = bool; //~ ERROR the trait bound `bool: Bar` is not satisfied
20+
type Assoc = bool;
21+
//~^ ERROR the trait bound `bool: Bar` is not satisfied
22+
//~| ERROR the trait bound `bool: Bar` is not satisfied
2023
}
2124

2225
trait Bat
@@ -27,7 +30,9 @@ where
2730
}
2831

2932
impl Bat for () {
30-
type Assoc = bool; //~ ERROR the trait bound `bool: Bar` is not satisfied
33+
type Assoc = bool;
34+
//~^ ERROR the trait bound `bool: Bar` is not satisfied
35+
//~| ERROR the trait bound `bool: Bar` is not satisfied
3136
}
3237

3338
fn main() {}

tests/ui/associated-types/point-at-type-on-obligation-failure-2.stderr

+45-5
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,27 @@ LL | type Assoc: Bar;
1616
| ^^^ required by this bound in `Foo::Assoc`
1717

1818
error[E0277]: the trait bound `bool: Bar` is not satisfied
19-
--> $DIR/point-at-type-on-obligation-failure-2.rs:19:18
19+
--> $DIR/point-at-type-on-obligation-failure-2.rs:20:18
20+
|
21+
LL | type Assoc = bool;
22+
| ^^^^ the trait `Bar` is not implemented for `bool`, which is required by `<() as Baz>::Assoc: Bar`
23+
|
24+
help: this trait has no implementations, consider adding one
25+
--> $DIR/point-at-type-on-obligation-failure-2.rs:1:1
26+
|
27+
LL | trait Bar {}
28+
| ^^^^^^^^^
29+
note: required by a bound in `Baz`
30+
--> $DIR/point-at-type-on-obligation-failure-2.rs:14:18
31+
|
32+
LL | trait Baz
33+
| --- required by a bound in this trait
34+
LL | where
35+
LL | Self::Assoc: Bar,
36+
| ^^^ required by this bound in `Baz`
37+
38+
error[E0277]: the trait bound `bool: Bar` is not satisfied
39+
--> $DIR/point-at-type-on-obligation-failure-2.rs:20:18
2040
|
2141
LL | type Assoc = bool;
2242
| ^^^^ the trait `Bar` is not implemented for `bool`
@@ -27,7 +47,7 @@ help: this trait has no implementations, consider adding one
2747
LL | trait Bar {}
2848
| ^^^^^^^^^
2949
note: required by a bound in `Baz::Assoc`
30-
--> $DIR/point-at-type-on-obligation-failure-2.rs:13:18
50+
--> $DIR/point-at-type-on-obligation-failure-2.rs:14:18
3151
|
3252
LL | Self::Assoc: Bar,
3353
| ^^^ required by this bound in `Baz::Assoc`
@@ -36,7 +56,27 @@ LL | type Assoc;
3656
| ----- required by a bound in this associated type
3757

3858
error[E0277]: the trait bound `bool: Bar` is not satisfied
39-
--> $DIR/point-at-type-on-obligation-failure-2.rs:30:18
59+
--> $DIR/point-at-type-on-obligation-failure-2.rs:33:18
60+
|
61+
LL | type Assoc = bool;
62+
| ^^^^ the trait `Bar` is not implemented for `bool`, which is required by `<() as Bat>::Assoc: Bar`
63+
|
64+
help: this trait has no implementations, consider adding one
65+
--> $DIR/point-at-type-on-obligation-failure-2.rs:1:1
66+
|
67+
LL | trait Bar {}
68+
| ^^^^^^^^^
69+
note: required by a bound in `Bat`
70+
--> $DIR/point-at-type-on-obligation-failure-2.rs:27:27
71+
|
72+
LL | trait Bat
73+
| --- required by a bound in this trait
74+
LL | where
75+
LL | <Self as Bat>::Assoc: Bar,
76+
| ^^^ required by this bound in `Bat`
77+
78+
error[E0277]: the trait bound `bool: Bar` is not satisfied
79+
--> $DIR/point-at-type-on-obligation-failure-2.rs:33:18
4080
|
4181
LL | type Assoc = bool;
4282
| ^^^^ the trait `Bar` is not implemented for `bool`
@@ -47,14 +87,14 @@ help: this trait has no implementations, consider adding one
4787
LL | trait Bar {}
4888
| ^^^^^^^^^
4989
note: required by a bound in `Bat::Assoc`
50-
--> $DIR/point-at-type-on-obligation-failure-2.rs:24:27
90+
--> $DIR/point-at-type-on-obligation-failure-2.rs:27:27
5191
|
5292
LL | <Self as Bat>::Assoc: Bar,
5393
| ^^^ required by this bound in `Bat::Assoc`
5494
LL | {
5595
LL | type Assoc;
5696
| ----- required by a bound in this associated type
5797

58-
error: aborting due to 3 previous errors
98+
error: aborting due to 5 previous errors
5999

60100
For more information about this error, try `rustc --explain E0277`.

tests/ui/const-generics/not_wf_param_in_rpitit.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ LL | trait Trait<const N: Trait = bar> {
1111
| ^^^^^
1212
|
1313
= note: ...which immediately requires computing type of `Trait::N` again
14-
note: cycle used when computing explicit predicates of trait `Trait`
14+
note: cycle used when computing explicit predicates of `Trait`
1515
--> $DIR/not_wf_param_in_rpitit.rs:3:1
1616
|
1717
LL | trait Trait<const N: Trait = bar> {

tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ LL | trait Trait<const N: Trait = bar> {
4646
| ^^^^^
4747
|
4848
= note: ...which immediately requires computing type of `Trait::N` again
49-
note: cycle used when computing explicit predicates of trait `Trait`
49+
note: cycle used when computing explicit predicates of `Trait`
5050
--> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:1:1
5151
|
5252
LL | trait Trait<const N: Trait = bar> {

tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ note: ...which requires computing type of `Bar::M`...
3737
LL | trait Bar<const M: Foo<2>> {}
3838
| ^^^^^^^^^^^^^^^
3939
= note: ...which again requires computing type of `Foo::N`, completing the cycle
40-
note: cycle used when computing explicit predicates of trait `Foo`
40+
note: cycle used when computing explicit predicates of `Foo`
4141
--> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:2:1
4242
|
4343
LL | trait Foo<const N: Bar<2>> {

0 commit comments

Comments
 (0)