about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2018-06-08 10:08:44 -0400
committerNiko Matsakis <niko@alum.mit.edu>2018-06-26 10:49:24 -0400
commitc8cf710ce032e87947d0107dcfb5d3f4c90a6849 (patch)
tree290aa186fbf2a5873224024ad01b4a4ead97a5ac /src
parent2624c14a26bdab3af7c9a6d03c30d6b913cb77f5 (diff)
downloadrust-c8cf710ce032e87947d0107dcfb5d3f4c90a6849.tar.gz
rust-c8cf710ce032e87947d0107dcfb5d3f4c90a6849.zip
replace `LexicalRegionConstraintData` with `QueryRegionConstraint`
Diffstat (limited to 'src')
-rw-r--r--src/librustc/infer/canonical/mod.rs2
-rw-r--r--src/librustc/infer/canonical/query_result.rs2
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/constraint_conversion.rs134
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/liveness.rs5
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/mod.rs29
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/type_op/mod.rs37
6 files changed, 86 insertions, 123 deletions
diff --git a/src/librustc/infer/canonical/mod.rs b/src/librustc/infer/canonical/mod.rs
index 037fc637ec9..33e5f6cd3e2 100644
--- a/src/librustc/infer/canonical/mod.rs
+++ b/src/librustc/infer/canonical/mod.rs
@@ -44,7 +44,7 @@ use rustc_data_structures::indexed_vec::IndexVec;
 
 mod canonicalizer;
 
-mod query_result;
+pub mod query_result;
 
 mod substitute;
 
diff --git a/src/librustc/infer/canonical/query_result.rs b/src/librustc/infer/canonical/query_result.rs
index 88d5d10d3c2..4d03ccb42a9 100644
--- a/src/librustc/infer/canonical/query_result.rs
+++ b/src/librustc/infer/canonical/query_result.rs
@@ -325,7 +325,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
 
 /// Given the region obligations and constraints scraped from the infcx,
 /// creates query region constraints.
-fn make_query_outlives<'tcx>(
+pub fn make_query_outlives<'tcx>(
     tcx: TyCtxt<'_, '_, 'tcx>,
     region_obligations: Vec<(ast::NodeId, RegionObligation<'tcx>)>,
     region_constraints: &RegionConstraintData<'tcx>,
diff --git a/src/librustc_mir/borrow_check/nll/type_check/constraint_conversion.rs b/src/librustc_mir/borrow_check/nll/type_check/constraint_conversion.rs
index 44f8420ca7e..96e99aae693 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/constraint_conversion.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/constraint_conversion.rs
@@ -11,13 +11,15 @@
 use borrow_check::location::LocationTable;
 use borrow_check::nll::facts::AllFacts;
 use borrow_check::nll::region_infer::{OutlivesConstraint, RegionTest, TypeTest};
-use borrow_check::nll::type_check::{Locations, LexicalRegionConstraintData};
+use borrow_check::nll::type_check::Locations;
 use borrow_check::nll::universal_regions::UniversalRegions;
-use rustc::infer::{self, RegionObligation, SubregionOrigin};
+use rustc::infer::canonical::QueryRegionConstraint;
 use rustc::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelegate};
-use rustc::infer::region_constraints::{Constraint, GenericKind, VerifyBound};
+use rustc::infer::region_constraints::{GenericKind, VerifyBound};
+use rustc::infer::{self, SubregionOrigin};
 use rustc::mir::{Location, Mir};
 use rustc::ty::{self, TyCtxt};
+use rustc::ty::subst::UnpackedKind;
 use syntax::codemap::Span;
 
 crate struct ConstraintConversion<'a, 'gcx: 'tcx, 'tcx: 'a> {
@@ -63,49 +65,10 @@ impl<'a, 'gcx, 'tcx> ConstraintConversion<'a, 'gcx, 'tcx> {
         }
     }
 
