]> git.lizzy.rs Git - rust.git/commitdiff
implied bounds byebye nested hir ids
authorlcnr <rust@lcnr.de>
Wed, 29 Jun 2022 16:04:58 +0000 (18:04 +0200)
committerlcnr <rust@lcnr.de>
Mon, 4 Jul 2022 12:35:20 +0000 (14:35 +0200)
compiler/rustc_infer/src/infer/outlives/env.rs
compiler/rustc_infer/src/infer/outlives/obligations.rs
compiler/rustc_trait_selection/src/traits/auto_trait.rs
compiler/rustc_trait_selection/src/traits/coherence.rs
compiler/rustc_typeck/src/check/check.rs
compiler/rustc_typeck/src/check/compare_method.rs
compiler/rustc_typeck/src/check/wfcheck.rs

index 9ddda7b92eb5a57f11b57b1bd37df36993e828c7..b897de7315a02dd2b0c6f14592379d1f6059d4a4 100644 (file)
@@ -1,8 +1,6 @@
 use crate::infer::free_regions::FreeRegionMap;
 use crate::infer::{GenericKind, InferCtxt};
 use crate::traits::query::OutlivesBound;
-use rustc_data_structures::fx::FxHashMap;
-use rustc_hir as hir;
 use rustc_middle::ty::{self, ReEarlyBound, ReFree, ReVar, Region};
 
 use super::explicit_outlives_bounds;
@@ -31,9 +29,7 @@ pub struct OutlivesEnvironment<'tcx> {
     pub param_env: ty::ParamEnv<'tcx>,
     free_region_map: FreeRegionMap<'tcx>,
 
-    // Contains, for each body B that we are checking (that is, the fn
-    // item, but also any nested closures), the set of implied region
-    // bounds that are in scope in that particular body.
+    // Contains the implied region bounds in scope for our current body.
     //
     // Example:
     //
@@ -43,24 +39,15 @@ pub struct OutlivesEnvironment<'tcx> {
     // } // body B0
     // ```
     //
-    // Here, for body B0, the list would be `[T: 'a]`, because we
+    // Here, when checking the body B0, the list would be `[T: 'a]`, because we
     // infer that `T` must outlive `'a` from the implied bounds on the
     // fn declaration.
     //
-    // For the body B1, the list would be `[T: 'a, T: 'b]`, because we
+    // For the body B1 however, the list would be `[T: 'a, T: 'b]`, because we
     // also can see that -- within the closure body! -- `T` must
     // outlive `'b`. This is not necessarily true outside the closure
     // body, since the closure may never be called.
-    //
-    // We collect this map as we descend the tree. We then use the
-    // results when proving outlives obligations like `T: 'x` later
-    // (e.g., if `T: 'x` must be proven within the body B1, then we
-    // know it is true if either `'a: 'x` or `'b: 'x`).
-    region_bound_pairs_map: FxHashMap<hir::HirId, RegionBoundPairs<'tcx>>,
-
-    // Used to compute `region_bound_pairs_map`: contains the set of
-    // in-scope region-bound pairs thus far.
-    region_bound_pairs_accum: RegionBoundPairs<'tcx>,
+    region_bound_pairs: RegionBoundPairs<'tcx>,
 }
 
 /// "Region-bound pairs" tracks outlives relations that are known to
@@ -73,8 +60,7 @@ pub fn new(param_env: ty::ParamEnv<'tcx>) -> Self {
         let mut env = OutlivesEnvironment {
             param_env,
             free_region_map: Default::default(),
-            region_bound_pairs_map: Default::default(),
-            region_bound_pairs_accum: vec![],
+            region_bound_pairs: Default::default(),
         };
 
         env.add_outlives_bounds(None, explicit_outlives_bounds(param_env));
@@ -87,62 +73,9 @@ pub fn free_region_map(&self) -> &FreeRegionMap<'tcx> {
         &self.free_region_map
     }
 
