summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:18:25 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:18:25 +0000
commit5363f350887b1e5b5dd21a86f88c8af9d7fea6da (patch)
tree35ca005eb6e0e9a1ba3bb5dbc033209ad445dc17 /compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
parentAdding debian version 1.66.0+dfsg1-1. (diff)
downloadrustc-5363f350887b1e5b5dd21a86f88c8af9d7fea6da.tar.xz
rustc-5363f350887b1e5b5dd21a86f88c8af9d7fea6da.zip
Merging upstream version 1.67.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_borrowck/src/type_check/constraint_conversion.rs')
-rw-r--r--compiler/rustc_borrowck/src/type_check/constraint_conversion.rs82
1 files changed, 61 insertions, 21 deletions
diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
index d5bfc2f52..ce7f857e2 100644
--- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
+++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
@@ -1,10 +1,10 @@
-use rustc_infer::infer::canonical::QueryOutlivesConstraint;
+use rustc_hir::def_id::DefId;
use rustc_infer::infer::canonical::QueryRegionConstraints;
use rustc_infer::infer::outlives::env::RegionBoundPairs;
use rustc_infer::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelegate};
use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound};
use rustc_infer::infer::{self, InferCtxt, SubregionOrigin};
-use rustc_middle::mir::ConstraintCategory;
+use rustc_middle::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, ConstraintCategory};
use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::TypeFoldable;
use rustc_middle::ty::{self, TyCtxt};
@@ -38,6 +38,7 @@ pub(crate) struct ConstraintConversion<'a, 'tcx> {
locations: Locations,
span: Span,
category: ConstraintCategory<'tcx>,
+ from_closure: bool,
constraints: &'a mut MirTypeckRegionConstraints<'tcx>,
}
@@ -64,6 +65,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
span,
category,
constraints,
+ from_closure: false,
}
}
@@ -81,12 +83,62 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
}
self.constraints.member_constraints = tmp;
- for query_constraint in outlives {
- self.convert(query_constraint);
+ for (predicate, constraint_category) in outlives {
+ // 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 predicate = predicate.no_bound_vars().unwrap_or_else(|| {
+ bug!("query_constraint {:?} contained bound vars", predicate,);
+ });
+
+ self.convert(predicate, *constraint_category);
}
}
- fn convert(&mut self, query_constraint: &QueryOutlivesConstraint<'tcx>) {
+ /// Given an instance of the closure type, this method instantiates the "extra" requirements
+ /// that we computed for the closure. This has the effect of adding new outlives obligations
+ /// to existing region variables in `closure_substs`.
+ #[instrument(skip(self), level = "debug")]
+ pub fn apply_closure_requirements(
+ &mut self,
+ closure_requirements: &ClosureRegionRequirements<'tcx>,
+ closure_def_id: DefId,
+ closure_substs: ty::SubstsRef<'tcx>,
+ ) {
+ // Extract the values of the free regions in `closure_substs`
+ // into a vector. These are the regions that we will be
+ // relating to one another.
+ let closure_mapping = &UniversalRegions::closure_mapping(
+ self.tcx,
+ closure_substs,
+ closure_requirements.num_external_vids,
+ closure_def_id.expect_local(),
+ );
+ debug!(?closure_mapping);
+
+ // Create the predicates.
+ let backup = (self.category, self.span, self.from_closure);
+ self.from_closure = true;
+ for outlives_requirement in &closure_requirements.outlives_requirements {
+ let outlived_region = closure_mapping[outlives_requirement.outlived_free_region];
+ let subject = match outlives_requirement.subject {
+ ClosureOutlivesSubject::Region(re) => closure_mapping[re].into(),
+ ClosureOutlivesSubject::Ty(ty) => ty.into(),
+ };
+
+ self.category = outlives_requirement.category;
+ self.span = outlives_requirement.blame_span;
+ self.convert(ty::OutlivesPredicate(subject, outlived_region), self.category);
+ }
+ (self.category, self.span, self.from_closure) = backup;
+ }
+
+ fn convert(
+ &mut self,
+ predicate: ty::OutlivesPredicate<ty::GenericArg<'tcx>, ty::Region<'tcx>>,
+ constraint_category: ConstraintCategory<'tcx>,
+ ) {
debug!("generate: constraints at: {:#?}", self.locations);
// Extract out various useful fields we'll need below.
@@ -94,17 +146,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
tcx, region_bound_pairs, implicit_region_bound, param_env, ..
} = *self;
- // 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.0.no_bound_vars().unwrap_or_else(|| {
- bug!("query_constraint {:?} contained bound vars", query_constraint,);
- });
-
- let constraint_category = query_constraint.1;
-
+ let ty::OutlivesPredicate(k1, r2) = predicate;
match k1.unpack() {
GenericArgKind::Lifetime(r1) => {
let r1_vid = self.to_region_vid(r1);
@@ -127,10 +169,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
.type_must_outlive(origin, t1, r2, constraint_category);
}
- GenericArgKind::Const(_) => {
- // Consts cannot outlive one another, so we
- // don't need to handle any relations here.
- }
+ GenericArgKind::Const(_) => unreachable!(),
}
}
@@ -160,7 +199,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
verify_bound: VerifyBound<'tcx>,
) -> TypeTest<'tcx> {
let lower_bound = self.to_region_vid(region);
- TypeTest { generic_kind, lower_bound, locations: self.locations, verify_bound }
+ TypeTest { generic_kind, lower_bound, span: self.span, verify_bound }
}
fn to_region_vid(&mut self, r: ty::Region<'tcx>) -> ty::RegionVid {
@@ -188,6 +227,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
sub,
sup,
variance_info: ty::VarianceDiagInfo::default(),
+ from_closure: self.from_closure,
});
}