about summary refs log tree commit diff
path: root/compiler/rustc_borrowck/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-07-16 03:31:32 +0000
committerbors <bors@rust-lang.org>2022-07-16 03:31:32 +0000
commitefd358333ac55ca50f786ca1ab841c003bfdfff0 (patch)
tree1f273c18c6057e8a60dd17e88a84edfc67fd7a90 /compiler/rustc_borrowck/src
parent93ef0cd7fd86d3d05cee131070a8a2cb45f3efab (diff)
parentf0227e8b9fc502156532d9ce0d6164705af299f4 (diff)
downloadrust-efd358333ac55ca50f786ca1ab841c003bfdfff0.tar.gz
rust-efd358333ac55ca50f786ca1ab841c003bfdfff0.zip
Auto merge of #99300 - Mark-Simulacrum:beta-next, r=Mark-Simulacrum
[beta] rollup

*  Fix sized check ICE in asm check #99124
*  Windows: Fallback for overlapped I/O #98950
*  promote placeholder bounds to 'static obligations #98713
*  Create fresh lifetime parameters for bare fn trait too #98637

r? `@Mark-Simulacrum`
Diffstat (limited to 'compiler/rustc_borrowck/src')
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs38
1 files changed, 33 insertions, 5 deletions
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index 0fe3b45bc7c..44a0e6205b4 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -916,6 +916,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     /// The idea then is to lower the `T: 'X` constraint into multiple
     /// bounds -- e.g., if `'X` is the union of two free lifetimes,
     /// `'1` and `'2`, then we would create `T: '1` and `T: '2`.
+    #[instrument(level = "debug", skip(self, infcx, propagated_outlives_requirements))]
     fn try_promote_type_test(
         &self,
         infcx: &InferCtxt<'_, 'tcx>,
@@ -933,11 +934,41 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             return false;
         };
 
+        debug!("subject = {:?}", subject);
+
+        let r_scc = self.constraint_sccs.scc(*lower_bound);
+
+        debug!(
+            "lower_bound = {:?} r_scc={:?} universe={:?}",
+            lower_bound, r_scc, self.scc_universes[r_scc]
+        );
+
+        // If the type test requires that `T: 'a` where `'a` is a
+        // placeholder from another universe, that effectively requires
+        // `T: 'static`, so we have to propagate that requirement.
+        //
+        // It doesn't matter *what* universe because the promoted `T` will
+        // always be in the root universe.
+        if let Some(p) = self.scc_values.placeholders_contained_in(r_scc).next() {
+            debug!("encountered placeholder in higher universe: {:?}, requiring 'static", p);
+            let static_r = self.universal_regions.fr_static;
+            propagated_outlives_requirements.push(ClosureOutlivesRequirement {
+                subject,
+                outlived_free_region: static_r,
+                blame_span: locations.span(body),
+                category: ConstraintCategory::Boring,
+            });
+
+            // we can return here -- the code below might push add'l constraints
+            // but they would all be weaker than this one.
+            return true;
+        }
+
         // For each region outlived by lower_bound find a non-local,
         // universal region (it may be the same region) and add it to
         // `ClosureOutlivesRequirement`.
-        let r_scc = self.constraint_sccs.scc(*lower_bound);
         for ur in self.scc_values.universal_regions_outlived_by(r_scc) {
+            debug!("universal_region_outlived_by ur={:?}", ur);
             // Check whether we can already prove that the "subject" outlives `ur`.
             // If so, we don't have to propagate this requirement to our caller.
             //
@@ -962,8 +993,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                 continue;
             }
 
-            debug!("try_promote_type_test: ur={:?}", ur);
-
             let non_local_ub = self.universal_region_relations.non_local_upper_bounds(ur);
             debug!("try_promote_type_test: non_local_ub={:?}", non_local_ub);
 
@@ -1000,6 +1029,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     /// will use it's *external name*, which will be a `RegionKind`
     /// variant that can be used in query responses such as
     /// `ReEarlyBound`.
+    #[instrument(level = "debug", skip(self, infcx))]
     fn try_promote_type_test_subject(
         &self,
         infcx: &InferCtxt<'_, 'tcx>,
@@ -1007,8 +1037,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     ) -> Option<ClosureOutlivesSubject<'tcx>> {
         let tcx = infcx.tcx;
 
-        debug!("try_promote_type_test_subject(ty = {:?})", ty);
-
         let ty = tcx.fold_regions(ty, &mut false, |r, _depth| {
             let region_vid = self.to_region_vid(r);