]> git.lizzy.rs Git - rust.git/commitdiff
Check user types are well-formed in MIR borrow check
authorMatthew Jasper <mjjasper1@gmail.com>
Wed, 10 Oct 2018 07:38:17 +0000 (08:38 +0100)
committerMatthew Jasper <mjjasper1@gmail.com>
Wed, 10 Oct 2018 15:23:59 +0000 (16:23 +0100)
Also update some tests so that they don't have user types on `_` in
unreachable code.

20 files changed:
src/librustc_mir/borrow_check/nll/type_check/mod.rs
src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs
src/test/ui/associated-types/associated-types-subtyping-1.nll.stderr [new file with mode: 0644]
src/test/ui/associated-types/associated-types-subtyping-1.rs
src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.nll.stderr [new file with mode: 0644]
src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.rs
src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.stderr
src/test/ui/regions/regions-free-region-ordering-caller.nll.stderr [new file with mode: 0644]
src/test/ui/regions/regions-free-region-ordering-caller.rs
src/test/ui/regions/regions-free-region-ordering-caller.stderr
src/test/ui/regions/regions-free-region-ordering-caller1.nll.stderr
src/test/ui/regions/regions-implied-bounds-projection-gap-1.nll.stderr [new file with mode: 0644]
src/test/ui/regions/regions-implied-bounds-projection-gap-1.rs
src/test/ui/regions/regions-implied-bounds-projection-gap-1.stderr
src/test/ui/regions/regions-outlives-projection-container-wc.nll.stderr [new file with mode: 0644]
src/test/ui/regions/regions-outlives-projection-container-wc.rs
src/test/ui/regions/regions-outlives-projection-container-wc.stderr
src/test/ui/regions/regions-outlives-projection-container.nll.stderr [new file with mode: 0644]
src/test/ui/regions/regions-outlives-projection-container.rs
src/test/ui/regions/regions-outlives-projection-container.stderr

index 1f3498b7ae01ac25cbb7532e060966f073a093c1..e11f452e16be1e349010fe360cdc1126a5fabafe 100644 (file)
@@ -970,7 +970,7 @@ fn relate_type_and_user_type(
         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 @@ fn relate_type_and_user_type(
             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(
index 41aab02d1e8266f3b9c8a478663995a38e6fc933..1e279aef07981001ec7713df81c7338ba9249d32 100644 (file)
@@ -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/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 (file)
index 0000000..1156c77
--- /dev/null
@@ -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
+
index c3acffff240b535e6108e5ed5a50ad1b002a647e..479cb359a781f2d3437f12031c2093cd2a99afc3 100644 (file)
@@ -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/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 (file)
index 0000000..f711541
--- /dev/null
@@ -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
+
index 96eb65daaffefe407987d4839d56eeca1148cfed..741feb1f9eaf4184b1aa46989016011c86cf6e3d 100644 (file)
@@ -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() {
index 7b7881d6ea7caf30253d36d20c188af547869893..7959d1b6c2300091f254bd20b722d982f6c51dbe 100644 (file)
@@ -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 (file)
index 0000000..8d4f3d1
--- /dev/null
@@ -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
+
index ee6cd6c4b1523a2210682fa74d9924b68220bab9..66b16744cc7df38586facf55c2c8f1c3250422ea 100644 (file)
@@ -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
index 96502b69c0819ce022c50d7a0f4904a985856f7d..a3645995b5ea2284ab6c4d3aee1e179bd2fd919a 100644 (file)
@@ -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...
index 75758206d6b4817e4d7500d3da6ee5b1dbede3a1..9747602f1ba481343e3468f14faeac69cad1dc14 100644 (file)
@@ -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 (file)
index 0000000..2eb4ccf
--- /dev/null
@@ -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`.
index 01de3ddcdf8d9727026c94ef76e17a671d9bbaaa..65594ab8f2e29220ee603252622bf2e83b52fbe0 100644 (file)
@@ -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
index e6efb4d5c6b5d780fd206730fe65fc89d31f3a77..41ae515bb9a1615a67801d74b84565c917e7e6f5 100644 (file)
@@ -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-outlives-projection-container-wc.nll.stderr b/src/test/ui/regions/regions-outlives-projection-container-wc.nll.stderr
new file mode 100644 (file)
index 0000000..836f8c2
--- /dev/null
@@ -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
+
index 79300d5176eccb43fad99b86a974b7f3f4c0e76c..22ec58d1367bcef60137a534f60a88a950bd4831 100644 (file)
@@ -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
 }
 
index d0680ecbb99a20e00561ce6fa0e80f8248f3d3ee..e5bc52d7b663f7e8c0110f9b4ce99e05d23484f3 100644 (file)
@@ -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 (file)
index 0000000..126f505
--- /dev/null
@@ -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
+
index e4b7a0f82db39e416b5508fad42853f5358e4805..08fd7080e52c6153fa583138935d9635db68ea77 100644 (file)
@@ -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>() {
index 2a698f9bff5a4314ecfe28aab3dca246ea2dd509..2c37d94361603843d2eab9ac9f09db0e0edc870c 100644 (file)
@@ -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>() {
    |                          ^^