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,
|
item_super_predicates: item_bounds::item_super_predicates,
|
||||||
explicit_item_super_predicates: item_bounds::explicit_item_super_predicates,
|
explicit_item_super_predicates: item_bounds::explicit_item_super_predicates,
|
||||||
item_non_self_assumptions: item_bounds::item_non_self_assumptions,
|
item_non_self_assumptions: item_bounds::item_non_self_assumptions,
|
||||||
|
impl_super_outlives: item_bounds::impl_super_outlives,
|
||||||
generics_of: generics_of::generics_of,
|
generics_of: generics_of::generics_of,
|
||||||
predicates_of: predicates_of::predicates_of,
|
predicates_of: predicates_of::predicates_of,
|
||||||
predicates_defined_on,
|
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(
|
pub(super) fn item_non_self_assumptions(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
def_id: DefId,
|
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> {
|
struct AssocTyToOpaque<'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
fn_def_id: DefId,
|
fn_def_id: DefId,
|
||||||
|
|
|
@ -407,6 +407,10 @@ rustc_queries! {
|
||||||
desc { |tcx| "elaborating item assumptions for `{}`", tcx.def_path_str(key) }
|
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.
|
/// Look up all native libraries this crate depends on.
|
||||||
/// These are assembled from the following places:
|
/// These are assembled from the following places:
|
||||||
/// - `extern` blocks (depending on their `link` attributes)
|
/// - `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::relate::TypeRelation;
|
||||||
use rustc_infer::infer::BoundRegionConversionTime::{self, HigherRankedType};
|
use rustc_infer::infer::BoundRegionConversionTime::{self, HigherRankedType};
|
||||||
use rustc_infer::infer::DefineOpaqueTypes;
|
use rustc_infer::infer::DefineOpaqueTypes;
|
||||||
use rustc_infer::traits::util::elaborate;
|
|
||||||
use rustc_infer::traits::TraitObligation;
|
use rustc_infer::traits::TraitObligation;
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::dep_graph::{dep_kinds, DepNodeIndex};
|
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.
|
// Register any outlives obligations from the trait here, cc #124336.
|
||||||
if matches!(self.tcx().def_kind(def_id), DefKind::Impl { of_trait: true })
|
if matches!(tcx.def_kind(def_id), DefKind::Impl { of_trait: true }) {
|
||||||
&& let Some(header) = self.tcx().impl_trait_header(def_id)
|
for clause in tcx.impl_super_outlives(def_id).iter_instantiated(tcx, args) {
|
||||||
{
|
let clause = normalize_with_depth_to(
|
||||||
let trait_clause: ty::Clause<'tcx> =
|
self,
|
||||||
header.trait_ref.instantiate(self.tcx(), args).upcast(self.tcx());
|
param_env,
|
||||||
for clause in elaborate(self.tcx(), [trait_clause]) {
|
cause.clone(),
|
||||||
if matches!(
|
recursion_depth,
|
||||||
clause.kind().skip_binder(),
|
clause,
|
||||||
ty::ClauseKind::TypeOutlives(..) | ty::ClauseKind::RegionOutlives(..)
|
&mut obligations,
|
||||||
) {
|
);
|
||||||
let clause = normalize_with_depth_to(
|
obligations.push(Obligation {
|
||||||
self,
|
cause: cause.clone(),
|
||||||
param_env,
|
recursion_depth,
|
||||||
cause.clone(),
|
param_env,
|
||||||
recursion_depth,
|
predicate: clause.as_predicate(),
|
||||||
clause,
|
});
|
||||||
&mut obligations,
|
|
||||||
);
|
|
||||||
obligations.push(Obligation {
|
|
||||||
cause: cause.clone(),
|
|
||||||
recursion_depth,
|
|
||||||
param_env,
|
|
||||||
predicate: clause.as_predicate(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue