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>, + pub pick_constraints: Vec>, } 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>>, } +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 { } } +impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Rc { + type Lifted = Rc; + fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option { + tcx.lift(&**self).map(Rc::new) + } +} + impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for [T] { type Lifted = Vec; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { 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