Skip to content

Commit

Permalink
Auto merge of rust-lang#128746 - compiler-errors:cache-super-outlives…
Browse files Browse the repository at this point in the history
…, r=<try>

[perf] Cache supertrait outlives of impl header for soundness check

Try to win back some perf from rust-lang#124336 (comment)

r? `@ghost`
  • Loading branch information
bors committed Aug 6, 2024
2 parents 60d1465 + 7922852 commit 5be154b
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 26 deletions.
1 change: 1 addition & 0 deletions compiler/rustc_hir_analysis/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
21 changes: 21 additions & 0 deletions compiler/rustc_hir_analysis/src/collect/item_bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
42 changes: 16 additions & 26 deletions compiler/rustc_trait_selection/src/traits/select/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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(),
});
}
}

Expand Down

0 comments on commit 5be154b

Please sign in to comment.