]> git.lizzy.rs Git - rust.git/commitdiff
free RegionBoundPairs earlier and avoid normalizing twice
authorNiko Matsakis <niko@alum.mit.edu>
Thu, 26 Jul 2018 12:07:22 +0000 (15:07 +0300)
committerFelix S. Klock II <pnkfelix@pnkfx.org>
Tue, 31 Jul 2018 00:31:41 +0000 (02:31 +0200)
Normalization results are memoized, so this may not be worth it, but it
seems easy enough to do.

src/librustc_mir/borrow_check/nll/type_check/free_region_relations.rs
src/librustc_mir/borrow_check/nll/type_check/input_output.rs
src/librustc_mir/borrow_check/nll/type_check/mod.rs

index 26a694a30a27f7c90689b48d8a61cf1b798b86cb..e4b1aacd34f71fad8306bf6e1efa98696d147a66 100644 (file)
 /// 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 @@
     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
index 8571ac3235c33da7e5ccb0946d7fb35788f094b3..af42667016780618e7d0854706ba51f9ea09546e 100644 (file)
@@ -39,22 +39,24 @@ pub(super) fn equate_inputs_and_outputs(
         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 @@ pub(super) fn equate_inputs_and_outputs(
 
         // 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 @@ pub(super) fn equate_inputs_and_outputs(
                                 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 @@ pub(super) fn equate_inputs_and_outputs(
                     self,
                     Location::START,
                     "equate_inputs_and_outputs: `{:?}=={:?}` failed with `{:?}`",
-                    output_ty,
+                    normalized_output_ty,
                     mir_output_ty,
                     terr
                 );
index eb18a56523eb6faf82897665d85cf0571cd4739f..a18e2368bf724d55b81f5f5afba76711e8d149d3 100644 (file)
@@ -17,7 +17,7 @@
 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,
                 );
             },
         );