From c312e04d45fc6254cc25f7277b2d84ff3128c036 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Wed, 10 Oct 2018 08:38:17 +0100 Subject: [PATCH] Check user types are well-formed in MIR borrow check Also update some tests so that they don't have user types on `_` in unreachable code. --- .../borrow_check/nll/type_check/mod.rs | 10 +++- .../borrow_check/nll/type_check/relate_tys.rs | 21 ++++++-- .../associated-types-subtyping-1.nll.stderr | 24 ++++++++++ .../associated-types-subtyping-1.rs | 20 ++++---- ...n-supertrait-outlives-container.nll.stderr | 13 +++++ ...c-type-in-supertrait-outlives-container.rs | 7 +-- ...pe-in-supertrait-outlives-container.stderr | 14 +++--- ...ons-free-region-ordering-caller.nll.stderr | 33 +++++++++++++ .../regions-free-region-ordering-caller.rs | 2 - ...regions-free-region-ordering-caller.stderr | 6 +-- ...ns-free-region-ordering-caller1.nll.stderr | 20 +++++++- ...implied-bounds-projection-gap-1.nll.stderr | 11 +++++ ...regions-implied-bounds-projection-gap-1.rs | 2 - ...ons-implied-bounds-projection-gap-1.stderr | 4 +- ...utlives-projection-container-wc.nll.stderr | 13 +++++ ...egions-outlives-projection-container-wc.rs | 6 +-- ...ns-outlives-projection-container-wc.stderr | 14 +++--- ...s-outlives-projection-container.nll.stderr | 46 ++++++++++++++++++ .../regions-outlives-projection-container.rs | 12 +++-- ...gions-outlives-projection-container.stderr | 48 +++++++++---------- 20 files changed, 249 insertions(+), 77 deletions(-) create mode 100644 src/test/ui/associated-types/associated-types-subtyping-1.nll.stderr create mode 100644 src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.nll.stderr create mode 100644 src/test/ui/regions/regions-free-region-ordering-caller.nll.stderr create mode 100644 src/test/ui/regions/regions-implied-bounds-projection-gap-1.nll.stderr create mode 100644 src/test/ui/regions/regions-outlives-projection-container-wc.nll.stderr create mode 100644 src/test/ui/regions/regions-outlives-projection-container.nll.stderr 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 1f3498b7ae0..e11f452e16b 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -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( 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> { 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 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: >::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: >::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 { 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: >::Type = loop { }; - let b: >::Type = loop { }; + let a: >::Type = make_any(); + let b: >::Type = make_any(); let _c: >::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: >::Type = loop { }; - let b: >::Type = loop { }; + let a: >::Type = make_any(); + let b: >::Type = make_any(); let _c: >::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: >::Type = loop { }; - let b: >::Type = loop { }; + let a: >::Type = make_any(); + let b: >::Type = make_any(); let _c: >::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: >::Type = loop { }; - let b: >::Type = loop { }; + let a: >::Type = make_any(); + let b: >::Type = make_any(); let _c: >::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 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> = 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> = 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> = 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>`, 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> = loop { }; //~ ERROR reference has a longer lifetime - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | let _x: &'a WithAssoc> = 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-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> = 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> = loop { }; + // FIXME (#54943) NLL doesn't enforce WF condition in unreachable code if + // `_x` is changed to `_` + let _x: &'a WithAssoc> = 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>`, 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> = loop { }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | let _x: &'a WithAssoc> = 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> = 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> = 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>>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>>(); //~ 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> = 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> = 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> = loop { }; + let _x: &'a WithAssoc> = 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> = loop { }; //~ ERROR reference has a longer lifetime + let _x: &'a WithoutAssoc> = 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>`, 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> = loop { }; //~ ERROR reference has a longer lifetime - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | let _x: &'a WithAssoc> = 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>`, 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> = loop { }; //~ ERROR reference has a longer lifetime - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | let _x: &'a WithoutAssoc> = 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>`, 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>>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | -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>`, 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>>(); //~ 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>() { | ^^ -- 2.44.0