about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2020-04-09 10:55:27 +0000
committerNiko Matsakis <niko@alum.mit.edu>2020-04-16 11:03:41 +0000
commitb8caef423d8aaef7afe228c75cb5228431e459f9 (patch)
tree9c261bbb200a0237f913aab60fe65c5386b2ee5a
parent771fdd99852ba8465b76674466b470a1ee3dd3c2 (diff)
downloadrust-b8caef423d8aaef7afe228c75cb5228431e459f9.tar.gz
rust-b8caef423d8aaef7afe228c75cb5228431e459f9.zip
reserve variable for empty root region
-rw-r--r--src/librustc_infer/infer/mod.rs4
-rw-r--r--src/librustc_mir/borrow_check/region_infer/mod.rs18
-rw-r--r--src/librustc_mir/borrow_check/type_check/constraint_conversion.rs8
-rw-r--r--src/librustc_mir/borrow_check/universal_regions.rs19
-rw-r--r--src/test/mir-opt/nll/named-lifetimes-basic/rustc.use_x.nll.0.mir27
-rw-r--r--src/test/mir-opt/nll/region-subtyping-basic.rs4
-rw-r--r--src/test/mir-opt/nll/region-subtyping-basic/64bit/rustc.main.nll.0.mir143
-rw-r--r--src/test/mir-opt/storage_ranges/rustc.main.nll.0.mir11
-rw-r--r--src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr4
-rw-r--r--src/test/ui/hrtb/due-to-where-clause.nll.stderr2
-rw-r--r--src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.nll.stderr2
-rw-r--r--src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.nll.stderr2
-rw-r--r--src/test/ui/nll/issue-68550.rs15
-rw-r--r--src/test/ui/nll/issue-68550.stderr16
14 files changed, 164 insertions, 111 deletions
diff --git a/src/librustc_infer/infer/mod.rs b/src/librustc_infer/infer/mod.rs
index edaa7a04b34..497001d009f 100644
--- a/src/librustc_infer/infer/mod.rs
+++ b/src/librustc_infer/infer/mod.rs
@@ -472,6 +472,9 @@ pub enum NLLRegionVariableOrigin {
     /// from a `for<'a> T` binder). Meant to represent "any region".
     Placeholder(ty::PlaceholderRegion),
 
+    /// The variable we create to represent `'empty(U0)`.
+    RootEmptyRegion,
+
     Existential {
         /// If this is true, then this variable was created to represent a lifetime
         /// bound in a `for` binder. For example, it might have been created to
@@ -493,6 +496,7 @@ impl NLLRegionVariableOrigin {
             NLLRegionVariableOrigin::FreeRegion => true,
             NLLRegionVariableOrigin::Placeholder(..) => true,
             NLLRegionVariableOrigin::Existential { .. } => false,
+            NLLRegionVariableOrigin::RootEmptyRegion => false,
         }
     }
 
diff --git a/src/librustc_mir/borrow_check/region_infer/mod.rs b/src/librustc_mir/borrow_check/region_infer/mod.rs
index 9533d61b7e8..6e0b368b61a 100644
--- a/src/librustc_mir/borrow_check/region_infer/mod.rs
+++ b/src/librustc_mir/borrow_check/region_infer/mod.rs
@@ -481,7 +481,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                     }
                 }
 
-                NLLRegionVariableOrigin::Existential { .. } => {
+                NLLRegionVariableOrigin::RootEmptyRegion
+                | NLLRegionVariableOrigin::Existential { .. } => {
                     // For existential, regions, nothing to do.
                 }
             }
@@ -1323,7 +1324,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                     self.check_bound_universal_region(fr, placeholder, errors_buffer);
                 }
 
-                NLLRegionVariableOrigin::Existential { .. } => {
+                NLLRegionVariableOrigin::RootEmptyRegion
+                | NLLRegionVariableOrigin::Existential { .. } => {
                     // nothing to check here
                 }
             }
@@ -1425,7 +1427,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                     self.check_bound_universal_region(fr, placeholder, errors_buffer);
                 }
 
-                NLLRegionVariableOrigin::Existential { .. } => {
+                NLLRegionVariableOrigin::RootEmptyRegion
+                | NLLRegionVariableOrigin::Existential { .. } => {
                     // nothing to check here
                 }
             }
@@ -1698,9 +1701,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                 universe1.cannot_name(placeholder.universe)
             }
 
-            NLLRegionVariableOrigin::FreeRegion | NLLRegionVariableOrigin::Existential { .. } => {
-                false
-            }
+            NLLRegionVariableOrigin::RootEmptyRegion
+            | NLLRegionVariableOrigin::FreeRegion
+            | NLLRegionVariableOrigin::Existential { .. } => false,
         }
     }
 
@@ -2019,7 +2022,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         let blame_source = match from_region_origin {
             NLLRegionVariableOrigin::FreeRegion
             | NLLRegionVariableOrigin::Existential { from_forall: false } => true,
-            NLLRegionVariableOrigin::Placeholder(_)
+            NLLRegionVariableOrigin::RootEmptyRegion
+            | NLLRegionVariableOrigin::Placeholder(_)
             | NLLRegionVariableOrigin::Existential { from_forall: true } => false,
         };
 
