Skip to content

Commit 8104373

Browse files
committed
Auto merge of #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 f167efa + 8ca62f0 commit 8104373

11 files changed

+127
-201
lines changed

compiler/rustc_hir_analysis/src/collect.rs

+1-31
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use rustc_infer::traits::ObligationCause;
3434
use rustc_middle::hir::nested_filter;
3535
use rustc_middle::query::Providers;
3636
use rustc_middle::ty::util::{Discr, IntTypeExt};
37-
use rustc_middle::ty::{self, AdtKind, Const, IsSuggestable, Ty, TyCtxt, Upcast};
37+
use rustc_middle::ty::{self, AdtKind, Const, IsSuggestable, Ty, TyCtxt};
3838
use rustc_middle::{bug, span_bug};
3939
use rustc_span::symbol::{kw, sym, Ident, Symbol};
4040
use rustc_span::{Span, DUMMY_SP};
@@ -70,13 +70,11 @@ pub fn provide(providers: &mut Providers) {
7070
impl_super_outlives: item_bounds::impl_super_outlives,
7171
generics_of: generics_of::generics_of,
7272
predicates_of: predicates_of::predicates_of,
73-
predicates_defined_on,
7473
explicit_predicates_of: predicates_of::explicit_predicates_of,
7574
explicit_super_predicates_of: predicates_of::explicit_super_predicates_of,
7675
explicit_implied_predicates_of: predicates_of::explicit_implied_predicates_of,
7776
explicit_supertraits_containing_assoc_item:
7877
predicates_of::explicit_supertraits_containing_assoc_item,
79-
trait_explicit_predicates_and_bounds: predicates_of::trait_explicit_predicates_and_bounds,
8078
type_param_predicates: predicates_of::type_param_predicates,
8179
trait_def,
8280
adt_def,
@@ -1775,34 +1773,6 @@ fn early_bound_lifetimes_from_generics<'a, 'tcx: 'a>(
17751773
})
17761774
}
17771775

1778-
/// Returns a list of type predicates for the definition with ID `def_id`, including inferred
1779-
/// lifetime constraints. This includes all predicates returned by `explicit_predicates_of`, plus
1780-
/// inferred constraints concerning which regions outlive other regions.
1781-
#[instrument(level = "debug", skip(tcx))]
1782-
fn predicates_defined_on(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> {
1783-
let mut result = tcx.explicit_predicates_of(def_id);
1784-
debug!("predicates_defined_on: explicit_predicates_of({:?}) = {:?}", def_id, result);
1785-
let inferred_outlives = tcx.inferred_outlives_of(def_id);
1786-
if !inferred_outlives.is_empty() {
1787-
debug!(
1788-
"predicates_defined_on: inferred_outlives_of({:?}) = {:?}",
1789-
def_id, inferred_outlives,
1790-
);
1791-
let inferred_outlives_iter =
1792-
inferred_outlives.iter().map(|(clause, span)| ((*clause).upcast(tcx), *span));
1793-
if result.predicates.is_empty() {
1794-
result.predicates = tcx.arena.alloc_from_iter(inferred_outlives_iter);
1795-
} else {
1796-
result.predicates = tcx.arena.alloc_from_iter(
1797-
result.predicates.into_iter().copied().chain(inferred_outlives_iter),
1798-
);
1799-
}
1800-
}
1801-
1802-
debug!("predicates_defined_on({:?}) = {:?}", def_id, result);
1803-
result
1804-
}
1805-
18061776
fn compute_sig_of_foreign_fn_decl<'tcx>(
18071777
tcx: TyCtxt<'tcx>,
18081778
def_id: LocalDefId,

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

+69-111
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,26 @@ use crate::delegation::inherit_predicates_for_delegation_item;
1818
use crate::hir_ty_lowering::{HirTyLowerer, OnlySelfBounds, PredicateFilter, RegionInferReason};
1919

2020
/// Returns a list of all type predicates (explicit and implicit) for the definition with
21-
/// ID `def_id`. This includes all predicates returned by `predicates_defined_on`, plus
22-
/// `Self: Trait` predicates for traits.
21+
/// ID `def_id`. This includes all predicates returned by `explicit_predicates_of`, plus
22+
/// inferred constraints concerning which regions outlive other regions.
23+
#[instrument(level = "debug", skip(tcx))]
2324
pub(super) fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> {
24-
let mut result = tcx.predicates_defined_on(def_id);
25+
let mut result = tcx.explicit_predicates_of(def_id);
26+
debug!("predicates_of: explicit_predicates_of({:?}) = {:?}", def_id, result);
27+
28+
let inferred_outlives = tcx.inferred_outlives_of(def_id);
29+
if !inferred_outlives.is_empty() {
30+
debug!("predicates_of: inferred_outlives_of({:?}) = {:?}", def_id, inferred_outlives,);
31+
let inferred_outlives_iter =
32+
inferred_outlives.iter().map(|(clause, span)| ((*clause).upcast(tcx), *span));
33+
if result.predicates.is_empty() {
34+
result.predicates = tcx.arena.alloc_from_iter(inferred_outlives_iter);
35+
} else {
36+
result.predicates = tcx.arena.alloc_from_iter(
37+
result.predicates.into_iter().copied().chain(inferred_outlives_iter),
38+
);
39+
}
40+
}
2541

2642
if tcx.is_trait(def_id) {
2743
// For traits, add `Self: Trait` predicate. This is
@@ -51,7 +67,8 @@ pub(super) fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredic
5167
.chain(std::iter::once((ty::TraitRef::identity(tcx, def_id).upcast(tcx), span))),
5268
);
5369
}
54-
debug!("predicates_of(def_id={:?}) = {:?}", def_id, result);
70+
71+
debug!("predicates_of({:?}) = {:?}", def_id, result);
5572
result
5673
}
5774

