From f16584357dfa2a5e232548ea443af0fab02caa1a Mon Sep 17 00:00:00 2001 From: Jack Huey <31162821+jackh726@users.noreply.github.com> Date: Sat, 2 Jul 2022 18:27:49 -0400 Subject: [PATCH] Move EarlyBinder calls in rustc_typeck::outlives a bit further up --- compiler/rustc_middle/src/ty/sty.rs | 4 ++ .../rustc_typeck/src/outlives/explicit.rs | 8 ++-- .../src/outlives/implicit_infer.rs | 40 +++++++++++-------- compiler/rustc_typeck/src/outlives/mod.rs | 6 +-- compiler/rustc_typeck/src/outlives/utils.rs | 4 +- 5 files changed, 35 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 815e39aab57..e32e4c4f26e 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -932,6 +932,10 @@ impl EarlyBinder { let value = f(self.0)?; Ok(EarlyBinder(value)) } + + pub fn rebind(&self, value: U) -> EarlyBinder { + EarlyBinder(value) + } } impl EarlyBinder> { diff --git a/compiler/rustc_typeck/src/outlives/explicit.rs b/compiler/rustc_typeck/src/outlives/explicit.rs index bbf31de527e..7534482cce9 100644 --- a/compiler/rustc_typeck/src/outlives/explicit.rs +++ b/compiler/rustc_typeck/src/outlives/explicit.rs @@ -6,7 +6,7 @@ use super::utils::*; #[derive(Debug)] pub struct ExplicitPredicatesMap<'tcx> { - map: FxHashMap>, + map: FxHashMap>>, } impl<'tcx> ExplicitPredicatesMap<'tcx> { @@ -14,11 +14,11 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> { ExplicitPredicatesMap { map: FxHashMap::default() } } - pub fn explicit_predicates_of( + pub(crate) fn explicit_predicates_of( &mut self, tcx: TyCtxt<'tcx>, def_id: DefId, - ) -> &RequiredPredicates<'tcx> { + ) -> &ty::EarlyBinder> { self.map.entry(def_id).or_insert_with(|| { let predicates = if def_id.is_local() { tcx.explicit_predicates_of(def_id) @@ -63,7 +63,7 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> { } } - required_predicates + ty::EarlyBinder(required_predicates) }) } } diff --git a/compiler/rustc_typeck/src/outlives/implicit_infer.rs b/compiler/rustc_typeck/src/outlives/implicit_infer.rs index 52f9e386441..257a9520eeb 100644 --- a/compiler/rustc_typeck/src/outlives/implicit_infer.rs +++ b/compiler/rustc_typeck/src/outlives/implicit_infer.rs @@ -2,7 +2,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst}; -use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span; use super::explicit::ExplicitPredicatesMap; @@ -13,20 +13,19 @@ use super::utils::*; /// `global_inferred_outlives`: this is initially the empty map that /// was generated by walking the items in the crate. This will /// now be filled with inferred predicates. -pub fn infer_predicates<'tcx>( +pub(super) fn infer_predicates<'tcx>( tcx: TyCtxt<'tcx>, - explicit_map: &mut ExplicitPredicatesMap<'tcx>, -) -> FxHashMap> { +) -> FxHashMap>> { debug!("infer_predicates"); - let mut predicates_added = true; + let mut explicit_map = ExplicitPredicatesMap::new(); let mut global_inferred_outlives = FxHashMap::default(); // If new predicates were added then we need to re-calculate // all crates since there could be new implied predicates. - while predicates_added { - predicates_added = false; + 'outer: loop { + let mut predicates_added = false; // Visit all the crates and infer predicates for id in tcx.hir().items() { @@ -53,9 +52,9 @@ pub fn infer_predicates<'tcx>( tcx, field_ty, field_span, - &mut global_inferred_outlives, + &global_inferred_outlives, &mut item_required_predicates, - explicit_map, + &mut explicit_map, ); } } @@ -70,12 +69,17 @@ pub fn infer_predicates<'tcx>( // we walk the crates again and re-calculate predicates for all // items. let item_predicates_len: usize = - global_inferred_outlives.get(&item_did.to_def_id()).map_or(0, |p| p.len()); + global_inferred_outlives.get(&item_did.to_def_id()).map_or(0, |p| p.0.len()); if item_required_predicates.len() > item_predicates_len { predicates_added = true; - global_inferred_outlives.insert(item_did.to_def_id(), item_required_predicates); + global_inferred_outlives + .insert(item_did.to_def_id(), ty::EarlyBinder(item_required_predicates)); } } + + if !predicates_added { + break 'outer; + } } global_inferred_outlives @@ -85,7 +89,7 @@ fn insert_required_predicates_to_be_wf<'tcx>( tcx: TyCtxt<'tcx>, field_ty: Ty<'tcx>, field_span: Span, - global_inferred_outlives: &FxHashMap>, + global_inferred_outlives: &FxHashMap>>, required_predicates: &mut RequiredPredicates<'tcx>, explicit_map: &mut ExplicitPredicatesMap<'tcx>, ) { @@ -133,11 +137,13 @@ fn insert_required_predicates_to_be_wf<'tcx>( // 'a` holds for `Foo`. debug!("Adt"); if let Some(unsubstituted_predicates) = global_inferred_outlives.get(&def.did()) { - for (unsubstituted_predicate, &span) in unsubstituted_predicates { + for (unsubstituted_predicate, &span) in &unsubstituted_predicates.0 { // `unsubstituted_predicate` is `U: 'b` in the // example above. So apply the substitution to // get `T: 'a` (or `predicate`): - let predicate = EarlyBinder(*unsubstituted_predicate).subst(tcx, substs); + let predicate = unsubstituted_predicates + .rebind(*unsubstituted_predicate) + .subst(tcx, substs); insert_outlives_predicate( tcx, predicate.0, @@ -224,7 +230,7 @@ fn insert_required_predicates_to_be_wf<'tcx>( /// will give us `U: 'static` and `U: Foo`. The latter we /// can ignore, but we will want to process `U: 'static`, /// applying the substitution as above. -pub fn check_explicit_predicates<'tcx>( +fn check_explicit_predicates<'tcx>( tcx: TyCtxt<'tcx>, def_id: DefId, substs: &[GenericArg<'tcx>], @@ -242,7 +248,7 @@ pub fn check_explicit_predicates<'tcx>( ); let explicit_predicates = explicit_map.explicit_predicates_of(tcx, def_id); - for (outlives_predicate, &span) in explicit_predicates { + for (outlives_predicate, &span) in &explicit_predicates.0 { debug!("outlives_predicate = {:?}", &outlives_predicate); // Careful: If we are inferring the effects of a `dyn Trait<..>` @@ -287,7 +293,7 @@ pub fn check_explicit_predicates<'tcx>( continue; } - let predicate = EarlyBinder(*outlives_predicate).subst(tcx, substs); + let predicate = explicit_predicates.rebind(*outlives_predicate).subst(tcx, substs); debug!("predicate = {:?}", &predicate); insert_outlives_predicate(tcx, predicate.0, predicate.1, span, required_predicates); } diff --git a/compiler/rustc_typeck/src/outlives/mod.rs b/compiler/rustc_typeck/src/outlives/mod.rs index dccfee19960..8fa65d51e3b 100644 --- a/compiler/rustc_typeck/src/outlives/mod.rs +++ b/compiler/rustc_typeck/src/outlives/mod.rs @@ -88,9 +88,7 @@ fn inferred_outlives_crate(tcx: TyCtxt<'_>, (): ()) -> CratePredicatesMap<'_> { // for the type. // Compute the inferred predicates - let mut exp_map = explicit::ExplicitPredicatesMap::new(); - - let global_inferred_outlives = implicit_infer::infer_predicates(tcx, &mut exp_map); + let global_inferred_outlives = implicit_infer::infer_predicates(tcx); // Convert the inferred predicates into the "collected" form the // global data structure expects. @@ -100,7 +98,7 @@ fn inferred_outlives_crate(tcx: TyCtxt<'_>, (): ()) -> CratePredicatesMap<'_> { let predicates = global_inferred_outlives .iter() .map(|(&def_id, set)| { - let predicates = &*tcx.arena.alloc_from_iter(set.iter().filter_map( + let predicates = &*tcx.arena.alloc_from_iter(set.0.iter().filter_map( |(ty::OutlivesPredicate(kind1, region2), &span)| { match kind1.unpack() { GenericArgKind::Type(ty1) => Some(( diff --git a/compiler/rustc_typeck/src/outlives/utils.rs b/compiler/rustc_typeck/src/outlives/utils.rs index 14e3048cadc..b718ca94213 100644 --- a/compiler/rustc_typeck/src/outlives/utils.rs +++ b/compiler/rustc_typeck/src/outlives/utils.rs @@ -7,12 +7,12 @@ use std::collections::BTreeMap; /// Tracks the `T: 'a` or `'a: 'a` predicates that we have inferred /// must be added to the struct header. -pub type RequiredPredicates<'tcx> = +pub(crate) type RequiredPredicates<'tcx> = BTreeMap, ty::Region<'tcx>>, Span>; /// Given a requirement `T: 'a` or `'b: 'a`, deduce the /// outlives_component and add it to `required_predicates` -pub fn insert_outlives_predicate<'tcx>( +pub(crate) fn insert_outlives_predicate<'tcx>( tcx: TyCtxt<'tcx>, kind: GenericArg<'tcx>, outlived_region: Region<'tcx>,