diff --git a/src/librustc_mir/borrow_check/type_check/constraint_conversion.rs b/src/librustc_mir/borrow_check/type_check/constraint_conversion.rs
index 8e4f44e8195..711271a63fb 100644
--- a/src/librustc_mir/borrow_check/type_check/constraint_conversion.rs
+++ b/src/librustc_mir/borrow_check/type_check/constraint_conversion.rs
@@ -160,10 +160,6 @@ impl<'a, 'b, 'tcx> TypeOutlivesDelegate<'tcx> for &'a mut ConstraintConversion<'
         a: ty::Region<'tcx>,
         b: ty::Region<'tcx>,
     ) {
-        // FIXME -- this is not the fix I would prefer
-        if let ty::ReEmpty(ty::UniverseIndex::ROOT) = a {
-            return;
-        }
         let b = self.to_region_vid(b);
         let a = self.to_region_vid(a);
         self.add_outlives(b, a);
@@ -176,10 +172,6 @@ impl<'a, 'b, 'tcx> TypeOutlivesDelegate<'tcx> for &'a mut ConstraintConversion<'
         a: ty::Region<'tcx>,
         bound: VerifyBound<'tcx>,
     ) {
-        // FIXME: I'd prefer if NLL had a notion of empty
-        if let ty::ReEmpty(ty::UniverseIndex::ROOT) = a {
-            return;
-        }
         let type_test = self.verify_to_type_test(kind, a, bound);
         self.add_type_test(type_test);
     }
diff --git a/src/librustc_mir/borrow_check/universal_regions.rs b/src/librustc_mir/borrow_check/universal_regions.rs
index 4d67d7204ca..eb1141739a3 100644
--- a/src/librustc_mir/borrow_check/universal_regions.rs
+++ b/src/librustc_mir/borrow_check/universal_regions.rs
@@ -54,6 +54,13 @@ pub struct UniversalRegions<'tcx> {
     /// The total number of universal region variables instantiated.
     num_universals: usize,
 
+    /// A special region variable created for the `'empty(U0)` region.
+    /// Note that this is **not** a "universal" region, as it doesn't
+    /// represent a universally bound placeholder or any such thing.
+    /// But we do create it here in this type because it's a useful region
+    /// to have around in a few limited cases.
+    pub root_empty: RegionVid,
+
     /// The "defining" type for this function, with all universal
     /// regions instantiated. For a closure or generator, this is the
     /// closure type, but for a top-level function it's the `FnDef`.
@@ -316,7 +323,11 @@ impl<'tcx> UniversalRegions<'tcx> {
 
     /// See `UniversalRegionIndices::to_region_vid`.
     pub fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid {
-        self.indices.to_region_vid(r)
+        if let ty::ReEmpty(ty::UniverseIndex::ROOT) = r {
+            self.root_empty
+        } else {
+            self.indices.to_region_vid(r)
+        }
     }
 
     /// As part of the NLL unit tests, you can annotate a function with
@@ -472,10 +483,16 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
             _ => None,
         };
 
+        let root_empty = self
+            .infcx
+            .next_nll_region_var(NLLRegionVariableOrigin::RootEmptyRegion)
+            .to_region_vid();
+
         UniversalRegions {
             indices,
             fr_static,
             fr_fn_body,
+            root_empty,
             first_extern_index,
             first_local_index,
             num_universals,
diff --git a/src/test/mir-opt/nll/named-lifetimes-basic/rustc.use_x.nll.0.mir b/src/test/mir-opt/nll/named-lifetimes-basic/rustc.use_x.nll.0.mir
index a486af608ef..dcfb069b84a 100644
--- a/src/test/mir-opt/nll/named-lifetimes-basic/rustc.use_x.nll.0.mir
+++ b/src/test/mir-opt/nll/named-lifetimes-basic/rustc.use_x.nll.0.mir
@@ -13,10 +13,11 @@
 | '_#2r | U0 | {bb0[0..=1], '_#2r}
 | '_#3r | U0 | {bb0[0..=1], '_#3r}
 | '_#4r | U0 | {bb0[0..=1], '_#4r}
-| '_#5r | U0 | {bb0[0..=1], '_#1r}
-| '_#6r | U0 | {bb0[0..=1], '_#2r}
-| '_#7r | U0 | {bb0[0..=1], '_#1r}
-| '_#8r | U0 | {bb0[0..=1], '_#3r}
+| '_#5r | U0 | {}
+| '_#6r | U0 | {bb0[0..=1], '_#1r}
+| '_#7r | U0 | {bb0[0..=1], '_#2r}
+| '_#8r | U0 | {bb0[0..=1], '_#1r}
+| '_#9r | U0 | {bb0[0..=1], '_#3r}
 |
 | Inference Constraints
 | '_#0r live at {bb0[0..=1]}
@@ -24,16 +25,16 @@
 | '_#2r live at {bb0[0..=1]}
 | '_#3r live at {bb0[0..=1]}
 | '_#4r live at {bb0[0..=1]}
-| '_#1r: '_#5r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:26: 12:27)
-| '_#1r: '_#7r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:54: 12:55)
-| '_#2r: '_#6r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:42: 12:43)
-| '_#3r: '_#8r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:66: 12:67)
-| '_#5r: '_#1r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:26: 12:27)
-| '_#6r: '_#2r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:42: 12:43)
-| '_#7r: '_#1r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:54: 12:55)
-| '_#8r: '_#3r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:66: 12:67)
+| '_#1r: '_#6r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:26: 12:27)
+| '_#1r: '_#8r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:54: 12:55)
+| '_#2r: '_#7r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:42: 12:43)
+| '_#3r: '_#9r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:66: 12:67)
+| '_#6r: '_#1r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:26: 12:27)
+| '_#7r: '_#2r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:42: 12:43)
+| '_#8r: '_#1r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:54: 12:55)
+| '_#9r: '_#3r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:66: 12:67)
 |
-fn use_x(_1: &'_#5r mut i32, _2: &'_#6r u32, _3: &'_#7r u32, _4: &'_#8r u32) -> bool {
+fn use_x(_1: &'_#6r mut i32, _2: &'_#7r u32, _3: &'_#8r u32, _4: &'_#9r u32) -> bool {
     debug w => _1;                       // in scope 0 at $DIR/named-lifetimes-basic.rs:12:26: 12:27
     debug x => _2;                       // in scope 0 at $DIR/named-lifetimes-basic.rs:12:42: 12:43
     debug y => _3;                       // in scope 0 at $DIR/named-lifetimes-basic.rs:12:54: 12:55
diff --git a/src/test/mir-opt/nll/region-subtyping-basic.rs b/src/test/mir-opt/nll/region-subtyping-basic.rs
index 740cb1c5e96..66d7cda2b85 100644
--- a/src/test/mir-opt/nll/region-subtyping-basic.rs
+++ b/src/test/mir-opt/nll/region-subtyping-basic.rs
@@ -7,7 +7,9 @@
 
 #![allow(warnings)]
 
-fn use_x(_: usize) -> bool { true }
+fn use_x(_: usize) -> bool {
+    true
+}
 
 // EMIT_MIR_FOR_EACH_BIT_WIDTH
 // EMIT_MIR rustc.main.nll.0.mir
diff --git a/src/test/mir-opt/nll/region-subtyping-basic/64bit/rustc.main.nll.0.mir b/src/test/mir-opt/nll/region-subtyping-basic/64bit/rustc.main.nll.0.mir
index 4a285d035be..61db4dba586 100644
--- a/src/test/mir-opt/nll/region-subtyping-basic/64bit/rustc.main.nll.0.mir
+++ b/src/test/mir-opt/nll/region-subtyping-basic/64bit/rustc.main.nll.0.mir
@@ -7,164 +7,165 @@
 | Inferred Region Values
 | '_#0r | U0 | {bb0[0..=8], bb1[0], bb2[0..=8], bb3[0], bb4[0..=1], bb5[0..=3], bb6[0..=3], bb7[0..=2], bb8[0..=5], '_#0r, '_#1r}
 | '_#1r | U0 | {bb0[0..=8], bb1[0], bb2[0..=8], bb3[0], bb4[0..=1], bb5[0..=3], bb6[0..=3], bb7[0..=2], bb8[0..=5], '_#1r}
-| '_#2r | U0 | {bb2[0..=8], bb3[0], bb5[0..=2]}
-| '_#3r | U0 | {bb2[1..=8], bb3[0], bb5[0..=2]}
-| '_#4r | U0 | {bb2[4..=8], bb3[0], bb5[0..=2]}
+| '_#2r | U0 | {}
+| '_#3r | U0 | {bb2[0..=8], bb3[0], bb5[0..=2]}
+| '_#4r | U0 | {bb2[1..=8], bb3[0], bb5[0..=2]}
+| '_#5r | U0 | {bb2[4..=8], bb3[0], bb5[0..=2]}
 |
 | Inference Constraints
 | '_#0r live at {bb0[0..=8], bb1[0], bb2[0..=8], bb3[0], bb4[0..=1], bb5[0..=3], bb6[0..=3], bb7[0..=2], bb8[0..=5]}
 | '_#1r live at {bb0[0..=8], bb1[0], bb2[0..=8], bb3[0], bb4[0..=1], bb5[0..=3], bb6[0..=3], bb7[0..=2], bb8[0..=5]}
-| '_#2r live at {bb2[0]}
-| '_#3r live at {bb2[1..=3]}
-| '_#4r live at {bb2[4..=8], bb3[0], bb5[0..=2]}
-| '_#2r: '_#3r due to Assignment at Single(bb2[0])
-| '_#3r: '_#4r due to Assignment at Single(bb2[3])
+| '_#3r live at {bb2[0]}
+| '_#4r live at {bb2[1..=3]}
+| '_#5r live at {bb2[4..=8], bb3[0], bb5[0..=2]}
+| '_#3r: '_#4r due to Assignment at Single(bb2[0])
+| '_#4r: '_#5r due to Assignment at Single(bb2[3])
 |
 fn main() -> () {
-    let mut _0: ();                      // return place in scope 0 at $DIR/region-subtyping-basic.rs:14:11: 14:11
-    let mut _1: [usize; Const { ty: usize, val: Value(Scalar(0x0000000000000003)) }]; // in scope 0 at $DIR/region-subtyping-basic.rs:15:9: 15:14
-    let _3: usize;                       // in scope 0 at $DIR/region-subtyping-basic.rs:16:16: 16:17
-    let mut _4: usize;                   // in scope 0 at $DIR/region-subtyping-basic.rs:16:14: 16:18
-    let mut _5: bool;                    // in scope 0 at $DIR/region-subtyping-basic.rs:16:14: 16:18
-    let mut _7: bool;                    // in scope 0 at $DIR/region-subtyping-basic.rs:18:8: 18:12
-    let _8: bool;                        // in scope 0 at $DIR/region-subtyping-basic.rs:19:9: 19:18
-    let mut _9: usize;                   // in scope 0 at $DIR/region-subtyping-basic.rs:19:15: 19:17
-    let _10: bool;                       // in scope 0 at $DIR/region-subtyping-basic.rs:21:9: 21:18
+    let mut _0: ();                      // return place in scope 0 at $DIR/region-subtyping-basic.rs:16:11: 16:11
+    let mut _1: [usize; Const { ty: usize, val: Value(Scalar(0x0000000000000003)) }]; // in scope 0 at $DIR/region-subtyping-basic.rs:17:9: 17:14
+    let _3: usize;                       // in scope 0 at $DIR/region-subtyping-basic.rs:18:16: 18:17
+    let mut _4: usize;                   // in scope 0 at $DIR/region-subtyping-basic.rs:18:14: 18:18
+    let mut _5: bool;                    // in scope 0 at $DIR/region-subtyping-basic.rs:18:14: 18:18
+    let mut _7: bool;                    // in scope 0 at $DIR/region-subtyping-basic.rs:20:8: 20:12
+    let _8: bool;                        // in scope 0 at $DIR/region-subtyping-basic.rs:21:9: 21:18
+    let mut _9: usize;                   // in scope 0 at $DIR/region-subtyping-basic.rs:21:15: 21:17
+    let _10: bool;                       // in scope 0 at $DIR/region-subtyping-basic.rs:23:9: 23:18
     scope 1 {
-        debug v => _1;                   // in scope 1 at $DIR/region-subtyping-basic.rs:15:9: 15:14
-        let _2: &'_#3r usize;            // in scope 1 at $DIR/region-subtyping-basic.rs:16:9: 16:10
+        debug v => _1;                   // in scope 1 at $DIR/region-subtyping-basic.rs:17:9: 17:14
+        let _2: &'_#4r usize;            // in scope 1 at $DIR/region-subtyping-basic.rs:18:9: 18:10
         scope 2 {
-            debug p => _2;               // in scope 2 at $DIR/region-subtyping-basic.rs:16:9: 16:10
-            let _6: &'_#4r usize;        // in scope 2 at $DIR/region-subtyping-basic.rs:17:9: 17:10
+            debug p => _2;               // in scope 2 at $DIR/region-subtyping-basic.rs:18:9: 18:10
+            let _6: &'_#5r usize;        // in scope 2 at $DIR/region-subtyping-basic.rs:19:9: 19:10
             scope 3 {
-                debug q => _6;           // in scope 3 at $DIR/region-subtyping-basic.rs:17:9: 17:10
+                debug q => _6;           // in scope 3 at $DIR/region-subtyping-basic.rs:19:9: 19:10
             }
         }
     }
 
     bb0: {
-        StorageLive(_1);                 // bb0[0]: scope 0 at $DIR/region-subtyping-basic.rs:15:9: 15:14
-        _1 = [const Const(Value(Scalar(0x0000000000000001)): usize), const Const(Value(Scalar(0x0000000000000002)): usize), const Const(Value(Scalar(0x0000000000000003)): usize)]; // bb0[1]: scope 0 at $DIR/region-subtyping-basic.rs:15:17: 15:26
+        StorageLive(_1);                 // bb0[0]: scope 0 at $DIR/region-subtyping-basic.rs:17:9: 17:14
+        _1 = [const Const(Value(Scalar(0x0000000000000001)): usize), const Const(Value(Scalar(0x0000000000000002)): usize), const Const(Value(Scalar(0x0000000000000003)): usize)]; // bb0[1]: scope 0 at $DIR/region-subtyping-basic.rs:17:17: 17:26
                                          // ty::Const
                                          // + ty: usize
                                          // + val: Value(Scalar(0x0000000000000001))
                                          // mir::Constant
-                                         // + span: $DIR/region-subtyping-basic.rs:15:18: 15:19
+                                         // + span: $DIR/region-subtyping-basic.rs:17:18: 17:19
                                          // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000001)) }
                                          // ty::Const
                                          // + ty: usize
                                          // + val: Value(Scalar(0x0000000000000002))
                                          // mir::Constant
-                                         // + span: $DIR/region-subtyping-basic.rs:15:21: 15:22
+                                         // + span: $DIR/region-subtyping-basic.rs:17:21: 17:22
                                          // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000002)) }
                                          // ty::Const
                                          // + ty: usize
                                          // + val: Value(Scalar(0x0000000000000003))
                                          // mir::Constant
-                                         // + span: $DIR/region-subtyping-basic.rs:15:24: 15:25
+                                         // + span: $DIR/region-subtyping-basic.rs:17:24: 17:25
                                          // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000003)) }
-        FakeRead(ForLet, _1);            // bb0[2]: scope 0 at $DIR/region-subtyping-basic.rs:15:9: 15:14
-        StorageLive(_2);                 // bb0[3]: scope 1 at $DIR/region-subtyping-basic.rs:16:9: 16:10
-        StorageLive(_3);                 // bb0[4]: scope 1 at $DIR/region-subtyping-basic.rs:16:16: 16:17
-        _3 = const Const(Value(Scalar(0x0000000000000000)): usize); // bb0[5]: scope 1 at $DIR/region-subtyping-basic.rs:16:16: 16:17
+        FakeRead(ForLet, _1);            // bb0[2]: scope 0 at $DIR/region-subtyping-basic.rs:17:9: 17:14
+        StorageLive(_2);                 // bb0[3]: scope 1 at $DIR/region-subtyping-basic.rs:18:9: 18:10
+        StorageLive(_3);                 // bb0[4]: scope 1 at $DIR/region-subtyping-basic.rs:18:16: 18:17
+        _3 = const Const(Value(Scalar(0x0000000000000000)): usize); // bb0[5]: scope 1 at $DIR/region-subtyping-basic.rs:18:16: 18:17
                                          // ty::Const
                                          // + ty: usize
                                          // + val: Value(Scalar(0x0000000000000000))
                                          // mir::Constant
-                                         // + span: $DIR/region-subtyping-basic.rs:16:16: 16:17
+                                         // + span: $DIR/region-subtyping-basic.rs:18:16: 18:17
                                          // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000000)) }
-        _4 = Len(_1);                    // bb0[6]: scope 1 at $DIR/region-subtyping-basic.rs:16:14: 16:18
-        _5 = Lt(_3, _4);                 // bb0[7]: scope 1 at $DIR/region-subtyping-basic.rs:16:14: 16:18
-        assert(move _5, "index out of bounds: the len is {} but the index is {}", move _4, _3) -> [success: bb2, unwind: bb1]; // bb0[8]: scope 1 at $DIR/region-subtyping-basic.rs:16:14: 16:18
+        _4 = Len(_1);                    // bb0[6]: scope 1 at $DIR/region-subtyping-basic.rs:18:14: 18:18
+        _5 = Lt(_3, _4);                 // bb0[7]: scope 1 at $DIR/region-subtyping-basic.rs:18:14: 18:18
+        assert(move _5, "index out of bounds: the len is {} but the index is {}", move _4, _3) -> [success: bb2, unwind: bb1]; // bb0[8]: scope 1 at $DIR/region-subtyping-basic.rs:18:14: 18:18
     }
 
     bb1 (cleanup): {
-        resume;                          // bb1[0]: scope 0 at $DIR/region-subtyping-basic.rs:14:1: 23:2
+        resume;                          // bb1[0]: scope 0 at $DIR/region-subtyping-basic.rs:16:1: 25:2
     }
 
     bb2: {
-        _2 = &'_#2r _1[_3];              // bb2[0]: scope 1 at $DIR/region-subtyping-basic.rs:16:13: 16:18
-        FakeRead(ForLet, _2);            // bb2[1]: scope 1 at $DIR/region-subtyping-basic.rs:16:9: 16:10
-        StorageLive(_6);                 // bb2[2]: scope 2 at $DIR/region-subtyping-basic.rs:17:9: 17:10
-        _6 = _2;                         // bb2[3]: scope 2 at $DIR/region-subtyping-basic.rs:17:13: 17:14
-        FakeRead(ForLet, _6);            // bb2[4]: scope 2 at $DIR/region-subtyping-basic.rs:17:9: 17:10
-        StorageLive(_7);                 // bb2[5]: scope 3 at $DIR/region-subtyping-basic.rs:18:8: 18:12
-        _7 = const Const(Value(Scalar(0x01)): bool); // bb2[6]: scope 3 at $DIR/region-subtyping-basic.rs:18:8: 18:12
+        _2 = &'_#3r _1[_3];              // bb2[0]: scope 1 at $DIR/region-subtyping-basic.rs:18:13: 18:18
+        FakeRead(ForLet, _2);            // bb2[1]: scope 1 at $DIR/region-subtyping-basic.rs:18:9: 18:10
+        StorageLive(_6);                 // bb2[2]: scope 2 at $DIR/region-subtyping-basic.rs:19:9: 19:10
+        _6 = _2;                         // bb2[3]: scope 2 at $DIR/region-subtyping-basic.rs:19:13: 19:14
+        FakeRead(ForLet, _6);            // bb2[4]: scope 2 at $DIR/region-subtyping-basic.rs:19:9: 19:10
+        StorageLive(_7);                 // bb2[5]: scope 3 at $DIR/region-subtyping-basic.rs:20:8: 20:12
+        _7 = const Const(Value(Scalar(0x01)): bool); // bb2[6]: scope 3 at $DIR/region-subtyping-basic.rs:20:8: 20:12
                                          // ty::Const
                                          // + ty: bool
                                          // + val: Value(Scalar(0x01))
                                          // mir::Constant
-                                         // + span: $DIR/region-subtyping-basic.rs:18:8: 18:12
+                                         // + span: $DIR/region-subtyping-basic.rs:20:8: 20:12
                                          // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
-        FakeRead(ForMatchedPlace, _7);   // bb2[7]: scope 3 at $DIR/region-subtyping-basic.rs:18:8: 18:12
-        switchInt(_7) -> [Const(Value(Scalar(0x00)): bool): bb4, otherwise: bb3]; // bb2[8]: scope 3 at $DIR/region-subtyping-basic.rs:18:5: 22:6
+        FakeRead(ForMatchedPlace, _7);   // bb2[7]: scope 3 at $DIR/region-subtyping-basic.rs:20:8: 20:12
+        switchInt(_7) -> [Const(Value(Scalar(0x00)): bool): bb4, otherwise: bb3]; // bb2[8]: scope 3 at $DIR/region-subtyping-basic.rs:20:5: 24:6
     }
 
     bb3: {
-        falseEdges -> [real: bb5, imaginary: bb4]; // bb3[0]: scope 3 at $DIR/region-subtyping-basic.rs:18:5: 22:6
+        falseEdges -> [real: bb5, imaginary: bb4]; // bb3[0]: scope 3 at $DIR/region-subtyping-basic.rs:20:5: 24:6
     }
 
     bb4: {
-        StorageLive(_10);                // bb4[0]: scope 3 at $DIR/region-subtyping-basic.rs:21:9: 21:18
-        _10 = const Const(Value(Scalar(<ZST>)): fn(usize) -> bool {use_x})(const Const(Value(Scalar(0x0000000000000016)): usize)) -> [return: bb7, unwind: bb1]; // bb4[1]: scope 3 at $DIR/region-subtyping-basic.rs:21:9: 21:18
+        StorageLive(_10);                // bb4[0]: scope 3 at $DIR/region-subtyping-basic.rs:23:9: 23:18
+        _10 = const Const(Value(Scalar(<ZST>)): fn(usize) -> bool {use_x})(const Const(Value(Scalar(0x0000000000000016)): usize)) -> [return: bb7, unwind: bb1]; // bb4[1]: scope 3 at $DIR/region-subtyping-basic.rs:23:9: 23:18
                                          // ty::Const
                                          // + ty: fn(usize) -> bool {use_x}
                                          // + val: Value(Scalar(<ZST>))
                                          // mir::Constant
-                                         // + span: $DIR/region-subtyping-basic.rs:21:9: 21:14
+                                         // + span: $DIR/region-subtyping-basic.rs:23:9: 23:14
                                          // + literal: Const { ty: fn(usize) -> bool {use_x}, val: Value(Scalar(<ZST>)) }
                                          // ty::Const
                                          // + ty: usize
                                          // + val: Value(Scalar(0x0000000000000016))
                                          // mir::Constant
-                                         // + span: $DIR/region-subtyping-basic.rs:21:15: 21:17
+                                         // + span: $DIR/region-subtyping-basic.rs:23:15: 23:17
                                          // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000016)) }
     }
 
     bb5: {
-        StorageLive(_8);                 // bb5[0]: scope 3 at $DIR/region-subtyping-basic.rs:19:9: 19:18
-        StorageLive(_9);                 // bb5[1]: scope 3 at $DIR/region-subtyping-basic.rs:19:15: 19:17
-        _9 = (*_6);                      // bb5[2]: scope 3 at $DIR/region-subtyping-basic.rs:19:15: 19:17
-        _8 = const Const(Value(Scalar(<ZST>)): fn(usize) -> bool {use_x})(move _9) -> [return: bb6, unwind: bb1]; // bb5[3]: scope 3 at $DIR/region-subtyping-basic.rs:19:9: 19:18
+        StorageLive(_8);                 // bb5[0]: scope 3 at $DIR/region-subtyping-basic.rs:21:9: 21:18
+        StorageLive(_9);                 // bb5[1]: scope 3 at $DIR/region-subtyping-basic.rs:21:15: 21:17
+        _9 = (*_6);                      // bb5[2]: scope 3 at $DIR/region-subtyping-basic.rs:21:15: 21:17
+        _8 = const Const(Value(Scalar(<ZST>)): fn(usize) -> bool {use_x})(move _9) -> [return: bb6, unwind: bb1]; // bb5[3]: scope 3 at $DIR/region-subtyping-basic.rs:21:9: 21:18
                                          // ty::Const
                                          // + ty: fn(usize) -> bool {use_x}
                                          // + val: Value(Scalar(<ZST>))
                                          // mir::Constant
-                                         // + span: $DIR/region-subtyping-basic.rs:19:9: 19:14
+                                         // + span: $DIR/region-subtyping-basic.rs:21:9: 21:14
                                          // + literal: Const { ty: fn(usize) -> bool {use_x}, val: Value(Scalar(<ZST>)) }
     }
 
     bb6: {
-        StorageDead(_9);                 // bb6[0]: scope 3 at $DIR/region-subtyping-basic.rs:19:17: 19:18
-        StorageDead(_8);                 // bb6[1]: scope 3 at $DIR/region-subtyping-basic.rs:19:18: 19:19
-        _0 = const Const(Value(Scalar(<ZST>)): ()); // bb6[2]: scope 3 at $DIR/region-subtyping-basic.rs:18:13: 20:6
+        StorageDead(_9);                 // bb6[0]: scope 3 at $DIR/region-subtyping-basic.rs:21:17: 21:18
+        StorageDead(_8);                 // bb6[1]: scope 3 at $DIR/region-subtyping-basic.rs:21:18: 21:19
+        _0 = const Const(Value(Scalar(<ZST>)): ()); // bb6[2]: scope 3 at $DIR/region-subtyping-basic.rs:20:13: 22:6
                                          // ty::Const
                                          // + ty: ()
                                          // + val: Value(Scalar(<ZST>))
                                          // mir::Constant
-                                         // + span: $DIR/region-subtyping-basic.rs:18:13: 20:6
+                                         // + span: $DIR/region-subtyping-basic.rs:20:13: 22:6
                                          // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
-        goto -> bb8;                     // bb6[3]: scope 3 at $DIR/region-subtyping-basic.rs:18:5: 22:6
+        goto -> bb8;                     // bb6[3]: scope 3 at $DIR/region-subtyping-basic.rs:20:5: 24:6
     }
 
     bb7: {
-        StorageDead(_10);                // bb7[0]: scope 3 at $DIR/region-subtyping-basic.rs:21:18: 21:19
-        _0 = const Const(Value(Scalar(<ZST>)): ()); // bb7[1]: scope 3 at $DIR/region-subtyping-basic.rs:20:12: 22:6
+        StorageDead(_10);                // bb7[0]: scope 3 at $DIR/region-subtyping-basic.rs:23:18: 23:19
+        _0 = const Const(Value(Scalar(<ZST>)): ()); // bb7[1]: scope 3 at $DIR/region-subtyping-basic.rs:22:12: 24:6
                                          // ty::Const
                                          // + ty: ()
                                          // + val: Value(Scalar(<ZST>))
                                          // mir::Constant
-                                         // + span: $DIR/region-subtyping-basic.rs:20:12: 22:6
+                                         // + span: $DIR/region-subtyping-basic.rs:22:12: 24:6
                                          // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
-        goto -> bb8;                     // bb7[2]: scope 3 at $DIR/region-subtyping-basic.rs:18:5: 22:6
+        goto -> bb8;                     // bb7[2]: scope 3 at $DIR/region-subtyping-basic.rs:20:5: 24:6
     }
 
     bb8: {
-        StorageDead(_6);                 // bb8[0]: scope 2 at $DIR/region-subtyping-basic.rs:23:1: 23:2
-        StorageDead(_3);                 // bb8[1]: scope 1 at $DIR/region-subtyping-basic.rs:23:1: 23:2
-        StorageDead(_2);                 // bb8[2]: scope 1 at $DIR/region-subtyping-basic.rs:23:1: 23:2
-        StorageDead(_1);                 // bb8[3]: scope 0 at $DIR/region-subtyping-basic.rs:23:1: 23:2
-        StorageDead(_7);                 // bb8[4]: scope 0 at $DIR/region-subtyping-basic.rs:23:1: 23:2
-        return;                          // bb8[5]: scope 0 at $DIR/region-subtyping-basic.rs:23:2: 23:2
+        StorageDead(_6);                 // bb8[0]: scope 2 at $DIR/region-subtyping-basic.rs:25:1: 25:2
+        StorageDead(_3);                 // bb8[1]: scope 1 at $DIR/region-subtyping-basic.rs:25:1: 25:2
+        StorageDead(_2);                 // bb8[2]: scope 1 at $DIR/region-subtyping-basic.rs:25:1: 25:2
+        StorageDead(_1);                 // bb8[3]: scope 0 at $DIR/region-subtyping-basic.rs:25:1: 25:2
+        StorageDead(_7);                 // bb8[4]: scope 0 at $DIR/region-subtyping-basic.rs:25:1: 25:2
+        return;                          // bb8[5]: scope 0 at $DIR/region-subtyping-basic.rs:25:2: 25:2
     }
 }
diff --git a/src/test/mir-opt/storage_ranges/rustc.main.nll.0.mir b/src/test/mir-opt/storage_ranges/rustc.main.nll.0.mir
index e455a27642d..e66ca0b1355 100644
--- a/src/test/mir-opt/storage_ranges/rustc.main.nll.0.mir
+++ b/src/test/mir-opt/storage_ranges/rustc.main.nll.0.mir
@@ -7,15 +7,16 @@
 | Inferred Region Values
 | '_#0r | U0 | {bb0[0..=22], '_#0r, '_#1r}
 | '_#1r | U0 | {bb0[0..=22], '_#1r}
-| '_#2r | U0 | {bb0[10..=11]}
-| '_#3r | U0 | {bb0[11]}
+| '_#2r | U0 | {}
+| '_#3r | U0 | {bb0[10..=11]}
+| '_#4r | U0 | {bb0[11]}
 |
 | Inference Constraints
 | '_#0r live at {bb0[0..=22]}
 | '_#1r live at {bb0[0..=22]}
-| '_#2r live at {bb0[10]}
-| '_#3r live at {bb0[11]}
-| '_#2r: '_#3r due to Assignment at Single(bb0[10])
+| '_#3r live at {bb0[10]}
+| '_#4r live at {bb0[11]}
+| '_#3r: '_#4r due to Assignment at Single(bb0[10])
 |
 fn main() -> () {
     let mut _0: ();                      // return place in scope 0 at $DIR/storage_ranges.rs:3:11: 3:11
diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr
index c69595a3f4d..da584e8ad4e 100644
--- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr
+++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr
@@ -34,7 +34,7 @@ LL | |     (a, b)
 LL | | }
    | |_^
    |
-   = note: hidden type `(&u8, &u8)` captures lifetime '_#4r
+   = note: hidden type `(&u8, &u8)` captures lifetime '_#5r
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
   --> $DIR/ret-impl-trait-no-fg.rs:9:1
@@ -48,7 +48,7 @@ LL | |     (a, b)
 LL | | }
    | |_^
    |
-   = note: hidden type `(&u8, &u8)` captures lifetime '_#5r
+   = note: hidden type `(&u8, &u8)` captures lifetime '_#6r
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/hrtb/due-to-where-clause.nll.stderr b/src/test/ui/hrtb/due-to-where-clause.nll.stderr
index e476047a7a6..90803a0adb0 100644
--- a/src/test/ui/hrtb/due-to-where-clause.nll.stderr
+++ b/src/test/ui/hrtb/due-to-where-clause.nll.stderr
@@ -2,7 +2,7 @@ error: higher-ranked subtype error
   --> $DIR/due-to-where-clause.rs:2:5
    |
 LL |     test::<FooS>(&mut 42);
-   |     ^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.nll.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.nll.stderr
index 5bfc446f6a5..129af80ce4a 100644
--- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.nll.stderr
+++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.nll.stderr
@@ -4,7 +4,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e>
    |                                                                          ^^^^^^^^^^^^^^^^^^
    |
-   = note: hidden type `Ordinary<'_>` captures lifetime '_#8r
+   = note: hidden type `Ordinary<'_>` captures lifetime '_#9r
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.nll.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.nll.stderr
index 7291eee7b9e..de6d5edcae5 100644
--- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.nll.stderr
+++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.nll.stderr
@@ -4,7 +4,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b>
    |                                                              ^^^^^^^^^^^^^^^^^^
    |
-   = note: hidden type `Ordinary<'_>` captures lifetime '_#5r
+   = note: hidden type `Ordinary<'_>` captures lifetime '_#6r
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/issue-68550.rs b/src/test/ui/nll/issue-68550.rs
new file mode 100644
index 00000000000..6bfd18de18c
--- /dev/null
+++ b/src/test/ui/nll/issue-68550.rs
@@ -0,0 +1,15 @@
+// Regression test for issue #68550.
+//
+// The `&'static A:` where clause was triggering
+// ICEs because it wound up being compiled to reference
+// the `'empty(U0)` region.
+
+fn run<'a, A>(x: A)
+where
+    A: 'static,
+    &'static A: ,
+{
+    let _: &'a A = &x; //~ ERROR `x` does not live long enough
+}
+
+fn main() {}
diff --git a/src/test/ui/nll/issue-68550.stderr b/src/test/ui/nll/issue-68550.stderr
new file mode 100644
index 00000000000..e234ebb04e1
--- /dev/null
+++ b/src/test/ui/nll/issue-68550.stderr
@@ -0,0 +1,16 @@
+error[E0597]: `x` does not live long enough
+  --> $DIR/issue-68550.rs:12:20
+   |
+LL | fn run<'a, A>(x: A)
+   |        -- lifetime `'a` defined here
+...
+LL |     let _: &'a A = &x;
+   |            -----   ^^ borrowed value does not live long enough
+   |            |
+   |            type annotation requires that `x` is borrowed for `'a`
+LL | }
+   | - `x` dropped here while still borrowed
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.