diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 79a3a247c48a5..154a471a2b385 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -2295,7 +2295,13 @@ impl<'tcx> ClosureRegionRequirementsExt<'tcx> for ClosureRegionRequirements<'tcx outlives_requirement={:?}", region, outlived_region, outlives_requirement, ); - ty::Binder::dummy(ty::OutlivesPredicate(region.into(), outlived_region)) + ( + ty::Binder::dummy(ty::OutlivesPredicate( + region.into(), + outlived_region, + )), + ConstraintCategory::BoringNoLocation, + ) } ClosureOutlivesSubject::Ty(ty) => { @@ -2305,7 +2311,10 @@ impl<'tcx> ClosureRegionRequirementsExt<'tcx> for ClosureRegionRequirements<'tcx outlives_requirement={:?}", ty, outlived_region, outlives_requirement, ); - ty::Binder::dummy(ty::OutlivesPredicate(ty.into(), outlived_region)) + ( + ty::Binder::dummy(ty::OutlivesPredicate(ty.into(), outlived_region)), + ConstraintCategory::BoringNoLocation, + ) } } }) diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs index 9fab7ad914a84..2c9ab35f51b66 100644 --- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs +++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs @@ -98,9 +98,12 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { // 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_bound_vars().unwrap_or_else(|| { - bug!("query_constraint {:?} contained bound vars", query_constraint,); - }); + let ty::OutlivesPredicate(k1, r2) = + query_constraint.0.no_bound_vars().unwrap_or_else(|| { + bug!("query_constraint {:?} contained bound vars", query_constraint,); + }); + + let _constraint_category = query_constraint.1; match k1.unpack() { GenericArgKind::Lifetime(r1) => { diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index d2a54df10b571..5f714cf723ba2 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -2591,7 +2591,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { .enumerate() .filter_map(|(idx, constraint)| { let ty::OutlivesPredicate(k1, r2) = - constraint.no_bound_vars().unwrap_or_else(|| { + constraint.0.no_bound_vars().unwrap_or_else(|| { bug!("query_constraint {:?} contained bound vars", constraint,); }); diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index 64c759f73d410..d0c4846982617 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -22,6 +22,7 @@ use rustc_data_structures::captures::Captures; use rustc_index::vec::Idx; use rustc_index::vec::IndexVec; use rustc_middle::arena::ArenaAllocatable; +use rustc_middle::mir::ConstraintCategory; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::relate::TypeRelation; @@ -248,6 +249,8 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { // the original values `v_o` that was canonicalized into a // variable... + let constraint_category = ConstraintCategory::BoringNoLocation; + for (index, original_value) in original_values.var_values.iter().enumerate() { // ...with the value `v_r` of that variable from the query. let result_value = query_response.substitute_projected(self.tcx, &result_subst, |v| { @@ -263,12 +266,14 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { (GenericArgKind::Lifetime(v_o), GenericArgKind::Lifetime(v_r)) => { // To make `v_o = v_r`, we emit `v_o: v_r` and `v_r: v_o`. if v_o != v_r { - output_query_region_constraints - .outlives - .push(ty::Binder::dummy(ty::OutlivesPredicate(v_o.into(), v_r))); - output_query_region_constraints - .outlives - .push(ty::Binder::dummy(ty::OutlivesPredicate(v_r.into(), v_o))); + output_query_region_constraints.outlives.push(( + ty::Binder::dummy(ty::OutlivesPredicate(v_o.into(), v_r)), + constraint_category, + )); + output_query_region_constraints.outlives.push(( + ty::Binder::dummy(ty::OutlivesPredicate(v_r.into(), v_o)), + constraint_category, + )); } } @@ -314,7 +319,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { // Screen out `'a: 'a` cases -- we skip the binder here but // 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(); + let ty::OutlivesPredicate(k1, r2) = r_c.0.skip_binder(); if k1 != r2.into() { Some(r_c) } else { None } }), ); @@ -559,7 +564,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { cause: ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> Obligation<'tcx, ty::Predicate<'tcx>> { - let ty::OutlivesPredicate(k1, r2) = predicate.skip_binder(); + let ty::OutlivesPredicate(k1, r2) = predicate.0.skip_binder(); let atom = match k1.unpack() { GenericArgKind::Lifetime(r1) => { @@ -574,7 +579,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { span_bug!(cause.span, "unexpected const outlives {:?}", predicate); } }; - let predicate = predicate.rebind(atom).to_predicate(self.tcx); + let predicate = predicate.0.rebind(atom).to_predicate(self.tcx); Obligation::new(cause, param_env, predicate) } @@ -638,26 +643,34 @@ pub fn make_query_region_constraints<'tcx>( let outlives: Vec<_> = constraints .iter() - .map(|(k, _)| match *k { - // Swap regions because we are going from sub (<=) to outlives - // (>=). - Constraint::VarSubVar(v1, v2) => ty::OutlivesPredicate( - tcx.mk_region(ty::ReVar(v2)).into(), - tcx.mk_region(ty::ReVar(v1)), - ), - Constraint::VarSubReg(v1, r2) => { - ty::OutlivesPredicate(r2.into(), tcx.mk_region(ty::ReVar(v1))) - } - Constraint::RegSubVar(r1, v2) => { - ty::OutlivesPredicate(tcx.mk_region(ty::ReVar(v2)).into(), r1) - } - Constraint::RegSubReg(r1, r2) => ty::OutlivesPredicate(r2.into(), r1), + .map(|(k, _)| { + let constraint = ty::Binder::dummy(match *k { + // Swap regions because we are going from sub (<=) to outlives + // (>=). + Constraint::VarSubVar(v1, v2) => ty::OutlivesPredicate( + tcx.mk_region(ty::ReVar(v2)).into(), + tcx.mk_region(ty::ReVar(v1)), + ), + Constraint::VarSubReg(v1, r2) => { + ty::OutlivesPredicate(r2.into(), tcx.mk_region(ty::ReVar(v1))) + } + Constraint::RegSubVar(r1, v2) => { + ty::OutlivesPredicate(tcx.mk_region(ty::ReVar(v2)).into(), r1) + } + Constraint::RegSubReg(r1, r2) => ty::OutlivesPredicate(r2.into(), r1), + }); + + (constraint, ConstraintCategory::BoringNoLocation) }) - .map(ty::Binder::dummy) // no bound vars in the code above .chain( outlives_obligations - .map(|(ty, r)| ty::OutlivesPredicate(ty.into(), r)) - .map(ty::Binder::dummy), // no bound vars in the code above + // no bound vars in the code above + .map(|(ty, r)| { + ( + ty::Binder::dummy(ty::OutlivesPredicate(ty.into(), r)), + ConstraintCategory::BoringNoLocation, + ) + }), ) .collect(); diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index 6873785ace739..d3cf519b633c7 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -22,6 +22,7 @@ //! [c]: https://rust-lang.github.io/chalk/book/canonical_queries/canonicalization.html use crate::infer::MemberConstraint; +use crate::mir::ConstraintCategory; use crate::ty::subst::GenericArg; use crate::ty::{self, BoundVar, List, Region, Ty, TyCtxt}; use rustc_index::vec::IndexVec; @@ -301,8 +302,10 @@ impl<'tcx, V> Canonical<'tcx, V> { } } -pub type QueryOutlivesConstraint<'tcx> = - ty::Binder<'tcx, ty::OutlivesPredicate, Region<'tcx>>>; +pub type QueryOutlivesConstraint<'tcx> = ( + ty::Binder<'tcx, ty::OutlivesPredicate, Region<'tcx>>>, + ConstraintCategory<'tcx>, +); TrivialTypeTraversalAndLiftImpls! { for <'tcx> { diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index 594c14a642ded..d89efe2b3f024 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -327,7 +327,7 @@ rustc_data_structures::static_assert_size!(ConstraintCategory<'_>, 16); /// /// See also `rustc_const_eval::borrow_check::constraints`. #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)] -#[derive(TyEncodable, TyDecodable, HashStable)] +#[derive(TyEncodable, TyDecodable, HashStable, Lift, TypeVisitable, TypeFoldable)] pub enum ConstraintCategory<'tcx> { Return(ReturnConstraint), Yield, @@ -369,7 +369,7 @@ pub enum ConstraintCategory<'tcx> { } #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)] -#[derive(TyEncodable, TyDecodable, HashStable)] +#[derive(TyEncodable, TyDecodable, HashStable, TypeVisitable, TypeFoldable)] pub enum ReturnConstraint { Normal, ClosureUpvar(Field),