Rollup merge of #127045 - compiler-errors:explicit, r=oli-obk
Rename `super_predicates_of` and similar queries to `explicit_*` to note that they're not elaborated Rename: * `super_predicates_of` -> `explicit_super_predicates_of` * `implied_predicates_of` -> `explicit_implied_predicates_of` * `supertraits_containing_assoc_item` -> `explicit_supertraits_containing_assoc_item` This makes it clearer that, unlike (for example) [`TyCtxt::super_traits_of`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html#method.super_traits_of), we don't automatically elaborate this set of predicates. r? ``@lcnr`` or ``@oli-obk`` or someone from t-types idc
This commit is contained in:
commit
e9d5a2f45f
22 changed files with 71 additions and 97 deletions
|
@ -70,10 +70,10 @@ pub fn provide(providers: &mut Providers) {
|
||||||
predicates_of: predicates_of::predicates_of,
|
predicates_of: predicates_of::predicates_of,
|
||||||
predicates_defined_on,
|
predicates_defined_on,
|
||||||
explicit_predicates_of: predicates_of::explicit_predicates_of,
|
explicit_predicates_of: predicates_of::explicit_predicates_of,
|
||||||
super_predicates_of: predicates_of::super_predicates_of,
|
explicit_super_predicates_of: predicates_of::explicit_super_predicates_of,
|
||||||
implied_predicates_of: predicates_of::implied_predicates_of,
|
explicit_implied_predicates_of: predicates_of::explicit_implied_predicates_of,
|
||||||
super_predicates_that_define_assoc_item:
|
explicit_supertraits_containing_assoc_item:
|
||||||
predicates_of::super_predicates_that_define_assoc_item,
|
predicates_of::explicit_supertraits_containing_assoc_item,
|
||||||
trait_explicit_predicates_and_bounds: predicates_of::trait_explicit_predicates_and_bounds,
|
trait_explicit_predicates_and_bounds: predicates_of::trait_explicit_predicates_and_bounds,
|
||||||
type_param_predicates: predicates_of::type_param_predicates,
|
type_param_predicates: predicates_of::type_param_predicates,
|
||||||
trait_def,
|
trait_def,
|
||||||
|
@ -691,14 +691,14 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
|
||||||
hir::ItemKind::Trait(..) => {
|
hir::ItemKind::Trait(..) => {
|
||||||
tcx.ensure().generics_of(def_id);
|
tcx.ensure().generics_of(def_id);
|
||||||
tcx.ensure().trait_def(def_id);
|
tcx.ensure().trait_def(def_id);
|
||||||
tcx.at(it.span).super_predicates_of(def_id);
|
tcx.at(it.span).explicit_super_predicates_of(def_id);
|
||||||
tcx.ensure().predicates_of(def_id);
|
tcx.ensure().predicates_of(def_id);
|
||||||
tcx.ensure().associated_items(def_id);
|
tcx.ensure().associated_items(def_id);
|
||||||
}
|
}
|
||||||
hir::ItemKind::TraitAlias(..) => {
|
hir::ItemKind::TraitAlias(..) => {
|
||||||
tcx.ensure().generics_of(def_id);
|
tcx.ensure().generics_of(def_id);
|
||||||
tcx.at(it.span).implied_predicates_of(def_id);
|
tcx.at(it.span).explicit_implied_predicates_of(def_id);
|
||||||
tcx.at(it.span).super_predicates_of(def_id);
|
tcx.at(it.span).explicit_super_predicates_of(def_id);
|
||||||
tcx.ensure().predicates_of(def_id);
|
tcx.ensure().predicates_of(def_id);
|
||||||
}
|
}
|
||||||
hir::ItemKind::Struct(struct_def, _) | hir::ItemKind::Union(struct_def, _) => {
|
hir::ItemKind::Struct(struct_def, _) | hir::ItemKind::Union(struct_def, _) => {
|
||||||
|
|
|
@ -519,21 +519,21 @@ pub(super) fn explicit_predicates_of<'tcx>(
|
||||||
/// Ensures that the super-predicates of the trait with a `DefId`
|
/// Ensures that the super-predicates of the trait with a `DefId`
|
||||||
/// of `trait_def_id` are lowered and stored. This also ensures that
|
/// of `trait_def_id` are lowered and stored. This also ensures that
|
||||||
/// the transitive super-predicates are lowered.
|
/// the transitive super-predicates are lowered.
|
||||||
pub(super) fn super_predicates_of(
|
pub(super) fn explicit_super_predicates_of(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
trait_def_id: LocalDefId,
|
trait_def_id: LocalDefId,
|
||||||
) -> ty::GenericPredicates<'_> {
|
) -> ty::GenericPredicates<'_> {
|
||||||
implied_predicates_with_filter(tcx, trait_def_id.to_def_id(), PredicateFilter::SelfOnly)
|
implied_predicates_with_filter(tcx, trait_def_id.to_def_id(), PredicateFilter::SelfOnly)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn super_predicates_that_define_assoc_item(
|
pub(super) fn explicit_supertraits_containing_assoc_item(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
(trait_def_id, assoc_name): (DefId, Ident),
|
(trait_def_id, assoc_name): (DefId, Ident),
|
||||||
) -> ty::GenericPredicates<'_> {
|
) -> ty::GenericPredicates<'_> {
|
||||||
implied_predicates_with_filter(tcx, trait_def_id, PredicateFilter::SelfThatDefines(assoc_name))
|
implied_predicates_with_filter(tcx, trait_def_id, PredicateFilter::SelfThatDefines(assoc_name))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn implied_predicates_of(
|
pub(super) fn explicit_implied_predicates_of(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
trait_def_id: LocalDefId,
|
trait_def_id: LocalDefId,
|
||||||
) -> ty::GenericPredicates<'_> {
|
) -> ty::GenericPredicates<'_> {
|
||||||
|
@ -560,7 +560,7 @@ pub(super) fn implied_predicates_with_filter(
|
||||||
// if `assoc_name` is None, then the query should've been redirected to an
|
// if `assoc_name` is None, then the query should've been redirected to an
|
||||||
// external provider
|
// external provider
|
||||||
assert!(matches!(filter, PredicateFilter::SelfThatDefines(_)));
|
assert!(matches!(filter, PredicateFilter::SelfThatDefines(_)));
|
||||||
return tcx.super_predicates_of(trait_def_id);
|
return tcx.explicit_super_predicates_of(trait_def_id);
|
||||||
};
|
};
|
||||||
|
|
||||||
let Node::Item(item) = tcx.hir_node_by_def_id(trait_def_id) else {
|
let Node::Item(item) = tcx.hir_node_by_def_id(trait_def_id) else {
|
||||||
|
@ -601,7 +601,7 @@ pub(super) fn implied_predicates_with_filter(
|
||||||
if let ty::ClauseKind::Trait(bound) = pred.kind().skip_binder()
|
if let ty::ClauseKind::Trait(bound) = pred.kind().skip_binder()
|
||||||
&& bound.polarity == ty::PredicatePolarity::Positive
|
&& bound.polarity == ty::PredicatePolarity::Positive
|
||||||
{
|
{
|
||||||
tcx.at(span).super_predicates_of(bound.def_id());
|
tcx.at(span).explicit_super_predicates_of(bound.def_id());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -611,7 +611,7 @@ pub(super) fn implied_predicates_with_filter(
|
||||||
if let ty::ClauseKind::Trait(bound) = pred.kind().skip_binder()
|
if let ty::ClauseKind::Trait(bound) = pred.kind().skip_binder()
|
||||||
&& bound.polarity == ty::PredicatePolarity::Positive
|
&& bound.polarity == ty::PredicatePolarity::Positive
|
||||||
{
|
{
|
||||||
tcx.at(span).implied_predicates_of(bound.def_id());
|
tcx.at(span).explicit_implied_predicates_of(bound.def_id());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1760,7 +1760,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
||||||
if let Some(assoc_item) = trait_defines_associated_item_named(def_id) {
|
if let Some(assoc_item) = trait_defines_associated_item_named(def_id) {
|
||||||
break Some((bound_vars.into_iter().collect(), assoc_item));
|
break Some((bound_vars.into_iter().collect(), assoc_item));
|
||||||
}
|
}
|
||||||
let predicates = tcx.super_predicates_that_define_assoc_item((def_id, assoc_name));
|
let predicates = tcx.explicit_supertraits_containing_assoc_item((def_id, assoc_name));
|
||||||
let obligations = predicates.predicates.iter().filter_map(|&(pred, _)| {
|
let obligations = predicates.predicates.iter().filter_map(|&(pred, _)| {
|
||||||
let bound_predicate = pred.kind();
|
let bound_predicate = pred.kind();
|
||||||
match bound_predicate.skip_binder() {
|
match bound_predicate.skip_binder() {
|
||||||
|
|
|
@ -275,10 +275,10 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
|
||||||
}
|
}
|
||||||
// Get predicates implied by the trait, or only super predicates if we only care about self predicates.
|
// Get predicates implied by the trait, or only super predicates if we only care about self predicates.
|
||||||
let predicates = match self.mode {
|
let predicates = match self.mode {
|
||||||
Filter::All => tcx.implied_predicates_of(data.def_id()),
|
Filter::All => tcx.explicit_implied_predicates_of(data.def_id()),
|
||||||
Filter::OnlySelf => tcx.super_predicates_of(data.def_id()),
|
Filter::OnlySelf => tcx.explicit_super_predicates_of(data.def_id()),
|
||||||
Filter::OnlySelfThatDefines(ident) => {
|
Filter::OnlySelfThatDefines(ident) => {
|
||||||
tcx.super_predicates_that_define_assoc_item((data.def_id(), ident))
|
tcx.explicit_supertraits_containing_assoc_item((data.def_id(), ident))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -420,7 +420,7 @@ pub fn transitive_bounds<'tcx>(
|
||||||
|
|
||||||
/// A specialized variant of `elaborate` that only elaborates trait references that may
|
/// A specialized variant of `elaborate` that only elaborates trait references that may
|
||||||
/// define the given associated item with the name `assoc_name`. It uses the
|
/// define the given associated item with the name `assoc_name`. It uses the
|
||||||
/// `super_predicates_that_define_assoc_item` query to avoid enumerating super-predicates that
|
/// `explicit_supertraits_containing_assoc_item` query to avoid enumerating super-predicates that
|
||||||
/// aren't related to `assoc_item`. This is used when resolving types like `Self::Item` or
|
/// aren't related to `assoc_item`. This is used when resolving types like `Self::Item` or
|
||||||
/// `T::Item` and helps to avoid cycle errors (see e.g. #35237).
|
/// `T::Item` and helps to avoid cycle errors (see e.g. #35237).
|
||||||
pub fn transitive_bounds_that_define_assoc_item<'tcx>(
|
pub fn transitive_bounds_that_define_assoc_item<'tcx>(
|
||||||
|
|
|
@ -45,7 +45,7 @@ impl<'tcx> LateLintPass<'tcx> for MultipleSupertraitUpcastable {
|
||||||
{
|
{
|
||||||
let direct_super_traits_iter = cx
|
let direct_super_traits_iter = cx
|
||||||
.tcx
|
.tcx
|
||||||
.super_predicates_of(def_id)
|
.explicit_super_predicates_of(def_id)
|
||||||
.predicates
|
.predicates
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|(pred, _)| pred.as_trait_clause());
|
.filter_map(|(pred, _)| pred.as_trait_clause());
|
||||||
|
|
|
@ -211,8 +211,8 @@ provide! { tcx, def_id, other, cdata,
|
||||||
explicit_predicates_of => { table }
|
explicit_predicates_of => { table }
|
||||||
generics_of => { table }
|
generics_of => { table }
|
||||||
inferred_outlives_of => { table_defaulted_array }
|
inferred_outlives_of => { table_defaulted_array }
|
||||||
super_predicates_of => { table }
|
explicit_super_predicates_of => { table }
|
||||||
implied_predicates_of => { table }
|
explicit_implied_predicates_of => { table }
|
||||||
type_of => { table }
|
type_of => { table }
|
||||||
type_alias_is_lazy => { cdata.root.tables.type_alias_is_lazy.get(cdata, def_id.index) }
|
type_alias_is_lazy => { cdata.root.tables.type_alias_is_lazy.get(cdata, def_id.index) }
|
||||||
variances_of => { table }
|
variances_of => { table }
|
||||||
|
|
|
@ -1431,8 +1431,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
if let DefKind::Trait = def_kind {
|
if let DefKind::Trait = def_kind {
|
||||||
record!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id));
|
record!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id));
|
||||||
record!(self.tables.super_predicates_of[def_id] <- self.tcx.super_predicates_of(def_id));
|
record!(self.tables.explicit_super_predicates_of[def_id] <- self.tcx.explicit_super_predicates_of(def_id));
|
||||||
record!(self.tables.implied_predicates_of[def_id] <- self.tcx.implied_predicates_of(def_id));
|
record!(self.tables.explicit_implied_predicates_of[def_id] <- self.tcx.explicit_implied_predicates_of(def_id));
|
||||||
|
|
||||||
let module_children = self.tcx.module_children_local(local_id);
|
let module_children = self.tcx.module_children_local(local_id);
|
||||||
record_array!(self.tables.module_children_non_reexports[def_id] <-
|
record_array!(self.tables.module_children_non_reexports[def_id] <-
|
||||||
|
@ -1440,8 +1440,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
if let DefKind::TraitAlias = def_kind {
|
if let DefKind::TraitAlias = def_kind {
|
||||||
record!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id));
|
record!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id));
|
||||||
record!(self.tables.super_predicates_of[def_id] <- self.tcx.super_predicates_of(def_id));
|
record!(self.tables.explicit_super_predicates_of[def_id] <- self.tcx.explicit_super_predicates_of(def_id));
|
||||||
record!(self.tables.implied_predicates_of[def_id] <- self.tcx.implied_predicates_of(def_id));
|
record!(self.tables.explicit_implied_predicates_of[def_id] <- self.tcx.explicit_implied_predicates_of(def_id));
|
||||||
}
|
}
|
||||||
if let DefKind::Trait | DefKind::Impl { .. } = def_kind {
|
if let DefKind::Trait | DefKind::Impl { .. } = def_kind {
|
||||||
let associated_item_def_ids = self.tcx.associated_item_def_ids(def_id);
|
let associated_item_def_ids = self.tcx.associated_item_def_ids(def_id);
|
||||||
|
|
|
@ -416,10 +416,10 @@ define_tables! {
|
||||||
lookup_deprecation_entry: Table<DefIndex, LazyValue<attr::Deprecation>>,
|
lookup_deprecation_entry: Table<DefIndex, LazyValue<attr::Deprecation>>,
|
||||||
explicit_predicates_of: Table<DefIndex, LazyValue<ty::GenericPredicates<'static>>>,
|
explicit_predicates_of: Table<DefIndex, LazyValue<ty::GenericPredicates<'static>>>,
|
||||||
generics_of: Table<DefIndex, LazyValue<ty::Generics>>,
|
generics_of: Table<DefIndex, LazyValue<ty::Generics>>,
|
||||||
super_predicates_of: Table<DefIndex, LazyValue<ty::GenericPredicates<'static>>>,
|
explicit_super_predicates_of: Table<DefIndex, LazyValue<ty::GenericPredicates<'static>>>,
|
||||||
// As an optimization, we only store this for trait aliases,
|
// As an optimization, we only store this for trait aliases,
|
||||||
// since it's identical to super_predicates_of for traits.
|
// since it's identical to explicit_super_predicates_of for traits.
|
||||||
implied_predicates_of: Table<DefIndex, LazyValue<ty::GenericPredicates<'static>>>,
|
explicit_implied_predicates_of: Table<DefIndex, LazyValue<ty::GenericPredicates<'static>>>,
|
||||||
type_of: Table<DefIndex, LazyValue<ty::EarlyBinder<'static, Ty<'static>>>>,
|
type_of: Table<DefIndex, LazyValue<ty::EarlyBinder<'static, Ty<'static>>>>,
|
||||||
variances_of: Table<DefIndex, LazyArray<ty::Variance>>,
|
variances_of: Table<DefIndex, LazyArray<ty::Variance>>,
|
||||||
fn_sig: Table<DefIndex, LazyValue<ty::EarlyBinder<'static, ty::PolyFnSig<'static>>>>,
|
fn_sig: Table<DefIndex, LazyValue<ty::EarlyBinder<'static, ty::PolyFnSig<'static>>>>,
|
||||||
|
|
|
@ -646,6 +646,9 @@ rustc_queries! {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the predicates written explicitly by the user.
|
/// Returns the predicates written explicitly by the user.
|
||||||
|
///
|
||||||
|
/// You should probably use `predicates_of` unless you're looking for
|
||||||
|
/// predicates with explicit spans for diagnostics purposes.
|
||||||
query explicit_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> {
|
query explicit_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> {
|
||||||
desc { |tcx| "computing explicit predicates of `{}`", tcx.def_path_str(key) }
|
desc { |tcx| "computing explicit predicates of `{}`", tcx.def_path_str(key) }
|
||||||
cache_on_disk_if { key.is_local() }
|
cache_on_disk_if { key.is_local() }
|
||||||
|
@ -662,29 +665,32 @@ rustc_queries! {
|
||||||
feedable
|
feedable
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Maps from the `DefId` of a trait to the list of
|
/// Maps from the `DefId` of a trait to the list of super-predicates of the trait,
|
||||||
/// super-predicates. This is a subset of the full list of
|
/// *before* elaboration (so it doesn't contain transitive super-predicates). This
|
||||||
/// predicates. We store these in a separate map because we must
|
/// is a subset of the full list of predicates. We store these in a separate map
|
||||||
/// evaluate them even during type conversion, often before the
|
/// because we must evaluate them even during type conversion, often before the full
|
||||||
/// full predicates are available (note that supertraits have
|
/// predicates are available (note that super-predicates must not be cyclic).
|
||||||
/// additional acyclicity requirements).
|
query explicit_super_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> {
|
||||||
query super_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> {
|
|
||||||
desc { |tcx| "computing the super predicates of `{}`", tcx.def_path_str(key) }
|
desc { |tcx| "computing the super predicates of `{}`", tcx.def_path_str(key) }
|
||||||
cache_on_disk_if { key.is_local() }
|
cache_on_disk_if { key.is_local() }
|
||||||
separate_provide_extern
|
separate_provide_extern
|
||||||
}
|
}
|
||||||
|
|
||||||
query implied_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> {
|
/// The predicates of the trait that are implied during elaboration. This is a
|
||||||
|
/// superset of the super-predicates of the trait, but a subset of the predicates
|
||||||
|
/// of the trait. For regular traits, this includes all super-predicates and their
|
||||||
|
/// associated type bounds. For trait aliases, currently, this includes all of the
|
||||||
|
/// predicates of the trait alias.
|
||||||
|
query explicit_implied_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> {
|
||||||
desc { |tcx| "computing the implied predicates of `{}`", tcx.def_path_str(key) }
|
desc { |tcx| "computing the implied predicates of `{}`", tcx.def_path_str(key) }
|
||||||
cache_on_disk_if { key.is_local() }
|
cache_on_disk_if { key.is_local() }
|
||||||
separate_provide_extern
|
separate_provide_extern
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The `Option<Ident>` is the name of an associated type. If it is `None`, then this query
|
/// The Ident is the name of an associated type.The query returns only the subset
|
||||||
/// returns the full set of predicates. If `Some<Ident>`, then the query returns only the
|
/// of supertraits that define the given associated type. This is used to avoid
|
||||||
/// subset of super-predicates that reference traits that define the given associated type.
|
/// cycles in resolving type-dependent associated item paths like `T::Item`.
|
||||||
/// This is used to avoid cycles in resolving types like `T::Item`.
|
query explicit_supertraits_containing_assoc_item(key: (DefId, rustc_span::symbol::Ident)) -> ty::GenericPredicates<'tcx> {
|
||||||
query super_predicates_that_define_assoc_item(key: (DefId, rustc_span::symbol::Ident)) -> ty::GenericPredicates<'tcx> {
|
|
||||||
desc { |tcx| "computing the super traits of `{}` with associated type name `{}`",
|
desc { |tcx| "computing the super traits of `{}` with associated type name `{}`",
|
||||||
tcx.def_path_str(key.0),
|
tcx.def_path_str(key.0),
|
||||||
key.1
|
key.1
|
||||||
|
|
|
@ -35,7 +35,7 @@ struct Elaborator<'tcx> {
|
||||||
impl<'tcx> Elaborator<'tcx> {
|
impl<'tcx> Elaborator<'tcx> {
|
||||||
fn elaborate(&mut self, trait_ref: PolyTraitRef<'tcx>) {
|
fn elaborate(&mut self, trait_ref: PolyTraitRef<'tcx>) {
|
||||||
let super_predicates =
|
let super_predicates =
|
||||||
self.tcx.super_predicates_of(trait_ref.def_id()).predicates.iter().filter_map(
|
self.tcx.explicit_super_predicates_of(trait_ref.def_id()).predicates.iter().filter_map(
|
||||||
|&(pred, _)| {
|
|&(pred, _)| {
|
||||||
let clause = pred.instantiate_supertrait(self.tcx, trait_ref);
|
let clause = pred.instantiate_supertrait(self.tcx, trait_ref);
|
||||||
self.visited.insert(clause).then_some(clause)
|
self.visited.insert(clause).then_some(clause)
|
||||||
|
|
|
@ -342,12 +342,15 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn super_predicates_of(
|
fn explicit_super_predicates_of(
|
||||||
self,
|
self,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
|
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
|
||||||
ty::EarlyBinder::bind(
|
ty::EarlyBinder::bind(
|
||||||
self.super_predicates_of(def_id).instantiate_identity(self).predicates.into_iter(),
|
self.explicit_super_predicates_of(def_id)
|
||||||
|
.instantiate_identity(self)
|
||||||
|
.predicates
|
||||||
|
.into_iter(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2440,7 +2443,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
/// Given the def_id of a Trait `trait_def_id` and the name of an associated item `assoc_name`
|
/// Given the def_id of a Trait `trait_def_id` and the name of an associated item `assoc_name`
|
||||||
/// returns true if the `trait_def_id` defines an associated item of name `assoc_name`.
|
/// returns true if the `trait_def_id` defines an associated item of name `assoc_name`.
|
||||||
pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
|
pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
|
||||||
self.super_traits_of(trait_def_id).any(|trait_did| {
|
self.supertrait_def_ids(trait_def_id).any(|trait_did| {
|
||||||
self.associated_items(trait_did)
|
self.associated_items(trait_did)
|
||||||
.filter_by_name_unhygienic(assoc_name.name)
|
.filter_by_name_unhygienic(assoc_name.name)
|
||||||
.any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did))
|
.any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did))
|
||||||
|
@ -2463,9 +2466,9 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
|
|
||||||
/// Computes the def-ids of the transitive supertraits of `trait_def_id`. This (intentionally)
|
/// Computes the def-ids of the transitive supertraits of `trait_def_id`. This (intentionally)
|
||||||
/// does not compute the full elaborated super-predicates but just the set of def-ids. It is used
|
/// does not compute the full elaborated super-predicates but just the set of def-ids. It is used
|
||||||
/// to identify which traits may define a given associated type to help avoid cycle errors.
|
/// to identify which traits may define a given associated type to help avoid cycle errors,
|
||||||
/// Returns a `DefId` iterator.
|
/// and to make size estimates for vtable layout computation.
|
||||||
fn super_traits_of(self, trait_def_id: DefId) -> impl Iterator<Item = DefId> + 'tcx {
|
pub fn supertrait_def_ids(self, trait_def_id: DefId) -> impl Iterator<Item = DefId> + 'tcx {
|
||||||
let mut set = FxHashSet::default();
|
let mut set = FxHashSet::default();
|
||||||
let mut stack = vec![trait_def_id];
|
let mut stack = vec![trait_def_id];
|
||||||
|
|
||||||
|
@ -2473,7 +2476,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
|
|
||||||
iter::from_fn(move || -> Option<DefId> {
|
iter::from_fn(move || -> Option<DefId> {
|
||||||
let trait_did = stack.pop()?;
|
let trait_did = stack.pop()?;
|
||||||
let generic_predicates = self.super_predicates_of(trait_did);
|
let generic_predicates = self.explicit_super_predicates_of(trait_did);
|
||||||
|
|
||||||
for (predicate, _) in generic_predicates.predicates {
|
for (predicate, _) in generic_predicates.predicates {
|
||||||
if let ty::ClauseKind::Trait(data) = predicate.kind().skip_binder() {
|
if let ty::ClauseKind::Trait(data) = predicate.kind().skip_binder() {
|
||||||
|
|
|
@ -3,8 +3,6 @@ use std::fmt;
|
||||||
use crate::mir::interpret::{alloc_range, AllocId, Allocation, Pointer, Scalar};
|
use crate::mir::interpret::{alloc_range, AllocId, Allocation, Pointer, Scalar};
|
||||||
use crate::ty::{self, Instance, PolyTraitRef, Ty, TyCtxt};
|
use crate::ty::{self, Instance, PolyTraitRef, Ty, TyCtxt};
|
||||||
use rustc_ast::Mutability;
|
use rustc_ast::Mutability;
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
|
||||||
use rustc_hir::def_id::DefId;
|
|
||||||
use rustc_macros::HashStable;
|
use rustc_macros::HashStable;
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, HashStable)]
|
#[derive(Clone, Copy, PartialEq, HashStable)]
|
||||||
|
@ -42,45 +40,12 @@ impl<'tcx> fmt::Debug for VtblEntry<'tcx> {
|
||||||
impl<'tcx> TyCtxt<'tcx> {
|
impl<'tcx> TyCtxt<'tcx> {
|
||||||
pub const COMMON_VTABLE_ENTRIES: &'tcx [VtblEntry<'tcx>] =
|
pub const COMMON_VTABLE_ENTRIES: &'tcx [VtblEntry<'tcx>] =
|
||||||
&[VtblEntry::MetadataDropInPlace, VtblEntry::MetadataSize, VtblEntry::MetadataAlign];
|
&[VtblEntry::MetadataDropInPlace, VtblEntry::MetadataSize, VtblEntry::MetadataAlign];
|
||||||
|
|
||||||
pub fn supertrait_def_ids(self, trait_def_id: DefId) -> SupertraitDefIds<'tcx> {
|
|
||||||
SupertraitDefIds {
|
|
||||||
tcx: self,
|
|
||||||
stack: vec![trait_def_id],
|
|
||||||
visited: Some(trait_def_id).into_iter().collect(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const COMMON_VTABLE_ENTRIES_DROPINPLACE: usize = 0;
|
pub const COMMON_VTABLE_ENTRIES_DROPINPLACE: usize = 0;
|
||||||
pub const COMMON_VTABLE_ENTRIES_SIZE: usize = 1;
|
pub const COMMON_VTABLE_ENTRIES_SIZE: usize = 1;
|
||||||
pub const COMMON_VTABLE_ENTRIES_ALIGN: usize = 2;
|
pub const COMMON_VTABLE_ENTRIES_ALIGN: usize = 2;
|
||||||
|
|
||||||
pub struct SupertraitDefIds<'tcx> {
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
stack: Vec<DefId>,
|
|
||||||
visited: FxHashSet<DefId>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Iterator for SupertraitDefIds<'_> {
|
|
||||||
type Item = DefId;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<DefId> {
|
|
||||||
let def_id = self.stack.pop()?;
|
|
||||||
let predicates = self.tcx.super_predicates_of(def_id);
|
|
||||||
let visited = &mut self.visited;
|
|
||||||
self.stack.extend(
|
|
||||||
predicates
|
|
||||||
.predicates
|
|
||||||
.iter()
|
|
||||||
.filter_map(|(pred, _)| pred.as_trait_clause())
|
|
||||||
.map(|trait_ref| trait_ref.def_id())
|
|
||||||
.filter(|&super_def_id| visited.insert(super_def_id)),
|
|
||||||
);
|
|
||||||
Some(def_id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note that we don't have access to a self type here, this has to be purely based on the trait (and
|
// Note that we don't have access to a self type here, this has to be purely based on the trait (and
|
||||||
// supertrait) definitions. That means we can't call into the same vtable_entries code since that
|
// supertrait) definitions. That means we can't call into the same vtable_entries code since that
|
||||||
// returns a specific instantiation (e.g., with Vacant slots when bounds aren't satisfied). The goal
|
// returns a specific instantiation (e.g., with Vacant slots when bounds aren't satisfied). The goal
|
||||||
|
|
|
@ -668,8 +668,9 @@ where
|
||||||
{
|
{
|
||||||
let cx = ecx.cx();
|
let cx = ecx.cx();
|
||||||
let mut requirements = vec![];
|
let mut requirements = vec![];
|
||||||
requirements
|
requirements.extend(
|
||||||
.extend(cx.super_predicates_of(trait_ref.def_id).iter_instantiated(cx, trait_ref.args));
|
cx.explicit_super_predicates_of(trait_ref.def_id).iter_instantiated(cx, trait_ref.args),
|
||||||
|
);
|
||||||
|
|
||||||
// FIXME(associated_const_equality): Also add associated consts to
|
// FIXME(associated_const_equality): Also add associated consts to
|
||||||
// the requirements here.
|
// the requirements here.
|
||||||
|
|
|
@ -187,7 +187,7 @@ fn predicates_reference_self(
|
||||||
) -> SmallVec<[Span; 1]> {
|
) -> SmallVec<[Span; 1]> {
|
||||||
let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(tcx, trait_def_id));
|
let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(tcx, trait_def_id));
|
||||||
let predicates = if supertraits_only {
|
let predicates = if supertraits_only {
|
||||||
tcx.super_predicates_of(trait_def_id)
|
tcx.explicit_super_predicates_of(trait_def_id)
|
||||||
} else {
|
} else {
|
||||||
tcx.predicates_of(trait_def_id)
|
tcx.predicates_of(trait_def_id)
|
||||||
};
|
};
|
||||||
|
@ -256,7 +256,7 @@ fn super_predicates_have_non_lifetime_binders(
|
||||||
if !tcx.features().non_lifetime_binders {
|
if !tcx.features().non_lifetime_binders {
|
||||||
return SmallVec::new();
|
return SmallVec::new();
|
||||||
}
|
}
|
||||||
tcx.super_predicates_of(trait_def_id)
|
tcx.explicit_super_predicates_of(trait_def_id)
|
||||||
.predicates
|
.predicates
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|(pred, span)| pred.has_non_region_bound_vars().then_some(*span))
|
.filter_map(|(pred, span)| pred.has_non_region_bound_vars().then_some(*span))
|
||||||
|
|
|
@ -574,7 +574,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
// Check supertraits hold. This is so that their associated type bounds
|
// Check supertraits hold. This is so that their associated type bounds
|
||||||
// will be checked in the code below.
|
// will be checked in the code below.
|
||||||
for super_trait in tcx
|
for super_trait in tcx
|
||||||
.super_predicates_of(trait_predicate.def_id())
|
.explicit_super_predicates_of(trait_predicate.def_id())
|
||||||
.instantiate(tcx, trait_predicate.trait_ref.args)
|
.instantiate(tcx, trait_predicate.trait_ref.args)
|
||||||
.predicates
|
.predicates
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
|
@ -128,7 +128,7 @@ impl<'tcx> TraitAliasExpander<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get components of trait alias.
|
// Get components of trait alias.
|
||||||
let predicates = tcx.super_predicates_of(trait_ref.def_id());
|
let predicates = tcx.explicit_super_predicates_of(trait_ref.def_id());
|
||||||
debug!(?predicates);
|
debug!(?predicates);
|
||||||
|
|
||||||
let items = predicates.predicates.iter().rev().filter_map(|(pred, span)| {
|
let items = predicates.predicates.iter().rev().filter_map(|(pred, span)| {
|
||||||
|
|
|
@ -117,7 +117,7 @@ fn prepare_vtable_segments_inner<'tcx, T>(
|
||||||
let &(inner_most_trait_ref, _, _) = stack.last().unwrap();
|
let &(inner_most_trait_ref, _, _) = stack.last().unwrap();
|
||||||
|
|
||||||
let mut direct_super_traits_iter = tcx
|
let mut direct_super_traits_iter = tcx
|
||||||
.super_predicates_of(inner_most_trait_ref.def_id())
|
.explicit_super_predicates_of(inner_most_trait_ref.def_id())
|
||||||
.predicates
|
.predicates
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(move |(pred, _)| {
|
.filter_map(move |(pred, _)| {
|
||||||
|
|
|
@ -209,8 +209,7 @@ pub trait Interner:
|
||||||
def_id: Self::DefId,
|
def_id: Self::DefId,
|
||||||
) -> ty::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>>;
|
) -> ty::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>>;
|
||||||
|
|
||||||
// FIXME: Rename this so it's obvious it's only *immediate* super predicates.
|
fn explicit_super_predicates_of(
|
||||||
fn super_predicates_of(
|
|
||||||
self,
|
self,
|
||||||
def_id: Self::DefId,
|
def_id: Self::DefId,
|
||||||
) -> ty::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>>;
|
) -> ty::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>>;
|
||||||
|
|
|
@ -113,7 +113,7 @@ fn trait_is_same_or_supertrait(cx: &DocContext<'_>, child: DefId, trait_: DefId)
|
||||||
if child == trait_ {
|
if child == trait_ {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
let predicates = cx.tcx.super_predicates_of(child);
|
let predicates = cx.tcx.explicit_super_predicates_of(child);
|
||||||
debug_assert!(cx.tcx.generics_of(child).has_self);
|
debug_assert!(cx.tcx.generics_of(child).has_self);
|
||||||
let self_ty = cx.tcx.types.self_param;
|
let self_ty = cx.tcx.types.self_param;
|
||||||
predicates
|
predicates
|
||||||
|
|
|
@ -246,7 +246,7 @@ fn collect_supertrait_bounds<'tcx>(cx: &LateContext<'tcx>, bounds: GenericBounds
|
||||||
&& let [.., path] = poly_trait.trait_ref.path.segments
|
&& let [.., path] = poly_trait.trait_ref.path.segments
|
||||||
&& poly_trait.bound_generic_params.is_empty()
|
&& poly_trait.bound_generic_params.is_empty()
|
||||||
&& let Some(trait_def_id) = path.res.opt_def_id()
|
&& let Some(trait_def_id) = path.res.opt_def_id()
|
||||||
&& let predicates = cx.tcx.super_predicates_of(trait_def_id).predicates
|
&& let predicates = cx.tcx.explicit_super_predicates_of(trait_def_id).predicates
|
||||||
// If the trait has no supertrait, there is no need to collect anything from that bound
|
// If the trait has no supertrait, there is no need to collect anything from that bound
|
||||||
&& !predicates.is_empty()
|
&& !predicates.is_empty()
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,7 +24,7 @@ fn is_subtrait_of_any(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
|
||||||
cx.tcx.is_diagnostic_item(sym::Any, tr.def_id)
|
cx.tcx.is_diagnostic_item(sym::Any, tr.def_id)
|
||||||
|| cx
|
|| cx
|
||||||
.tcx
|
.tcx
|
||||||
.super_predicates_of(tr.def_id)
|
.explicit_super_predicates_of(tr.def_id)
|
||||||
.predicates
|
.predicates
|
||||||
.iter()
|
.iter()
|
||||||
.any(|(clause, _)| {
|
.any(|(clause, _)| {
|
||||||
|
|
|
@ -91,7 +91,7 @@ fn path_to_sized_bound(cx: &LateContext<'_>, trait_bound: &PolyTraitRef<'_>) ->
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for &(predicate, _) in cx.tcx.super_predicates_of(trait_def_id).predicates {
|
for &(predicate, _) in cx.tcx.explicit_super_predicates_of(trait_def_id).predicates {
|
||||||
if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder()
|
if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder()
|
||||||
&& trait_predicate.polarity == PredicatePolarity::Positive
|
&& trait_predicate.polarity == PredicatePolarity::Positive
|
||||||
&& !path.contains(&trait_predicate.def_id())
|
&& !path.contains(&trait_predicate.def_id())
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue