about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2018-07-26 15:07:22 +0300
committerFelix S. Klock II <pnkfelix@pnkfx.org>2018-07-31 02:31:41 +0200
commit68c2a39a720163db2e6b586aad2fb7d96040beda (patch)
tree6d9c98b4a2970651c23796498ad8420fa65ffcaf
parent490928f7099b8b5523eb8708919798e82006b054 (diff)
free RegionBoundPairs earlier and avoid normalizing twice
Normalization results are memoized, so this may not be worth it, but it
seems easy enough to do.
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/free_region_relations.rs25
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/input_output.rs31
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/mod.rs9
3 files changed, 41 insertions, 24 deletions
diff --git a/src/librustc_mir/borrow_check/nll/type_check/free_region_relations.rs b/src/librustc_mir/borrow_check/nll/type_check/free_region_relations.rs
index 26a694a30a2..e4b1aacd34f 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/free_region_relations.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/free_region_relations.rs
@@ -53,6 +53,18 @@ crate struct UniversalRegionRelations<'tcx> {
 /// our special inference variable there, we would mess that up.
 type RegionBoundPairs<'tcx> = Vec<(ty::Region<'tcx>, GenericKind<'tcx>)>;
 
+/// As part of computing the free region relations, we also have to
+/// normalize the input-output types, which we then need later. So we
+/// return those.  This vector consists of first the input types and
+/// then the output type as the last element.
+type NormalizedInputsAndOutput<'tcx> = Vec<Ty<'tcx>>;
+
+crate struct CreateResult<'tcx> {
+    crate universal_region_relations: Rc<UniversalRegionRelations<'tcx>>,
+    crate region_bound_pairs: RegionBoundPairs<'tcx>,
+    crate normalized_inputs_and_output: NormalizedInputsAndOutput<'tcx>,
+}
+
 crate fn create(
     infcx: &InferCtxt<'_, '_, 'tcx>,
     mir_def_id: DefId,
@@ -62,7 +74,7 @@ crate fn create(
     universal_regions: &Rc<UniversalRegions<'tcx>>,
     constraints: &mut MirTypeckRegionConstraints<'tcx>,
     all_facts: &mut Option<AllFacts>,
-) -> (Rc<UniversalRegionRelations<'tcx>>, RegionBoundPairs<'tcx>) {
+) -> CreateResult<'tcx> {
     let mir_node_id = infcx.tcx.hir.as_local_node_id(mir_def_id).unwrap();
     UniversalRegionRelationsBuilder {
         infcx,
@@ -215,7 +227,7 @@ struct UniversalRegionRelationsBuilder<'this, 'gcx: 'tcx, 'tcx: 'this> {
 }
 
 impl UniversalRegionRelationsBuilder<'cx, 'gcx, 'tcx> {
-    crate fn create(mut self) -> (Rc<UniversalRegionRelations<'tcx>>, RegionBoundPairs<'tcx>) {
+    crate fn create(mut self) -> CreateResult<'tcx> {
         let unnormalized_input_output_tys = self
             .universal_regions
             .unnormalized_input_tys
@@ -231,6 +243,8 @@ impl UniversalRegionRelationsBuilder<'cx, 'gcx, 'tcx> {
         //   the `region_bound_pairs` and so forth.
         // - After this is done, we'll process the constraints, once
         //   the `relations` is built.
+        let mut normalized_inputs_and_output =
+            Vec::with_capacity(self.universal_regions.unnormalized_input_tys.len() + 1);
         let constraint_sets: Vec<_> = unnormalized_input_output_tys
             .flat_map(|ty| {
                 debug!("build: input_or_output={:?}", ty);
@@ -240,6 +254,7 @@ impl UniversalRegionRelationsBuilder<'cx, 'gcx, 'tcx> {
                     .fully_perform(self.infcx)
                     .unwrap_or_else(|_| bug!("failed to normalize {:?}", ty));
                 self.add_implied_bounds(ty);
+                normalized_inputs_and_output.push(ty);
                 constraints
             })
             .collect();
@@ -280,7 +295,11 @@ impl UniversalRegionRelationsBuilder<'cx, 'gcx, 'tcx> {
             ).convert_all(&data);
         }
 
-        (Rc::new(self.relations), self.region_bound_pairs)
+        CreateResult {
+            universal_region_relations: Rc::new(self.relations),
+            region_bound_pairs: self.region_bound_pairs,
+            normalized_inputs_and_output,
+        }
     }
 
     /// Update the type of a single local, which should represent
diff --git a/src/librustc_mir/borrow_check/nll/type_check/input_output.rs b/src/librustc_mir/borrow_check/nll/type_check/input_output.rs
index 8571ac3235c..af426670167 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/input_output.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/input_output.rs
@@ -39,22 +39,24 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
         mir_def_id: DefId,
         universal_regions: &UniversalRegions<'tcx>,
         universal_region_relations: &UniversalRegionRelations<'tcx>,
+        normalized_inputs_and_output: &[Ty<'tcx>],
     ) {
         let tcx = self.infcx.tcx;
 
-        let &UniversalRegions {
-            unnormalized_output_ty,
-            unnormalized_input_tys,
-            ..
-        } = universal_regions;
+        let (&normalized_output_ty, normalized_input_tys) =
+            normalized_inputs_and_output.split_last().unwrap();
         let infcx = self.infcx;
 
         // Equate expected input tys with those in the MIR.
         let argument_locals = (1..).map(Local::new);
-        for (&unnormalized_input_ty, local) in unnormalized_input_tys.iter().zip(argument_locals) {
-            let input_ty = self.normalize(unnormalized_input_ty, Locations::All);
+        for (&normalized_input_ty, local) in normalized_input_tys.iter().zip(argument_locals) {
+            debug!(
+                "equate_inputs_and_outputs: normalized_input_ty = {:?}",
+                normalized_input_ty
+            );
+
             let mir_input_ty = mir.local_decls[local].ty;
-            self.equate_normalized_input_or_output(input_ty, mir_input_ty);
+            self.equate_normalized_input_or_output(normalized_input_ty, mir_input_ty);
         }
 
         assert!(
@@ -68,15 +70,6 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
 
         // Return types are a bit more complex. They may contain existential `impl Trait`
         // types.
-        debug!(
-            "equate_inputs_and_outputs: unnormalized_output_ty={:?}",
-            unnormalized_output_ty
-        );
-        let output_ty = self.normalize(unnormalized_output_ty, Locations::All);
-        debug!(
-            "equate_inputs_and_outputs: normalized output_ty={:?}",
-            output_ty
-        );
         let param_env = self.param_env;
         let mir_output_ty = mir.local_decls[RETURN_PLACE].ty;
         let anon_type_map =
@@ -92,7 +85,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
                                 mir_def_id,
                                 dummy_body_id,
                                 param_env,
-                                &output_ty,
+                                &normalized_output_ty,
                             ));
                         debug!(
                             "equate_inputs_and_outputs: instantiated output_ty={:?}",
@@ -146,7 +139,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
                     self,
                     Location::START,
                     "equate_inputs_and_outputs: `{:?}=={:?}` failed with `{:?}`",
-                    output_ty,
+                    normalized_output_ty,
                     mir_output_ty,
                     terr
                 );
diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
index eb18a56523e..a18e2368bf7 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -17,7 +17,7 @@ use borrow_check::nll::constraints::{ConstraintSet, OutlivesConstraint};
 use borrow_check::nll::facts::AllFacts;
 use borrow_check::nll::region_infer::values::{RegionValueElements, LivenessValues};
 use borrow_check::nll::region_infer::{ClosureRegionRequirementsExt, TypeTest};
-use borrow_check::nll::type_check::free_region_relations::UniversalRegionRelations;
+use borrow_check::nll::type_check::free_region_relations::{CreateResult, UniversalRegionRelations};
 use borrow_check::nll::universal_regions::UniversalRegions;
 use borrow_check::nll::LocalWithRegion;
 use borrow_check::nll::ToRegionVid;
@@ -132,7 +132,11 @@ pub(crate) fn type_check<'gcx, 'tcx>(
         type_tests: Vec::default(),
     };
 
-    let (universal_region_relations, region_bound_pairs) = free_region_relations::create(
+    let CreateResult {
+        universal_region_relations,
+        region_bound_pairs,
+        normalized_inputs_and_output,
+    } = free_region_relations::create(
         infcx,
         mir_def_id,
         param_env,
@@ -168,6 +172,7 @@ pub(crate) fn type_check<'gcx, 'tcx>(
                     mir_def_id,
                     universal_regions,
                     &universal_region_relations,
+                    &normalized_inputs_and_output,
                 );
             },
         );