mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Rollup merge of #129725 - compiler-errors:predicates-of, r=fmease
Stop using `ty::GenericPredicates` for non-predicates_of queries
`GenericPredicates` is a struct of several parts: A list of of an item's own predicates, and a parent def id (and some effects related stuff, but ignore that since it's kinda irrelevant). When instantiating these generic predicates, it calls `predicates_of` on the parent and instantiates its predicates, and appends the item's own instantiated predicates too:
acb4e8b625/compiler/rustc_middle/src/ty/generics.rs (L407-L413)
Notice how this should result in a recursive set of calls to `predicates_of`... However, `GenericPredicates` is *also* misused by a bunch of *other* queries as a convenient way of passing around a list of predicates. For these queries, we don't ever set the parent def id of the `GenericPredicates`, but if we did, then this would be very easy to mistakenly call `predicates_of` instead of some other intended parent query.
Given that footgun, and the fact that we don't ever even *use* the parent def id in the `GenericPredicates` returned from queries like `explicit_super_predicates_of`, It really has no benefit over just returning `&'tcx [(Clause<'tcx>, Span)]`.
This PR additionally opts to wrap the results of `EarlyBinder`, as we've tended to use that in the return type of these kinds of queries to properly convey that the user has params to deal with, and it also gives a convenient way of iterating over a slice of things after instantiating.
This commit is contained in:
commit
5f10a99c7a
@ -420,7 +420,7 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
|
|||||||
span: Span,
|
span: Span,
|
||||||
def_id: LocalDefId,
|
def_id: LocalDefId,
|
||||||
assoc_name: Ident,
|
assoc_name: Ident,
|
||||||
) -> ty::GenericPredicates<'tcx> {
|
) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
|
||||||
self.tcx.at(span).type_param_predicates((self.item_def_id, def_id, assoc_name))
|
self.tcx.at(span).type_param_predicates((self.item_def_id, def_id, assoc_name))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -580,24 +580,24 @@ 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 explicit_super_predicates_of(
|
pub(super) fn explicit_super_predicates_of<'tcx>(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'tcx>,
|
||||||
trait_def_id: LocalDefId,
|
trait_def_id: LocalDefId,
|
||||||
) -> ty::GenericPredicates<'_> {
|
) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
|
||||||
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 explicit_supertraits_containing_assoc_item(
|
pub(super) fn explicit_supertraits_containing_assoc_item<'tcx>(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'tcx>,
|
||||||
(trait_def_id, assoc_name): (DefId, Ident),
|
(trait_def_id, assoc_name): (DefId, Ident),
|
||||||
) -> ty::GenericPredicates<'_> {
|
) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
|
||||||
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 explicit_implied_predicates_of(
|
pub(super) fn explicit_implied_predicates_of<'tcx>(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'tcx>,
|
||||||
trait_def_id: LocalDefId,
|
trait_def_id: LocalDefId,
|
||||||
) -> ty::GenericPredicates<'_> {
|
) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
|
||||||
implied_predicates_with_filter(
|
implied_predicates_with_filter(
|
||||||
tcx,
|
tcx,
|
||||||
trait_def_id.to_def_id(),
|
trait_def_id.to_def_id(),
|
||||||
@ -612,11 +612,11 @@ pub(super) fn explicit_implied_predicates_of(
|
|||||||
/// 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 implied_predicates_with_filter(
|
pub(super) fn implied_predicates_with_filter<'tcx>(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'tcx>,
|
||||||
trait_def_id: DefId,
|
trait_def_id: DefId,
|
||||||
filter: PredicateFilter,
|
filter: PredicateFilter,
|
||||||
) -> ty::GenericPredicates<'_> {
|
) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
|
||||||
let Some(trait_def_id) = trait_def_id.as_local() else {
|
let Some(trait_def_id) = trait_def_id.as_local() else {
|
||||||
// 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
|
||||||
@ -679,20 +679,16 @@ pub(super) fn implied_predicates_with_filter(
|
|||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::GenericPredicates {
|
ty::EarlyBinder::bind(implied_bounds)
|
||||||
parent: None,
|
|
||||||
predicates: implied_bounds,
|
|
||||||
effects_min_tys: ty::List::empty(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the predicates defined on `item_def_id` of the form
|
/// Returns the predicates defined on `item_def_id` of the form
|
||||||
/// `X: Foo` where `X` is the type parameter `def_id`.
|
/// `X: Foo` where `X` is the type parameter `def_id`.
|
||||||
#[instrument(level = "trace", skip(tcx))]
|
#[instrument(level = "trace", skip(tcx))]
|
||||||
pub(super) fn type_param_predicates(
|
pub(super) fn type_param_predicates<'tcx>(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'tcx>,
|
||||||
(item_def_id, def_id, assoc_name): (LocalDefId, LocalDefId, Ident),
|
(item_def_id, def_id, assoc_name): (LocalDefId, LocalDefId, Ident),
|
||||||
) -> ty::GenericPredicates<'_> {
|
) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
|
||||||
use rustc_hir::*;
|
use rustc_hir::*;
|
||||||
use rustc_middle::ty::Ty;
|
use rustc_middle::ty::Ty;
|
||||||
|
|
||||||
@ -713,18 +709,20 @@ pub(super) fn type_param_predicates(
|
|||||||
tcx.generics_of(item_def_id).parent.map(|def_id| def_id.expect_local())
|
tcx.generics_of(item_def_id).parent.map(|def_id| def_id.expect_local())
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut result = parent
|
let result = if let Some(parent) = parent {
|
||||||
.map(|parent| {
|
let icx = ItemCtxt::new(tcx, parent);
|
||||||
let icx = ItemCtxt::new(tcx, parent);
|
icx.probe_ty_param_bounds(DUMMY_SP, def_id, assoc_name)
|
||||||
icx.probe_ty_param_bounds(DUMMY_SP, def_id, assoc_name)
|
} else {
|
||||||
})
|
ty::EarlyBinder::bind(&[] as &[_])
|
||||||
.unwrap_or_default();
|
};
|
||||||
let mut extend = None;
|
let mut extend = None;
|
||||||
|
|
||||||
let item_hir_id = tcx.local_def_id_to_hir_id(item_def_id);
|
let item_hir_id = tcx.local_def_id_to_hir_id(item_def_id);
|
||||||
|
|
||||||
let hir_node = tcx.hir_node(item_hir_id);
|
let hir_node = tcx.hir_node(item_hir_id);
|
||||||
let Some(hir_generics) = hir_node.generics() else { return result };
|
let Some(hir_generics) = hir_node.generics() else {
|
||||||
|
return result;
|
||||||
|
};
|
||||||
if let Node::Item(item) = hir_node
|
if let Node::Item(item) = hir_node
|
||||||
&& let ItemKind::Trait(..) = item.kind
|
&& let ItemKind::Trait(..) = item.kind
|
||||||
// Implied `Self: Trait` and supertrait bounds.
|
// Implied `Self: Trait` and supertrait bounds.
|
||||||
@ -748,9 +746,10 @@ pub(super) fn type_param_predicates(
|
|||||||
_ => false,
|
_ => false,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
result.predicates =
|
|
||||||
tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(extra_predicates));
|
ty::EarlyBinder::bind(
|
||||||
result
|
tcx.arena.alloc_from_iter(result.skip_binder().iter().copied().chain(extra_predicates)),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> ItemCtxt<'tcx> {
|
impl<'tcx> ItemCtxt<'tcx> {
|
||||||
|
@ -1761,7 +1761,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
|||||||
break Some((bound_vars.into_iter().collect(), assoc_item));
|
break Some((bound_vars.into_iter().collect(), assoc_item));
|
||||||
}
|
}
|
||||||
let predicates = tcx.explicit_supertraits_containing_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.iter_identity_copied().filter_map(|(pred, _)| {
|
||||||
let bound_predicate = pred.kind();
|
let bound_predicate = pred.kind();
|
||||||
match bound_predicate.skip_binder() {
|
match bound_predicate.skip_binder() {
|
||||||
ty::ClauseKind::Trait(data) => {
|
ty::ClauseKind::Trait(data) => {
|
||||||
|
@ -136,7 +136,7 @@ pub trait HirTyLowerer<'tcx> {
|
|||||||
span: Span,
|
span: Span,
|
||||||
def_id: LocalDefId,
|
def_id: LocalDefId,
|
||||||
assoc_name: Ident,
|
assoc_name: Ident,
|
||||||
) -> ty::GenericPredicates<'tcx>;
|
) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]>;
|
||||||
|
|
||||||
/// Lower an associated type to a projection.
|
/// Lower an associated type to a projection.
|
||||||
///
|
///
|
||||||
@ -831,13 +831,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||||||
debug!(?ty_param_def_id, ?assoc_name, ?span);
|
debug!(?ty_param_def_id, ?assoc_name, ?span);
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
|
|
||||||
let predicates = &self.probe_ty_param_bounds(span, ty_param_def_id, assoc_name).predicates;
|
let predicates = &self.probe_ty_param_bounds(span, ty_param_def_id, assoc_name);
|
||||||
debug!("predicates={:#?}", predicates);
|
debug!("predicates={:#?}", predicates);
|
||||||
|
|
||||||
self.probe_single_bound_for_assoc_item(
|
self.probe_single_bound_for_assoc_item(
|
||||||
|| {
|
|| {
|
||||||
let trait_refs = predicates
|
let trait_refs = predicates
|
||||||
.iter()
|
.iter_identity_copied()
|
||||||
.filter_map(|(p, _)| Some(p.as_trait_clause()?.map_bound(|t| t.trait_ref)));
|
.filter_map(|(p, _)| Some(p.as_trait_clause()?.map_bound(|t| t.trait_ref)));
|
||||||
traits::transitive_bounds_that_define_assoc_item(tcx, trait_refs, assoc_name)
|
traits::transitive_bounds_that_define_assoc_item(tcx, trait_refs, assoc_name)
|
||||||
},
|
},
|
||||||
|
@ -263,27 +263,24 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> {
|
|||||||
_: Span,
|
_: Span,
|
||||||
def_id: LocalDefId,
|
def_id: LocalDefId,
|
||||||
_: Ident,
|
_: Ident,
|
||||||
) -> ty::GenericPredicates<'tcx> {
|
) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
let item_def_id = tcx.hir().ty_param_owner(def_id);
|
let item_def_id = tcx.hir().ty_param_owner(def_id);
|
||||||
let generics = tcx.generics_of(item_def_id);
|
let generics = tcx.generics_of(item_def_id);
|
||||||
let index = generics.param_def_id_to_index[&def_id.to_def_id()];
|
let index = generics.param_def_id_to_index[&def_id.to_def_id()];
|
||||||
// HACK(eddyb) should get the original `Span`.
|
// HACK(eddyb) should get the original `Span`.
|
||||||
let span = tcx.def_span(def_id);
|
let span = tcx.def_span(def_id);
|
||||||
ty::GenericPredicates {
|
|
||||||
parent: None,
|
ty::EarlyBinder::bind(tcx.arena.alloc_from_iter(
|
||||||
predicates: tcx.arena.alloc_from_iter(
|
self.param_env.caller_bounds().iter().filter_map(|predicate| {
|
||||||
self.param_env.caller_bounds().iter().filter_map(|predicate| {
|
match predicate.kind().skip_binder() {
|
||||||
match predicate.kind().skip_binder() {
|
ty::ClauseKind::Trait(data) if data.self_ty().is_param(index) => {
|
||||||
ty::ClauseKind::Trait(data) if data.self_ty().is_param(index) => {
|
Some((predicate, span))
|
||||||
Some((predicate, span))
|
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
}
|
}
|
||||||
}),
|
_ => None,
|
||||||
),
|
}
|
||||||
effects_min_tys: ty::List::empty(),
|
}),
|
||||||
}
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_assoc_ty(
|
fn lower_assoc_ty(
|
||||||
|
@ -123,7 +123,7 @@ pub fn transitive_bounds_that_define_assoc_item<'tcx>(
|
|||||||
|
|
||||||
stack.extend(
|
stack.extend(
|
||||||
tcx.explicit_supertraits_containing_assoc_item((trait_ref.def_id(), assoc_name))
|
tcx.explicit_supertraits_containing_assoc_item((trait_ref.def_id(), assoc_name))
|
||||||
.instantiate_own_identity()
|
.iter_identity_copied()
|
||||||
.map(|(clause, _)| clause.instantiate_supertrait(tcx, trait_ref))
|
.map(|(clause, _)| clause.instantiate_supertrait(tcx, trait_ref))
|
||||||
.filter_map(|clause| clause.as_trait_clause())
|
.filter_map(|clause| clause.as_trait_clause())
|
||||||
// FIXME: Negative supertraits are elaborated here lol
|
// FIXME: Negative supertraits are elaborated here lol
|
||||||
|
@ -45,8 +45,7 @@ impl<'tcx> LateLintPass<'tcx> for MultipleSupertraitUpcastable {
|
|||||||
let direct_super_traits_iter = cx
|
let direct_super_traits_iter = cx
|
||||||
.tcx
|
.tcx
|
||||||
.explicit_super_predicates_of(def_id)
|
.explicit_super_predicates_of(def_id)
|
||||||
.predicates
|
.iter_identity_copied()
|
||||||
.into_iter()
|
|
||||||
.filter_map(|(pred, _)| pred.as_trait_clause());
|
.filter_map(|(pred, _)| pred.as_trait_clause());
|
||||||
if direct_super_traits_iter.count() > 1 {
|
if direct_super_traits_iter.count() > 1 {
|
||||||
cx.emit_span_lint(
|
cx.emit_span_lint(
|
||||||
|
@ -76,6 +76,24 @@ impl<'a, 'tcx, T: Copy + Decodable<DecodeContext<'a, 'tcx>>> ProcessQueryValue<'
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, 'tcx, T: Copy + Decodable<DecodeContext<'a, 'tcx>>>
|
||||||
|
ProcessQueryValue<'tcx, ty::EarlyBinder<'tcx, &'tcx [T]>>
|
||||||
|
for Option<DecodeIterator<'a, 'tcx, T>>
|
||||||
|
{
|
||||||
|
#[inline(always)]
|
||||||
|
fn process_decoded(
|
||||||
|
self,
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
_err: impl Fn() -> !,
|
||||||
|
) -> ty::EarlyBinder<'tcx, &'tcx [T]> {
|
||||||
|
ty::EarlyBinder::bind(if let Some(iter) = self {
|
||||||
|
tcx.arena.alloc_from_iter(iter)
|
||||||
|
} else {
|
||||||
|
&[]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx, T: Copy + Decodable<DecodeContext<'a, 'tcx>>>
|
impl<'a, 'tcx, T: Copy + Decodable<DecodeContext<'a, 'tcx>>>
|
||||||
ProcessQueryValue<'tcx, Option<&'tcx [T]>> for Option<DecodeIterator<'a, 'tcx, T>>
|
ProcessQueryValue<'tcx, Option<&'tcx [T]>> for Option<DecodeIterator<'a, 'tcx, T>>
|
||||||
{
|
{
|
||||||
|
@ -1446,8 +1446,10 @@ 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.explicit_super_predicates_of[def_id] <- self.tcx.explicit_super_predicates_of(def_id));
|
record_array!(self.tables.explicit_super_predicates_of[def_id] <-
|
||||||
record!(self.tables.explicit_implied_predicates_of[def_id] <- self.tcx.explicit_implied_predicates_of(def_id));
|
self.tcx.explicit_super_predicates_of(def_id).skip_binder());
|
||||||
|
record_array!(self.tables.explicit_implied_predicates_of[def_id] <-
|
||||||
|
self.tcx.explicit_implied_predicates_of(def_id).skip_binder());
|
||||||
|
|
||||||
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] <-
|
||||||
@ -1455,8 +1457,10 @@ 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.explicit_super_predicates_of[def_id] <- self.tcx.explicit_super_predicates_of(def_id));
|
record_array!(self.tables.explicit_super_predicates_of[def_id] <-
|
||||||
record!(self.tables.explicit_implied_predicates_of[def_id] <- self.tcx.explicit_implied_predicates_of(def_id));
|
self.tcx.explicit_super_predicates_of(def_id).skip_binder());
|
||||||
|
record_array!(self.tables.explicit_implied_predicates_of[def_id] <-
|
||||||
|
self.tcx.explicit_implied_predicates_of(def_id).skip_binder());
|
||||||
}
|
}
|
||||||
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);
|
||||||
|
@ -419,10 +419,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>>,
|
||||||
explicit_super_predicates_of: Table<DefIndex, LazyValue<ty::GenericPredicates<'static>>>,
|
explicit_super_predicates_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
|
||||||
// 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 explicit_super_predicates_of for traits.
|
// since it's identical to explicit_super_predicates_of for traits.
|
||||||
explicit_implied_predicates_of: Table<DefIndex, LazyValue<ty::GenericPredicates<'static>>>,
|
explicit_implied_predicates_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
|
||||||
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>>>>,
|
||||||
|
@ -651,7 +651,7 @@ rustc_queries! {
|
|||||||
/// is a subset of the full list of predicates. We store these in a separate map
|
/// is a subset of the full list of predicates. We store these in a separate map
|
||||||
/// because we must evaluate them even during type conversion, often before the full
|
/// because we must evaluate them even during type conversion, often before the full
|
||||||
/// predicates are available (note that super-predicates must not be cyclic).
|
/// predicates are available (note that super-predicates must not be cyclic).
|
||||||
query explicit_super_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> {
|
query explicit_super_predicates_of(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
|
||||||
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
|
||||||
@ -662,7 +662,7 @@ rustc_queries! {
|
|||||||
/// of the trait. For regular traits, this includes all super-predicates and their
|
/// 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
|
/// associated type bounds. For trait aliases, currently, this includes all of the
|
||||||
/// predicates of the trait alias.
|
/// predicates of the trait alias.
|
||||||
query explicit_implied_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> {
|
query explicit_implied_predicates_of(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
|
||||||
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
|
||||||
@ -671,7 +671,9 @@ rustc_queries! {
|
|||||||
/// The Ident is the name of an associated type.The query returns only the subset
|
/// The Ident is the name of an associated type.The query returns only the subset
|
||||||
/// of supertraits that define the given associated type. This is used to avoid
|
/// of supertraits that define the given associated type. This is used to avoid
|
||||||
/// cycles in resolving type-dependent associated item paths like `T::Item`.
|
/// cycles in resolving type-dependent associated item paths like `T::Item`.
|
||||||
query explicit_supertraits_containing_assoc_item(key: (DefId, rustc_span::symbol::Ident)) -> ty::GenericPredicates<'tcx> {
|
query explicit_supertraits_containing_assoc_item(
|
||||||
|
key: (DefId, rustc_span::symbol::Ident)
|
||||||
|
) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
|
||||||
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
|
||||||
@ -680,7 +682,9 @@ rustc_queries! {
|
|||||||
|
|
||||||
/// To avoid cycles within the predicates of a single item we compute
|
/// To avoid cycles within the predicates of a single item we compute
|
||||||
/// per-type-parameter predicates for resolving `T::AssocTy`.
|
/// per-type-parameter predicates for resolving `T::AssocTy`.
|
||||||
query type_param_predicates(key: (LocalDefId, LocalDefId, rustc_span::symbol::Ident)) -> ty::GenericPredicates<'tcx> {
|
query type_param_predicates(
|
||||||
|
key: (LocalDefId, LocalDefId, rustc_span::symbol::Ident)
|
||||||
|
) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
|
||||||
desc { |tcx| "computing the bounds for type parameter `{}`", tcx.hir().ty_param_name(key.1) }
|
desc { |tcx| "computing the bounds for type parameter `{}`", tcx.hir().ty_param_name(key.1) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -349,16 +349,14 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
|||||||
self,
|
self,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>> {
|
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>> {
|
||||||
ty::EarlyBinder::bind(self.explicit_super_predicates_of(def_id).instantiate_identity(self))
|
self.explicit_super_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn explicit_implied_predicates_of(
|
fn explicit_implied_predicates_of(
|
||||||
self,
|
self,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>> {
|
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>> {
|
||||||
ty::EarlyBinder::bind(
|
self.explicit_implied_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied())
|
||||||
self.explicit_implied_predicates_of(def_id).instantiate_identity(self),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has_target_features(self, def_id: DefId) -> bool {
|
fn has_target_features(self, def_id: DefId) -> bool {
|
||||||
|
@ -185,12 +185,11 @@ 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.explicit_super_predicates_of(trait_def_id)
|
tcx.explicit_super_predicates_of(trait_def_id).skip_binder()
|
||||||
} else {
|
} else {
|
||||||
tcx.predicates_of(trait_def_id)
|
tcx.predicates_of(trait_def_id).predicates
|
||||||
};
|
};
|
||||||
predicates
|
predicates
|
||||||
.predicates
|
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&(predicate, sp)| (predicate.instantiate_supertrait(tcx, trait_ref), sp))
|
.map(|&(predicate, sp)| (predicate.instantiate_supertrait(tcx, trait_ref), sp))
|
||||||
.filter_map(|(clause, sp)| {
|
.filter_map(|(clause, sp)| {
|
||||||
@ -266,9 +265,8 @@ fn super_predicates_have_non_lifetime_binders(
|
|||||||
return SmallVec::new();
|
return SmallVec::new();
|
||||||
}
|
}
|
||||||
tcx.explicit_super_predicates_of(trait_def_id)
|
tcx.explicit_super_predicates_of(trait_def_id)
|
||||||
.predicates
|
.iter_identity_copied()
|
||||||
.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))
|
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -600,21 +600,19 @@ 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 (supertrait, _) in tcx
|
||||||
.explicit_super_predicates_of(trait_predicate.def_id())
|
.explicit_super_predicates_of(trait_predicate.def_id())
|
||||||
.instantiate(tcx, trait_predicate.trait_ref.args)
|
.iter_instantiated_copied(tcx, trait_predicate.trait_ref.args)
|
||||||
.predicates
|
|
||||||
.into_iter()
|
|
||||||
{
|
{
|
||||||
let normalized_super_trait = normalize_with_depth_to(
|
let normalized_supertrait = normalize_with_depth_to(
|
||||||
self,
|
self,
|
||||||
obligation.param_env,
|
obligation.param_env,
|
||||||
obligation.cause.clone(),
|
obligation.cause.clone(),
|
||||||
obligation.recursion_depth + 1,
|
obligation.recursion_depth + 1,
|
||||||
super_trait,
|
supertrait,
|
||||||
&mut nested,
|
&mut nested,
|
||||||
);
|
);
|
||||||
nested.push(obligation.with(tcx, normalized_super_trait));
|
nested.push(obligation.with(tcx, normalized_supertrait));
|
||||||
}
|
}
|
||||||
|
|
||||||
let assoc_types: Vec<_> = tcx
|
let assoc_types: Vec<_> = tcx
|
||||||
|
@ -131,7 +131,7 @@ impl<'tcx> TraitAliasExpander<'tcx> {
|
|||||||
let predicates = tcx.explicit_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.skip_binder().iter().rev().filter_map(|(pred, span)| {
|
||||||
pred.instantiate_supertrait(tcx, trait_ref)
|
pred.instantiate_supertrait(tcx, trait_ref)
|
||||||
.as_trait_clause()
|
.as_trait_clause()
|
||||||
.map(|trait_ref| item.clone_and_push(trait_ref.map_bound(|t| t.trait_ref), *span))
|
.map(|trait_ref| item.clone_and_push(trait_ref.map_bound(|t| t.trait_ref), *span))
|
||||||
|
@ -120,8 +120,7 @@ fn prepare_vtable_segments_inner<'tcx, T>(
|
|||||||
|
|
||||||
let mut direct_super_traits_iter = tcx
|
let mut direct_super_traits_iter = tcx
|
||||||
.explicit_super_predicates_of(inner_most_trait_ref.def_id())
|
.explicit_super_predicates_of(inner_most_trait_ref.def_id())
|
||||||
.predicates
|
.iter_identity_copied()
|
||||||
.into_iter()
|
|
||||||
.filter_map(move |(pred, _)| {
|
.filter_map(move |(pred, _)| {
|
||||||
pred.instantiate_supertrait(tcx, inner_most_trait_ref).as_trait_clause()
|
pred.instantiate_supertrait(tcx, inner_most_trait_ref).as_trait_clause()
|
||||||
});
|
});
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
use rustc_data_structures::fx::FxIndexMap;
|
use rustc_data_structures::fx::FxIndexMap;
|
||||||
use rustc_data_structures::unord::UnordSet;
|
use rustc_data_structures::unord::UnordSet;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_middle::ty;
|
|
||||||
use thin_vec::ThinVec;
|
use thin_vec::ThinVec;
|
||||||
|
|
||||||
use crate::clean;
|
use crate::clean;
|
||||||
@ -113,18 +112,9 @@ fn trait_is_same_or_supertrait(cx: &DocContext<'_>, child: DefId, trait_: DefId)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
let predicates = cx.tcx.explicit_super_predicates_of(child);
|
let predicates = cx.tcx.explicit_super_predicates_of(child);
|
||||||
debug_assert!(cx.tcx.generics_of(child).has_self);
|
|
||||||
let self_ty = cx.tcx.types.self_param;
|
|
||||||
predicates
|
predicates
|
||||||
.predicates
|
.iter_identity_copied()
|
||||||
.iter()
|
.filter_map(|(pred, _)| Some(pred.as_trait_clause()?.def_id()))
|
||||||
.filter_map(|(pred, _)| {
|
|
||||||
if let ty::ClauseKind::Trait(pred) = pred.kind().skip_binder() {
|
|
||||||
if pred.trait_ref.self_ty() == self_ty { Some(pred.def_id()) } else { None }
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.any(|did| trait_is_same_or_supertrait(cx, did, trait_))
|
.any(|did| trait_is_same_or_supertrait(cx, did, trait_))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.explicit_super_predicates_of(trait_def_id).predicates
|
&& let predicates = cx.tcx.explicit_super_predicates_of(trait_def_id).skip_binder()
|
||||||
// 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()
|
||||||
{
|
{
|
||||||
|
@ -25,8 +25,7 @@ fn is_subtrait_of_any(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
|
|||||||
|| cx
|
|| cx
|
||||||
.tcx
|
.tcx
|
||||||
.explicit_super_predicates_of(tr.def_id)
|
.explicit_super_predicates_of(tr.def_id)
|
||||||
.predicates
|
.iter_identity_copied()
|
||||||
.iter()
|
|
||||||
.any(|(clause, _)| {
|
.any(|(clause, _)| {
|
||||||
matches!(clause.kind().skip_binder(), ty::ClauseKind::Trait(super_tr)
|
matches!(clause.kind().skip_binder(), ty::ClauseKind::Trait(super_tr)
|
||||||
if cx.tcx.is_diagnostic_item(sym::Any, super_tr.def_id()))
|
if cx.tcx.is_diagnostic_item(sym::Any, super_tr.def_id()))
|
||||||
|
@ -91,7 +91,7 @@ fn path_to_sized_bound(cx: &LateContext<'_>, trait_bound: &PolyTraitRef<'_>) ->
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for &(predicate, _) in cx.tcx.explicit_super_predicates_of(trait_def_id).predicates {
|
for (predicate, _) in cx.tcx.explicit_super_predicates_of(trait_def_id).iter_identity_copied() {
|
||||||
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…
Reference in New Issue
Block a user