-    /// Borrows current value of the `region_bound_pairs`.
-    pub fn region_bound_pairs_map(&self) -> &FxHashMap<hir::HirId, RegionBoundPairs<'tcx>> {
-        &self.region_bound_pairs_map
-    }
-
-    /// This is a hack to support the old-school regionck, which
-    /// processes region constraints from the main function and the
-    /// closure together. In that context, when we enter a closure, we
-    /// want to be able to "save" the state of the surrounding a
-    /// function. We can then add implied bounds and the like from the
-    /// closure arguments into the environment -- these should only
-    /// apply in the closure body, so once we exit, we invoke
-    /// `pop_snapshot_post_typeck_child` to remove them.
-    ///
-    /// Example:
-    ///
-    /// ```ignore (pseudo-rust)
-    /// fn foo<T>() {
-    ///    callback(for<'a> |x: &'a T| {
-    ///         // ^^^^^^^ not legal syntax, but probably should be
-    ///         // within this closure body, `T: 'a` holds
-    ///    })
-    /// }
-    /// ```
-    ///
-    /// This "containment" of closure's effects only works so well. In
-    /// particular, we (intentionally) leak relationships between free
-    /// regions that are created by the closure's bounds. The case
-    /// where this is useful is when you have (e.g.) a closure with a
-    /// signature like `for<'a, 'b> fn(x: &'a &'b u32)` -- in this
-    /// case, we want to keep the relationship `'b: 'a` in the
-    /// free-region-map, so that later if we have to take `LUB('b,
-    /// 'a)` we can get the result `'b`.
-    ///
-    /// I have opted to keep **all modifications** to the
-    /// free-region-map, however, and not just those that concern free
-    /// variables bound in the closure. The latter seems more correct,
-    /// but it is not the existing behavior, and I could not find a
-    /// case where the existing behavior went wrong. In any case, it
-    /// seems like it'd be readily fixed if we wanted. There are
-    /// similar leaks around givens that seem equally suspicious, to
-    /// be honest. --nmatsakis
-    pub fn push_snapshot_pre_typeck_child(&self) -> usize {
-        self.region_bound_pairs_accum.len()
-    }
-
-    /// See `push_snapshot_pre_typeck_child`.
-    pub fn pop_snapshot_post_typeck_child(&mut self, len: usize) {
-        self.region_bound_pairs_accum.truncate(len);
-    }
-
-    /// Save the current set of region-bound pairs under the given `body_id`.
-    pub fn save_implied_bounds(&mut self, body_id: hir::HirId) {
-        let old =
-            self.region_bound_pairs_map.insert(body_id, self.region_bound_pairs_accum.clone());
-        assert!(old.is_none());
+    /// Borrows current `region_bound_pairs`.
+    pub fn region_bound_pairs(&self) -> &RegionBoundPairs<'tcx> {
+        &self.region_bound_pairs
     }
 
     /// Processes outlives bounds that are known to hold, whether from implied or other sources.
