]> git.lizzy.rs Git - rust.git/commitdiff
Move EarlyBinder calls in rustc_typeck::outlives a bit further up
authorJack Huey <31162821+jackh726@users.noreply.github.com>
Sat, 2 Jul 2022 22:27:49 +0000 (18:27 -0400)
committerJack Huey <31162821+jackh726@users.noreply.github.com>
Fri, 8 Jul 2022 02:09:16 +0000 (22:09 -0400)
compiler/rustc_middle/src/ty/sty.rs
compiler/rustc_typeck/src/outlives/explicit.rs
compiler/rustc_typeck/src/outlives/implicit_infer.rs
compiler/rustc_typeck/src/outlives/mod.rs
compiler/rustc_typeck/src/outlives/utils.rs

index 815e39aab571535987472c823d0bafded31b1d78..e32e4c4f26efaac176e8e862807f299dc9b0c73f 100644 (file)
@@ -932,6 +932,10 @@ pub fn try_map_bound<F, U, E>(self, f: F) -> Result<EarlyBinder<U>, E>
         let value = f(self.0)?;
         Ok(EarlyBinder(value))
     }
+
+    pub fn rebind<U>(&self, value: U) -> EarlyBinder<U> {
+        EarlyBinder(value)
+    }
 }
 
 impl<T> EarlyBinder<Option<T>> {
index bbf31de527eb3fb7205507ee6707981b3ec8859f..7534482cce9bba7f3deccbe62887ac6e42554efa 100644 (file)
@@ -6,7 +6,7 @@
 
 #[derive(Debug)]
 pub struct ExplicitPredicatesMap<'tcx> {
-    map: FxHashMap<DefId, RequiredPredicates<'tcx>>,
+    map: FxHashMap<DefId, ty::EarlyBinder<RequiredPredicates<'tcx>>>,
 }
 
 impl<'tcx> ExplicitPredicatesMap<'tcx> {
@@ -14,11 +14,11 @@ pub fn new() -> 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<RequiredPredicates<'tcx>> {
         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 @@ pub fn explicit_predicates_of(
                 }
             }
 
-            required_predicates
+            ty::EarlyBinder(required_predicates)
         })
     }
 }
index 52f9e386441a434e5595e2f49e9af0206487f821..257a9520eeb25f87fc269e8197fd32096430ba08 100644 (file)
@@ -2,7 +2,7 @@
 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;
 /// `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<DefId, RequiredPredicates<'tcx>> {
+) -> FxHashMap<DefId, ty::EarlyBinder<RequiredPredicates<'tcx>>> {
     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<DefId, RequiredPredicates<'tcx>>,
+    global_inferred_outlives: &FxHashMap<DefId, ty::EarlyBinder<RequiredPredicates<'tcx>>>,
     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);
     }
index dccfee19960c50d28243529417bdeabf3fdb2905..8fa65d51e3ba16cad63b955716d377928eb33da7 100644 (file)
@@ -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((
index 14e3048cadc62453499e56c798857e743786a98f..b718ca942133674130857776d1bab4c34b215f12 100644 (file)
@@ -7,12 +7,12 @@
 
 /// 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::OutlivesPredicate<GenericArg<'tcx>, 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>,