@@ -442,122 +459,63 @@ fn const_evaluatable_predicates_of(
442459
collector.preds
443460
}
444461

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

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

compiler/rustc_middle/src/query/mod.rs

-37
Original file line numberDiff line numberDiff line change
@@ -312,17 +312,6 @@ rustc_queries! {
312312
/// predicates (where-clauses) that must be proven true in order
313313
/// to reference it. This is almost always the "predicates query"
314314
/// that you want.
315-
///
316-
/// `predicates_of` builds on `predicates_defined_on` -- in fact,
317-
/// it is almost always the same as that query, except for the
318-
/// case of traits. For traits, `predicates_of` contains
319-
/// an additional `Self: Trait<...>` predicate that users don't
320-
/// actually write. This reflects the fact that to invoke the
321-
/// trait (e.g., via `Default::default`) you must supply types
322-
/// that actually implement the trait. (However, this extra
323-
/// predicate gets in the way of some checks, which are intended
324-
/// to operate over only the actual where-clauses written by the
325-
/// user.)
326315
query predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> {
327316
desc { |tcx| "computing predicates of `{}`", tcx.def_path_str(key) }
328317
cache_on_disk_if { key.is_local() }
@@ -617,32 +606,6 @@ rustc_queries! {
617606
desc { "getting wasm import module map" }
618607
}
619608

620-
/// Maps from the `DefId` of an item (trait/struct/enum/fn) to the
621-
/// predicates (where-clauses) directly defined on it. This is
622-
/// equal to the `explicit_predicates_of` predicates plus the
623-
/// `inferred_outlives_of` predicates.
624-
query predicates_defined_on(key: DefId) -> ty::GenericPredicates<'tcx> {
625-
desc { |tcx| "computing predicates of `{}`", tcx.def_path_str(key) }
626-
}
627-
628-
/// Returns everything that looks like a predicate written explicitly
629-
/// by the user on a trait item.
630-
///
631-
/// Traits are unusual, because predicates on associated types are
632-
/// converted into bounds on that type for backwards compatibility:
633-
///
634-
/// trait X where Self::U: Copy { type U; }
635-
///
636-
/// becomes
637-
///
638-
/// trait X { type U: Copy; }
639-
///
640-
/// `explicit_predicates_of` and `explicit_item_bounds` will then take
641-
/// the appropriate subsets of the predicates here.
642-
query trait_explicit_predicates_and_bounds(key: LocalDefId) -> ty::GenericPredicates<'tcx> {
643-
desc { |tcx| "computing explicit predicates of trait `{}`", tcx.def_path_str(key) }
644-
}
645-
646609
/// Returns the predicates written explicitly by the user.
647610
///
648611
/// You should probably use `predicates_of` unless you're looking for

tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr

-5
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,6 @@ error[E0391]: cycle detected when computing predicates of `Foo`
44
LL | struct Foo {
55
| ^^^^^^^^^^
66
|
7-
note: ...which requires computing predicates of `Foo`...
8-
--> $DIR/cycle-iat-inside-of-adt.rs:7:1
9-
|
10-
LL | struct Foo {
11-
| ^^^^^^^^^^
127
note: ...which requires computing inferred outlives predicates of `Foo`...
138
--> $DIR/cycle-iat-inside-of-adt.rs:7:1
149
|

tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-where-predicate.stderr

-5
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,6 @@ error[E0391]: cycle detected when computing predicates of `user`
44
LL | fn user<T>() where S<T>::P: std::fmt::Debug {}
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66
|
7-
note: ...which requires computing predicates of `user`...
8-
--> $DIR/cycle-iat-inside-of-where-predicate.rs:8:1
9-
|
10-
LL | fn user<T>() where S<T>::P: std::fmt::Debug {}
11-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
127
note: ...which requires computing explicit predicates of `user`...
138
--> $DIR/cycle-iat-inside-of-where-predicate.rs:8:1
149
|

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() {}

0 commit comments

Comments
 (0)