Cache supertrait outlives of impl header for soundness check
This commit is contained in:
parent
60d146580c
commit
79228526bf
4 changed files with 42 additions and 26 deletions
|
@ -67,6 +67,7 @@ pub fn provide(providers: &mut Providers) {
|
|||
item_super_predicates: item_bounds::item_super_predicates,
|
||||
explicit_item_super_predicates: item_bounds::explicit_item_super_predicates,
|
||||
item_non_self_assumptions: item_bounds::item_non_self_assumptions,
|
||||
impl_super_outlives: item_bounds::impl_super_outlives,
|
||||
generics_of: generics_of::generics_of,
|
||||
predicates_of: predicates_of::predicates_of,
|
||||
predicates_defined_on,
|
||||
|
|
|
@ -212,6 +212,8 @@ pub(super) fn item_super_predicates(
|
|||
})
|
||||
}
|
||||
|
||||
/// This exists as an optimization to compute only the item bounds of the item
|
||||
/// that are not `Self` bounds.
|
||||
pub(super) fn item_non_self_assumptions(
|
||||
tcx: TyCtxt<'_>,
|
||||
def_id: DefId,
|
||||
|
@ -226,6 +228,25 @@ pub(super) fn item_non_self_assumptions(
|
|||
}
|
||||
}
|
||||
|
||||
/// This exists as an optimization to compute only the supertraits of this impl's
|
||||
/// trait that are outlives bounds.
|
||||
pub(super) fn impl_super_outlives(
|
||||
tcx: TyCtxt<'_>,
|
||||
def_id: DefId,
|
||||
) -> ty::EarlyBinder<'_, ty::Clauses<'_>> {
|
||||
tcx.impl_trait_header(def_id).expect("expected an impl of trait").trait_ref.map_bound(
|
||||
|trait_ref| {
|
||||
let clause: ty::Clause<'_> = trait_ref.upcast(tcx);
|
||||
tcx.mk_clauses_from_iter(util::elaborate(tcx, [clause]).filter(|clause| {
|
||||
matches!(
|
||||
clause.kind().skip_binder(),
|
||||
ty::ClauseKind::TypeOutlives(_) | ty::ClauseKind::RegionOutlives(_)
|
||||
)
|
||||
}))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
struct AssocTyToOpaque<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
fn_def_id: DefId,
|
||||
|
|
|
@ -407,6 +407,10 @@ rustc_queries! {
|
|||
desc { |tcx| "elaborating item assumptions for `{}`", tcx.def_path_str(key) }
|
||||
}
|
||||
|
||||
query impl_super_outlives(key: DefId) -> ty::EarlyBinder<'tcx, ty::Clauses<'tcx>> {
|
||||
desc { |tcx| "elaborating supertrait outlives for trait of `{}`", tcx.def_path_str(key) }
|
||||
}
|
||||
|
||||
/// Look up all native libraries this crate depends on.
|
||||
/// These are assembled from the following places:
|
||||
/// - `extern` blocks (depending on their `link` attributes)
|
||||
|
|
|
@ -17,7 +17,6 @@ use rustc_hir::LangItem;
|
|||
use rustc_infer::infer::relate::TypeRelation;
|
||||
use rustc_infer::infer::BoundRegionConversionTime::{self, HigherRankedType};
|
||||
use rustc_infer::infer::DefineOpaqueTypes;
|
||||
use rustc_infer::traits::util::elaborate;
|
||||
use rustc_infer::traits::TraitObligation;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::dep_graph::{dep_kinds, DepNodeIndex};
|
||||
|
@ -2801,31 +2800,22 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
|||
}
|
||||
|
||||
// Register any outlives obligations from the trait here, cc #124336.
|
||||
if matches!(self.tcx().def_kind(def_id), DefKind::Impl { of_trait: true })
|
||||
&& let Some(header) = self.tcx().impl_trait_header(def_id)
|
||||
{
|
||||
let trait_clause: ty::Clause<'tcx> =
|
||||
header.trait_ref.instantiate(self.tcx(), args).upcast(self.tcx());
|
||||
for clause in elaborate(self.tcx(), [trait_clause]) {
|
||||
if matches!(
|
||||
clause.kind().skip_binder(),
|
||||
ty::ClauseKind::TypeOutlives(..) | ty::ClauseKind::RegionOutlives(..)
|
||||
) {
|
||||
let clause = normalize_with_depth_to(
|
||||
self,
|
||||
param_env,
|
||||
cause.clone(),
|
||||
recursion_depth,
|
||||
clause,
|
||||
&mut obligations,
|
||||
);
|
||||
obligations.push(Obligation {
|
||||
cause: cause.clone(),
|
||||
recursion_depth,
|
||||
param_env,
|
||||
predicate: clause.as_predicate(),
|
||||
});
|
||||
}
|
||||
if matches!(tcx.def_kind(def_id), DefKind::Impl { of_trait: true }) {
|
||||
for clause in tcx.impl_super_outlives(def_id).iter_instantiated(tcx, args) {
|
||||
let clause = normalize_with_depth_to(
|
||||
self,
|
||||
param_env,
|
||||
cause.clone(),
|
||||
recursion_depth,
|
||||
clause,
|
||||
&mut obligations,
|
||||
);
|
||||
obligations.push(Obligation {
|
||||
cause: cause.clone(),
|
||||
recursion_depth,
|
||||
param_env,
|
||||
predicate: clause.as_predicate(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue