about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-10-12 21:28:42 +0000
committerbors <bors@rust-lang.org>2018-10-12 21:28:42 +0000
commit2c2e2c57dc2140cfb62a8abb9312b89f02c59f3c (patch)
tree7c0ceebbf2041990fc9899f550ee7adcbd7fedae /src
parent945372d26818f93d6f5cded7b751749e280b67bf (diff)
parentc312e04d45fc6254cc25f7277b2d84ff3128c036 (diff)
downloadrust-2c2e2c57dc2140cfb62a8abb9312b89f02c59f3c.tar.gz
rust-2c2e2c57dc2140cfb62a8abb9312b89f02c59f3c.zip
Auto merge of #54942 - matthewjasper:wf-type-annotations, r=nikomatsakis
[NLL] Check user types are well-formed

Also contains a change of span for AscribeUserType.
I'm not quite sure if this was what @nikomatsakis was thinking.

Closes #54620

r? @nikomatsakis
Diffstat (limited to 'src')
-rw-r--r--src/librustc/mir/mod.rs2
-rw-r--r--src/librustc/mir/visit.rs2
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/mod.rs14
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs21
-rw-r--r--src/librustc_mir/build/matches/mod.rs37
-rw-r--r--src/librustc_mir/build/matches/simplify.rs4
-rw-r--r--src/librustc_mir/hair/cx/block.rs1
-rw-r--r--src/librustc_mir/hair/pattern/mod.rs4
-rw-r--r--src/test/mir-opt/basic_assignment.rs2
-rw-r--r--src/test/ui/associated-types/associated-types-subtyping-1.nll.stderr24
-rw-r--r--src/test/ui/associated-types/associated-types-subtyping-1.rs20
-rw-r--r--src/test/ui/nll/relate_tys/hr-fn-aaa-as-aba.stderr4
-rw-r--r--src/test/ui/nll/user-annotations/patterns.stderr4
-rw-r--r--src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr4
-rw-r--r--src/test/ui/regions/regions-addr-of-self.nll.stderr4
-rw-r--r--src/test/ui/regions/regions-addr-of-upvar-self.nll.stderr12
-rw-r--r--src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.nll.stderr13
-rw-r--r--src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.rs7
-rw-r--r--src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.stderr14
-rw-r--r--src/test/ui/regions/regions-free-region-ordering-caller.nll.stderr33
-rw-r--r--src/test/ui/regions/regions-free-region-ordering-caller.rs2
-rw-r--r--src/test/ui/regions/regions-free-region-ordering-caller.stderr6
-rw-r--r--src/test/ui/regions/regions-free-region-ordering-caller1.nll.stderr20
-rw-r--r--src/test/ui/regions/regions-implied-bounds-projection-gap-1.nll.stderr11
-rw-r--r--src/test/ui/regions/regions-implied-bounds-projection-gap-1.rs2
-rw-r--r--src/test/ui/regions/regions-implied-bounds-projection-gap-1.stderr4
-rw-r--r--src/test/ui/regions/regions-infer-contravariance-due-to-decl.nll.stderr4
-rw-r--r--src/test/ui/regions/regions-infer-covariance-due-to-decl.nll.stderr4
-rw-r--r--src/test/ui/regions/regions-outlives-projection-container-wc.nll.stderr13
-rw-r--r--src/test/ui/regions/regions-outlives-projection-container-wc.rs6
-rw-r--r--src/test/ui/regions/regions-outlives-projection-container-wc.stderr14
-rw-r--r--src/test/ui/regions/regions-outlives-projection-container.nll.stderr46
-rw-r--r--src/test/ui/regions/regions-outlives-projection-container.rs12
-rw-r--r--src/test/ui/regions/regions-outlives-projection-container.stderr48
-rw-r--r--src/test/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.nll.stderr4
-rw-r--r--src/test/ui/regions/regions-variance-contravariant-use-covariant.nll.stderr4
-rw-r--r--src/test/ui/regions/regions-variance-covariant-use-contravariant.nll.stderr4
-rw-r--r--src/test/ui/regions/regions-variance-invariant-use-contravariant.nll.stderr4
-rw-r--r--src/test/ui/regions/regions-variance-invariant-use-covariant.nll.stderr4
-rw-r--r--src/test/ui/try-block/try-block-bad-lifetime.stderr2
-rw-r--r--src/test/ui/variance/variance-cell-is-invariant.nll.stderr4
-rw-r--r--src/test/ui/wf/wf-static-method.nll.stderr33
42 files changed, 343 insertions, 134 deletions
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index ea4eb761964..2587e19b1cb 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -710,7 +710,7 @@ pub struct LocalDecl<'tcx> {
     /// e.g. via `let x: T`, then we carry that type here. The MIR
     /// borrow checker needs this information since it can affect
     /// region inference.
-    pub user_ty: Option<CanonicalTy<'tcx>>,
+    pub user_ty: Option<(CanonicalTy<'tcx>, Span)>,
 
     /// Name of the local, used in debuginfo and pretty-printing.
     ///
diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs
index d2b0a6a37a7..920dc88d6a8 100644
--- a/src/librustc/mir/visit.rs
+++ b/src/librustc/mir/visit.rs
@@ -735,7 +735,7 @@ macro_rules! make_mir_visitor {
                     local,
                     source_info: *source_info,
                 });
-                if let Some(user_ty) = user_ty {
+                if let Some((user_ty, _)) = user_ty {
                     self.visit_user_ty(user_ty);
                 }
                 self.visit_source_info(source_info);
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 36eb695186c..e11f452e16b 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -310,12 +310,12 @@ impl<'a, 'b, 'gcx, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'gcx, 'tcx> {
         self.super_local_decl(local, local_decl);
         self.sanitize_type(local_decl, local_decl.ty);
 
-        if let Some(user_ty) = local_decl.user_ty {
+        if let Some((user_ty, span)) = local_decl.user_ty {
             if let Err(terr) = self.cx.relate_type_and_user_type(
                 local_decl.ty,
                 ty::Variance::Invariant,
                 user_ty,
-                Locations::All(local_decl.source_info.span),
+                Locations::All(span),
                 ConstraintCategory::TypeAnnotation,
             ) {
                 span_mirbug!(
@@ -970,7 +970,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
         locations: Locations,
         category: ConstraintCategory,
     ) -> Fallible<()> {
-        relate_tys::relate_type_and_user_type(
+        let ty = relate_tys::relate_type_and_user_type(
             self.infcx,
             a,
             v,
@@ -978,7 +978,13 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
             locations,
             category,
             self.borrowck_context.as_mut().map(|x| &mut **x),
-        )
+        )?;
+        self.prove_predicate(
+            ty::Predicate::WellFormed(ty),
+            locations,
+            category,
+        );
+        Ok(())
     }
 
     fn eq_opaque_type_and_type(
diff --git a/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs b/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs
index 41aab02d1e8..1e279aef079 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs
@@ -10,7 +10,7 @@
 
 use borrow_check::nll::constraints::OutlivesConstraint;
 use borrow_check::nll::type_check::{BorrowCheckContext, Locations};
-use rustc::infer::canonical::{Canonical, CanonicalVarInfos};
+use rustc::infer::canonical::{Canonical, CanonicalVarInfos, CanonicalVarValues};
 use rustc::infer::{InferCtxt, NLLRegionVariableOrigin};
 use rustc::mir::ConstraintCategory;
 use rustc::traits::query::Fallible;
@@ -70,7 +70,7 @@ pub(super) fn relate_type_and_user_type<'tcx>(
     locations: Locations,
     category: ConstraintCategory,
     borrowck_context: Option<&mut BorrowCheckContext<'_, 'tcx>>,
-) -> Fallible<()> {
+) -> Fallible<Ty<'tcx>> {
     debug!(
         "sub_type_and_user_type(a={:?}, b={:?}, locations={:?})",
         a, b, locations
@@ -85,13 +85,24 @@ pub(super) fn relate_type_and_user_type<'tcx>(
     // variance to get the right relationship.
     let v1 = ty::Contravariant.xform(v);
 
-    TypeRelating::new(
+    let mut type_relating = TypeRelating::new(
         infcx.tcx,
         NllTypeRelatingDelegate::new(infcx, borrowck_context, locations, category),
         v1,
         b_variables,
-    ).relate(&b_value, &a)?;
-    Ok(())
+    );
+    type_relating.relate(&b_value, &a)?;
+
+    Ok(b.substitute(
+        infcx.tcx,
+        &CanonicalVarValues {
+            var_values: type_relating
+                .canonical_var_values
+                .into_iter()
+                .map(|x| x.expect("unsubstituted canonical variable"))
+                .collect(),
+        },
+    ))
 }
 
 struct TypeRelating<'me, 'gcx: 'tcx, 'tcx: 'me, D>
diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs
index c2a7172d54c..394fa4e077c 100644
--- a/src/librustc_mir/build/matches/mod.rs
+++ b/src/librustc_mir/build/matches/mod.rs
@@ -292,30 +292,32 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                     ..
                 },
                 user_ty: ascription_user_ty,
+                user_ty_span,
             } => {
                 let place =
                     self.storage_live_binding(block, var, irrefutable_pat.span, OutsideGuard);
                 unpack!(block = self.into(&place, block, initializer));
 
-                let source_info = self.source_info(irrefutable_pat.span);
+                // Inject a fake read, see comments on `FakeReadCause::ForLet`.
+                let pattern_source_info = self.source_info(irrefutable_pat.span);
                 self.cfg.push(
                     block,
                     Statement {
-                        source_info,
-                        kind: StatementKind::AscribeUserType(
-                            place.clone(),
-                            ty::Variance::Invariant,
-                            ascription_user_ty,
-                        ),
+                        source_info: pattern_source_info,
+                        kind: StatementKind::FakeRead(FakeReadCause::ForLet, place.clone()),
                     },
                 );
 
-                // Inject a fake read, see comments on `FakeReadCause::ForLet`.
+                let ty_source_info = self.source_info(user_ty_span);
                 self.cfg.push(
                     block,
                     Statement {
-                        source_info,
-                        kind: StatementKind::FakeRead(FakeReadCause::ForLet, place.clone()),
+                        source_info: ty_source_info,
+                        kind: StatementKind::AscribeUserType(
+                            place.clone(),
+                            ty::Variance::Invariant,
+                            ascription_user_ty,
+                        ),
                     },
                 );
 
@@ -489,7 +491,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
     pub fn visit_bindings(
         &mut self,
         pattern: &Pattern<'tcx>,
-        mut pattern_user_ty: Option<CanonicalTy<'tcx>>,
+        mut pattern_user_ty: Option<(CanonicalTy<'tcx>, Span)>,
         f: &mut impl FnMut(
             &mut Self,
             Mutability,
@@ -498,7 +500,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
             NodeId,
             Span,
             Ty<'tcx>,
-            Option<CanonicalTy<'tcx>>,
+            Option<(CanonicalTy<'tcx>, Span)>,
         ),
     ) {
         match *pattern.kind {
@@ -549,16 +551,15 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                 // FIXME(#47184): extract or handle `pattern_user_ty` somehow
                 self.visit_bindings(subpattern, None, f);
             }
-            PatternKind::AscribeUserType { ref subpattern, user_ty } => {
+            PatternKind::AscribeUserType { ref subpattern, user_ty, user_ty_span } => {
                 // This corresponds to something like
                 //
                 // ```
-                // let (p1: T1): T2 = ...;
+                // let A::<'a>(_): A<'static> = ...;
                 // ```
                 //
-                // Not presently possible, though maybe someday.
-                assert!(pattern_user_ty.is_none());
-                self.visit_bindings(subpattern, Some(user_ty), f)
+                // FIXME(#47184): handle `pattern_user_ty` somehow
+                self.visit_bindings(subpattern, Some((user_ty, user_ty_span)), f)
             }
             PatternKind::Leaf { ref subpatterns }
             | PatternKind::Variant {
@@ -1469,7 +1470,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
         num_patterns: usize,
         var_id: NodeId,
         var_ty: Ty<'tcx>,
-        user_var_ty: Option<CanonicalTy<'tcx>>,
+        user_var_ty: Option<(CanonicalTy<'tcx>, Span)>,
         has_guard: ArmHasGuard,
         opt_match_place: Option<(Option<Place<'tcx>>, Span)>,
         pat_span: Span,
diff --git a/src/librustc_mir/build/matches/simplify.rs b/src/librustc_mir/build/matches/simplify.rs
index 14da8e90838..494e7c03c3e 100644
--- a/src/librustc_mir/build/matches/simplify.rs
+++ b/src/librustc_mir/build/matches/simplify.rs
@@ -63,9 +63,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                                  candidate: &mut Candidate<'pat, 'tcx>)
                                  -> Result<(), MatchPair<'pat, 'tcx>> {
         match *match_pair.pattern.kind {
-            PatternKind::AscribeUserType { ref subpattern, user_ty } => {
+            PatternKind::AscribeUserType { ref subpattern, user_ty, user_ty_span } => {
                 candidate.ascriptions.push(Ascription {
-                    span: match_pair.pattern.span,
+                    span: user_ty_span,
                     user_ty,
                     source: match_pair.place.clone(),
                 });
diff --git a/src/librustc_mir/hair/cx/block.rs b/src/librustc_mir/hair/cx/block.rs
index 2ab0a57a855..022c606a0f8 100644
--- a/src/librustc_mir/hair/cx/block.rs
+++ b/src/librustc_mir/hair/cx/block.rs
@@ -92,6 +92,7 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
                                     span: pattern.span,
                                     kind: Box::new(PatternKind::AscribeUserType {
                                         user_ty: *user_ty,
+                                        user_ty_span: ty.span,
                                         subpattern: pattern
                                     })
                                 };
diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs
index 04090e5087f..0238a23895e 100644
--- a/src/librustc_mir/hair/pattern/mod.rs
+++ b/src/librustc_mir/hair/pattern/mod.rs
@@ -71,6 +71,7 @@ pub enum PatternKind<'tcx> {
     AscribeUserType {
         user_ty: CanonicalTy<'tcx>,
         subpattern: Pattern<'tcx>,
+        user_ty_span: Span,
     },
 
     /// x, ref x, x @ P, etc
@@ -692,6 +693,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
             kind = PatternKind::AscribeUserType {
                 subpattern,
                 user_ty,
+                user_ty_span: span,
             };
         }
 
@@ -1015,9 +1017,11 @@ impl<'tcx> PatternFoldable<'tcx> for PatternKind<'tcx> {
             PatternKind::AscribeUserType {
                 ref subpattern,
                 user_ty,
+                user_ty_span,
             } => PatternKind::AscribeUserType {
                 subpattern: subpattern.fold_with(folder),
                 user_ty: user_ty.fold_with(folder),
+                user_ty_span,
             },
             PatternKind::Binding {
                 mutability,
diff --git a/src/test/mir-opt/basic_assignment.rs b/src/test/mir-opt/basic_assignment.rs
index b474e1a0d6c..1abe63afa80 100644
--- a/src/test/mir-opt/basic_assignment.rs
+++ b/src/test/mir-opt/basic_assignment.rs
@@ -55,8 +55,8 @@ fn main() {
 //        StorageDead(_3);
 //        StorageLive(_4);
 //        _4 = std::option::Option<std::boxed::Box<u32>>::None;
-//        AscribeUserType(_4, o, Canonical { variables: [], value: std::option::Option<std::boxed::Box<u32>> });
 //        FakeRead(ForLet, _4);
+//        AscribeUserType(_4, o, Canonical { variables: [], value: std::option::Option<std::boxed::Box<u32>> });
 //        StorageLive(_5);
 //        StorageLive(_6);
 //        _6 = move _4;
diff --git a/src/test/ui/associated-types/associated-types-subtyping-1.nll.stderr b/src/test/ui/associated-types/associated-types-subtyping-1.nll.stderr
new file mode 100644
index 00000000000..1156c773b8c
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-subtyping-1.nll.stderr
@@ -0,0 +1,24 @@
+error: unsatisfied lifetime constraints
+  --> $DIR/associated-types-subtyping-1.rs:36:13
+   |
+LL | fn method2<'a,'b,T>(x: &'a T, y: &'b T)
+   |            -- -- lifetime `'b` defined here
+   |            |
+   |            lifetime `'a` defined here
+...
+LL |     let _c: <T as Trait<'b>>::Type = a; //~ ERROR E0623
+   |             ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
+
+error: unsatisfied lifetime constraints
+  --> $DIR/associated-types-subtyping-1.rs:44:12
+   |
+LL | fn method3<'a,'b,T>(x: &'a T, y: &'b T)
+   |            -- -- lifetime `'b` defined here
+   |            |
+   |            lifetime `'a` defined here
+...
+LL |     let b: <T as Trait<'b>>::Type = make_any();
+   |            ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/associated-types/associated-types-subtyping-1.rs b/src/test/ui/associated-types/associated-types-subtyping-1.rs
index c3acffff240..479cb359a78 100644
--- a/src/test/ui/associated-types/associated-types-subtyping-1.rs
+++ b/src/test/ui/associated-types/associated-types-subtyping-1.rs
@@ -8,10 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-compare-mode-nll
-
 #![allow(unused_variables)]
 
+fn make_any<T>() -> T {  loop {} }
+
 trait Trait<'a> {
     type Type;
 
@@ -22,8 +22,8 @@ fn method1<'a,'b,T>(x: &'a T, y: &'b T)
     where T : for<'z> Trait<'z>, 'a : 'b
 {
     // Note that &'static T <: &'a T.
-    let a: <T as Trait<'a>>::Type = loop { };
-    let b: <T as Trait<'b>>::Type = loop { };
+    let a: <T as Trait<'a>>::Type = make_any();
+    let b: <T as Trait<'b>>::Type = make_any();
     let _c: <T as Trait<'a>>::Type = a;
 }
 
@@ -31,8 +31,8 @@ fn method2<'a,'b,T>(x: &'a T, y: &'b T)
     where T : for<'z> Trait<'z>, 'a : 'b
 {
     // Note that &'static T <: &'a T.
-    let a: <T as Trait<'a>>::Type = loop { };
-    let b: <T as Trait<'b>>::Type = loop { };
+    let a: <T as Trait<'a>>::Type = make_any();
+    let b: <T as Trait<'b>>::Type = make_any();
     let _c: <T as Trait<'b>>::Type = a; //~ ERROR E0623
 }
 
@@ -40,8 +40,8 @@ fn method3<'a,'b,T>(x: &'a T, y: &'b T)
     where T : for<'z> Trait<'z>, 'a : 'b
 {
     // Note that &'static T <: &'a T.
-    let a: <T as Trait<'a>>::Type = loop { };
-    let b: <T as Trait<'b>>::Type = loop { };
+    let a: <T as Trait<'a>>::Type = make_any();
+    let b: <T as Trait<'b>>::Type = make_any();
     let _c: <T as Trait<'a>>::Type = b; //~ ERROR E0623
 }
 
@@ -49,8 +49,8 @@ fn method4<'a,'b,T>(x: &'a T, y: &'b T)
     where T : for<'z> Trait<'z>, 'a : 'b
 {
     // Note that &'static T <: &'a T.
-    let a: <T as Trait<'a>>::Type = loop { };
-    let b: <T as Trait<'b>>::Type = loop { };
+    let a: <T as Trait<'a>>::Type = make_any();
+    let b: <T as Trait<'b>>::Type = make_any();
     let _c: <T as Trait<'b>>::Type = b;
 }
 
diff --git a/src/test/ui/nll/relate_tys/hr-fn-aaa-as-aba.stderr b/src/test/ui/nll/relate_tys/hr-fn-aaa-as-aba.stderr
index 9a83872b965..a4d47eed6fb 100644
--- a/src/test/ui/nll/relate_tys/hr-fn-aaa-as-aba.stderr
+++ b/src/test/ui/nll/relate_tys/hr-fn-aaa-as-aba.stderr
@@ -5,10 +5,10 @@ LL |     let a: for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32 = make_it();
    |                                                          ^^^^^^^^^
 
 error: higher-ranked subtype error
-  --> $DIR/hr-fn-aaa-as-aba.rs:32:9
+  --> $DIR/hr-fn-aaa-as-aba.rs:32:12
    |
 LL |     let _: for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32 = make_it();
-   |         ^
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/nll/user-annotations/patterns.stderr b/src/test/ui/nll/user-annotations/patterns.stderr
index b01dc65fc5f..0b0848e9913 100644
--- a/src/test/ui/nll/user-annotations/patterns.stderr
+++ b/src/test/ui/nll/user-annotations/patterns.stderr
@@ -131,12 +131,12 @@ LL |     y //~ ERROR
    |     ^ returning this value requires that `'a` must outlive `'static`
 
 error: unsatisfied lifetime constraints
-  --> $DIR/patterns.rs:117:9
+  --> $DIR/patterns.rs:117:18
    |
 LL | fn a_to_static_then_static<'a>(x: &'a u32) -> &'static u32 {
    |                            -- lifetime `'a` defined here
 LL |     let (y, _z): (&'static u32, u32) = (x, 44); //~ ERROR
-   |         ^^^^^^^ type annotation requires that `'a` must outlive `'static`
+   |                  ^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
 
 error: aborting due to 14 previous errors
 
diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr
index 53d3b2d5323..8fd195639fe 100644
--- a/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr
+++ b/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr
@@ -1,10 +1,10 @@
 error[E0621]: explicit lifetime required in the type of `v`
-  --> $DIR/region-object-lifetime-in-coercion.rs:18:9
+  --> $DIR/region-object-lifetime-in-coercion.rs:18:12
    |
 LL | fn a(v: &[u8]) -> Box<Foo + 'static> {
    |         ----- help: add explicit lifetime `'static` to the type of `v`: `&'static [u8]`
 LL |     let x: Box<Foo + 'static> = Box::new(v);
-   |         ^ lifetime `'static` required
+   |            ^^^^^^^^^^^^^^^^^^ lifetime `'static` required
 
 error[E0621]: explicit lifetime required in the type of `v`
   --> $DIR/region-object-lifetime-in-coercion.rs:24:5
diff --git a/src/test/ui/regions/regions-addr-of-self.nll.stderr b/src/test/ui/regions/regions-addr-of-self.nll.stderr
index 0e38abef668..1454c856f97 100644
--- a/src/test/ui/regions/regions-addr-of-self.nll.stderr
+++ b/src/test/ui/regions/regions-addr-of-self.nll.stderr
@@ -1,10 +1,10 @@
 error: unsatisfied lifetime constraints
-  --> $DIR/regions-addr-of-self.rs:17:13
+  --> $DIR/regions-addr-of-self.rs:17:16
    |
 LL |     pub fn chase_cat(&mut self) {
    |                      - let's call the lifetime of this reference `'1`
 LL |         let p: &'static mut usize = &mut self.cats_chased; //~ ERROR cannot infer
-   |             ^ type annotation requires that `'1` must outlive `'static`
+   |                ^^^^^^^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'static`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/regions/regions-addr-of-upvar-self.nll.stderr b/src/test/ui/regions/regions-addr-of-upvar-self.nll.stderr
index fd52494b499..0e48192eaff 100644
--- a/src/test/ui/regions/regions-addr-of-upvar-self.nll.stderr
+++ b/src/test/ui/regions/regions-addr-of-upvar-self.nll.stderr
@@ -1,33 +1,33 @@
 error: unsatisfied lifetime constraints
-  --> $DIR/regions-addr-of-upvar-self.rs:20:17
+  --> $DIR/regions-addr-of-upvar-self.rs:20:20
    |
 LL |         let _f = || {
    |                  -- lifetime `'1` represents this closure's body
 LL |             let p: &'static mut usize = &mut self.food; //~ ERROR cannot infer
-   |                 ^ type annotation requires that `'1` must outlive `'static`
+   |                    ^^^^^^^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'static`
    |
    = note: closure implements `FnMut`, so references to captured variables can't escape the closure
 
 error: unsatisfied lifetime constraints
-  --> $DIR/regions-addr-of-upvar-self.rs:20:17
+  --> $DIR/regions-addr-of-upvar-self.rs:20:20
    |
 LL |     pub fn chase_cat(&mut self) {
    |                      --------- lifetime `'2` appears in the type of `self`
 LL |         let _f = || {
    |                  -- lifetime `'1` represents this closure's body
 LL |             let p: &'static mut usize = &mut self.food; //~ ERROR cannot infer
-   |                 ^ type annotation requires that `'1` must outlive `'2`
+   |                    ^^^^^^^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'2`
    |
    = note: closure implements `FnMut`, so references to captured variables can't escape the closure
 
 error: unsatisfied lifetime constraints
-  --> $DIR/regions-addr-of-upvar-self.rs:20:17
+  --> $DIR/regions-addr-of-upvar-self.rs:20:20
    |
 LL |     pub fn chase_cat(&mut self) {
    |                      - let's call the lifetime of this reference `'1`
 LL |         let _f = || {
 LL |             let p: &'static mut usize = &mut self.food; //~ ERROR cannot infer
-   |                 ^ type annotation requires that `'1` must outlive `'static`
+   |                    ^^^^^^^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'static`
 
 error[E0597]: `self` does not live long enough
   --> $DIR/regions-addr-of-upvar-self.rs:20:46
diff --git a/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.nll.stderr b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.nll.stderr
new file mode 100644
index 00000000000..f711541fbd5
--- /dev/null
+++ b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.nll.stderr
@@ -0,0 +1,13 @@
+error: unsatisfied lifetime constraints
+  --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:52:13
+   |
+LL | fn with_assoc<'a,'b>() {
+   |               -- -- lifetime `'b` defined here
+   |               |
+   |               lifetime `'a` defined here
+...
+LL |     let _x: &'a WithAssoc<TheType<'b>> = loop { };
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.rs b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.rs
index 96eb65daaff..741feb1f9ea 100644
--- a/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.rs
+++ b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-compare-mode-nll
-
 // Test that we are imposing the requirement that every associated
 // type of a bound that appears in the where clause on a struct must
 // outlive the location in which the type appears, even when the
@@ -49,7 +47,10 @@ fn with_assoc<'a,'b>() {
     // outlive 'a. In this case, that means TheType<'b>::TheAssocType,
     // which is &'b (), must outlive 'a.
 
-    let _: &'a WithAssoc<TheType<'b>> = loop { }; //~ ERROR reference has a longer lifetime
+    // FIXME (#54943) NLL doesn't enforce WF condition in unreachable code if
+    // `_x` is changed to `_`
+    let _x: &'a WithAssoc<TheType<'b>> = loop { };
+    //~^ ERROR reference has a longer lifetime
 }
 
 fn main() {
diff --git a/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.stderr b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.stderr
index 7b7881d6ea7..7959d1b6c23 100644
--- a/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.stderr
+++ b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.stderr
@@ -1,16 +1,16 @@
 error[E0491]: in type `&'a WithAssoc<TheType<'b>>`, reference has a longer lifetime than the data it references
-  --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:52:12
+  --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:52:13
    |
-LL |     let _: &'a WithAssoc<TheType<'b>> = loop { }; //~ ERROR reference has a longer lifetime
-   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     let _x: &'a WithAssoc<TheType<'b>> = loop { };
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: the pointer is valid for the lifetime 'a as defined on the function body at 46:15
-  --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:46:15
+note: the pointer is valid for the lifetime 'a as defined on the function body at 44:15
+  --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:44:15
    |
 LL | fn with_assoc<'a,'b>() {
    |               ^^
-note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 46:18
-  --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:46:18
+note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 44:18
+  --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:44:18
    |
 LL | fn with_assoc<'a,'b>() {
    |                  ^^
diff --git a/src/test/ui/regions/regions-free-region-ordering-caller.nll.stderr b/src/test/ui/regions/regions-free-region-ordering-caller.nll.stderr
new file mode 100644
index 00000000000..8d4f3d1e87f
--- /dev/null
+++ b/src/test/ui/regions/regions-free-region-ordering-caller.nll.stderr
@@ -0,0 +1,33 @@
+error: unsatisfied lifetime constraints
+  --> $DIR/regions-free-region-ordering-caller.rs:18:12
+   |
+LL | fn call2<'a, 'b>(a: &'a usize, b: &'b usize) {
+   |          --  -- lifetime `'b` defined here
+   |          |
+   |          lifetime `'a` defined here
+LL |     let z: Option<&'b &'a usize> = None;//~ ERROR E0623
+   |            ^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'b`
+
+error: unsatisfied lifetime constraints
+  --> $DIR/regions-free-region-ordering-caller.rs:23:12
+   |
+LL | fn call3<'a, 'b>(a: &'a usize, b: &'b usize) {
+   |          --  -- lifetime `'b` defined here
+   |          |
+   |          lifetime `'a` defined here
+LL |     let y: Paramd<'a> = Paramd { x: a };
+LL |     let z: Option<&'b Paramd<'a>> = None;//~ ERROR E0623
+   |            ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'b`
+
+error: unsatisfied lifetime constraints
+  --> $DIR/regions-free-region-ordering-caller.rs:27:12
+   |
+LL | fn call4<'a, 'b>(a: &'a usize, b: &'b usize) {
+   |          --  -- lifetime `'b` defined here
+   |          |
+   |          lifetime `'a` defined here
+LL |     let z: Option<&'a &'b usize> = None;//~ ERROR E0623
+   |            ^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/regions/regions-free-region-ordering-caller.rs b/src/test/ui/regions/regions-free-region-ordering-caller.rs
index ee6cd6c4b15..66b16744cc7 100644
--- a/src/test/ui/regions/regions-free-region-ordering-caller.rs
+++ b/src/test/ui/regions/regions-free-region-ordering-caller.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-compare-mode-nll
-
 // Test various ways to construct a pointer with a longer lifetime
 // than the thing it points at and ensure that they result in
 // errors. See also regions-free-region-ordering-callee.rs
diff --git a/src/test/ui/regions/regions-free-region-ordering-caller.stderr b/src/test/ui/regions/regions-free-region-ordering-caller.stderr
index 96502b69c08..a3645995b5e 100644
--- a/src/test/ui/regions/regions-free-region-ordering-caller.stderr
+++ b/src/test/ui/regions/regions-free-region-ordering-caller.stderr
@@ -1,5 +1,5 @@
 error[E0623]: lifetime mismatch
-  --> $DIR/regions-free-region-ordering-caller.rs:20:12
+  --> $DIR/regions-free-region-ordering-caller.rs:18:12
    |
 LL | fn call2<'a, 'b>(a: &'a usize, b: &'b usize) {
    |                     ---------     ---------
@@ -9,7 +9,7 @@ LL |     let z: Option<&'b &'a usize> = None;//~ ERROR E0623
    |            ^^^^^^^^^^^^^^^^^^^^^ ...but data from `a` flows into `b` here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/regions-free-region-ordering-caller.rs:25:12
+  --> $DIR/regions-free-region-ordering-caller.rs:23:12
    |
 LL | fn call3<'a, 'b>(a: &'a usize, b: &'b usize) {
    |                     ---------     ---------
@@ -20,7 +20,7 @@ LL |     let z: Option<&'b Paramd<'a>> = None;//~ ERROR E0623
    |            ^^^^^^^^^^^^^^^^^^^^^^ ...but data from `a` flows into `b` here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/regions-free-region-ordering-caller.rs:29:12
+  --> $DIR/regions-free-region-ordering-caller.rs:27:12
    |
 LL | fn call4<'a, 'b>(a: &'a usize, b: &'b usize) {
    |                     ---------     --------- these two types are declared with different lifetimes...
diff --git a/src/test/ui/regions/regions-free-region-ordering-caller1.nll.stderr b/src/test/ui/regions/regions-free-region-ordering-caller1.nll.stderr
index 75758206d6b..9747602f1ba 100644
--- a/src/test/ui/regions/regions-free-region-ordering-caller1.nll.stderr
+++ b/src/test/ui/regions/regions-free-region-ordering-caller1.nll.stderr
@@ -13,6 +13,22 @@ note: borrowed value must be valid for the lifetime 'a as defined on the functio
 LL | fn call1<'a>(x: &'a usize) {
    |          ^^
 
-error: aborting due to previous error
+error[E0597]: `y` does not live long enough
+  --> $DIR/regions-free-region-ordering-caller1.rs:19:27
+   |
+LL |     let z: &'a & usize = &(&y);
+   |                           ^^^^ borrowed value does not live long enough
+...
+LL | }
+   | - `y` dropped here while still borrowed
+   |
+note: borrowed value must be valid for the lifetime 'a as defined on the function body at 15:10...
+  --> $DIR/regions-free-region-ordering-caller1.rs:15:10
+   |
+LL | fn call1<'a>(x: &'a usize) {
+   |          ^^
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0716`.
+Some errors occurred: E0597, E0716.
+For more information about an error, try `rustc --explain E0597`.
diff --git a/src/test/ui/regions/regions-implied-bounds-projection-gap-1.nll.stderr b/src/test/ui/regions/regions-implied-bounds-projection-gap-1.nll.stderr
new file mode 100644
index 00000000000..2eb4ccf1c35
--- /dev/null
+++ b/src/test/ui/regions/regions-implied-bounds-projection-gap-1.nll.stderr
@@ -0,0 +1,11 @@
+error[E0309]: the parameter type `T` may not live long enough
+  --> $DIR/regions-implied-bounds-projection-gap-1.rs:26:5
+   |
+LL |     wf::<&'x T>();
+   |     ^^^^^^^^^^^^^
+   |
+   = help: consider adding an explicit lifetime bound `T: 'x`...
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0309`.
diff --git a/src/test/ui/regions/regions-implied-bounds-projection-gap-1.rs b/src/test/ui/regions/regions-implied-bounds-projection-gap-1.rs
index 01de3ddcdf8..65594ab8f2e 100644
--- a/src/test/ui/regions/regions-implied-bounds-projection-gap-1.rs
+++ b/src/test/ui/regions/regions-implied-bounds-projection-gap-1.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-compare-mode-nll
-
 // Illustrates the "projection gap": in this test, even though we know
 // that `T::Foo: 'x`, that does not tell us that `T: 'x`, because
 // there might be other ways for the caller of `func` to show that
diff --git a/src/test/ui/regions/regions-implied-bounds-projection-gap-1.stderr b/src/test/ui/regions/regions-implied-bounds-projection-gap-1.stderr
index e6efb4d5c6b..41ae515bb9a 100644
--- a/src/test/ui/regions/regions-implied-bounds-projection-gap-1.stderr
+++ b/src/test/ui/regions/regions-implied-bounds-projection-gap-1.stderr
@@ -1,5 +1,5 @@
 error[E0309]: the parameter type `T` may not live long enough
-  --> $DIR/regions-implied-bounds-projection-gap-1.rs:28:10
+  --> $DIR/regions-implied-bounds-projection-gap-1.rs:26:10
    |
 LL | fn func<'x, T:Trait1<'x>>(t: &'x T::Foo)
    |             -- help: consider adding an explicit lifetime bound `T: 'x`...
@@ -8,7 +8,7 @@ LL |     wf::<&'x T>();
    |          ^^^^^
    |
 note: ...so that the reference type `&'x T` does not outlive the data it points at
-  --> $DIR/regions-implied-bounds-projection-gap-1.rs:28:10
+  --> $DIR/regions-implied-bounds-projection-gap-1.rs:26:10
    |
 LL |     wf::<&'x T>();
    |          ^^^^^
diff --git a/src/test/ui/regions/regions-infer-contravariance-due-to-decl.nll.stderr b/src/test/ui/regions/regions-infer-contravariance-due-to-decl.nll.stderr
index 2f3c7166867..aba285d427b 100644
--- a/src/test/ui/regions/regions-infer-contravariance-due-to-decl.nll.stderr
+++ b/src/test/ui/regions/regions-infer-contravariance-due-to-decl.nll.stderr
@@ -1,5 +1,5 @@
 error: unsatisfied lifetime constraints
-  --> $DIR/regions-infer-contravariance-due-to-decl.rs:35:9
+  --> $DIR/regions-infer-contravariance-due-to-decl.rs:35:12
    |
 LL | fn use_<'short,'long>(c: Contravariant<'short>,
    |         ------ ----- lifetime `'long` defined here
@@ -7,7 +7,7 @@ LL | fn use_<'short,'long>(c: Contravariant<'short>,
    |         lifetime `'short` defined here
 ...
 LL |     let _: Contravariant<'long> = c; //~ ERROR E0623
-   |         ^ type annotation requires that `'short` must outlive `'long`
+   |            ^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/regions/regions-infer-covariance-due-to-decl.nll.stderr b/src/test/ui/regions/regions-infer-covariance-due-to-decl.nll.stderr
index 835438e9e5d..8bc6d565cf1 100644
--- a/src/test/ui/regions/regions-infer-covariance-due-to-decl.nll.stderr
+++ b/src/test/ui/regions/regions-infer-covariance-due-to-decl.nll.stderr
@@ -1,5 +1,5 @@
 error: unsatisfied lifetime constraints
-  --> $DIR/regions-infer-covariance-due-to-decl.rs:32:9
+  --> $DIR/regions-infer-covariance-due-to-decl.rs:32:12
    |
 LL | fn use_<'short,'long>(c: Covariant<'long>,
    |         ------ ----- lifetime `'long` defined here
@@ -7,7 +7,7 @@ LL | fn use_<'short,'long>(c: Covariant<'long>,
    |         lifetime `'short` defined here
 ...
 LL |     let _: Covariant<'short> = c; //~ ERROR E0623
-   |         ^ type annotation requires that `'short` must outlive `'long`
+   |            ^^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/regions/regions-outlives-projection-container-wc.nll.stderr b/src/test/ui/regions/regions-outlives-projection-container-wc.nll.stderr
new file mode 100644
index 00000000000..836f8c28a73
--- /dev/null
+++ b/src/test/ui/regions/regions-outlives-projection-container-wc.nll.stderr
@@ -0,0 +1,13 @@
+error: unsatisfied lifetime constraints
+  --> $DIR/regions-outlives-projection-container-wc.rs:46:13
+   |
+LL | fn with_assoc<'a,'b>() {
+   |               -- -- lifetime `'b` defined here
+   |               |
+   |               lifetime `'a` defined here
+...
+LL |     let _x: &'a WithAssoc<TheType<'b>> = loop { };
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/regions/regions-outlives-projection-container-wc.rs b/src/test/ui/regions/regions-outlives-projection-container-wc.rs
index 79300d5176e..22ec58d1367 100644
--- a/src/test/ui/regions/regions-outlives-projection-container-wc.rs
+++ b/src/test/ui/regions/regions-outlives-projection-container-wc.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-compare-mode-nll
-
 // Test that we are imposing the requirement that every associated
 // type of a bound that appears in the where clause on a struct must
 // outlive the location in which the type appears, even when the
@@ -43,7 +41,9 @@ fn with_assoc<'a,'b>() {
     // outlive 'a. In this case, that means TheType<'b>::TheAssocType,
     // which is &'b (), must outlive 'a.
 
-    let _: &'a WithAssoc<TheType<'b>> = loop { };
+    // FIXME (#54943) NLL doesn't enforce WF condition in unreachable code if
+    // `_x` is changed to `_`
+    let _x: &'a WithAssoc<TheType<'b>> = loop { };
     //~^ ERROR reference has a longer lifetime
 }
 
diff --git a/src/test/ui/regions/regions-outlives-projection-container-wc.stderr b/src/test/ui/regions/regions-outlives-projection-container-wc.stderr
index d0680ecbb99..e5bc52d7b66 100644
--- a/src/test/ui/regions/regions-outlives-projection-container-wc.stderr
+++ b/src/test/ui/regions/regions-outlives-projection-container-wc.stderr
@@ -1,16 +1,16 @@
 error[E0491]: in type `&'a WithAssoc<TheType<'b>>`, reference has a longer lifetime than the data it references
-  --> $DIR/regions-outlives-projection-container-wc.rs:46:12
+  --> $DIR/regions-outlives-projection-container-wc.rs:46:13
    |
-LL |     let _: &'a WithAssoc<TheType<'b>> = loop { };
-   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     let _x: &'a WithAssoc<TheType<'b>> = loop { };
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: the pointer is valid for the lifetime 'a as defined on the function body at 40:15
-  --> $DIR/regions-outlives-projection-container-wc.rs:40:15
+note: the pointer is valid for the lifetime 'a as defined on the function body at 38:15
+  --> $DIR/regions-outlives-projection-container-wc.rs:38:15
    |
 LL | fn with_assoc<'a,'b>() {
    |               ^^
-note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 40:18
-  --> $DIR/regions-outlives-projection-container-wc.rs:40:18
+note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 38:18
+  --> $DIR/regions-outlives-projection-container-wc.rs:38:18
    |
 LL | fn with_assoc<'a,'b>() {
    |                  ^^
diff --git a/src/test/ui/regions/regions-outlives-projection-container.nll.stderr b/src/test/ui/regions/regions-outlives-projection-container.nll.stderr
new file mode 100644
index 00000000000..126f50577c8
--- /dev/null
+++ b/src/test/ui/regions/regions-outlives-projection-container.nll.stderr
@@ -0,0 +1,46 @@
+error: unsatisfied lifetime constraints
+  --> $DIR/regions-outlives-projection-container.rs:50:13
+   |
+LL | fn with_assoc<'a,'b>() {
+   |               -- -- lifetime `'b` defined here
+   |               |
+   |               lifetime `'a` defined here
+...
+LL |     let _x: &'a WithAssoc<TheType<'b>> = loop { };
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
+
+error: unsatisfied lifetime constraints
+  --> $DIR/regions-outlives-projection-container.rs:68:13
+   |
+LL | fn without_assoc<'a,'b>() {
+   |                  -- -- lifetime `'b` defined here
+   |                  |
+   |                  lifetime `'a` defined here
+...
+LL |     let _x: &'a WithoutAssoc<TheType<'b>> = loop { };
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
+
+error: unsatisfied lifetime constraints
+  --> $DIR/regions-outlives-projection-container.rs:77:5
+   |
+LL | fn call_with_assoc<'a,'b>() {
+   |                    -- -- lifetime `'b` defined here
+   |                    |
+   |                    lifetime `'a` defined here
+...
+LL |     call::<&'a WithAssoc<TheType<'b>>>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'a`
+
+error: unsatisfied lifetime constraints
+  --> $DIR/regions-outlives-projection-container.rs:84:5
+   |
+LL | fn call_without_assoc<'a,'b>() {
+   |                       -- -- lifetime `'b` defined here
+   |                       |
+   |                       lifetime `'a` defined here
+...
+LL |     call::<&'a WithoutAssoc<TheType<'b>>>(); //~ ERROR reference has a longer lifetime
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'a`
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/regions/regions-outlives-projection-container.rs b/src/test/ui/regions/regions-outlives-projection-container.rs
index e4b7a0f82db..08fd7080e52 100644
--- a/src/test/ui/regions/regions-outlives-projection-container.rs
+++ b/src/test/ui/regions/regions-outlives-projection-container.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-compare-mode-nll
-
 // Test that we are imposing the requirement that every associated
 // type of a bound that appears in the where clause on a struct must
 // outlive the location in which the type appears. Issue #22246.
@@ -47,7 +45,10 @@ fn with_assoc<'a,'b>() {
     // outlive 'a. In this case, that means TheType<'b>::TheAssocType,
     // which is &'b (), must outlive 'a.
 
-    let _: &'a WithAssoc<TheType<'b>> = loop { }; //~ ERROR reference has a longer lifetime
+    // FIXME (#54943) NLL doesn't enforce WF condition in unreachable code if
+    // `_x` is changed to `_`
+    let _x: &'a WithAssoc<TheType<'b>> = loop { };
+    //~^ ERROR reference has a longer lifetime
 }
 
 fn with_assoc1<'a,'b>() where 'b : 'a {
@@ -57,14 +58,15 @@ fn with_assoc1<'a,'b>() where 'b : 'a {
     // which is &'b (), must outlive 'a, so 'b : 'a must hold, and
     // that is in the where clauses, so we're fine.
 
-    let _: &'a WithAssoc<TheType<'b>> = loop { };
+    let _x: &'a WithAssoc<TheType<'b>> = loop { };
 }
 
 fn without_assoc<'a,'b>() {
     // Here there are no associated types but there is a requirement
     // that `'b:'a` holds because the `'b` appears in `TheType<'b>`.
 
-    let _: &'a WithoutAssoc<TheType<'b>> = loop { }; //~ ERROR reference has a longer lifetime
+    let _x: &'a WithoutAssoc<TheType<'b>> = loop { };
+    //~^ ERROR reference has a longer lifetime
 }
 
 fn call_with_assoc<'a,'b>() {
diff --git a/src/test/ui/regions/regions-outlives-projection-container.stderr b/src/test/ui/regions/regions-outlives-projection-container.stderr
index 2a698f9bff5..2c37d943616 100644
--- a/src/test/ui/regions/regions-outlives-projection-container.stderr
+++ b/src/test/ui/regions/regions-outlives-projection-container.stderr
@@ -1,67 +1,67 @@
 error[E0491]: in type `&'a WithAssoc<TheType<'b>>`, reference has a longer lifetime than the data it references
-  --> $DIR/regions-outlives-projection-container.rs:50:12
+  --> $DIR/regions-outlives-projection-container.rs:50:13
    |
-LL |     let _: &'a WithAssoc<TheType<'b>> = loop { }; //~ ERROR reference has a longer lifetime
-   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     let _x: &'a WithAssoc<TheType<'b>> = loop { };
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: the pointer is valid for the lifetime 'a as defined on the function body at 44:15
-  --> $DIR/regions-outlives-projection-container.rs:44:15
+note: the pointer is valid for the lifetime 'a as defined on the function body at 42:15
+  --> $DIR/regions-outlives-projection-container.rs:42:15
    |
 LL | fn with_assoc<'a,'b>() {
    |               ^^
-note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 44:18
-  --> $DIR/regions-outlives-projection-container.rs:44:18
+note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 42:18
+  --> $DIR/regions-outlives-projection-container.rs:42:18
    |
 LL | fn with_assoc<'a,'b>() {
    |                  ^^
 
 error[E0491]: in type `&'a WithoutAssoc<TheType<'b>>`, reference has a longer lifetime than the data it references
-  --> $DIR/regions-outlives-projection-container.rs:67:12
+  --> $DIR/regions-outlives-projection-container.rs:68:13
    |
-LL |     let _: &'a WithoutAssoc<TheType<'b>> = loop { }; //~ ERROR reference has a longer lifetime
-   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     let _x: &'a WithoutAssoc<TheType<'b>> = loop { };
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: the pointer is valid for the lifetime 'a as defined on the function body at 63:18
-  --> $DIR/regions-outlives-projection-container.rs:63:18
+note: the pointer is valid for the lifetime 'a as defined on the function body at 64:18
+  --> $DIR/regions-outlives-projection-container.rs:64:18
    |
 LL | fn without_assoc<'a,'b>() {
    |                  ^^
-note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 63:21
-  --> $DIR/regions-outlives-projection-container.rs:63:21
+note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 64:21
+  --> $DIR/regions-outlives-projection-container.rs:64:21
    |
 LL | fn without_assoc<'a,'b>() {
    |                     ^^
 
 error[E0491]: in type `&'a WithAssoc<TheType<'b>>`, reference has a longer lifetime than the data it references
-  --> $DIR/regions-outlives-projection-container.rs:75:12
+  --> $DIR/regions-outlives-projection-container.rs:77:12
    |
 LL |     call::<&'a WithAssoc<TheType<'b>>>();
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: the pointer is valid for the lifetime 'a as defined on the function body at 70:20
-  --> $DIR/regions-outlives-projection-container.rs:70:20
+note: the pointer is valid for the lifetime 'a as defined on the function body at 72:20
+  --> $DIR/regions-outlives-projection-container.rs:72:20
    |
 LL | fn call_with_assoc<'a,'b>() {
    |                    ^^
-note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 70:23
-  --> $DIR/regions-outlives-projection-container.rs:70:23
+note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 72:23
+  --> $DIR/regions-outlives-projection-container.rs:72:23
    |
 LL | fn call_with_assoc<'a,'b>() {
    |                       ^^
 
 error[E0491]: in type `&'a WithoutAssoc<TheType<'b>>`, reference has a longer lifetime than the data it references
-  --> $DIR/regions-outlives-projection-container.rs:82:12
+  --> $DIR/regions-outlives-projection-container.rs:84:12
    |
 LL |     call::<&'a WithoutAssoc<TheType<'b>>>(); //~ ERROR reference has a longer lifetime
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: the pointer is valid for the lifetime 'a as defined on the function body at 79:23
-  --> $DIR/regions-outlives-projection-container.rs:79:23
+note: the pointer is valid for the lifetime 'a as defined on the function body at 81:23
+  --> $DIR/regions-outlives-projection-container.rs:81:23
    |
 LL | fn call_without_assoc<'a,'b>() {
    |                       ^^
-note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 79:26
-  --> $DIR/regions-outlives-projection-container.rs:79:26
+note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 81:26
+  --> $DIR/regions-outlives-projection-container.rs:81:26
    |
 LL | fn call_without_assoc<'a,'b>() {
    |                          ^^
diff --git a/src/test/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.nll.stderr b/src/test/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.nll.stderr
index 706d00a8424..668b75f5733 100644
--- a/src/test/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.nll.stderr
+++ b/src/test/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.nll.stderr
@@ -1,5 +1,5 @@
 error: unsatisfied lifetime constraints
-  --> $DIR/regions-variance-contravariant-use-covariant-in-second-position.rs:35:9
+  --> $DIR/regions-variance-contravariant-use-covariant-in-second-position.rs:35:12
    |
 LL | fn use_<'short,'long>(c: S<'long, 'short>,
    |         ------ ----- lifetime `'long` defined here
@@ -7,7 +7,7 @@ LL | fn use_<'short,'long>(c: S<'long, 'short>,
    |         lifetime `'short` defined here
 ...
 LL |     let _: S<'long, 'long> = c; //~ ERROR E0623
-   |         ^ type annotation requires that `'short` must outlive `'long`
+   |            ^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/regions/regions-variance-contravariant-use-covariant.nll.stderr b/src/test/ui/regions/regions-variance-contravariant-use-covariant.nll.stderr
index 144aa67f905..5d787e6dab6 100644
--- a/src/test/ui/regions/regions-variance-contravariant-use-covariant.nll.stderr
+++ b/src/test/ui/regions/regions-variance-contravariant-use-covariant.nll.stderr
@@ -1,5 +1,5 @@
 error: unsatisfied lifetime constraints
-  --> $DIR/regions-variance-contravariant-use-covariant.rs:33:9
+  --> $DIR/regions-variance-contravariant-use-covariant.rs:33:12
    |
 LL | fn use_<'short,'long>(c: Contravariant<'short>,
    |         ------ ----- lifetime `'long` defined here
@@ -7,7 +7,7 @@ LL | fn use_<'short,'long>(c: Contravariant<'short>,
    |         lifetime `'short` defined here
 ...
 LL |     let _: Contravariant<'long> = c; //~ ERROR E0623
-   |         ^ type annotation requires that `'short` must outlive `'long`
+   |            ^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/regions/regions-variance-covariant-use-contravariant.nll.stderr b/src/test/ui/regions/regions-variance-covariant-use-contravariant.nll.stderr
index c9789f8555e..3fb29009668 100644
--- a/src/test/ui/regions/regions-variance-covariant-use-contravariant.nll.stderr
+++ b/src/test/ui/regions/regions-variance-covariant-use-contravariant.nll.stderr
@@ -1,5 +1,5 @@
 error: unsatisfied lifetime constraints
-  --> $DIR/regions-variance-covariant-use-contravariant.rs:33:9
+  --> $DIR/regions-variance-covariant-use-contravariant.rs:33:12
    |
 LL | fn use_<'short,'long>(c: Covariant<'long>,
    |         ------ ----- lifetime `'long` defined here
@@ -7,7 +7,7 @@ LL | fn use_<'short,'long>(c: Covariant<'long>,
    |         lifetime `'short` defined here
 ...
 LL |     let _: Covariant<'short> = c; //~ ERROR E0623
-   |         ^ type annotation requires that `'short` must outlive `'long`
+   |            ^^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/regions/regions-variance-invariant-use-contravariant.nll.stderr b/src/test/ui/regions/regions-variance-invariant-use-contravariant.nll.stderr
index 488b70b5f0f..fb59ec1ca10 100644
--- a/src/test/ui/regions/regions-variance-invariant-use-contravariant.nll.stderr
+++ b/src/test/ui/regions/regions-variance-invariant-use-contravariant.nll.stderr
@@ -1,5 +1,5 @@
 error: unsatisfied lifetime constraints
-  --> $DIR/regions-variance-invariant-use-contravariant.rs:30:9
+  --> $DIR/regions-variance-invariant-use-contravariant.rs:30:12
    |
 LL | fn use_<'short,'long>(c: Invariant<'long>,
    |         ------ ----- lifetime `'long` defined here
@@ -7,7 +7,7 @@ LL | fn use_<'short,'long>(c: Invariant<'long>,
    |         lifetime `'short` defined here
 ...
 LL |     let _: Invariant<'short> = c; //~ ERROR E0623
-   |         ^ type annotation requires that `'short` must outlive `'long`
+   |            ^^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/regions/regions-variance-invariant-use-covariant.nll.stderr b/src/test/ui/regions/regions-variance-invariant-use-covariant.nll.stderr
index fa7cfc33dc0..daf6a79136a 100644
--- a/src/test/ui/regions/regions-variance-invariant-use-covariant.nll.stderr
+++ b/src/test/ui/regions/regions-variance-invariant-use-covariant.nll.stderr
@@ -1,11 +1,11 @@
 error: unsatisfied lifetime constraints
-  --> $DIR/regions-variance-invariant-use-covariant.rs:27:9
+  --> $DIR/regions-variance-invariant-use-covariant.rs:27:12
    |
 LL | fn use_<'b>(c: Invariant<'b>) {
    |         -- lifetime `'b` defined here
 ...
 LL |     let _: Invariant<'static> = c; //~ ERROR mismatched types
-   |         ^ type annotation requires that `'b` must outlive `'static`
+   |            ^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'static`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/try-block/try-block-bad-lifetime.stderr b/src/test/ui/try-block/try-block-bad-lifetime.stderr
index ebf56dc9835..061bc19cec9 100644
--- a/src/test/ui/try-block/try-block-bad-lifetime.stderr
+++ b/src/test/ui/try-block/try-block-bad-lifetime.stderr
@@ -2,7 +2,7 @@ error[E0597]: `my_string` does not live long enough
   --> $DIR/try-block-bad-lifetime.rs:25:33
    |
 LL |         let result: Result<(), &str> = try {
-   |             ------ borrow later used here
+   |             ------ borrow later stored here
 LL |             let my_string = String::from("");
 LL |             let my_str: & str = & my_string;
    |                                 ^^^^^^^^^^^ borrowed value does not live long enough
diff --git a/src/test/ui/variance/variance-cell-is-invariant.nll.stderr b/src/test/ui/variance/variance-cell-is-invariant.nll.stderr
index 0172fcdc8f1..eb01c2bbb05 100644
--- a/src/test/ui/variance/variance-cell-is-invariant.nll.stderr
+++ b/src/test/ui/variance/variance-cell-is-invariant.nll.stderr
@@ -1,5 +1,5 @@
 error: unsatisfied lifetime constraints
-  --> $DIR/variance-cell-is-invariant.rs:24:9
+  --> $DIR/variance-cell-is-invariant.rs:24:12
    |
 LL | fn use_<'short,'long>(c: Foo<'short>,
    |         ------ ----- lifetime `'long` defined here
@@ -7,7 +7,7 @@ LL | fn use_<'short,'long>(c: Foo<'short>,
    |         lifetime `'short` defined here
 ...
 LL |     let _: Foo<'long> = c; //~ ERROR E0623
-   |         ^ type annotation requires that `'short` must outlive `'long`
+   |            ^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-static-method.nll.stderr b/src/test/ui/wf/wf-static-method.nll.stderr
index 51aec2a949f..bfcb16c654f 100644
--- a/src/test/ui/wf/wf-static-method.nll.stderr
+++ b/src/test/ui/wf/wf-static-method.nll.stderr
@@ -10,6 +10,17 @@ LL |         u //~ ERROR E0312
    |         ^ returning this value requires that `'b` must outlive `'a`
 
 error: unsatisfied lifetime constraints
+  --> $DIR/wf-static-method.rs:36:18
+   |
+LL | impl<'a, 'b> Foo<'a, 'b, ()> for IndirectEvil<'a, 'b> {
+   |      --  -- lifetime `'b` defined here
+   |      |
+   |      lifetime `'a` defined here
+...
+LL |         let me = Self::make_me(); //~ ERROR lifetime bound not satisfied
+   |                  ^^^^^^^^^^^^^^^ requires that `'b` must outlive `'a`
+
+error: unsatisfied lifetime constraints
   --> $DIR/wf-static-method.rs:43:9
    |
 LL | impl<'a, 'b> Evil<'a, 'b> {
@@ -20,5 +31,25 @@ LL |     fn inherent_evil(u: &'b u32) -> &'a u32 {
 LL |         u //~ ERROR E0312
    |         ^ returning this value requires that `'b` must outlive `'a`
 
-error: aborting due to 2 previous errors
+error: unsatisfied lifetime constraints
+  --> $DIR/wf-static-method.rs:51:5
+   |
+LL | fn evil<'a, 'b>(b: &'b u32) -> &'a u32 {
+   |         --  -- lifetime `'b` defined here
+   |         |
+   |         lifetime `'a` defined here
+LL |     <()>::static_evil(b) //~ ERROR cannot infer an appropriate lifetime
+   |     ^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'b` must outlive `'a`
+
+error: unsatisfied lifetime constraints
+  --> $DIR/wf-static-method.rs:55:5
+   |
+LL | fn indirect_evil<'a, 'b>(b: &'b u32) -> &'a u32 {
+   |                  --  -- lifetime `'b` defined here
+   |                  |
+   |                  lifetime `'a` defined here
+LL |     <IndirectEvil>::static_evil(b)
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'b` must outlive `'a`
+
+error: aborting due to 5 previous errors