@@ -164,11 +97,10 @@ pub fn add_outlives_bounds<I>(
             debug!("add_outlives_bounds: outlives_bound={:?}", outlives_bound);
             match outlives_bound {
                 OutlivesBound::RegionSubParam(r_a, param_b) => {
-                    self.region_bound_pairs_accum.push((r_a, GenericKind::Param(param_b)));
+                    self.region_bound_pairs.push((r_a, GenericKind::Param(param_b)));
                 }
                 OutlivesBound::RegionSubProjection(r_a, projection_b) => {
-                    self.region_bound_pairs_accum
-                        .push((r_a, GenericKind::Projection(projection_b)));
+                    self.region_bound_pairs.push((r_a, GenericKind::Projection(projection_b)));
                 }
                 OutlivesBound::RegionSubRegion(r_a, r_b) => {
                     if let (ReEarlyBound(_) | ReFree(_), ReVar(vid_b)) = (r_a.kind(), r_b.kind()) {
index 15882a471a47729ed2841f77ecc105c1a61b5712..91d6479c5cd81ede14ef522ae3b439a50ebb18dd 100644 (file)
 //! imply that `'b: 'a`.
 
 use crate::infer::outlives::components::{push_outlives_components, Component};
+use crate::infer::outlives::env::OutlivesEnvironment;
 use crate::infer::outlives::env::RegionBoundPairs;
 use crate::infer::outlives::verify::VerifyBoundCx;
 use crate::infer::{
     self, GenericKind, InferCtxt, RegionObligation, SubregionOrigin, UndoLog, VerifyBound,
 };
 use crate::traits::{ObligationCause, ObligationCauseCode};
-use rustc_middle::ty::subst::GenericArgKind;
-use rustc_middle::ty::{self, Region, Ty, TyCtxt, TypeFoldable};
-
-use crate::infer::outlives::env::OutlivesEnvironment;
-use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::undo_log::UndoLogs;
 use rustc_hir as hir;
+use rustc_middle::ty::subst::GenericArgKind;
+use rustc_middle::ty::{self, Region, Ty, TyCtxt, TypeFoldable};
 use smallvec::smallvec;
 
 impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
@@ -145,10 +143,10 @@ pub fn take_registered_region_obligations(&self) -> Vec<(hir::HirId, RegionOblig
     /// - `param_env` is the parameter environment for the enclosing function.
     /// - `body_id` is the body-id whose region obligations are being
     ///   processed.
-    #[instrument(level = "debug", skip(self, region_bound_pairs_map))]
+    #[instrument(level = "debug", skip(self, region_bound_pairs))]
     pub fn process_registered_region_obligations(
         &self,
-        region_bound_pairs_map: &FxHashMap<hir::HirId, RegionBoundPairs<'tcx>>,
+        region_bound_pairs: &RegionBoundPairs<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
     ) {
         assert!(
@@ -158,7 +156,7 @@ pub fn process_registered_region_obligations(
 
         let my_region_obligations = self.take_registered_region_obligations();
 
-        for (body_id, RegionObligation { sup_type, sub_region, origin }) in my_region_obligations {
+        for (_body_id, RegionObligation { sup_type, sub_region, origin }) in my_region_obligations {
             debug!(
                 "process_registered_region_obligations: sup_type={:?} sub_region={:?} origin={:?}",
                 sup_type, sub_region, origin
@@ -166,16 +164,9 @@ pub fn process_registered_region_obligations(
 
             let sup_type = self.resolve_vars_if_possible(sup_type);
 
-            if let Some(region_bound_pairs) = region_bound_pairs_map.get(&body_id) {
-                let outlives =
-                    &mut TypeOutlives::new(self, self.tcx, &region_bound_pairs, None, param_env);
-                outlives.type_must_outlive(origin, sup_type, sub_region);
-            } else {
-                self.tcx.sess.delay_span_bug(
-                    origin.span(),
-                    &format!("no region-bound-pairs for {:?}", body_id),
-                );
-            }
+            let outlives =
+                &mut TypeOutlives::new(self, self.tcx, &region_bound_pairs, None, param_env);
+            outlives.type_must_outlive(origin, sup_type, sub_region);
         }
     }
 
@@ -184,7 +175,7 @@ pub fn check_region_obligations_and_report_errors(
         outlives_env: &OutlivesEnvironment<'tcx>,
     ) {
         self.process_registered_region_obligations(
-            outlives_env.region_bound_pairs_map(),
+            outlives_env.region_bound_pairs(),
             outlives_env.param_env,
         );
 
index 90ff07cba026a595b77a85e369204f95e875014d..49434ec142828d8ae3e35fbe892afb82eb144ce0 100644 (file)
@@ -212,15 +212,7 @@ pub fn find_auto_trait_generics<A>(
                 panic!("Unable to fulfill trait {:?} for '{:?}': {:?}", trait_did, ty, errors);
             }
 
-            let body_id_map: FxHashMap<_, _> = infcx
-                .inner
-                .borrow()
-                .region_obligations()
-                .iter()
-                .map(|&(id, _)| (id, vec![]))
-                .collect();
-
-            infcx.process_registered_region_obligations(&body_id_map, full_env);
+            infcx.process_registered_region_obligations(&Default::default(), full_env);
 
             let region_data = infcx
                 .inner
index 0e6bbd6bddbcf9d64347be0e594c4aa26893f65c..ae69f2f7eb3244d5fc82346e488a17908bdfaf65 100644 (file)
@@ -16,7 +16,6 @@
 //use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::Diagnostic;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
-use rustc_hir::CRATE_HIR_ID;
 use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
 use rustc_infer::traits::{util, TraitEngine};
 use rustc_middle::traits::specialization_graph::OverlapMode;
@@ -394,17 +393,9 @@ fn resolve_negative_obligation<'cx, 'tcx>(
         return false;
     }
 
-    let mut outlives_env = OutlivesEnvironment::new(param_env);
-    // FIXME -- add "assumed to be well formed" types into the `outlives_env`
-
-    // "Save" the accumulated implied bounds into the outlives environment
-    // (due to the FIXME above, there aren't any, but this step is still needed).
-    // The "body id" is given as `CRATE_HIR_ID`, which is the same body-id used
-    // by the "dummy" causes elsewhere (body-id is only relevant when checking
-    // function bodies with closures).
-    outlives_env.save_implied_bounds(CRATE_HIR_ID);
-
-    infcx.process_registered_region_obligations(outlives_env.region_bound_pairs_map(), param_env);
+    // FIXME -- also add "assumed to be well formed" types into the `outlives_env`
+    let outlives_env = OutlivesEnvironment::new(param_env);
+    infcx.process_registered_region_obligations(outlives_env.region_bound_pairs(), param_env);
 
     let errors = infcx.resolve_regions(&outlives_env);
 
index fab4bb0d934bcbcc98b3b79d80b326325a440512..ef74214781e5d614d5e1476bb5457d592d152b9b 100644 (file)
@@ -737,8 +737,7 @@ fn check_opaque_meets_bounds<'tcx>(
             hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) => {}
             // Can have different predicates to their defining use
             hir::OpaqueTyOrigin::TyAlias => {
-                let mut outlives_environment = OutlivesEnvironment::new(param_env);
-                outlives_environment.save_implied_bounds(hir_id);
+                let outlives_environment = OutlivesEnvironment::new(param_env);
                 infcx.check_region_obligations_and_report_errors(&outlives_environment);
             }
         }
index e233c026a39b25de02e816006bb3ea87cd1919e9..0a9b6863ef577cf42a7c51bd4671555fef8ae88b 100644 (file)
@@ -403,7 +403,6 @@ fn compare_predicate_entailment<'tcx>(
         // lifetime parameters.
         let mut outlives_environment = OutlivesEnvironment::new(param_env);
         outlives_environment.add_implied_bounds(infcx, wf_tys, impl_m_hir_id);
-        outlives_environment.save_implied_bounds(impl_m_hir_id);
         infcx.check_region_obligations_and_report_errors(&outlives_environment);
 
         Ok(())
@@ -1159,8 +1158,7 @@ pub(crate) fn compare_const_impl<'tcx>(
             return;
         }
 
-        let mut outlives_environment = OutlivesEnvironment::new(param_env);
-        outlives_environment.save_implied_bounds(impl_c_hir_id);
+        let outlives_environment = OutlivesEnvironment::new(param_env);
         infcx.resolve_regions_and_report_errors(&outlives_environment);
     });
 }
@@ -1279,8 +1277,7 @@ fn compare_type_predicate_entailment<'tcx>(
 
         // Finally, resolve all regions. This catches wily misuses of
         // lifetime parameters.
-        let mut outlives_environment = OutlivesEnvironment::new(param_env);
-        outlives_environment.save_implied_bounds(impl_ty_hir_id);
+        let outlives_environment = OutlivesEnvironment::new(param_env);
         infcx.check_region_obligations_and_report_errors(&outlives_environment);
 
         Ok(())
@@ -1514,7 +1511,6 @@ pub fn check_type_bounds<'tcx>(
         };
         let mut outlives_environment = OutlivesEnvironment::new(param_env);
         outlives_environment.add_implied_bounds(infcx, implied_bounds, impl_ty_hir_id);
-        outlives_environment.save_implied_bounds(impl_ty_hir_id);
         infcx.check_region_obligations_and_report_errors(&outlives_environment);
 
         Ok(())
index 9240d9e06b9c35265d361869c597dae23d675c4b..c76c3a4c7baee14901ffeed19ed7daaf8432d5dd 100644 (file)
@@ -65,7 +65,6 @@ pub(super) fn with_fcx<F>(&mut self, f: F)
 
             let mut outlives_environment = OutlivesEnvironment::new(param_env);
             outlives_environment.add_implied_bounds(&fcx.infcx, wf_tys, id);
-            outlives_environment.save_implied_bounds(id);
             fcx.infcx.check_region_obligations_and_report_errors(&outlives_environment);
         });
     }
@@ -660,8 +659,7 @@ fn resolve_regions_with_wf_tys<'tcx>(
     tcx.infer_ctxt().enter(|infcx| {
         let mut outlives_environment = OutlivesEnvironment::new(param_env);
         outlives_environment.add_implied_bounds(&infcx, wf_tys.clone(), id);
-        outlives_environment.save_implied_bounds(id);
-        let region_bound_pairs = outlives_environment.region_bound_pairs_map().get(&id).unwrap();
+        let region_bound_pairs = outlives_environment.region_bound_pairs();
 
         add_constraints(&infcx, region_bound_pairs);