Skip to content

Commit 48090b1

Browse files
committed
Auto merge of rust-lang#128746 - compiler-errors:cache-super-outlives, r=lcnr
Cache supertrait outlives of impl header for soundness check This caches the results of computing the transitive supertraits of an impl and filtering it to its outlives obligations. This is purely an optimization to improve rust-lang#124336.
2 parents 7347f8e + 7922852 commit 48090b1

File tree

4 files changed

+42
-26
lines changed

4 files changed

+42
-26
lines changed

Diff for: compiler/rustc_hir_analysis/src/collect.rs

+1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ pub fn provide(providers: &mut Providers) {
6767
item_super_predicates: item_bounds::item_super_predicates,
6868
explicit_item_super_predicates: item_bounds::explicit_item_super_predicates,
6969
item_non_self_assumptions: item_bounds::item_non_self_assumptions,
70+
impl_super_outlives: item_bounds::impl_super_outlives,
7071
generics_of: generics_of::generics_of,
7172
predicates_of: predicates_of::predicates_of,
7273
predicates_defined_on,

Diff for: compiler/rustc_hir_analysis/src/collect/item_bounds.rs

+21
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,8 @@ pub(super) fn item_super_predicates(
212212
})
213213
}
214214

215+
/// This exists as an optimization to compute only the item bounds of the item
216+
/// that are not `Self` bounds.
215217
pub(super) fn item_non_self_assumptions(
216218
tcx: TyCtxt<'_>,
217219
def_id: DefId,
@@ -226,6 +228,25 @@ pub(super) fn item_non_self_assumptions(
226228
}
227229
}
228230

231+
/// This exists as an optimization to compute only the supertraits of this impl's
232+
/// trait that are outlives bounds.
233+
pub(super) fn impl_super_outlives(
234+
tcx: TyCtxt<'_>,
235+
def_id: DefId,
236+
) -> ty::EarlyBinder<'_, ty::Clauses<'_>> {
237+
tcx.impl_trait_header(def_id).expect("expected an impl of trait").trait_ref.map_bound(
238+
|trait_ref| {
239+
let clause: ty::Clause<'_> = trait_ref.upcast(tcx);
240+
tcx.mk_clauses_from_iter(util::elaborate(tcx, [clause]).filter(|clause| {
241+
matches!(
242+
clause.kind().skip_binder(),
243+
ty::ClauseKind::TypeOutlives(_) | ty::ClauseKind::RegionOutlives(_)
244+
)
245+
}))
246+
},
247+
)
248+
}
249+
229250
struct AssocTyToOpaque<'tcx> {
230251
tcx: TyCtxt<'tcx>,
231252
fn_def_id: DefId,

Diff for: compiler/rustc_middle/src/query/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,10 @@ rustc_queries! {
407407
desc { |tcx| "elaborating item assumptions for `{}`", tcx.def_path_str(key) }
408408
}
409409

410+
query impl_super_outlives(key: DefId) -> ty::EarlyBinder<'tcx, ty::Clauses<'tcx>> {
411+
desc { |tcx| "elaborating supertrait outlives for trait of `{}`", tcx.def_path_str(key) }
412+
}
413+
410414
/// Look up all native libraries this crate depends on.
411415
/// These are assembled from the following places:
412416
/// - `extern` blocks (depending on their `link` attributes)

Diff for: compiler/rustc_trait_selection/src/traits/select/mod.rs

+16-26
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ use rustc_hir::LangItem;
1717
use rustc_infer::infer::relate::TypeRelation;
1818
use rustc_infer::infer::BoundRegionConversionTime::{self, HigherRankedType};
1919
use rustc_infer::infer::DefineOpaqueTypes;
20-
use rustc_infer::traits::util::elaborate;
2120
use rustc_infer::traits::TraitObligation;
2221
use rustc_middle::bug;
2322
use rustc_middle::dep_graph::{dep_kinds, DepNodeIndex};
@@ -2801,31 +2800,22 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
28012800
}
28022801

28032802
// Register any outlives obligations from the trait here, cc #124336.
2804-
if matches!(self.tcx().def_kind(def_id), DefKind::Impl { of_trait: true })
2805-
&& let Some(header) = self.tcx().impl_trait_header(def_id)
2806-
{
2807-
let trait_clause: ty::Clause<'tcx> =
2808-
header.trait_ref.instantiate(self.tcx(), args).upcast(self.tcx());
2809-
for clause in elaborate(self.tcx(), [trait_clause]) {
2810-
if matches!(
2811-
clause.kind().skip_binder(),
2812-
ty::ClauseKind::TypeOutlives(..) | ty::ClauseKind::RegionOutlives(..)
2813-
) {
2814-
let clause = normalize_with_depth_to(
2815-
self,
2816-
param_env,
2817-
cause.clone(),
2818-
recursion_depth,
2819-
clause,
2820-
&mut obligations,
2821-
);
2822-
obligations.push(Obligation {
2823-
cause: cause.clone(),
2824-
recursion_depth,
2825-
param_env,
2826-
predicate: clause.as_predicate(),
2827-
});
2828-
}
2803+
if matches!(tcx.def_kind(def_id), DefKind::Impl { of_trait: true }) {
2804+
for clause in tcx.impl_super_outlives(def_id).iter_instantiated(tcx, args) {
2805+
let clause = normalize_with_depth_to(
2806+
self,
2807+
param_env,
2808+
cause.clone(),
2809+
recursion_depth,
2810+
clause,
2811+
&mut obligations,
2812+
);
2813+
obligations.push(Obligation {
2814+
cause: cause.clone(),
2815+
recursion_depth,
2816+
param_env,
2817+
predicate: clause.as_predicate(),
2818+
});
28292819
}
28302820
}
28312821

0 commit comments

Comments
 (0)