diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 638dd6d756b58..d623e72613944 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -33,7 +33,7 @@ use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs} use rustc_middle::mir::mono::Linkage; use rustc_middle::ty::query::Providers; use rustc_middle::ty::util::{Discr, IntTypeExt}; -use rustc_middle::ty::{self, AdtKind, Const, DefIdTree, IsSuggestable, Ty, TyCtxt}; +use rustc_middle::ty::{self, AdtKind, Const, DefIdTree, IsSuggestable, ToPredicate, Ty, TyCtxt}; use rustc_session::lint; use rustc_session::parse::feature_err; use rustc_span::symbol::{kw, sym, Ident, Symbol}; @@ -1366,12 +1366,14 @@ fn predicates_defined_on(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicate "predicates_defined_on: inferred_outlives_of({:?}) = {:?}", def_id, inferred_outlives, ); + let inferred_outlives_iter = + inferred_outlives.iter().map(|(clause, span)| ((*clause).to_predicate(tcx), *span)); if result.predicates.is_empty() { - result.predicates = inferred_outlives; + result.predicates = tcx.arena.alloc_from_iter(inferred_outlives_iter); } else { - result.predicates = tcx - .arena - .alloc_from_iter(result.predicates.iter().chain(inferred_outlives).copied()); + result.predicates = tcx.arena.alloc_from_iter( + result.predicates.into_iter().copied().chain(inferred_outlives_iter), + ); } } diff --git a/compiler/rustc_hir_analysis/src/outlives/mod.rs b/compiler/rustc_hir_analysis/src/outlives/mod.rs index c8f37176836c5..81fe32000d307 100644 --- a/compiler/rustc_hir_analysis/src/outlives/mod.rs +++ b/compiler/rustc_hir_analysis/src/outlives/mod.rs @@ -3,7 +3,7 @@ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_middle::ty::query::Providers; use rustc_middle::ty::subst::GenericArgKind; -use rustc_middle::ty::{self, CratePredicatesMap, ToPredicate, TyCtxt}; +use rustc_middle::ty::{self, CratePredicatesMap, TyCtxt}; use rustc_span::symbol::sym; use rustc_span::Span; @@ -17,7 +17,7 @@ pub fn provide(providers: &mut Providers) { *providers = Providers { inferred_outlives_of, inferred_outlives_crate, ..*providers }; } -fn inferred_outlives_of(tcx: TyCtxt<'_>, item_def_id: DefId) -> &[(ty::Predicate<'_>, Span)] { +fn inferred_outlives_of(tcx: TyCtxt<'_>, item_def_id: DefId) -> &[(ty::Clause<'_>, Span)] { let id = tcx.hir().local_def_id_to_hir_id(item_def_id.expect_local()); if matches!(tcx.def_kind(item_def_id), hir::def::DefKind::AnonConst) && tcx.lazy_normalization() @@ -50,12 +50,10 @@ fn inferred_outlives_of(tcx: TyCtxt<'_>, item_def_id: DefId) -> &[(ty::Predicate if tcx.has_attr(item_def_id, sym::rustc_outlives) { let mut pred: Vec = predicates .iter() - .map(|(out_pred, _)| match out_pred.kind().skip_binder() { - ty::PredicateKind::Clause(ty::Clause::RegionOutlives(p)) => { - p.to_string() - } - ty::PredicateKind::Clause(ty::Clause::TypeOutlives(p)) => p.to_string(), - err => bug!("unexpected predicate {:?}", err), + .map(|(out_pred, _)| match out_pred { + ty::Clause::RegionOutlives(p) => p.to_string(), + ty::Clause::TypeOutlives(p) => p.to_string(), + err => bug!("unexpected clause {:?}", err), }) .collect(); pred.sort(); @@ -103,19 +101,11 @@ fn inferred_outlives_crate(tcx: TyCtxt<'_>, (): ()) -> CratePredicatesMap<'_> { |(ty::OutlivesPredicate(kind1, region2), &span)| { match kind1.unpack() { GenericArgKind::Type(ty1) => Some(( - ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::TypeOutlives( - ty::OutlivesPredicate(ty1, *region2), - ))) - .to_predicate(tcx), + ty::Clause::TypeOutlives(ty::OutlivesPredicate(ty1, *region2)), span, )), GenericArgKind::Lifetime(region1) => Some(( - ty::Binder::dummy(ty::PredicateKind::Clause( - ty::Clause::RegionOutlives(ty::OutlivesPredicate( - region1, *region2, - )), - )) - .to_predicate(tcx), + ty::Clause::RegionOutlives(ty::OutlivesPredicate(region1, *region2)), span, )), GenericArgKind::Const(_) => { diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 93d81125f4885..825093384fba7 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -2046,16 +2046,13 @@ declare_lint_pass!(ExplicitOutlivesRequirements => [EXPLICIT_OUTLIVES_REQUIREMEN impl ExplicitOutlivesRequirements { fn lifetimes_outliving_lifetime<'tcx>( - inferred_outlives: &'tcx [(ty::Predicate<'tcx>, Span)], + inferred_outlives: &'tcx [(ty::Clause<'tcx>, Span)], def_id: DefId, ) -> Vec> { inferred_outlives .iter() - .filter_map(|(pred, _)| match pred.kind().skip_binder() { - ty::PredicateKind::Clause(ty::Clause::RegionOutlives(ty::OutlivesPredicate( - a, - b, - ))) => match *a { + .filter_map(|(clause, _)| match *clause { + ty::Clause::RegionOutlives(ty::OutlivesPredicate(a, b)) => match *a { ty::ReEarlyBound(ebr) if ebr.def_id == def_id => Some(b), _ => None, }, @@ -2065,16 +2062,15 @@ impl ExplicitOutlivesRequirements { } fn lifetimes_outliving_type<'tcx>( - inferred_outlives: &'tcx [(ty::Predicate<'tcx>, Span)], + inferred_outlives: &'tcx [(ty::Clause<'tcx>, Span)], index: u32, ) -> Vec> { inferred_outlives .iter() - .filter_map(|(pred, _)| match pred.kind().skip_binder() { - ty::PredicateKind::Clause(ty::Clause::TypeOutlives(ty::OutlivesPredicate( - a, - b, - ))) => a.is_param(index).then_some(b), + .filter_map(|(clause, _)| match *clause { + ty::Clause::TypeOutlives(ty::OutlivesPredicate(a, b)) => { + a.is_param(index).then_some(b) + } _ => None, }) .collect() diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index c51b8f96c7151..6b60577c9023f 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -353,7 +353,7 @@ define_tables! { explicit_predicates_of: Table>>, generics_of: Table>, // As an optimization, a missing entry indicates an empty `&[]`. - inferred_outlives_of: Table, Span)>>, + inferred_outlives_of: Table, Span)>>, super_predicates_of: Table>>, type_of: Table>>, variances_of: Table>, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 38b72ec923193..e1220320eea1b 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -562,7 +562,7 @@ rustc_queries! { /// Returns the inferred outlives predicates (e.g., for `struct /// Foo<'a, T> { x: &'a T }`, this would return `T: 'a`). - query inferred_outlives_of(key: DefId) -> &'tcx [(ty::Predicate<'tcx>, Span)] { + query inferred_outlives_of(key: DefId) -> &'tcx [(ty::Clause<'tcx>, Span)] { desc { |tcx| "computing inferred outlives predicates of `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index b22b3961f34ea..75f2d45eadb81 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -345,6 +345,14 @@ impl<'tcx, D: TyDecoder>> RefDecodable<'tcx, D> } } +impl<'tcx, D: TyDecoder>> RefDecodable<'tcx, D> for [(ty::Clause<'tcx>, Span)] { + fn decode(decoder: &mut D) -> &'tcx Self { + decoder.interner().arena.alloc_from_iter( + (0..decoder.read_usize()).map(|_| Decodable::decode(decoder)).collect::>(), + ) + } +} + impl<'tcx, D: TyDecoder>> RefDecodable<'tcx, D> for ty::List { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 595b73986a87b..7be9fee3b0cf6 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -734,7 +734,7 @@ pub struct CratePredicatesMap<'tcx> { /// For each struct with outlive bounds, maps to a vector of the /// predicate of its outlive bounds. If an item has no outlives /// bounds, it will have no entry. - pub predicates: FxHashMap, Span)]>, + pub predicates: FxHashMap, Span)]>, } impl<'tcx> Predicate<'tcx> { @@ -1167,6 +1167,13 @@ impl<'tcx> ToPredicate<'tcx, Predicate<'tcx>> for Binder<'tcx, PredicateKind<'tc } } +impl<'tcx> ToPredicate<'tcx, Predicate<'tcx>> for Clause<'tcx> { + #[inline(always)] + fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { + tcx.mk_predicate(ty::Binder::dummy(ty::PredicateKind::Clause(self))) + } +} + impl<'tcx> ToPredicate<'tcx, Predicate<'tcx>> for Binder<'tcx, TraitRef<'tcx>> { #[inline(always)] fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs index b2bcf0e29cd9d..c7d6c6abd1c22 100644 --- a/compiler/rustc_middle/src/ty/parameterized.rs +++ b/compiler/rustc_middle/src/ty/parameterized.rs @@ -5,7 +5,7 @@ use rustc_index::vec::{Idx, IndexVec}; use crate::middle::exported_symbols::ExportedSymbol; use crate::mir::Body; use crate::ty::{ - self, Const, FnSig, GeneratorDiagnosticData, GenericPredicates, Predicate, TraitRef, Ty, + self, Clause, Const, FnSig, GeneratorDiagnosticData, GenericPredicates, Predicate, TraitRef, Ty, }; pub trait ParameterizedOverTcx: 'static { @@ -121,6 +121,7 @@ parameterized_over_tcx! { TraitRef, Const, Predicate, + Clause, GeneratorDiagnosticData, Body, ExportedSymbol, diff --git a/compiler/rustc_query_impl/src/on_disk_cache.rs b/compiler/rustc_query_impl/src/on_disk_cache.rs index c61d2a9c2d0c6..ac9653b90071c 100644 --- a/compiler/rustc_query_impl/src/on_disk_cache.rs +++ b/compiler/rustc_query_impl/src/on_disk_cache.rs @@ -818,6 +818,12 @@ impl<'a, 'tcx> Decodable> for &'tcx [(ty::Predicate<'tcx> } } +impl<'a, 'tcx> Decodable> for &'tcx [(ty::Clause<'tcx>, Span)] { + fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self { + RefDecodable::decode(d) + } +} + impl<'a, 'tcx> Decodable> for &'tcx [rustc_ast::InlineAsmTemplatePiece] { fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self { RefDecodable::decode(d)