about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/infer/canonical/mod.rs8
-rw-r--r--src/librustc/infer/canonical/query_response.rs14
-rw-r--r--src/librustc/infer/region_constraints/mod.rs15
-rw-r--r--src/librustc/ty/structural_impls.rs7
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/free_region_relations.rs2
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/mod.rs5
6 files changed, 39 insertions, 12 deletions
diff --git a/src/librustc/infer/canonical/mod.rs b/src/librustc/infer/canonical/mod.rs
index f18eeca3610..4693cf7181e 100644
--- a/src/librustc/infer/canonical/mod.rs
+++ b/src/librustc/infer/canonical/mod.rs
@@ -23,6 +23,7 @@
 
 use crate::infer::{InferCtxt, RegionVariableOrigin, TypeVariableOrigin, TypeVariableOriginKind};
 use crate::infer::{ConstVariableOrigin, ConstVariableOriginKind};
+use crate::infer::region_constraints::PickConstraint;
 use crate::mir::interpret::ConstValue;
 use rustc_data_structures::indexed_vec::IndexVec;
 use rustc_macros::HashStable;
@@ -197,13 +198,14 @@ pub struct QueryResponse<'tcx, R> {
 #[derive(Clone, Debug, Default, HashStable)]
 pub struct QueryRegionConstraints<'tcx> {
     pub outlives: Vec<QueryOutlivesConstraint<'tcx>>,
+    pub pick_constraints: Vec<PickConstraint<'tcx>>,
 }
 
 impl QueryRegionConstraints<'_> {
     /// Represents an empty (trivially true) set of region
     /// constraints.
     pub fn is_empty(&self) -> bool {
-        self.outlives.is_empty()
+        self.outlives.is_empty() && self.pick_constraints.is_empty()
     }
 }
 
@@ -555,14 +557,14 @@ BraceStructLiftImpl! {
 
 BraceStructTypeFoldableImpl! {
     impl<'tcx> TypeFoldable<'tcx> for QueryRegionConstraints<'tcx> {
-        outlives
+        outlives, pick_constraints
     }
 }
 
 BraceStructLiftImpl! {
     impl<'a, 'tcx> Lift<'tcx> for QueryRegionConstraints<'a> {
         type Lifted = QueryRegionConstraints<'tcx>;
-        outlives
+        outlives, pick_constraints
     }
 }
 
diff --git a/src/librustc/infer/canonical/query_response.rs b/src/librustc/infer/canonical/query_response.rs
index 6ce644f8446..02a5005be76 100644
--- a/src/librustc/infer/canonical/query_response.rs
+++ b/src/librustc/infer/canonical/query_response.rs
@@ -340,7 +340,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
                 let r_c = substitute_value(self.tcx, &result_subst, r_c);
 
                 // Screen out `'a: 'a` cases -- we skip the binder here but
-                // only care the inner values to one another, so they are still at
+                // only compare the inner values to one another, so they are still at
                 // consistent binding levels.
                 let &ty::OutlivesPredicate(k1, r2) = r_c.skip_binder();
                 if k1 != r2.into() {
@@ -351,6 +351,13 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
             })
         );
 
+        // ...also include the query pick constraints.
+        output_query_region_constraints.pick_constraints.extend(
+            query_response.value.region_constraints.pick_constraints.iter().map(|p_c| {
+                substitute_value(self.tcx, &result_subst, p_c)
+            })
+        );
+
         let user_result: R =
             query_response.substitute_projected(self.tcx, &result_subst, |q_r| &q_r.value);
 
@@ -662,9 +669,6 @@ pub fn make_query_region_constraints<'tcx>(
     assert!(verifys.is_empty());
     assert!(givens.is_empty());
 
-    // FIXME(ndm) -- we have to think about what to do here, perhaps
-    assert!(pick_constraints.is_empty());
-
     let outlives: Vec<_> = constraints
         .into_iter()
         .map(|(k, _)| match *k {
@@ -690,5 +694,5 @@ pub fn make_query_region_constraints<'tcx>(
         )
         .collect();
 
-    QueryRegionConstraints { outlives }
+    QueryRegionConstraints { outlives, pick_constraints: pick_constraints.clone() }
 }
diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs
index 1340fb807ee..a56c71b2b1f 100644
--- a/src/librustc/infer/region_constraints/mod.rs
+++ b/src/librustc/infer/region_constraints/mod.rs
@@ -150,7 +150,7 @@ impl Constraint<'_> {
 /// ```
 /// pick R0 from [O1..On]
 /// ```
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, HashStable)]
 pub struct PickConstraint<'tcx> {
     /// the def-id of the opaque type causing this constraint: used for error reporting
     pub opaque_type_def_id: DefId,
@@ -165,6 +165,19 @@ pub struct PickConstraint<'tcx> {
     pub option_regions: Rc<Vec<Region<'tcx>>>,
 }
 
+BraceStructTypeFoldableImpl! {
+    impl<'tcx> TypeFoldable<'tcx> for PickConstraint<'tcx> {
+        opaque_type_def_id, hidden_ty, pick_region, option_regions
+    }
+}
+
+BraceStructLiftImpl! {
+    impl<'a, 'tcx> Lift<'tcx> for PickConstraint<'a> {
+        type Lifted = PickConstraint<'tcx>;
+        opaque_type_def_id, hidden_ty, pick_region, option_regions
+    }
+}
+
 /// `VerifyGenericBound(T, _, R, RS)`: the parameter type `T` (or
 /// associated type) must outlive the region `R`. `T` is known to
 /// outlive `RS`. Therefore, verify that `R <= RS[i]` for some
diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs
index 27cd745c20f..74970ebe081 100644
--- a/src/librustc/ty/structural_impls.rs
+++ b/src/librustc/ty/structural_impls.rs
@@ -378,6 +378,13 @@ impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Box<T> {
     }
 }
 
+impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Rc<T> {
+    type Lifted = Rc<T::Lifted>;
+    fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
+        tcx.lift(&**self).map(Rc::new)
+    }
+}
+
 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for [T] {
     type Lifted = Vec<T::Lifted>;
     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
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 2a21da064fa..e92a10f6d48 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
@@ -288,7 +288,7 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> {
         }
 
         for data in constraint_sets {
-            let QueryRegionConstraints { outlives } = &*data;
+            let QueryRegionConstraints { outlives, pick_constraints: _ } = &*data; // TODO
             constraint_conversion::ConstraintConversion::new(
                 self.infcx,
                 &self.universal_regions,
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 08553e6e81f..def4132295d 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -1100,7 +1100,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             locations, data
         );
 
-        let QueryRegionConstraints { outlives } = data;
+        let QueryRegionConstraints { outlives, pick_constraints: _ } = data; // TODO
 
         constraint_conversion::ConstraintConversion::new(
             self.infcx,
@@ -2511,7 +2511,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
     ) -> ty::InstantiatedPredicates<'tcx> {
         if let Some(closure_region_requirements) = tcx.mir_borrowck(def_id).closure_requirements {
             let closure_constraints = QueryRegionConstraints {
-                outlives: closure_region_requirements.apply_requirements(tcx, def_id, substs)
+                outlives: closure_region_requirements.apply_requirements(tcx, def_id, substs),
+                pick_constraints: vec![], // TODO
             };
 
             let bounds_mapping = closure_constraints