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.
This commit is contained in:
parent
55ec104313
commit
c312e04d45
20 changed files with 249 additions and 77 deletions
|
@ -970,7 +970,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
||||||
locations: Locations,
|
locations: Locations,
|
||||||
category: ConstraintCategory,
|
category: ConstraintCategory,
|
||||||
) -> Fallible<()> {
|
) -> Fallible<()> {
|
||||||
relate_tys::relate_type_and_user_type(
|
let ty = relate_tys::relate_type_and_user_type(
|
||||||
self.infcx,
|
self.infcx,
|
||||||
a,
|
a,
|
||||||
v,
|
v,
|
||||||
|
@ -978,7 +978,13 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
||||||
locations,
|
locations,
|
||||||
category,
|
category,
|
||||||
self.borrowck_context.as_mut().map(|x| &mut **x),
|
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(
|
fn eq_opaque_type_and_type(
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
use borrow_check::nll::constraints::OutlivesConstraint;
|
use borrow_check::nll::constraints::OutlivesConstraint;
|
||||||
use borrow_check::nll::type_check::{BorrowCheckContext, Locations};
|
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::infer::{InferCtxt, NLLRegionVariableOrigin};
|
||||||
use rustc::mir::ConstraintCategory;
|
use rustc::mir::ConstraintCategory;
|
||||||
use rustc::traits::query::Fallible;
|
use rustc::traits::query::Fallible;
|
||||||
|
@ -70,7 +70,7 @@ pub(super) fn relate_type_and_user_type<'tcx>(
|
||||||
locations: Locations,
|
locations: Locations,
|
||||||
category: ConstraintCategory,
|
category: ConstraintCategory,
|
||||||
borrowck_context: Option<&mut BorrowCheckContext<'_, 'tcx>>,
|
borrowck_context: Option<&mut BorrowCheckContext<'_, 'tcx>>,
|
||||||
) -> Fallible<()> {
|
) -> Fallible<Ty<'tcx>> {
|
||||||
debug!(
|
debug!(
|
||||||
"sub_type_and_user_type(a={:?}, b={:?}, locations={:?})",
|
"sub_type_and_user_type(a={:?}, b={:?}, locations={:?})",
|
||||||
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.
|
// variance to get the right relationship.
|
||||||
let v1 = ty::Contravariant.xform(v);
|
let v1 = ty::Contravariant.xform(v);
|
||||||
|
|
||||||
TypeRelating::new(
|
let mut type_relating = TypeRelating::new(
|
||||||
infcx.tcx,
|
infcx.tcx,
|
||||||
NllTypeRelatingDelegate::new(infcx, borrowck_context, locations, category),
|
NllTypeRelatingDelegate::new(infcx, borrowck_context, locations, category),
|
||||||
v1,
|
v1,
|
||||||
b_variables,
|
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>
|
struct TypeRelating<'me, 'gcx: 'tcx, 'tcx: 'me, D>
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -8,10 +8,10 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// ignore-compare-mode-nll
|
|
||||||
|
|
||||||
#![allow(unused_variables)]
|
#![allow(unused_variables)]
|
||||||
|
|
||||||
|
fn make_any<T>() -> T { loop {} }
|
||||||
|
|
||||||
trait Trait<'a> {
|
trait Trait<'a> {
|
||||||
type Type;
|
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
|
where T : for<'z> Trait<'z>, 'a : 'b
|
||||||
{
|
{
|
||||||
// Note that &'static T <: &'a T.
|
// Note that &'static T <: &'a T.
|
||||||
let a: <T as Trait<'a>>::Type = loop { };
|
let a: <T as Trait<'a>>::Type = make_any();
|
||||||
let b: <T as Trait<'b>>::Type = loop { };
|
let b: <T as Trait<'b>>::Type = make_any();
|
||||||
let _c: <T as Trait<'a>>::Type = a;
|
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
|
where T : for<'z> Trait<'z>, 'a : 'b
|
||||||
{
|
{
|
||||||
// Note that &'static T <: &'a T.
|
// Note that &'static T <: &'a T.
|
||||||
let a: <T as Trait<'a>>::Type = loop { };
|
let a: <T as Trait<'a>>::Type = make_any();
|
||||||
let b: <T as Trait<'b>>::Type = loop { };
|
let b: <T as Trait<'b>>::Type = make_any();
|
||||||
let _c: <T as Trait<'b>>::Type = a; //~ ERROR E0623
|
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
|
where T : for<'z> Trait<'z>, 'a : 'b
|
||||||
{
|
{
|
||||||
// Note that &'static T <: &'a T.
|
// Note that &'static T <: &'a T.
|
||||||
let a: <T as Trait<'a>>::Type = loop { };
|
let a: <T as Trait<'a>>::Type = make_any();
|
||||||
let b: <T as Trait<'b>>::Type = loop { };
|
let b: <T as Trait<'b>>::Type = make_any();
|
||||||
let _c: <T as Trait<'a>>::Type = b; //~ ERROR E0623
|
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
|
where T : for<'z> Trait<'z>, 'a : 'b
|
||||||
{
|
{
|
||||||
// Note that &'static T <: &'a T.
|
// Note that &'static T <: &'a T.
|
||||||
let a: <T as Trait<'a>>::Type = loop { };
|
let a: <T as Trait<'a>>::Type = make_any();
|
||||||
let b: <T as Trait<'b>>::Type = loop { };
|
let b: <T as Trait<'b>>::Type = make_any();
|
||||||
let _c: <T as Trait<'b>>::Type = b;
|
let _c: <T as Trait<'b>>::Type = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -8,8 +8,6 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// ignore-compare-mode-nll
|
|
||||||
|
|
||||||
// Test that we are imposing the requirement that every associated
|
// Test that we are imposing the requirement that every associated
|
||||||
// type of a bound that appears in the where clause on a struct must
|
// 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
|
// 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,
|
// outlive 'a. In this case, that means TheType<'b>::TheAssocType,
|
||||||
// which is &'b (), must outlive 'a.
|
// 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() {
|
fn main() {
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
error[E0491]: in type `&'a WithAssoc<TheType<'b>>`, reference has a longer lifetime than the data it references
|
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
|
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:46:15
|
--> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:44:15
|
||||||
|
|
|
|
||||||
LL | fn with_assoc<'a,'b>() {
|
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
|
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:46:18
|
--> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:44:18
|
||||||
|
|
|
|
||||||
LL | fn with_assoc<'a,'b>() {
|
LL | fn with_assoc<'a,'b>() {
|
||||||
| ^^
|
| ^^
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -8,8 +8,6 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// ignore-compare-mode-nll
|
|
||||||
|
|
||||||
// Test various ways to construct a pointer with a longer lifetime
|
// Test various ways to construct a pointer with a longer lifetime
|
||||||
// than the thing it points at and ensure that they result in
|
// than the thing it points at and ensure that they result in
|
||||||
// errors. See also regions-free-region-ordering-callee.rs
|
// errors. See also regions-free-region-ordering-callee.rs
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0623]: lifetime mismatch
|
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) {
|
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
|
| ^^^^^^^^^^^^^^^^^^^^^ ...but data from `a` flows into `b` here
|
||||||
|
|
||||||
error[E0623]: lifetime mismatch
|
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) {
|
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
|
| ^^^^^^^^^^^^^^^^^^^^^^ ...but data from `a` flows into `b` here
|
||||||
|
|
||||||
error[E0623]: lifetime mismatch
|
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) {
|
LL | fn call4<'a, 'b>(a: &'a usize, b: &'b usize) {
|
||||||
| --------- --------- these two types are declared with different lifetimes...
|
| --------- --------- these two types are declared with different lifetimes...
|
||||||
|
|
|
@ -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) {
|
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) {
|
||||||
|
| ^^
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0716`.
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
Some errors occurred: E0597, E0716.
|
||||||
|
For more information about an error, try `rustc --explain E0597`.
|
||||||
|
|
|
@ -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`.
|
|
@ -8,8 +8,6 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// ignore-compare-mode-nll
|
|
||||||
|
|
||||||
// Illustrates the "projection gap": in this test, even though we know
|
// Illustrates the "projection gap": in this test, even though we know
|
||||||
// that `T::Foo: 'x`, that does not tell us that `T: 'x`, because
|
// 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
|
// there might be other ways for the caller of `func` to show that
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0309]: the parameter type `T` may not live long enough
|
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)
|
LL | fn func<'x, T:Trait1<'x>>(t: &'x T::Foo)
|
||||||
| -- help: consider adding an explicit lifetime bound `T: 'x`...
|
| -- 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
|
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>();
|
LL | wf::<&'x T>();
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -8,8 +8,6 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// ignore-compare-mode-nll
|
|
||||||
|
|
||||||
// Test that we are imposing the requirement that every associated
|
// Test that we are imposing the requirement that every associated
|
||||||
// type of a bound that appears in the where clause on a struct must
|
// 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
|
// 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,
|
// outlive 'a. In this case, that means TheType<'b>::TheAssocType,
|
||||||
// which is &'b (), must outlive 'a.
|
// 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
|
//~^ ERROR reference has a longer lifetime
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
error[E0491]: in type `&'a WithAssoc<TheType<'b>>`, reference has a longer lifetime than the data it references
|
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
|
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:40:15
|
--> $DIR/regions-outlives-projection-container-wc.rs:38:15
|
||||||
|
|
|
|
||||||
LL | fn with_assoc<'a,'b>() {
|
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
|
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:40:18
|
--> $DIR/regions-outlives-projection-container-wc.rs:38:18
|
||||||
|
|
|
|
||||||
LL | fn with_assoc<'a,'b>() {
|
LL | fn with_assoc<'a,'b>() {
|
||||||
| ^^
|
| ^^
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -8,8 +8,6 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// ignore-compare-mode-nll
|
|
||||||
|
|
||||||
// Test that we are imposing the requirement that every associated
|
// Test that we are imposing the requirement that every associated
|
||||||
// type of a bound that appears in the where clause on a struct must
|
// type of a bound that appears in the where clause on a struct must
|
||||||
// outlive the location in which the type appears. Issue #22246.
|
// 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,
|
// outlive 'a. In this case, that means TheType<'b>::TheAssocType,
|
||||||
// which is &'b (), must outlive 'a.
|
// 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 {
|
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
|
// which is &'b (), must outlive 'a, so 'b : 'a must hold, and
|
||||||
// that is in the where clauses, so we're fine.
|
// 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>() {
|
fn without_assoc<'a,'b>() {
|
||||||
// Here there are no associated types but there is a requirement
|
// Here there are no associated types but there is a requirement
|
||||||
// that `'b:'a` holds because the `'b` appears in `TheType<'b>`.
|
// 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>() {
|
fn call_with_assoc<'a,'b>() {
|
||||||
|
|
|
@ -1,67 +1,67 @@
|
||||||
error[E0491]: in type `&'a WithAssoc<TheType<'b>>`, reference has a longer lifetime than the data it references
|
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
|
note: the pointer is valid for the lifetime 'a as defined on the function body at 42:15
|
||||||
--> $DIR/regions-outlives-projection-container.rs:44:15
|
--> $DIR/regions-outlives-projection-container.rs:42:15
|
||||||
|
|
|
|
||||||
LL | fn with_assoc<'a,'b>() {
|
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
|
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:44:18
|
--> $DIR/regions-outlives-projection-container.rs:42:18
|
||||||
|
|
|
|
||||||
LL | fn with_assoc<'a,'b>() {
|
LL | fn with_assoc<'a,'b>() {
|
||||||
| ^^
|
| ^^
|
||||||
|
|
||||||
error[E0491]: in type `&'a WithoutAssoc<TheType<'b>>`, reference has a longer lifetime than the data it references
|
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
|
note: the pointer is valid for the lifetime 'a as defined on the function body at 64:18
|
||||||
--> $DIR/regions-outlives-projection-container.rs:63:18
|
--> $DIR/regions-outlives-projection-container.rs:64:18
|
||||||
|
|
|
|
||||||
LL | fn without_assoc<'a,'b>() {
|
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
|
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:63:21
|
--> $DIR/regions-outlives-projection-container.rs:64:21
|
||||||
|
|
|
|
||||||
LL | fn without_assoc<'a,'b>() {
|
LL | fn without_assoc<'a,'b>() {
|
||||||
| ^^
|
| ^^
|
||||||
|
|
||||||
error[E0491]: in type `&'a WithAssoc<TheType<'b>>`, reference has a longer lifetime than the data it references
|
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>>>();
|
LL | call::<&'a WithAssoc<TheType<'b>>>();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: the pointer is valid for the lifetime 'a as defined on the function body at 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:70:20
|
--> $DIR/regions-outlives-projection-container.rs:72:20
|
||||||
|
|
|
|
||||||
LL | fn call_with_assoc<'a,'b>() {
|
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
|
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:70:23
|
--> $DIR/regions-outlives-projection-container.rs:72:23
|
||||||
|
|
|
|
||||||
LL | fn call_with_assoc<'a,'b>() {
|
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
|
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
|
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
|
note: the pointer is valid for the lifetime 'a as defined on the function body at 81:23
|
||||||
--> $DIR/regions-outlives-projection-container.rs:79:23
|
--> $DIR/regions-outlives-projection-container.rs:81:23
|
||||||
|
|
|
|
||||||
LL | fn call_without_assoc<'a,'b>() {
|
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
|
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:79:26
|
--> $DIR/regions-outlives-projection-container.rs:81:26
|
||||||
|
|
|
|
||||||
LL | fn call_without_assoc<'a,'b>() {
|
LL | fn call_without_assoc<'a,'b>() {
|
||||||
| ^^
|
| ^^
|
||||||
|
|
Loading…
Add table
Reference in a new issue