-    pub(super) fn convert(&mut self, data: &LexicalRegionConstraintData<'tcx>) {
+    pub(super) fn convert(&mut self, query_constraints: &[QueryRegionConstraint<'tcx>]) {
         debug!("generate: constraints at: {:#?}", self.locations);
-        let LexicalRegionConstraintData {
-            constraints,
-            region_obligations,
-        } = data;
-
-        for constraint in constraints {
-            debug!("generate: constraint: {:?}", constraint);
-            let (a_vid, b_vid) = match constraint {
-                Constraint::VarSubVar(a_vid, b_vid) => (*a_vid, *b_vid),
-                Constraint::RegSubVar(a_r, b_vid) => (self.to_region_vid(a_r), *b_vid),
-                Constraint::VarSubReg(a_vid, b_r) => (*a_vid, self.to_region_vid(b_r)),
-                Constraint::RegSubReg(a_r, b_r) => {
-                    (self.to_region_vid(a_r), self.to_region_vid(b_r))
-                }
-            };
-
-            // We have the constraint that `a_vid <= b_vid`. Add
-            // `b_vid: a_vid` to our region checker. Note that we
-            // reverse direction, because `regioncx` talks about
-            // "outlives" (`>=`) whereas the region constraints
-            // talk about `<=`.
-            self.add_outlives(b_vid, a_vid);
-
-            // In the new analysis, all outlives relations etc
-            // "take effect" at the mid point of the statement
-            // that requires them, so ignore the `at_location`.
-            if let Some(all_facts) = &mut self.all_facts {
-                if let Some(from_location) = self.locations.from_location() {
-                    all_facts.outlives.push((
-                        b_vid,
-                        a_vid,
-                        self.location_table.mid_index(from_location),
-                    ));
-                } else {
-                    for location in self.location_table.all_points() {
-                        all_facts.outlives.push((b_vid, a_vid, location));
-                    }
-                }
-            }
-        }
 
+        // Extract out various useful fields we'll need below.
         let ConstraintConversion {
             tcx,
             region_bound_pairs,
@@ -113,23 +76,59 @@ impl<'a, 'gcx, 'tcx> ConstraintConversion<'a, 'gcx, 'tcx> {
             param_env,
             ..
         } = *self;
-        for r_o in region_obligations {
-            let RegionObligation {
-                sup_type,
-                sub_region,
-                cause,
-            } = r_o;
-
-            // we don't actually use this for anything.
-            let origin = infer::RelateParamBound(cause.span, sup_type);
-
-            TypeOutlives::new(
-                &mut *self,
-                tcx,
-                region_bound_pairs,
-                implicit_region_bound,
-                param_env,
-            ).type_must_outlive(origin, sup_type, sub_region);
+
+        for query_constraint in query_constraints {
+            // At the moment, we never generate any "higher-ranked"
+            // region constraints like `for<'a> 'a: 'b`. At some point
+            // when we move to universes, we will, and this assertion
+            // will start to fail.
+            let ty::OutlivesPredicate(k1, r2) =
+                query_constraint.no_late_bound_regions().unwrap_or_else(|| {
+                    span_bug!(
+                        self.span(),
+                        "query_constraint {:?} contained bound regions",
+                        query_constraint,
+                    );
+                });
+
+            match k1.unpack() {
+                UnpackedKind::Lifetime(r1) => {
+                    let r1_vid = self.to_region_vid(r1);
+                    let r2_vid = self.to_region_vid(r2);
+                    self.add_outlives(r1_vid, r2_vid);
+
+                    // In the new analysis, all outlives relations etc
+                    // "take effect" at the mid point of the statement
+                    // that requires them, so ignore the `at_location`.
+                    if let Some(all_facts) = &mut self.all_facts {
+                        if let Some(from_location) = self.locations.from_location() {
+                            all_facts.outlives.push((
+                                r1_vid,
+                                r2_vid,
+                                self.location_table.mid_index(from_location),
+                            ));
+                        } else {
+                            for location in self.location_table.all_points() {
+                                all_facts.outlives.push((r1_vid, r2_vid, location));
+                            }
+                        }
+                    }
+                }
+
+                UnpackedKind::Type(t1) => {
+                    // we don't actually use this for anything, but
+                    // the `TypeOutlives` code needs an origin.
+                    let origin = infer::RelateParamBound(self.span(), t1);
+
+                    TypeOutlives::new(
+                        &mut *self,
+                        tcx,
+                        region_bound_pairs,
+                        implicit_region_bound,
+                        param_env,
+                    ).type_must_outlive(origin, t1, r2);
+                }
+            }
         }
     }
 
@@ -185,17 +184,12 @@ impl<'a, 'gcx, 'tcx> ConstraintConversion<'a, 'gcx, 'tcx> {
     }
 
     fn span(&self) -> Span {
-        self
-            .mir
+        self.mir
             .source_info(self.locations.from_location().unwrap_or(Location::START))
             .span
     }
 
-    fn add_outlives(
-        &mut self,
-        sup: ty::RegionVid,
-        sub: ty::RegionVid,
-    ) {
+    fn add_outlives(&mut self, sup: ty::RegionVid, sub: ty::RegionVid) {
         let span = self.span();
         let point = self.locations.at_location().unwrap_or(Location::START);
 
@@ -213,7 +207,9 @@ impl<'a, 'gcx, 'tcx> ConstraintConversion<'a, 'gcx, 'tcx> {
     }
 }
 
-impl<'a, 'b, 'gcx, 'tcx> TypeOutlivesDelegate<'tcx> for &'a mut ConstraintConversion<'b, 'gcx, 'tcx> {
+impl<'a, 'b, 'gcx, 'tcx> TypeOutlivesDelegate<'tcx>
+    for &'a mut ConstraintConversion<'b, 'gcx, 'tcx>
+{
     fn push_sub_region_constraint(
         &mut self,
         _origin: SubregionOrigin<'tcx>,
diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness.rs
index 92a60602b79..37898adeb92 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/liveness.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/liveness.rs
@@ -10,10 +10,11 @@
 
 use borrow_check::nll::region_infer::Cause;
 use borrow_check::nll::type_check::type_op::{DropckOutlives, TypeOp};
-use borrow_check::nll::type_check::{AtLocation, LexicalRegionConstraintData};
+use borrow_check::nll::type_check::AtLocation;
 use dataflow::move_paths::{HasMoveData, MoveData};
 use dataflow::MaybeInitializedPlaces;
 use dataflow::{FlowAtLocation, FlowsAtLocation};
+use rustc::infer::canonical::QueryRegionConstraint;
 use rustc::mir::Local;
 use rustc::mir::{BasicBlock, Location, Mir};
 use rustc::ty::subst::Kind;
@@ -70,7 +71,7 @@ where
 
 struct DropData<'tcx> {
     dropped_kinds: Vec<Kind<'tcx>>,
-    region_constraint_data: Option<Rc<LexicalRegionConstraintData<'tcx>>>,
+    region_constraint_data: Option<Rc<Vec<QueryRegionConstraint<'tcx>>>>,
 }
 
 impl<'gen, 'typeck, 'flow, 'gcx, 'tcx> TypeLivenessGenerator<'gen, 'typeck, 'flow, 'gcx, 'tcx> {
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 cb16461de49..92ee1f2a892 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -20,8 +20,9 @@ use dataflow::move_paths::MoveData;
 use dataflow::FlowAtLocation;
 use dataflow::MaybeInitializedPlaces;
 use rustc::hir::def_id::DefId;
-use rustc::infer::region_constraints::{Constraint, GenericKind};
-use rustc::infer::{InferCtxt, LateBoundRegionConversionTime, RegionObligation, UnitResult};
+use rustc::infer::canonical::QueryRegionConstraint;
+use rustc::infer::region_constraints::GenericKind;
+use rustc::infer::{InferCtxt, LateBoundRegionConversionTime, UnitResult};
 use rustc::mir::interpret::EvalErrorKind::BoundsCheck;
 use rustc::mir::tcx::PlaceTy;
 use rustc::mir::visit::{PlaceContext, Visitor};
@@ -625,21 +626,6 @@ crate struct MirTypeckRegionConstraints<'tcx> {
     crate type_tests: Vec<TypeTest<'tcx>>,
 }
 
-/// The type checker layers on top of the "old" inference engine.  The
-/// idea is that we run some operations, like trait selection, and
-/// then we "scrape out" the region constraints that have accumulated
-/// from the old lexical solver. This struct just collects the bits of
-/// that data that we care about into one place.
-#[derive(Debug)]
-struct LexicalRegionConstraintData<'tcx> {
-    /// The `'a <= 'b` constraints extracted from `RegionConstraintData`.
-    constraints: Vec<Constraint<'tcx>>,
-
-    /// The `T: 'a` (and `'a: 'b`, in some cases) constraints
-    /// extracted from the pending "region obligations".
-    region_obligations: Vec<RegionObligation<'tcx>>,
-}
-
 /// The `Locations` type summarizes *where* region constraints are
 /// required to hold. Normally, this is at a particular point which
 /// created the obligation, but for constraints that the user gave, we
@@ -759,7 +745,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
     fn push_region_constraints(
         &mut self,
         locations: Locations,
-        data: &LexicalRegionConstraintData<'tcx>,
+        data: &[QueryRegionConstraint<'tcx>],
     ) {
         debug!(
             "push_region_constraints: constraints generated at {:?} are {:#?}",
@@ -1703,10 +1689,3 @@ impl ToLocations for Location {
         self.at_self()
     }
 }
-
-impl<'tcx> LexicalRegionConstraintData<'tcx> {
-    fn is_empty(&self) -> bool {
-        let LexicalRegionConstraintData { constraints, region_obligations } = self;
-        constraints.is_empty() && region_obligations.is_empty()
-    }
-}
diff --git a/src/librustc_mir/borrow_check/nll/type_check/type_op/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/type_op/mod.rs
index 263bce8067f..434b1d799ae 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/type_op/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/type_op/mod.rs
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use borrow_check::nll::type_check::LexicalRegionConstraintData;
-use rustc::infer::region_constraints::RegionConstraintData;
+use rustc::infer::canonical::query_result;
+use rustc::infer::canonical::QueryRegionConstraint;
 use rustc::infer::{InferCtxt, InferOk, InferResult};
 use rustc::traits::query::NoSolution;
 use rustc::traits::{Normalized, Obligation, ObligationCause, PredicateObligation, TraitEngine};
@@ -44,7 +44,7 @@ pub(super) trait TypeOp<'gcx, 'tcx>: Sized + fmt::Debug {
     fn fully_perform(
         self,
         infcx: &InferCtxt<'_, 'gcx, 'tcx>,
-    ) -> Result<(Self::Output, Option<Rc<LexicalRegionConstraintData<'tcx>>>), TypeError<'tcx>> {
+    ) -> Result<(Self::Output, Option<Rc<Vec<QueryRegionConstraint<'tcx>>>>), TypeError<'tcx>> {
         let op = match self.trivial_noop() {
             Ok(r) => return Ok((r, None)),
             Err(op) => op,
@@ -66,33 +66,20 @@ pub(super) trait TypeOp<'gcx, 'tcx>: Sized + fmt::Debug {
             );
         }
 
-        let region_obligations: Vec<_> = infcx
-            .take_registered_region_obligations()
-            .into_iter()
-            .map(|(_node_id, region_obligation)| region_obligation)
-            .collect();
+        let region_obligations = infcx.take_registered_region_obligations();
 
-        let RegionConstraintData {
-            constraints,
-            verifys,
-            givens,
-        } = infcx.take_and_reset_region_constraints();
+        let region_constraint_data = infcx.take_and_reset_region_constraints();
 
-        // These are created when we "process" the registered region
-        // obliations, and that hasn't happened yet.
-        assert!(verifys.is_empty());
-
-        // NLL doesn't use givens (and thank goodness!).
-        assert!(givens.is_empty());
-
-        let data = LexicalRegionConstraintData {
-            constraints: constraints.keys().cloned().collect(),
+        let outlives = query_result::make_query_outlives(
+            infcx.tcx,
             region_obligations,
-        };
-        if data.is_empty() {
+            &region_constraint_data,
+        );
+
+        if outlives.is_empty() {
             Ok((value, None))
         } else {
-            Ok((value, Some(Rc::new(data))))
+            Ok((value, Some(Rc::new(outlives))))
         }
     }
 }