diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:13 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:13 +0000 |
commit | 218caa410aa38c29984be31a5229b9fa717560ee (patch) | |
tree | c54bd55eeb6e4c508940a30e94c0032fbd45d677 /tests/ui/nll/user-annotations | |
parent | Releasing progress-linux version 1.67.1+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-218caa410aa38c29984be31a5229b9fa717560ee.tar.xz rustc-218caa410aa38c29984be31a5229b9fa717560ee.zip |
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/ui/nll/user-annotations')
94 files changed, 3533 insertions, 0 deletions
diff --git a/tests/ui/nll/user-annotations/adt-brace-enums.rs b/tests/ui/nll/user-annotations/adt-brace-enums.rs new file mode 100644 index 000000000..0d9828342 --- /dev/null +++ b/tests/ui/nll/user-annotations/adt-brace-enums.rs @@ -0,0 +1,50 @@ +// Unit test for the "user substitutions" that are annotated on each +// node. + +enum SomeEnum<T> { + SomeVariant { t: T } +} + +fn no_annot() { + let c = 66; + SomeEnum::SomeVariant { t: &c }; +} + +fn annot_underscore() { + let c = 66; + SomeEnum::SomeVariant::<_> { t: &c }; +} + +fn annot_reference_any_lifetime() { + let c = 66; + SomeEnum::SomeVariant::<&u32> { t: &c }; +} + +fn annot_reference_static_lifetime() { + let c = 66; + SomeEnum::SomeVariant::<&'static u32> { t: &c }; //~ ERROR +} + +fn annot_reference_named_lifetime<'a>(_d: &'a u32) { + let c = 66; + SomeEnum::SomeVariant::<&'a u32> { t: &c }; //~ ERROR +} + +fn annot_reference_named_lifetime_ok<'a>(c: &'a u32) { + SomeEnum::SomeVariant::<&'a u32> { t: c }; +} + +fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { + let _closure = || { + let c = 66; + SomeEnum::SomeVariant::<&'a u32> { t: &c }; //~ ERROR + }; +} + +fn annot_reference_named_lifetime_in_closure_ok<'a>(c: &'a u32) { + let _closure = || { + SomeEnum::SomeVariant::<&'a u32> { t: c }; + }; +} + +fn main() { } diff --git a/tests/ui/nll/user-annotations/adt-brace-enums.stderr b/tests/ui/nll/user-annotations/adt-brace-enums.stderr new file mode 100644 index 000000000..253e38251 --- /dev/null +++ b/tests/ui/nll/user-annotations/adt-brace-enums.stderr @@ -0,0 +1,42 @@ +error[E0597]: `c` does not live long enough + --> $DIR/adt-brace-enums.rs:25:48 + | +LL | SomeEnum::SomeVariant::<&'static u32> { t: &c }; + | ^^ + | | + | borrowed value does not live long enough + | this usage requires that `c` is borrowed for `'static` +LL | } + | - `c` dropped here while still borrowed + +error[E0597]: `c` does not live long enough + --> $DIR/adt-brace-enums.rs:30:43 + | +LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) { + | -- lifetime `'a` defined here +LL | let c = 66; +LL | SomeEnum::SomeVariant::<&'a u32> { t: &c }; + | ^^ + | | + | borrowed value does not live long enough + | this usage requires that `c` is borrowed for `'a` +LL | } + | - `c` dropped here while still borrowed + +error[E0597]: `c` does not live long enough + --> $DIR/adt-brace-enums.rs:40:47 + | +LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { + | -- lifetime `'a` defined here +... +LL | SomeEnum::SomeVariant::<&'a u32> { t: &c }; + | ^^ + | | + | borrowed value does not live long enough + | this usage requires that `c` is borrowed for `'a` +LL | }; + | - `c` dropped here while still borrowed + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/nll/user-annotations/adt-brace-structs.rs b/tests/ui/nll/user-annotations/adt-brace-structs.rs new file mode 100644 index 000000000..bdbfd87d5 --- /dev/null +++ b/tests/ui/nll/user-annotations/adt-brace-structs.rs @@ -0,0 +1,48 @@ +// Unit test for the "user substitutions" that are annotated on each +// node. + +struct SomeStruct<T> { t: T } + +fn no_annot() { + let c = 66; + SomeStruct { t: &c }; +} + +fn annot_underscore() { + let c = 66; + SomeStruct::<_> { t: &c }; +} + +fn annot_reference_any_lifetime() { + let c = 66; + SomeStruct::<&u32> { t: &c }; +} + +fn annot_reference_static_lifetime() { + let c = 66; + SomeStruct::<&'static u32> { t: &c }; //~ ERROR +} + +fn annot_reference_named_lifetime<'a>(_d: &'a u32) { + let c = 66; + SomeStruct::<&'a u32> { t: &c }; //~ ERROR +} + +fn annot_reference_named_lifetime_ok<'a>(c: &'a u32) { + SomeStruct::<&'a u32> { t: c }; +} + +fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { + let _closure = || { + let c = 66; + SomeStruct::<&'a u32> { t: &c }; //~ ERROR + }; +} + +fn annot_reference_named_lifetime_in_closure_ok<'a>(c: &'a u32) { + let _closure = || { + SomeStruct::<&'a u32> { t: c }; + }; +} + +fn main() { } diff --git a/tests/ui/nll/user-annotations/adt-brace-structs.stderr b/tests/ui/nll/user-annotations/adt-brace-structs.stderr new file mode 100644 index 000000000..8b9d1705d --- /dev/null +++ b/tests/ui/nll/user-annotations/adt-brace-structs.stderr @@ -0,0 +1,42 @@ +error[E0597]: `c` does not live long enough + --> $DIR/adt-brace-structs.rs:23:37 + | +LL | SomeStruct::<&'static u32> { t: &c }; + | ^^ + | | + | borrowed value does not live long enough + | this usage requires that `c` is borrowed for `'static` +LL | } + | - `c` dropped here while still borrowed + +error[E0597]: `c` does not live long enough + --> $DIR/adt-brace-structs.rs:28:32 + | +LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) { + | -- lifetime `'a` defined here +LL | let c = 66; +LL | SomeStruct::<&'a u32> { t: &c }; + | ^^ + | | + | borrowed value does not live long enough + | this usage requires that `c` is borrowed for `'a` +LL | } + | - `c` dropped here while still borrowed + +error[E0597]: `c` does not live long enough + --> $DIR/adt-brace-structs.rs:38:36 + | +LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { + | -- lifetime `'a` defined here +... +LL | SomeStruct::<&'a u32> { t: &c }; + | ^^ + | | + | borrowed value does not live long enough + | this usage requires that `c` is borrowed for `'a` +LL | }; + | - `c` dropped here while still borrowed + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/nll/user-annotations/adt-nullary-enums.rs b/tests/ui/nll/user-annotations/adt-nullary-enums.rs new file mode 100644 index 000000000..53853668d --- /dev/null +++ b/tests/ui/nll/user-annotations/adt-nullary-enums.rs @@ -0,0 +1,69 @@ +// Unit test for the "user substitutions" that are annotated on each +// node. + +#![allow(warnings)] + +use std::cell::Cell; + +enum SomeEnum<T> { + SomeVariant(T), + SomeOtherVariant, +} + +fn combine<T>(_: T, _: T) { } + +fn no_annot() { + let c = 66; + combine(SomeEnum::SomeVariant(Cell::new(&c)), SomeEnum::SomeOtherVariant); +} + +fn annot_underscore() { + let c = 66; + combine(SomeEnum::SomeVariant(Cell::new(&c)), SomeEnum::SomeOtherVariant::<Cell<_>>); +} + +fn annot_reference_any_lifetime() { + let c = 66; + combine(SomeEnum::SomeVariant(Cell::new(&c)), SomeEnum::SomeOtherVariant::<Cell<&u32>>); +} + +fn annot_reference_static_lifetime() { + let c = 66; + combine( + SomeEnum::SomeVariant(Cell::new(&c)), //~ ERROR + SomeEnum::SomeOtherVariant::<Cell<&'static u32>>, + ); +} + +fn annot_reference_named_lifetime<'a>(_d: &'a u32) { + let c = 66; + combine( + SomeEnum::SomeVariant(Cell::new(&c)), //~ ERROR + SomeEnum::SomeOtherVariant::<Cell<&'a u32>>, + ); +} + +fn annot_reference_named_lifetime_ok<'a>(c: &'a u32) { + combine(SomeEnum::SomeVariant(Cell::new(c)), SomeEnum::SomeOtherVariant::<Cell<&'a u32>>); +} + +fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { + let _closure = || { + let c = 66; + combine( + SomeEnum::SomeVariant(Cell::new(&c)), //~ ERROR + SomeEnum::SomeOtherVariant::<Cell<&'a u32>>, + ); + }; +} + +fn annot_reference_named_lifetime_in_closure_ok<'a>(c: &'a u32) { + let _closure = || { + combine( + SomeEnum::SomeVariant(Cell::new(c)), + SomeEnum::SomeOtherVariant::<Cell<&'a u32>>, + ); + }; +} + +fn main() { } diff --git a/tests/ui/nll/user-annotations/adt-nullary-enums.stderr b/tests/ui/nll/user-annotations/adt-nullary-enums.stderr new file mode 100644 index 000000000..3326fa521 --- /dev/null +++ b/tests/ui/nll/user-annotations/adt-nullary-enums.stderr @@ -0,0 +1,45 @@ +error[E0597]: `c` does not live long enough + --> $DIR/adt-nullary-enums.rs:33:41 + | +LL | / combine( +LL | | SomeEnum::SomeVariant(Cell::new(&c)), + | | ^^ borrowed value does not live long enough +LL | | SomeEnum::SomeOtherVariant::<Cell<&'static u32>>, +LL | | ); + | |_____- argument requires that `c` is borrowed for `'static` +LL | } + | - `c` dropped here while still borrowed + +error[E0597]: `c` does not live long enough + --> $DIR/adt-nullary-enums.rs:41:41 + | +LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) { + | -- lifetime `'a` defined here +... +LL | SomeEnum::SomeVariant(Cell::new(&c)), + | ----------^^- + | | | + | | borrowed value does not live long enough + | argument requires that `c` is borrowed for `'a` +... +LL | } + | - `c` dropped here while still borrowed + +error[E0597]: `c` does not live long enough + --> $DIR/adt-nullary-enums.rs:54:45 + | +LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { + | -- lifetime `'a` defined here +... +LL | SomeEnum::SomeVariant(Cell::new(&c)), + | ----------^^- + | | | + | | borrowed value does not live long enough + | argument requires that `c` is borrowed for `'a` +... +LL | }; + | - `c` dropped here while still borrowed + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/nll/user-annotations/adt-tuple-enums.rs b/tests/ui/nll/user-annotations/adt-tuple-enums.rs new file mode 100644 index 000000000..efe8dfda1 --- /dev/null +++ b/tests/ui/nll/user-annotations/adt-tuple-enums.rs @@ -0,0 +1,53 @@ +// Unit test for the "user substitutions" that are annotated on each +// node. + +#![allow(warnings)] + +enum SomeEnum<T> { + SomeVariant(T), + SomeOtherVariant, +} + +fn no_annot() { + let c = 66; + SomeEnum::SomeVariant(&c); +} + +fn annot_underscore() { + let c = 66; + SomeEnum::SomeVariant::<_>(&c); +} + +fn annot_reference_any_lifetime() { + let c = 66; + SomeEnum::SomeVariant::<&u32>(&c); +} + +fn annot_reference_static_lifetime() { + let c = 66; + SomeEnum::SomeVariant::<&'static u32>(&c); //~ ERROR +} + +fn annot_reference_named_lifetime<'a>(_d: &'a u32) { + let c = 66; + SomeEnum::SomeVariant::<&'a u32>(&c); //~ ERROR +} + +fn annot_reference_named_lifetime_ok<'a>(c: &'a u32) { + SomeEnum::SomeVariant::<&'a u32>(c); +} + +fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { + let _closure = || { + let c = 66; + SomeEnum::SomeVariant::<&'a u32>(&c); //~ ERROR + }; +} + +fn annot_reference_named_lifetime_in_closure_ok<'a>(c: &'a u32) { + let _closure = || { + SomeEnum::SomeVariant::<&'a u32>(c); + }; +} + +fn main() { } diff --git a/tests/ui/nll/user-annotations/adt-tuple-enums.stderr b/tests/ui/nll/user-annotations/adt-tuple-enums.stderr new file mode 100644 index 000000000..2fa704263 --- /dev/null +++ b/tests/ui/nll/user-annotations/adt-tuple-enums.stderr @@ -0,0 +1,42 @@ +error[E0597]: `c` does not live long enough + --> $DIR/adt-tuple-enums.rs:28:43 + | +LL | SomeEnum::SomeVariant::<&'static u32>(&c); + | ^^ + | | + | borrowed value does not live long enough + | this usage requires that `c` is borrowed for `'static` +LL | } + | - `c` dropped here while still borrowed + +error[E0597]: `c` does not live long enough + --> $DIR/adt-tuple-enums.rs:33:38 + | +LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) { + | -- lifetime `'a` defined here +LL | let c = 66; +LL | SomeEnum::SomeVariant::<&'a u32>(&c); + | ^^ + | | + | borrowed value does not live long enough + | this usage requires that `c` is borrowed for `'a` +LL | } + | - `c` dropped here while still borrowed + +error[E0597]: `c` does not live long enough + --> $DIR/adt-tuple-enums.rs:43:42 + | +LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { + | -- lifetime `'a` defined here +... +LL | SomeEnum::SomeVariant::<&'a u32>(&c); + | ^^ + | | + | borrowed value does not live long enough + | this usage requires that `c` is borrowed for `'a` +LL | }; + | - `c` dropped here while still borrowed + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/nll/user-annotations/adt-tuple-struct-calls.rs b/tests/ui/nll/user-annotations/adt-tuple-struct-calls.rs new file mode 100644 index 000000000..116583223 --- /dev/null +++ b/tests/ui/nll/user-annotations/adt-tuple-struct-calls.rs @@ -0,0 +1,71 @@ +// Unit test for the "user substitutions" that are annotated on each +// node. + +struct SomeStruct<T>(T); + +fn no_annot() { + let c = 66; + let f = SomeStruct; + f(&c); +} + +fn annot_underscore() { + let c = 66; + let f = SomeStruct::<_>; + f(&c); +} + +fn annot_reference_any_lifetime() { + let c = 66; + let f = SomeStruct::<&u32>; + f(&c); +} + +fn annot_reference_static_lifetime() { + let c = 66; + let f = SomeStruct::<&'static u32>; + f(&c); //~ ERROR +} + +fn annot_reference_named_lifetime<'a>(_d: &'a u32) { + let c = 66; + let f = SomeStruct::<&'a u32>; + f(&c); //~ ERROR +} + +fn annot_reference_named_lifetime_ok<'a>(c: &'a u32) { + let f = SomeStruct::<&'a u32>; + f(c); +} + +fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { + let _closure = || { + let c = 66; + let f = SomeStruct::<&'a u32>; + f(&c); //~ ERROR + }; +} + +fn annot_reference_named_lifetime_across_closure<'a>(_: &'a u32) { + let f = SomeStruct::<&'a u32>; + let _closure = || { + let c = 66; + f(&c); //~ ERROR + }; +} + +fn annot_reference_named_lifetime_in_closure_ok<'a>(c: &'a u32) { + let _closure = || { + let f = SomeStruct::<&'a u32>; + f(c); + }; +} + +fn annot_reference_named_lifetime_across_closure_ok<'a>(c: &'a u32) { + let f = SomeStruct::<&'a u32>; + let _closure = || { + f(c); + }; +} + +fn main() { } diff --git a/tests/ui/nll/user-annotations/adt-tuple-struct-calls.stderr b/tests/ui/nll/user-annotations/adt-tuple-struct-calls.stderr new file mode 100644 index 000000000..9664fb9f5 --- /dev/null +++ b/tests/ui/nll/user-annotations/adt-tuple-struct-calls.stderr @@ -0,0 +1,56 @@ +error[E0597]: `c` does not live long enough + --> $DIR/adt-tuple-struct-calls.rs:27:7 + | +LL | f(&c); + | --^^- + | | | + | | borrowed value does not live long enough + | argument requires that `c` is borrowed for `'static` +LL | } + | - `c` dropped here while still borrowed + +error[E0597]: `c` does not live long enough + --> $DIR/adt-tuple-struct-calls.rs:33:7 + | +LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) { + | -- lifetime `'a` defined here +... +LL | f(&c); + | --^^- + | | | + | | borrowed value does not live long enough + | argument requires that `c` is borrowed for `'a` +LL | } + | - `c` dropped here while still borrowed + +error[E0597]: `c` does not live long enough + --> $DIR/adt-tuple-struct-calls.rs:45:11 + | +LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { + | -- lifetime `'a` defined here +... +LL | f(&c); + | --^^- + | | | + | | borrowed value does not live long enough + | argument requires that `c` is borrowed for `'a` +LL | }; + | - `c` dropped here while still borrowed + +error[E0597]: `c` does not live long enough + --> $DIR/adt-tuple-struct-calls.rs:53:11 + | +LL | let f = SomeStruct::<&'a u32>; + | - lifetime `'1` appears in the type of `f` +... +LL | f(&c); + | --^^- + | | | + | | borrowed value does not live long enough + | argument requires that `c` is borrowed for `'1` +LL | }; + | - `c` dropped here while still borrowed + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/nll/user-annotations/adt-tuple-struct.rs b/tests/ui/nll/user-annotations/adt-tuple-struct.rs new file mode 100644 index 000000000..37284e1fd --- /dev/null +++ b/tests/ui/nll/user-annotations/adt-tuple-struct.rs @@ -0,0 +1,48 @@ +// Unit test for the "user substitutions" that are annotated on each +// node. + +struct SomeStruct<T>(T); + +fn no_annot() { + let c = 66; + SomeStruct(&c); +} + +fn annot_underscore() { + let c = 66; + SomeStruct::<_>(&c); +} + +fn annot_reference_any_lifetime() { + let c = 66; + SomeStruct::<&u32>(&c); +} + +fn annot_reference_static_lifetime() { + let c = 66; + SomeStruct::<&'static u32>(&c); //~ ERROR +} + +fn annot_reference_named_lifetime<'a>(_d: &'a u32) { + let c = 66; + SomeStruct::<&'a u32>(&c); //~ ERROR +} + +fn annot_reference_named_lifetime_ok<'a>(c: &'a u32) { + SomeStruct::<&'a u32>(c); +} + +fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { + let _closure = || { + let c = 66; + SomeStruct::<&'a u32>(&c); //~ ERROR + }; +} + +fn annot_reference_named_lifetime_in_closure_ok<'a>(c: &'a u32) { + let _closure = || { + SomeStruct::<&'a u32>(c); + }; +} + +fn main() { } diff --git a/tests/ui/nll/user-annotations/adt-tuple-struct.stderr b/tests/ui/nll/user-annotations/adt-tuple-struct.stderr new file mode 100644 index 000000000..76b525225 --- /dev/null +++ b/tests/ui/nll/user-annotations/adt-tuple-struct.stderr @@ -0,0 +1,42 @@ +error[E0597]: `c` does not live long enough + --> $DIR/adt-tuple-struct.rs:23:32 + | +LL | SomeStruct::<&'static u32>(&c); + | ^^ + | | + | borrowed value does not live long enough + | this usage requires that `c` is borrowed for `'static` +LL | } + | - `c` dropped here while still borrowed + +error[E0597]: `c` does not live long enough + --> $DIR/adt-tuple-struct.rs:28:27 + | +LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) { + | -- lifetime `'a` defined here +LL | let c = 66; +LL | SomeStruct::<&'a u32>(&c); + | ^^ + | | + | borrowed value does not live long enough + | this usage requires that `c` is borrowed for `'a` +LL | } + | - `c` dropped here while still borrowed + +error[E0597]: `c` does not live long enough + --> $DIR/adt-tuple-struct.rs:38:31 + | +LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { + | -- lifetime `'a` defined here +... +LL | SomeStruct::<&'a u32>(&c); + | ^^ + | | + | borrowed value does not live long enough + | this usage requires that `c` is borrowed for `'a` +LL | }; + | - `c` dropped here while still borrowed + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/nll/user-annotations/ascribed-type-wf.rs b/tests/ui/nll/user-annotations/ascribed-type-wf.rs new file mode 100644 index 000000000..5db02c46e --- /dev/null +++ b/tests/ui/nll/user-annotations/ascribed-type-wf.rs @@ -0,0 +1,17 @@ +// Regression test for #101350. +// check-fail + +trait Trait { + type Ty; +} + +impl Trait for &'static () { + type Ty = (); +} + +fn extend<'a>() { + None::<<&'a () as Trait>::Ty>; + //~^ ERROR lifetime may not live long enough +} + +fn main() {} diff --git a/tests/ui/nll/user-annotations/ascribed-type-wf.stderr b/tests/ui/nll/user-annotations/ascribed-type-wf.stderr new file mode 100644 index 000000000..91e7c6b8e --- /dev/null +++ b/tests/ui/nll/user-annotations/ascribed-type-wf.stderr @@ -0,0 +1,10 @@ +error: lifetime may not live long enough + --> $DIR/ascribed-type-wf.rs:13:5 + | +LL | fn extend<'a>() { + | -- lifetime `'a` defined here +LL | None::<<&'a () as Trait>::Ty>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` + +error: aborting due to previous error + diff --git a/tests/ui/nll/user-annotations/cast_static_lifetime.rs b/tests/ui/nll/user-annotations/cast_static_lifetime.rs new file mode 100644 index 000000000..bb6129dac --- /dev/null +++ b/tests/ui/nll/user-annotations/cast_static_lifetime.rs @@ -0,0 +1,6 @@ +#![allow(warnings)] + +fn main() { + let x = 22_u32; + let y: &u32 = (&x) as &'static u32; //~ ERROR `x` does not live long enough +} diff --git a/tests/ui/nll/user-annotations/cast_static_lifetime.stderr b/tests/ui/nll/user-annotations/cast_static_lifetime.stderr new file mode 100644 index 000000000..4599d04e7 --- /dev/null +++ b/tests/ui/nll/user-annotations/cast_static_lifetime.stderr @@ -0,0 +1,14 @@ +error[E0597]: `x` does not live long enough + --> $DIR/cast_static_lifetime.rs:5:19 + | +LL | let y: &u32 = (&x) as &'static u32; + | ^^^^---------------- + | | + | borrowed value does not live long enough + | type annotation requires that `x` is borrowed for `'static` +LL | } + | - `x` dropped here while still borrowed + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/nll/user-annotations/closure-sig.rs b/tests/ui/nll/user-annotations/closure-sig.rs new file mode 100644 index 000000000..4dbd3fd8d --- /dev/null +++ b/tests/ui/nll/user-annotations/closure-sig.rs @@ -0,0 +1,15 @@ +// This test fails if #104478 is fixed before #104477. + +// check-pass + +struct Printer<'a, 'b>(&'a (), &'b ()); + +impl Printer<'_, '_> { + fn test(self) { + let clo = |_: &'_ Self| {}; + clo(&self); + clo(&self); + } +} + +fn main() {} diff --git a/tests/ui/nll/user-annotations/closure-substs.polonius.stderr b/tests/ui/nll/user-annotations/closure-substs.polonius.stderr new file mode 100644 index 000000000..af159a6cd --- /dev/null +++ b/tests/ui/nll/user-annotations/closure-substs.polonius.stderr @@ -0,0 +1,61 @@ +error: lifetime may not live long enough + --> $DIR/closure-substs.rs:8:16 + | +LL | fn foo<'a>() { + | -- lifetime `'a` defined here +... +LL | return x; + | ^ returning this value requires that `'a` must outlive `'static` + | + = help: consider replacing `'a` with `'static` + +error: lifetime may not live long enough + --> $DIR/closure-substs.rs:15:16 + | +LL | |x: &i32| -> &'static i32 { + | - let's call the lifetime of this reference `'1` +LL | return x; + | ^ returning this value requires that `'1` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/closure-substs.rs:15:16 + | +LL | |x: &i32| -> &'static i32 { + | - - let's call the lifetime of this reference `'2` + | | + | let's call the lifetime of this reference `'1` +LL | return x; + | ^ returning this value requires that `'1` must outlive `'2` + +error: lifetime may not live long enough + --> $DIR/closure-substs.rs:22:9 + | +LL | fn bar<'a>() { + | -- lifetime `'a` defined here +... +LL | b(x); + | ^^^^ argument requires that `'a` must outlive `'static` + | + = help: consider replacing `'a` with `'static` + +error[E0521]: borrowed data escapes outside of closure + --> $DIR/closure-substs.rs:29:9 + | +LL | |x: &i32, b: fn(&'static i32)| { + | - `x` is a reference that is only valid in the closure body +LL | b(x); + | ^^^^ `x` escapes the closure body here + +error[E0521]: borrowed data escapes outside of closure + --> $DIR/closure-substs.rs:29:9 + | +LL | |x: &i32, b: fn(&'static i32)| { + | - - `b` declared here, outside of the closure body + | | + | `x` is a reference that is only valid in the closure body +LL | b(x); + | ^^^^ `x` escapes the closure body here + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0521`. diff --git a/tests/ui/nll/user-annotations/closure-substs.rs b/tests/ui/nll/user-annotations/closure-substs.rs new file mode 100644 index 000000000..f7af54e8d --- /dev/null +++ b/tests/ui/nll/user-annotations/closure-substs.rs @@ -0,0 +1,31 @@ +// Test that we enforce user-provided type annotations on closures. + +fn foo<'a>() { + // Here `x` is free in the closure sig: + |x: &'a i32| -> &'static i32 { + return x; //~ ERROR lifetime may not live long enough + }; +} + +fn foo1() { + // Here `x` is bound in the closure sig: + |x: &i32| -> &'static i32 { + return x; //~ ERROR lifetime may not live long enough + }; +} + +fn bar<'a>() { + // Here `x` is free in the closure sig: + |x: &'a i32, b: fn(&'static i32)| { + b(x); //~ ERROR lifetime may not live long enough + }; +} + +fn bar1() { + // Here `x` is bound in the closure sig: + |x: &i32, b: fn(&'static i32)| { + b(x); //~ ERROR borrowed data escapes outside of closure + }; +} + +fn main() {} diff --git a/tests/ui/nll/user-annotations/closure-substs.stderr b/tests/ui/nll/user-annotations/closure-substs.stderr new file mode 100644 index 000000000..1e8de4ba9 --- /dev/null +++ b/tests/ui/nll/user-annotations/closure-substs.stderr @@ -0,0 +1,42 @@ +error: lifetime may not live long enough + --> $DIR/closure-substs.rs:6:16 + | +LL | fn foo<'a>() { + | -- lifetime `'a` defined here +... +LL | return x; + | ^ returning this value requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/closure-substs.rs:13:16 + | +LL | |x: &i32| -> &'static i32 { + | - let's call the lifetime of this reference `'1` +LL | return x; + | ^ returning this value requires that `'1` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/closure-substs.rs:20:9 + | +LL | fn bar<'a>() { + | -- lifetime `'a` defined here +... +LL | b(x); + | ^^^^ argument requires that `'a` must outlive `'static` + +error[E0521]: borrowed data escapes outside of closure + --> $DIR/closure-substs.rs:27:9 + | +LL | |x: &i32, b: fn(&'static i32)| { + | - - let's call the lifetime of this reference `'1` + | | + | `x` is a reference that is only valid in the closure body +LL | b(x); + | ^^^^ + | | + | `x` escapes the closure body here + | argument requires that `'1` must outlive `'static` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0521`. diff --git a/tests/ui/nll/user-annotations/constant-in-expr-inherent-1.rs b/tests/ui/nll/user-annotations/constant-in-expr-inherent-1.rs new file mode 100644 index 000000000..e3a8a5f58 --- /dev/null +++ b/tests/ui/nll/user-annotations/constant-in-expr-inherent-1.rs @@ -0,0 +1,12 @@ +struct Foo<'a> { x: &'a u32 } + +impl<'a> Foo<'a> { + const C: &'a u32 = &22; +} + +fn foo<'a>(_: &'a u32) -> &'static u32 { + <Foo<'a>>::C //~ ERROR +} + +fn main() { +} diff --git a/tests/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr b/tests/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr new file mode 100644 index 000000000..c39301588 --- /dev/null +++ b/tests/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr @@ -0,0 +1,10 @@ +error: lifetime may not live long enough + --> $DIR/constant-in-expr-inherent-1.rs:8:5 + | +LL | fn foo<'a>(_: &'a u32) -> &'static u32 { + | -- lifetime `'a` defined here +LL | <Foo<'a>>::C + | ^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` + +error: aborting due to previous error + diff --git a/tests/ui/nll/user-annotations/constant-in-expr-inherent-2.rs b/tests/ui/nll/user-annotations/constant-in-expr-inherent-2.rs new file mode 100644 index 000000000..90696d4b1 --- /dev/null +++ b/tests/ui/nll/user-annotations/constant-in-expr-inherent-2.rs @@ -0,0 +1,27 @@ +// Test that we still check constants are well-formed, even when we there's no +// type annotation to check. + +const FUN: fn(&'static ()) = |_| {}; +struct A; +impl A { + const ASSOCIATED_FUN: fn(&'static ()) = |_| {}; +} + +struct B<'a>(&'a ()); +impl B<'static> { + const ALSO_ASSOCIATED_FUN: fn(&'static ()) = |_| {}; +} + +trait Z: 'static { + const TRAIT_ASSOCIATED_FUN: fn(&'static Self) = |_| (); +} + +impl Z for () {} + +fn main() { + let x = (); + FUN(&x); //~ ERROR `x` does not live long enough + A::ASSOCIATED_FUN(&x); //~ ERROR `x` does not live long enough + B::ALSO_ASSOCIATED_FUN(&x); //~ ERROR `x` does not live long enough + <_>::TRAIT_ASSOCIATED_FUN(&x); //~ ERROR `x` does not live long enough +} diff --git a/tests/ui/nll/user-annotations/constant-in-expr-inherent-2.stderr b/tests/ui/nll/user-annotations/constant-in-expr-inherent-2.stderr new file mode 100644 index 000000000..12065a85a --- /dev/null +++ b/tests/ui/nll/user-annotations/constant-in-expr-inherent-2.stderr @@ -0,0 +1,50 @@ +error[E0597]: `x` does not live long enough + --> $DIR/constant-in-expr-inherent-2.rs:23:9 + | +LL | FUN(&x); + | ----^^- + | | | + | | borrowed value does not live long enough + | argument requires that `x` is borrowed for `'static` +... +LL | } + | - `x` dropped here while still borrowed + +error[E0597]: `x` does not live long enough + --> $DIR/constant-in-expr-inherent-2.rs:24:23 + | +LL | A::ASSOCIATED_FUN(&x); + | ------------------^^- + | | | + | | borrowed value does not live long enough + | argument requires that `x` is borrowed for `'static` +... +LL | } + | - `x` dropped here while still borrowed + +error[E0597]: `x` does not live long enough + --> $DIR/constant-in-expr-inherent-2.rs:25:28 + | +LL | B::ALSO_ASSOCIATED_FUN(&x); + | -----------------------^^- + | | | + | | borrowed value does not live long enough + | argument requires that `x` is borrowed for `'static` +LL | <_>::TRAIT_ASSOCIATED_FUN(&x); +LL | } + | - `x` dropped here while still borrowed + +error[E0597]: `x` does not live long enough + --> $DIR/constant-in-expr-inherent-2.rs:26:31 + | +LL | <_>::TRAIT_ASSOCIATED_FUN(&x); + | --------------------------^^- + | | | + | | borrowed value does not live long enough + | argument requires that `x` is borrowed for `'static` +LL | } + | - `x` dropped here while still borrowed + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/nll/user-annotations/constant-in-expr-normalize.rs b/tests/ui/nll/user-annotations/constant-in-expr-normalize.rs new file mode 100644 index 000000000..b7095430d --- /dev/null +++ b/tests/ui/nll/user-annotations/constant-in-expr-normalize.rs @@ -0,0 +1,22 @@ +trait Mirror { + type Me; +} + +impl<T> Mirror for T { + type Me = T; +} + +trait Foo<'a> { + const C: <&'a u32 as Mirror>::Me; +} + +impl<'a, T> Foo<'a> for T { + const C: &'a u32 = &22; +} + +fn foo<'a>(_: &'a u32) -> &'static u32 { + <() as Foo<'a>>::C //~ ERROR +} + +fn main() { +} diff --git a/tests/ui/nll/user-annotations/constant-in-expr-normalize.stderr b/tests/ui/nll/user-annotations/constant-in-expr-normalize.stderr new file mode 100644 index 000000000..541a2cfaf --- /dev/null +++ b/tests/ui/nll/user-annotations/constant-in-expr-normalize.stderr @@ -0,0 +1,10 @@ +error: lifetime may not live long enough + --> $DIR/constant-in-expr-normalize.rs:18:5 + | +LL | fn foo<'a>(_: &'a u32) -> &'static u32 { + | -- lifetime `'a` defined here +LL | <() as Foo<'a>>::C + | ^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` + +error: aborting due to previous error + diff --git a/tests/ui/nll/user-annotations/constant-in-expr-trait-item-1.rs b/tests/ui/nll/user-annotations/constant-in-expr-trait-item-1.rs new file mode 100644 index 000000000..e0400b2cc --- /dev/null +++ b/tests/ui/nll/user-annotations/constant-in-expr-trait-item-1.rs @@ -0,0 +1,14 @@ +trait Foo<'a> { + const C: &'a u32; +} + +impl<'a, T> Foo<'a> for T { + const C: &'a u32 = &22; +} + +fn foo<'a>(_: &'a u32) -> &'static u32 { + <() as Foo<'a>>::C //~ ERROR +} + +fn main() { +} diff --git a/tests/ui/nll/user-annotations/constant-in-expr-trait-item-1.stderr b/tests/ui/nll/user-annotations/constant-in-expr-trait-item-1.stderr new file mode 100644 index 000000000..ea0fcb6d6 --- /dev/null +++ b/tests/ui/nll/user-annotations/constant-in-expr-trait-item-1.stderr @@ -0,0 +1,10 @@ +error: lifetime may not live long enough + --> $DIR/constant-in-expr-trait-item-1.rs:10:5 + | +LL | fn foo<'a>(_: &'a u32) -> &'static u32 { + | -- lifetime `'a` defined here +LL | <() as Foo<'a>>::C + | ^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` + +error: aborting due to previous error + diff --git a/tests/ui/nll/user-annotations/constant-in-expr-trait-item-2.rs b/tests/ui/nll/user-annotations/constant-in-expr-trait-item-2.rs new file mode 100644 index 000000000..73c4e577b --- /dev/null +++ b/tests/ui/nll/user-annotations/constant-in-expr-trait-item-2.rs @@ -0,0 +1,14 @@ +trait Foo<'a> { + const C: &'a u32; +} + +impl<'a, T> Foo<'a> for T { + const C: &'a u32 = &22; +} + +fn foo<'a, T: Foo<'a>>() -> &'static u32 { + <T as Foo<'a>>::C //~ ERROR +} + +fn main() { +} diff --git a/tests/ui/nll/user-annotations/constant-in-expr-trait-item-2.stderr b/tests/ui/nll/user-annotations/constant-in-expr-trait-item-2.stderr new file mode 100644 index 000000000..ff549f1d8 --- /dev/null +++ b/tests/ui/nll/user-annotations/constant-in-expr-trait-item-2.stderr @@ -0,0 +1,10 @@ +error: lifetime may not live long enough + --> $DIR/constant-in-expr-trait-item-2.rs:10:5 + | +LL | fn foo<'a, T: Foo<'a>>() -> &'static u32 { + | -- lifetime `'a` defined here +LL | <T as Foo<'a>>::C + | ^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` + +error: aborting due to previous error + diff --git a/tests/ui/nll/user-annotations/constant-in-expr-trait-item-3.rs b/tests/ui/nll/user-annotations/constant-in-expr-trait-item-3.rs new file mode 100644 index 000000000..567e31ef9 --- /dev/null +++ b/tests/ui/nll/user-annotations/constant-in-expr-trait-item-3.rs @@ -0,0 +1,14 @@ +trait Foo<'a> { + const C: &'a u32; +} + +impl<'a, T> Foo<'a> for T { + const C: &'a u32 = &22; +} + +fn foo<'a, T: Foo<'a>>() -> &'static u32 { + T::C //~ ERROR +} + +fn main() { +} diff --git a/tests/ui/nll/user-annotations/constant-in-expr-trait-item-3.stderr b/tests/ui/nll/user-annotations/constant-in-expr-trait-item-3.stderr new file mode 100644 index 000000000..7f160d8e3 --- /dev/null +++ b/tests/ui/nll/user-annotations/constant-in-expr-trait-item-3.stderr @@ -0,0 +1,10 @@ +error: lifetime may not live long enough + --> $DIR/constant-in-expr-trait-item-3.rs:10:5 + | +LL | fn foo<'a, T: Foo<'a>>() -> &'static u32 { + | -- lifetime `'a` defined here +LL | T::C + | ^^^^ returning this value requires that `'a` must outlive `'static` + +error: aborting due to previous error + diff --git a/tests/ui/nll/user-annotations/downcast-infer.rs b/tests/ui/nll/user-annotations/downcast-infer.rs new file mode 100644 index 000000000..b27429f4d --- /dev/null +++ b/tests/ui/nll/user-annotations/downcast-infer.rs @@ -0,0 +1,11 @@ +// check-pass + +// Check that we don't try to downcast `_` when type-checking the annotation. +fn main() { + let x = Some(Some(Some(1))); + + match x { + Some::<Option<_>>(Some(Some(v))) => (), + _ => (), + } +} diff --git a/tests/ui/nll/user-annotations/dump-adt-brace-struct.rs b/tests/ui/nll/user-annotations/dump-adt-brace-struct.rs new file mode 100644 index 000000000..ccda9129d --- /dev/null +++ b/tests/ui/nll/user-annotations/dump-adt-brace-struct.rs @@ -0,0 +1,20 @@ +// Unit test for the "user substitutions" that are annotated on each +// node. + +// compile-flags:-Zverbose + +#![allow(warnings)] +#![feature(rustc_attrs)] + +struct SomeStruct<T> { t: T } + +#[rustc_dump_user_substs] +fn main() { + SomeStruct { t: 22 }; // Nothing given, no annotation. + + SomeStruct::<_> { t: 22 }; // Nothing interesting given, no annotation. + + SomeStruct::<u32> { t: 22 }; // No lifetime bounds given. + + SomeStruct::<&'static u32> { t: &22 }; //~ ERROR [&ReStatic u32] +} diff --git a/tests/ui/nll/user-annotations/dump-adt-brace-struct.stderr b/tests/ui/nll/user-annotations/dump-adt-brace-struct.stderr new file mode 100644 index 000000000..586062190 --- /dev/null +++ b/tests/ui/nll/user-annotations/dump-adt-brace-struct.stderr @@ -0,0 +1,8 @@ +error: user substs: UserSubsts { substs: [&ReStatic u32], user_self_ty: None } + --> $DIR/dump-adt-brace-struct.rs:19:5 + | +LL | SomeStruct::<&'static u32> { t: &22 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/nll/user-annotations/dump-fn-method.rs b/tests/ui/nll/user-annotations/dump-fn-method.rs new file mode 100644 index 000000000..148d63d84 --- /dev/null +++ b/tests/ui/nll/user-annotations/dump-fn-method.rs @@ -0,0 +1,57 @@ +// Unit test for the "user substitutions" that are annotated on each +// node. + +// compile-flags:-Zverbose + +#![feature(rustc_attrs)] + +// Note: we reference the names T and U in the comments below. +trait Bazoom<T> { + fn method<U>(&self, arg: T, arg2: U) { } +} + +impl<S, T> Bazoom<T> for S { +} + +fn foo<'a, T>(_: T) { } + +#[rustc_dump_user_substs] +fn main() { + // Here: nothing is given, so we don't have any annotation. + let x = foo; + x(22); + + // Here: `u32` is given, which doesn't contain any lifetimes, so we don't + // have any annotation. + let x = foo::<u32>; + x(22); + + let x = foo::<&'static u32>; //~ ERROR [&ReStatic u32] + x(&22); + + // Here: we only want the `T` to be given, the rest should be variables. + // + // (`T` refers to the declaration of `Bazoom`) + let x = <_ as Bazoom<u32>>::method::<_>; //~ ERROR [^0, u32, ^1] + x(&22, 44, 66); + + // Here: all are given and definitely contain no lifetimes, so we + // don't have any annotation. + let x = <u8 as Bazoom<u16>>::method::<u32>; + x(&22, 44, 66); + + // Here: all are given and we have a lifetime. + let x = <u8 as Bazoom<&'static u16>>::method::<u32>; //~ ERROR [u8, &ReStatic u16, u32] + x(&22, &44, 66); + + // Here: we want in particular that *only* the method `U` + // annotation is given, the rest are variables. + // + // (`U` refers to the declaration of `Bazoom`) + let y = 22_u32; + y.method::<u32>(44, 66); //~ ERROR [^0, ^1, u32] + + // Here: nothing is given, so we don't have any annotation. + let y = 22_u32; + y.method(44, 66); +} diff --git a/tests/ui/nll/user-annotations/dump-fn-method.stderr b/tests/ui/nll/user-annotations/dump-fn-method.stderr new file mode 100644 index 000000000..d139efa88 --- /dev/null +++ b/tests/ui/nll/user-annotations/dump-fn-method.stderr @@ -0,0 +1,26 @@ +error: user substs: UserSubsts { substs: [&ReStatic u32], user_self_ty: None } + --> $DIR/dump-fn-method.rs:29:13 + | +LL | let x = foo::<&'static u32>; + | ^^^^^^^^^^^^^^^^^^^ + +error: user substs: UserSubsts { substs: [^0, u32, ^1], user_self_ty: None } + --> $DIR/dump-fn-method.rs:35:13 + | +LL | let x = <_ as Bazoom<u32>>::method::<_>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: user substs: UserSubsts { substs: [u8, &ReStatic u16, u32], user_self_ty: None } + --> $DIR/dump-fn-method.rs:44:13 + | +LL | let x = <u8 as Bazoom<&'static u16>>::method::<u32>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: user substs: UserSubsts { substs: [^0, ^1, u32], user_self_ty: None } + --> $DIR/dump-fn-method.rs:52:5 + | +LL | y.method::<u32>(44, 66); + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors + diff --git a/tests/ui/nll/user-annotations/fns.rs b/tests/ui/nll/user-annotations/fns.rs new file mode 100644 index 000000000..38db6d1c4 --- /dev/null +++ b/tests/ui/nll/user-annotations/fns.rs @@ -0,0 +1,48 @@ +// Unit test for the "user substitutions" that are annotated on each +// node. + +fn some_fn<T>(arg: T) { } + +fn no_annot() { + let c = 66; + some_fn(&c); // OK +} + +fn annot_underscore() { + let c = 66; + some_fn::<_>(&c); // OK +} + +fn annot_reference_any_lifetime() { + let c = 66; + some_fn::<&u32>(&c); // OK +} + +fn annot_reference_static_lifetime() { + let c = 66; + some_fn::<&'static u32>(&c); //~ ERROR +} + +fn annot_reference_named_lifetime<'a>(_d: &'a u32) { + let c = 66; + some_fn::<&'a u32>(&c); //~ ERROR +} + +fn annot_reference_named_lifetime_ok<'a>(c: &'a u32) { + some_fn::<&'a u32>(c); +} + +fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { + let _closure = || { + let c = 66; + some_fn::<&'a u32>(&c); //~ ERROR + }; +} + +fn annot_reference_named_lifetime_in_closure_ok<'a>(c: &'a u32) { + let _closure = || { + some_fn::<&'a u32>(c); + }; +} + +fn main() { } diff --git a/tests/ui/nll/user-annotations/fns.stderr b/tests/ui/nll/user-annotations/fns.stderr new file mode 100644 index 000000000..e0640da39 --- /dev/null +++ b/tests/ui/nll/user-annotations/fns.stderr @@ -0,0 +1,42 @@ +error[E0597]: `c` does not live long enough + --> $DIR/fns.rs:23:29 + | +LL | some_fn::<&'static u32>(&c); + | ------------------------^^- + | | | + | | borrowed value does not live long enough + | argument requires that `c` is borrowed for `'static` +LL | } + | - `c` dropped here while still borrowed + +error[E0597]: `c` does not live long enough + --> $DIR/fns.rs:28:24 + | +LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) { + | -- lifetime `'a` defined here +LL | let c = 66; +LL | some_fn::<&'a u32>(&c); + | -------------------^^- + | | | + | | borrowed value does not live long enough + | argument requires that `c` is borrowed for `'a` +LL | } + | - `c` dropped here while still borrowed + +error[E0597]: `c` does not live long enough + --> $DIR/fns.rs:38:28 + | +LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { + | -- lifetime `'a` defined here +... +LL | some_fn::<&'a u32>(&c); + | -------------------^^- + | | | + | | borrowed value does not live long enough + | argument requires that `c` is borrowed for `'a` +LL | }; + | - `c` dropped here while still borrowed + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/nll/user-annotations/inherent-associated-constants.rs b/tests/ui/nll/user-annotations/inherent-associated-constants.rs new file mode 100644 index 000000000..fe2641fd6 --- /dev/null +++ b/tests/ui/nll/user-annotations/inherent-associated-constants.rs @@ -0,0 +1,15 @@ +struct A<'a>(&'a ()); + +impl A<'static> { + const IC: i32 = 10; +} + +fn non_wf_associated_const<'a>(x: i32) { + A::<'a>::IC; //~ ERROR lifetime may not live long enough +} + +fn wf_associated_const<'a>(x: i32) { + A::<'static>::IC; +} + +fn main() {} diff --git a/tests/ui/nll/user-annotations/inherent-associated-constants.stderr b/tests/ui/nll/user-annotations/inherent-associated-constants.stderr new file mode 100644 index 000000000..ffbfc40f5 --- /dev/null +++ b/tests/ui/nll/user-annotations/inherent-associated-constants.stderr @@ -0,0 +1,10 @@ +error: lifetime may not live long enough + --> $DIR/inherent-associated-constants.rs:8:5 + | +LL | fn non_wf_associated_const<'a>(x: i32) { + | -- lifetime `'a` defined here +LL | A::<'a>::IC; + | ^^^^^^^^^^^ requires that `'a` must outlive `'static` + +error: aborting due to previous error + diff --git a/tests/ui/nll/user-annotations/issue-54124.rs b/tests/ui/nll/user-annotations/issue-54124.rs new file mode 100644 index 000000000..5ae03c894 --- /dev/null +++ b/tests/ui/nll/user-annotations/issue-54124.rs @@ -0,0 +1,8 @@ +fn test<'a>() { + let _:fn(&()) = |_:&'a ()| {}; //~ ERROR lifetime may not live long enough + //~^ ERROR lifetime may not live long enough +} + +fn main() { + test(); +} diff --git a/tests/ui/nll/user-annotations/issue-54124.stderr b/tests/ui/nll/user-annotations/issue-54124.stderr new file mode 100644 index 000000000..2556af2dd --- /dev/null +++ b/tests/ui/nll/user-annotations/issue-54124.stderr @@ -0,0 +1,20 @@ +error: lifetime may not live long enough + --> $DIR/issue-54124.rs:2:22 + | +LL | fn test<'a>() { + | -- lifetime `'a` defined here +LL | let _:fn(&()) = |_:&'a ()| {}; + | ^ - let's call the lifetime of this reference `'1` + | | + | requires that `'1` must outlive `'a` + +error: lifetime may not live long enough + --> $DIR/issue-54124.rs:2:22 + | +LL | fn test<'a>() { + | -- lifetime `'a` defined here +LL | let _:fn(&()) = |_:&'a ()| {}; + | ^ requires that `'a` must outlive `'static` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/nll/user-annotations/issue-54570-bootstrapping.rs b/tests/ui/nll/user-annotations/issue-54570-bootstrapping.rs new file mode 100644 index 000000000..ff5b2244e --- /dev/null +++ b/tests/ui/nll/user-annotations/issue-54570-bootstrapping.rs @@ -0,0 +1,30 @@ +// check-pass + +// This test is reduced from a scenario pnkfelix encountered while +// bootstrapping the compiler. + +#[derive(Copy, Clone)] +pub struct Spanned<T> { + pub node: T, + pub span: Span, +} + +pub type Variant = Spanned<VariantKind>; +// #[derive(Clone)] pub struct Variant { pub node: VariantKind, pub span: Span, } + +#[derive(Clone)] +pub struct VariantKind { } + +#[derive(Copy, Clone)] +pub struct Span; + +pub fn variant_to_span(variant: Variant) { + match variant { + Variant { + span: _span, + .. + } => { } + }; +} + +fn main() { } diff --git a/tests/ui/nll/user-annotations/issue-55219.rs b/tests/ui/nll/user-annotations/issue-55219.rs new file mode 100644 index 000000000..147413663 --- /dev/null +++ b/tests/ui/nll/user-annotations/issue-55219.rs @@ -0,0 +1,18 @@ +// Regression test for #55219: +// +// The `Self::HASH_LEN` here expands to a "self-type" where `T` is not +// known. This unbound inference variable was causing an ICE. +// +// check-pass + +pub struct Foo<T>(T); + +impl<T> Foo<T> { + const HASH_LEN: usize = 20; + + fn stuff() { + let _ = Self::HASH_LEN; + } +} + +fn main() { } diff --git a/tests/ui/nll/user-annotations/issue-55241.rs b/tests/ui/nll/user-annotations/issue-55241.rs new file mode 100644 index 000000000..29969c7b4 --- /dev/null +++ b/tests/ui/nll/user-annotations/issue-55241.rs @@ -0,0 +1,26 @@ +// Regression test for #55241: +// +// The reference to `C::HASHED_NULL_NODE` resulted in a type like `<C +// as NodeCodec<_>>::Out`; normalizing this type requires knowing the +// value of `_`; solving that requires having normalized, so we can +// test against `C: NodeCodec<H>` in the environment. +// +// run-pass + +pub trait Hasher { + type Out: Eq; +} + +pub trait NodeCodec<H: Hasher> { + const HASHED_NULL_NODE: H::Out; +} + +pub trait Trie<H: Hasher, C: NodeCodec<H>> { + /// Returns the root of the trie. + fn root(&self) -> &H::Out; + + /// Is the trie empty? + fn is_empty(&self) -> bool { *self.root() == C::HASHED_NULL_NODE } +} + +fn main() { } diff --git a/tests/ui/nll/user-annotations/issue-55748-pat-types-constrain-bindings.rs b/tests/ui/nll/user-annotations/issue-55748-pat-types-constrain-bindings.rs new file mode 100644 index 000000000..c71937a50 --- /dev/null +++ b/tests/ui/nll/user-annotations/issue-55748-pat-types-constrain-bindings.rs @@ -0,0 +1,68 @@ +// This test is ensuring that type ascriptions on let bindings +// constrain both: +// +// 1. the input expression on the right-hand side (after any potential +// coercion, and allowing for covariance), *and* +// +// 2. the bindings (if any) nested within the pattern on the left-hand +// side (and here, the type-constraint is *invariant*). + +#![allow(dead_code, unused_mut)] +type PairUncoupled<'a, 'b, T> = (&'a T, &'b T); +type PairCoupledRegions<'a, T> = (&'a T, &'a T); +type PairCoupledTypes<T> = (T, T); + +fn uncoupled_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + let ((mut y, mut _z),): (PairUncoupled<u32>,) = ((s, &_x),); // ok + // Above compiling does *not* imply below would compile. + // ::std::mem::swap(&mut y, &mut _z); + y +} + +fn swap_regions((mut y, mut _z): PairCoupledRegions<u32>) { + ::std::mem::swap(&mut y, &mut _z); +} + +fn coupled_regions_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + let ((y, _z),): (PairCoupledRegions<u32>,) = ((s, &_x),); + // If above line compiled, so should line below ... + + // swap_regions((y, _z)); + + // ... but the ascribed type also invalidates this use of `y` + y //~ ERROR lifetime may not live long enough +} + +fn swap_types((mut y, mut _z): PairCoupledTypes<&u32>) { + ::std::mem::swap(&mut y, &mut _z); +} + +fn coupled_types_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + let ((y, _z),): (PairCoupledTypes<&u32>,) = ((s, &_x),); + // If above line compiled, so should line below ... + + // swap_types((y, _z)); + + // ... but the ascribed type also invalidates this use of `y` + y //~ ERROR lifetime may not live long enough +} + +fn swap_wilds((mut y, mut _z): PairCoupledTypes<&u32>) { + ::std::mem::swap(&mut y, &mut _z); +} + +fn coupled_wilds_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + let ((y, _z),): (PairCoupledTypes<_>,) = ((s, &_x),); + // If above line compiled, so should line below + // swap_wilds((y, _z)); + + // ... but the ascribed type also invalidates this use of `y` + y //~ ERROR lifetime may not live long enough +} + +fn main() { + uncoupled_lhs(&3, &4); + coupled_regions_lhs(&3, &4); + coupled_types_lhs(&3, &4); + coupled_wilds_lhs(&3, &4); +} diff --git a/tests/ui/nll/user-annotations/issue-55748-pat-types-constrain-bindings.stderr b/tests/ui/nll/user-annotations/issue-55748-pat-types-constrain-bindings.stderr new file mode 100644 index 000000000..8399ef04e --- /dev/null +++ b/tests/ui/nll/user-annotations/issue-55748-pat-types-constrain-bindings.stderr @@ -0,0 +1,29 @@ +error: lifetime may not live long enough + --> $DIR/issue-55748-pat-types-constrain-bindings.rs:33:5 + | +LL | fn coupled_regions_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + | -- lifetime `'a` defined here +... +LL | y + | ^ returning this value requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/issue-55748-pat-types-constrain-bindings.rs:47:5 + | +LL | fn coupled_types_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + | -- lifetime `'a` defined here +... +LL | y + | ^ returning this value requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/issue-55748-pat-types-constrain-bindings.rs:60:5 + | +LL | fn coupled_wilds_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + | -- lifetime `'a` defined here +... +LL | y + | ^ returning this value requires that `'a` must outlive `'static` + +error: aborting due to 3 previous errors + diff --git a/tests/ui/nll/user-annotations/issue-57731-ascibed-coupled-types.rs b/tests/ui/nll/user-annotations/issue-57731-ascibed-coupled-types.rs new file mode 100644 index 000000000..95c655654 --- /dev/null +++ b/tests/ui/nll/user-annotations/issue-57731-ascibed-coupled-types.rs @@ -0,0 +1,40 @@ +// Check that repeated type variables are correctly handled + +#![allow(unused)] +#![feature(type_ascription)] + +type PairUncoupled<'a, 'b, T> = (&'a T, &'b T); +type PairCoupledTypes<T> = (T, T); +type PairCoupledRegions<'a, T> = (&'a T, &'a T); + +fn uncoupled_wilds_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + let ((y, _z),) = type_ascribe!(((s, _x),), (PairUncoupled<_>,)); + y // OK +} + +fn coupled_wilds_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + let ((y, _z),) = type_ascribe!(((s, _x),), (PairCoupledTypes<_>,)); + y //~ ERROR lifetime may not live long enough +} + +fn coupled_regions_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + let ((y, _z),) = type_ascribe!(((s, _x),), (PairCoupledRegions<_>,)); + y //~ ERROR lifetime may not live long enough +} + +fn cast_uncoupled_wilds_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + let ((y, _z),) = ((s, _x),) as (PairUncoupled<_>,); + y // OK +} + +fn cast_coupled_wilds_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + let ((y, _z),) = ((s, _x),) as (PairCoupledTypes<_>,); + y //~ ERROR lifetime may not live long enough +} + +fn cast_coupled_regions_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + let ((y, _z),) = ((s, _x),) as (PairCoupledRegions<_>,); + y //~ ERROR lifetime may not live long enough +} + +fn main() {} diff --git a/tests/ui/nll/user-annotations/issue-57731-ascibed-coupled-types.stderr b/tests/ui/nll/user-annotations/issue-57731-ascibed-coupled-types.stderr new file mode 100644 index 000000000..8601691e8 --- /dev/null +++ b/tests/ui/nll/user-annotations/issue-57731-ascibed-coupled-types.stderr @@ -0,0 +1,38 @@ +error: lifetime may not live long enough + --> $DIR/issue-57731-ascibed-coupled-types.rs:17:5 + | +LL | fn coupled_wilds_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + | -- lifetime `'a` defined here +LL | let ((y, _z),) = type_ascribe!(((s, _x),), (PairCoupledTypes<_>,)); +LL | y + | ^ returning this value requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/issue-57731-ascibed-coupled-types.rs:22:5 + | +LL | fn coupled_regions_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + | -- lifetime `'a` defined here +LL | let ((y, _z),) = type_ascribe!(((s, _x),), (PairCoupledRegions<_>,)); +LL | y + | ^ returning this value requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/issue-57731-ascibed-coupled-types.rs:32:5 + | +LL | fn cast_coupled_wilds_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + | -- lifetime `'a` defined here +LL | let ((y, _z),) = ((s, _x),) as (PairCoupledTypes<_>,); +LL | y + | ^ returning this value requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/issue-57731-ascibed-coupled-types.rs:37:5 + | +LL | fn cast_coupled_regions_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + | -- lifetime `'a` defined here +LL | let ((y, _z),) = ((s, _x),) as (PairCoupledRegions<_>,); +LL | y + | ^ returning this value requires that `'a` must outlive `'static` + +error: aborting due to 4 previous errors + diff --git a/tests/ui/nll/user-annotations/method-call.rs b/tests/ui/nll/user-annotations/method-call.rs new file mode 100644 index 000000000..beafc597a --- /dev/null +++ b/tests/ui/nll/user-annotations/method-call.rs @@ -0,0 +1,69 @@ +// Unit test for the "user substitutions" that are annotated on each +// node. + +trait Bazoom<T> { + fn method<U>(&self, arg: T, arg2: U) { } +} + +impl<T, U> Bazoom<U> for T { +} + +fn no_annot() { + let a = 22; + let b = 44; + let c = 66; + a.method(b, &c); // OK +} + +fn annot_underscore() { + let a = 22; + let b = 44; + let c = 66; + a.method::<_>(b, &c); // OK +} + +fn annot_reference_any_lifetime() { + let a = 22; + let b = 44; + let c = 66; + a.method::<&u32>(b, &c); // OK +} + +fn annot_reference_static_lifetime() { + let a = 22; + let b = 44; + let c = 66; + a.method::<&'static u32>(b, &c); //~ ERROR +} + +fn annot_reference_named_lifetime<'a>(_d: &'a u32) { + let a = 22; + let b = 44; + let c = 66; + a.method::<&'a u32>(b, &c); //~ ERROR +} + +fn annot_reference_named_lifetime_ok<'a>(c: &'a u32) { + let a = 22; + let b = 44; + a.method::<&'a u32>(b, c); +} + +fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { + let a = 22; + let b = 44; + let _closure = || { + let c = 66; + a.method::<&'a u32>(b, &c); //~ ERROR + }; +} + +fn annot_reference_named_lifetime_in_closure_ok<'a>(c: &'a u32) { + let a = 22; + let b = 44; + let _closure = || { + a.method::<&'a u32>(b, c); + }; +} + +fn main() { } diff --git a/tests/ui/nll/user-annotations/method-call.stderr b/tests/ui/nll/user-annotations/method-call.stderr new file mode 100644 index 000000000..10447e45a --- /dev/null +++ b/tests/ui/nll/user-annotations/method-call.stderr @@ -0,0 +1,42 @@ +error[E0597]: `c` does not live long enough + --> $DIR/method-call.rs:36:34 + | +LL | a.method::<&'static u32>(b, &c); + | -----------------------------^^- + | | | + | | borrowed value does not live long enough + | argument requires that `c` is borrowed for `'static` +LL | } + | - `c` dropped here while still borrowed + +error[E0597]: `c` does not live long enough + --> $DIR/method-call.rs:43:29 + | +LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) { + | -- lifetime `'a` defined here +... +LL | a.method::<&'a u32>(b, &c); + | ------------------------^^- + | | | + | | borrowed value does not live long enough + | argument requires that `c` is borrowed for `'a` +LL | } + | - `c` dropped here while still borrowed + +error[E0597]: `c` does not live long enough + --> $DIR/method-call.rs:57:33 + | +LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { + | -- lifetime `'a` defined here +... +LL | a.method::<&'a u32>(b, &c); + | ------------------------^^- + | | | + | | borrowed value does not live long enough + | argument requires that `c` is borrowed for `'a` +LL | }; + | - `c` dropped here while still borrowed + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/nll/user-annotations/method-ufcs-1.rs b/tests/ui/nll/user-annotations/method-ufcs-1.rs new file mode 100644 index 000000000..950771f35 --- /dev/null +++ b/tests/ui/nll/user-annotations/method-ufcs-1.rs @@ -0,0 +1,63 @@ +// Unit test for the "user substitutions" that are annotated on each +// node. + +trait Bazoom<T>: Sized { + fn method<U>(self, arg: T, arg2: U) { } +} + +impl<T, U> Bazoom<U> for T { +} + +fn annot_underscore() { + let a = 22; + let b = 44; + let c = 66; + <_ as Bazoom<_>>::method::<_>(&a, b, c); // OK +} + +fn annot_reference_any_lifetime() { + let a = 22; + let b = 44; + let c = 66; + <&u32 as Bazoom<_>>::method(&a, b, c); // OK +} + +fn annot_reference_static_lifetime() { + let a = 22; + let b = 44; + let c = 66; + let x = <&'static u32 as Bazoom<_>>::method; + x(&a, b, c); //~ ERROR +} + +fn annot_reference_named_lifetime<'a>(_d: &'a u32) { + let a = 22; + let b = 44; + let c = 66; + <&'a u32 as Bazoom<_>>::method(&a, b, c); //~ ERROR +} + +fn annot_reference_named_lifetime_ok<'a>(a: &'a u32) { + let b = 44; + let c = 66; + <&'a u32 as Bazoom<_>>::method(&a, b, c); +} + +fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { + let a = 22; + let b = 44; + let _closure = || { + let c = 66; + <&'a u32 as Bazoom<_>>::method(&a, b, c); //~ ERROR + }; +} + +fn annot_reference_named_lifetime_in_closure_ok<'a>(a: &'a u32) { + let b = 44; + let c = 66; + let _closure = || { + <&'a u32 as Bazoom<_>>::method(&a, b, c); + }; +} + +fn main() { } diff --git a/tests/ui/nll/user-annotations/method-ufcs-1.stderr b/tests/ui/nll/user-annotations/method-ufcs-1.stderr new file mode 100644 index 000000000..962ddfd2b --- /dev/null +++ b/tests/ui/nll/user-annotations/method-ufcs-1.stderr @@ -0,0 +1,46 @@ +error[E0597]: `a` does not live long enough + --> $DIR/method-ufcs-1.rs:30:7 + | +LL | x(&a, b, c); + | --^^------- + | | | + | | borrowed value does not live long enough + | argument requires that `a` is borrowed for `'static` +LL | } + | - `a` dropped here while still borrowed + +error[E0597]: `a` does not live long enough + --> $DIR/method-ufcs-1.rs:37:36 + | +LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) { + | -- lifetime `'a` defined here +... +LL | <&'a u32 as Bazoom<_>>::method(&a, b, c); + | -------------------------------^^------- + | | | + | | borrowed value does not live long enough + | argument requires that `a` is borrowed for `'a` +LL | } + | - `a` dropped here while still borrowed + +error[E0597]: `a` does not live long enough + --> $DIR/method-ufcs-1.rs:51:41 + | +LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { + | -- lifetime `'a` defined here +... +LL | let _closure = || { + | -- value captured here +LL | let c = 66; +LL | <&'a u32 as Bazoom<_>>::method(&a, b, c); + | --------------------------------^------- + | | | + | | borrowed value does not live long enough + | argument requires that `a` is borrowed for `'a` +LL | }; +LL | } + | - `a` dropped here while still borrowed + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/nll/user-annotations/method-ufcs-2.rs b/tests/ui/nll/user-annotations/method-ufcs-2.rs new file mode 100644 index 000000000..7dc0f0c12 --- /dev/null +++ b/tests/ui/nll/user-annotations/method-ufcs-2.rs @@ -0,0 +1,63 @@ +// Unit test for the "user substitutions" that are annotated on each +// node. + +trait Bazoom<T>: Sized { + fn method<U>(self, arg: T, arg2: U) { } +} + +impl<T, U> Bazoom<U> for T { +} + +fn annot_underscore() { + let a = 22; + let b = 44; + let c = 66; + <_ as Bazoom<_>>::method(a, &b, c); // OK +} + +fn annot_reference_any_lifetime() { + let a = 22; + let b = 44; + let c = 66; + <_ as Bazoom<&u32>>::method(a, &b, c); // OK +} + +fn annot_reference_static_lifetime() { + let a = 22; + let b = 44; + let c = 66; + let x = <&'static u32 as Bazoom<_>>::method; + x(&a, b, c); //~ ERROR +} + +fn annot_reference_named_lifetime<'a>(_d: &'a u32) { + let a = 22; + let b = 44; + let c = 66; + <_ as Bazoom<&'a u32>>::method(a, &b, c); //~ ERROR +} + +fn annot_reference_named_lifetime_ok<'a>(b: &'a u32) { + let a = 44; + let c = 66; + <_ as Bazoom<&'a u32>>::method(a, &b, c); +} + +fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { + let a = 22; + let b = 44; + let _closure = || { + let c = 66; + <_ as Bazoom<&'a u32>>::method(a, &b, c); //~ ERROR + }; +} + +fn annot_reference_named_lifetime_in_closure_ok<'a>(b: &'a u32) { + let a = 44; + let c = 66; + let _closure = || { + <_ as Bazoom<&'a u32>>::method(a, &b, c); + }; +} + +fn main() { } diff --git a/tests/ui/nll/user-annotations/method-ufcs-2.stderr b/tests/ui/nll/user-annotations/method-ufcs-2.stderr new file mode 100644 index 000000000..63d59905e --- /dev/null +++ b/tests/ui/nll/user-annotations/method-ufcs-2.stderr @@ -0,0 +1,46 @@ +error[E0597]: `a` does not live long enough + --> $DIR/method-ufcs-2.rs:30:7 + | +LL | x(&a, b, c); + | --^^------- + | | | + | | borrowed value does not live long enough + | argument requires that `a` is borrowed for `'static` +LL | } + | - `a` dropped here while still borrowed + +error[E0597]: `b` does not live long enough + --> $DIR/method-ufcs-2.rs:37:39 + | +LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) { + | -- lifetime `'a` defined here +... +LL | <_ as Bazoom<&'a u32>>::method(a, &b, c); + | ----------------------------------^^---- + | | | + | | borrowed value does not live long enough + | argument requires that `b` is borrowed for `'a` +LL | } + | - `b` dropped here while still borrowed + +error[E0597]: `b` does not live long enough + --> $DIR/method-ufcs-2.rs:51:44 + | +LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { + | -- lifetime `'a` defined here +... +LL | let _closure = || { + | -- value captured here +LL | let c = 66; +LL | <_ as Bazoom<&'a u32>>::method(a, &b, c); + | -----------------------------------^---- + | | | + | | borrowed value does not live long enough + | argument requires that `b` is borrowed for `'a` +LL | }; +LL | } + | - `b` dropped here while still borrowed + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/nll/user-annotations/method-ufcs-3.rs b/tests/ui/nll/user-annotations/method-ufcs-3.rs new file mode 100644 index 000000000..59d2009d1 --- /dev/null +++ b/tests/ui/nll/user-annotations/method-ufcs-3.rs @@ -0,0 +1,69 @@ +// Unit test for the "user substitutions" that are annotated on each +// node. + +trait Bazoom<T> { + fn method<U>(&self, arg: T, arg2: U) { } +} + +impl<T, U> Bazoom<U> for T { +} + +fn no_annot() { + let a = 22; + let b = 44; + let c = 66; + <_ as Bazoom<_>>::method(&a, b, &c); // OK +} + +fn annot_underscore() { + let a = 22; + let b = 44; + let c = 66; + <_ as Bazoom<_>>::method::<_>(&a, b, &c); // OK +} + +fn annot_reference_any_lifetime() { + let a = 22; + let b = 44; + let c = 66; + <_ as Bazoom<_>>::method::<&u32>(&a, b, &c); // OK +} + +fn annot_reference_static_lifetime() { + let a = 22; + let b = 44; + let c = 66; + <_ as Bazoom<_>>::method::<&'static u32>(&a, b, &c); //~ ERROR +} + +fn annot_reference_named_lifetime<'a>(_d: &'a u32) { + let a = 22; + let b = 44; + let c = 66; + <_ as Bazoom<_>>::method::<&'a u32>(&a, b, &c); //~ ERROR +} + +fn annot_reference_named_lifetime_ok<'a>(c: &'a u32) { + let a = 22; + let b = 44; + <_ as Bazoom<_>>::method::<&'a u32>(&a, b, c); +} + +fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { + let a = 22; + let b = 44; + let _closure = || { + let c = 66; + <_ as Bazoom<_>>::method::<&'a u32>(&a, b, &c); //~ ERROR + }; +} + +fn annot_reference_named_lifetime_in_closure_ok<'a>(c: &'a u32) { + let a = 22; + let b = 44; + let _closure = || { + <_ as Bazoom<_>>::method::<&'a u32>(&a, b, c); + }; +} + +fn main() { } diff --git a/tests/ui/nll/user-annotations/method-ufcs-3.stderr b/tests/ui/nll/user-annotations/method-ufcs-3.stderr new file mode 100644 index 000000000..e7851833e --- /dev/null +++ b/tests/ui/nll/user-annotations/method-ufcs-3.stderr @@ -0,0 +1,42 @@ +error[E0597]: `c` does not live long enough + --> $DIR/method-ufcs-3.rs:36:53 + | +LL | <_ as Bazoom<_>>::method::<&'static u32>(&a, b, &c); + | ------------------------------------------------^^- + | | | + | | borrowed value does not live long enough + | argument requires that `c` is borrowed for `'static` +LL | } + | - `c` dropped here while still borrowed + +error[E0597]: `c` does not live long enough + --> $DIR/method-ufcs-3.rs:43:48 + | +LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) { + | -- lifetime `'a` defined here +... +LL | <_ as Bazoom<_>>::method::<&'a u32>(&a, b, &c); + | -------------------------------------------^^- + | | | + | | borrowed value does not live long enough + | argument requires that `c` is borrowed for `'a` +LL | } + | - `c` dropped here while still borrowed + +error[E0597]: `c` does not live long enough + --> $DIR/method-ufcs-3.rs:57:52 + | +LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { + | -- lifetime `'a` defined here +... +LL | <_ as Bazoom<_>>::method::<&'a u32>(&a, b, &c); + | -------------------------------------------^^- + | | | + | | borrowed value does not live long enough + | argument requires that `c` is borrowed for `'a` +LL | }; + | - `c` dropped here while still borrowed + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/nll/user-annotations/method-ufcs-inherent-1.rs b/tests/ui/nll/user-annotations/method-ufcs-inherent-1.rs new file mode 100644 index 000000000..7bfed61d4 --- /dev/null +++ b/tests/ui/nll/user-annotations/method-ufcs-inherent-1.rs @@ -0,0 +1,18 @@ +// Check that substitutions given on the self type (here, `A`) carry +// through to NLL. + +struct A<'a> { x: &'a u32 } + +impl<'a> A<'a> { + fn new<'b, T>(x: &'a u32, y: T) -> Self { + Self { x } + } +} + +fn foo<'a>() { + let v = 22; + let x = A::<'a>::new(&v, 22); + //~^ ERROR +} + +fn main() {} diff --git a/tests/ui/nll/user-annotations/method-ufcs-inherent-1.stderr b/tests/ui/nll/user-annotations/method-ufcs-inherent-1.stderr new file mode 100644 index 000000000..94861babd --- /dev/null +++ b/tests/ui/nll/user-annotations/method-ufcs-inherent-1.stderr @@ -0,0 +1,18 @@ +error[E0597]: `v` does not live long enough + --> $DIR/method-ufcs-inherent-1.rs:14:26 + | +LL | fn foo<'a>() { + | -- lifetime `'a` defined here +LL | let v = 22; +LL | let x = A::<'a>::new(&v, 22); + | -------------^^----- + | | | + | | borrowed value does not live long enough + | argument requires that `v` is borrowed for `'a` +LL | +LL | } + | - `v` dropped here while still borrowed + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/nll/user-annotations/method-ufcs-inherent-2.rs b/tests/ui/nll/user-annotations/method-ufcs-inherent-2.rs new file mode 100644 index 000000000..cfbc0bcf6 --- /dev/null +++ b/tests/ui/nll/user-annotations/method-ufcs-inherent-2.rs @@ -0,0 +1,19 @@ +// Check that substitutions given on the self type (here, `A`) can be +// used in combination with annotations given for method arguments. + +struct A<'a> { x: &'a u32 } + +impl<'a> A<'a> { + fn new<'b, T>(x: &'a u32, y: T) -> Self { + Self { x } + } +} + +fn foo<'a>() { + let v = 22; + let x = A::<'a>::new::<&'a u32>(&v, &v); + //~^ ERROR + //~| ERROR +} + +fn main() {} diff --git a/tests/ui/nll/user-annotations/method-ufcs-inherent-2.stderr b/tests/ui/nll/user-annotations/method-ufcs-inherent-2.stderr new file mode 100644 index 000000000..06f20d9b2 --- /dev/null +++ b/tests/ui/nll/user-annotations/method-ufcs-inherent-2.stderr @@ -0,0 +1,33 @@ +error[E0597]: `v` does not live long enough + --> $DIR/method-ufcs-inherent-2.rs:14:37 + | +LL | fn foo<'a>() { + | -- lifetime `'a` defined here +LL | let v = 22; +LL | let x = A::<'a>::new::<&'a u32>(&v, &v); + | ------------------------^^----- + | | | + | | borrowed value does not live long enough + | argument requires that `v` is borrowed for `'a` +... +LL | } + | - `v` dropped here while still borrowed + +error[E0597]: `v` does not live long enough + --> $DIR/method-ufcs-inherent-2.rs:14:41 + | +LL | fn foo<'a>() { + | -- lifetime `'a` defined here +LL | let v = 22; +LL | let x = A::<'a>::new::<&'a u32>(&v, &v); + | ----------------------------^^- + | | | + | | borrowed value does not live long enough + | argument requires that `v` is borrowed for `'a` +... +LL | } + | - `v` dropped here while still borrowed + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/nll/user-annotations/method-ufcs-inherent-3.rs b/tests/ui/nll/user-annotations/method-ufcs-inherent-3.rs new file mode 100644 index 000000000..7ddb13360 --- /dev/null +++ b/tests/ui/nll/user-annotations/method-ufcs-inherent-3.rs @@ -0,0 +1,18 @@ +// Check that inherent methods invoked with `<T>::new` style +// carry their annotations through to NLL. + +struct A<'a> { x: &'a u32 } + +impl<'a> A<'a> { + fn new<'b, T>(x: &'a u32, y: T) -> Self { + Self { x } + } +} + +fn foo<'a>() { + let v = 22; + let x = <A<'a>>::new(&v, 22); + //~^ ERROR +} + +fn main() {} diff --git a/tests/ui/nll/user-annotations/method-ufcs-inherent-3.stderr b/tests/ui/nll/user-annotations/method-ufcs-inherent-3.stderr new file mode 100644 index 000000000..4ad61dc81 --- /dev/null +++ b/tests/ui/nll/user-annotations/method-ufcs-inherent-3.stderr @@ -0,0 +1,18 @@ +error[E0597]: `v` does not live long enough + --> $DIR/method-ufcs-inherent-3.rs:14:26 + | +LL | fn foo<'a>() { + | -- lifetime `'a` defined here +LL | let v = 22; +LL | let x = <A<'a>>::new(&v, 22); + | -------------^^----- + | | | + | | borrowed value does not live long enough + | argument requires that `v` is borrowed for `'a` +LL | +LL | } + | - `v` dropped here while still borrowed + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/nll/user-annotations/method-ufcs-inherent-4.rs b/tests/ui/nll/user-annotations/method-ufcs-inherent-4.rs new file mode 100644 index 000000000..85e759739 --- /dev/null +++ b/tests/ui/nll/user-annotations/method-ufcs-inherent-4.rs @@ -0,0 +1,20 @@ +// Check that inherent methods invoked with `<T>::new` style +// carry their annotations through to NLL in connection with +// method type parameters. + +struct A<'a> { x: &'a u32 } + +impl<'a> A<'a> { + fn new<'b, T>(x: &'a u32, y: T) -> Self { + Self { x } + } +} + +fn foo<'a>() { + let v = 22; + let x = <A<'a>>::new::<&'a u32>(&v, &v); + //~^ ERROR + //~| ERROR +} + +fn main() {} diff --git a/tests/ui/nll/user-annotations/method-ufcs-inherent-4.stderr b/tests/ui/nll/user-annotations/method-ufcs-inherent-4.stderr new file mode 100644 index 000000000..0f83e99cd --- /dev/null +++ b/tests/ui/nll/user-annotations/method-ufcs-inherent-4.stderr @@ -0,0 +1,33 @@ +error[E0597]: `v` does not live long enough + --> $DIR/method-ufcs-inherent-4.rs:15:37 + | +LL | fn foo<'a>() { + | -- lifetime `'a` defined here +LL | let v = 22; +LL | let x = <A<'a>>::new::<&'a u32>(&v, &v); + | ------------------------^^----- + | | | + | | borrowed value does not live long enough + | argument requires that `v` is borrowed for `'a` +... +LL | } + | - `v` dropped here while still borrowed + +error[E0597]: `v` does not live long enough + --> $DIR/method-ufcs-inherent-4.rs:15:41 + | +LL | fn foo<'a>() { + | -- lifetime `'a` defined here +LL | let v = 22; +LL | let x = <A<'a>>::new::<&'a u32>(&v, &v); + | ----------------------------^^- + | | | + | | borrowed value does not live long enough + | argument requires that `v` is borrowed for `'a` +... +LL | } + | - `v` dropped here while still borrowed + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/nll/user-annotations/normalization-2.rs b/tests/ui/nll/user-annotations/normalization-2.rs new file mode 100644 index 000000000..be23c3b74 --- /dev/null +++ b/tests/ui/nll/user-annotations/normalization-2.rs @@ -0,0 +1,152 @@ +// Make sure we honor region constraints when normalizing type annotations. + +// check-fail + +#![feature(more_qualified_paths)] + +trait Trait { + type Assoc; +} + +impl<T> Trait for T +where + T: 'static, +{ + type Assoc = MyTy<()>; +} + +enum MyTy<T> { + Unit, + Tuple(), + Struct {}, + Dumb(T), +} + +impl<T> MyTy<T> { + const CONST: () = (); + fn method<X>() {} + fn method2<X>(&self) {} +} + +trait TraitAssoc { + const TRAIT_CONST: (); + fn trait_method<X>(&self); +} +impl<T> TraitAssoc for T { + const TRAIT_CONST: () = (); + fn trait_method<X>(&self) {} +} + +type Ty<'a> = <&'a () as Trait>::Assoc; + +fn test_local<'a>() { + let _: Ty<'a> = MyTy::Unit; + //~^ ERROR lifetime may not live long enough +} + +fn test_closure_sig<'a, 'b>() { + |_: Ty<'a>| {}; + //~^ ERROR lifetime may not live long enough + || -> Option<Ty<'b>> { None }; + //~^ ERROR lifetime may not live long enough +} + +fn test_path<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h>() { + <Ty<'a>>::method::<Ty<'static>>; + //~^ ERROR lifetime may not live long enough + <Ty<'static>>::method::<Ty<'b>>; + //~^ ERROR lifetime may not live long enough + + <Ty<'c>>::trait_method::<Ty<'static>>; + //~^ ERROR lifetime may not live long enough + <Ty<'static>>::trait_method::<Ty<'d>>; + //~^ ERROR lifetime may not live long enough + + <Ty<'e>>::CONST; + //~^ ERROR lifetime may not live long enough + <Ty<'f>>::TRAIT_CONST; + //~^ ERROR lifetime may not live long enough + + <Ty<'static>>::method::<Ty<'static>>; + <Ty<'static>>::trait_method::<Ty<'static>>; + <Ty<'static>>::CONST; + <Ty<'static>>::TRAIT_CONST; + + MyTy::Unit::<Ty<'g>>; + //~^ ERROR lifetime may not live long enough + MyTy::<Ty<'h>>::Unit; + //~^ ERROR lifetime may not live long enough +} + +fn test_call<'a, 'b, 'c>() { + <Ty<'a>>::method::<Ty<'static>>(); + //~^ ERROR lifetime may not live long enough + <Ty<'static>>::method::<Ty<'b>>(); + //~^ ERROR lifetime may not live long enough +} + +fn test_variants<'a, 'b, 'c>() { + <Ty<'a>>::Struct {}; + //~^ ERROR lifetime may not live long enough + <Ty<'b>>::Tuple(); + //~^ ERROR lifetime may not live long enough + <Ty<'c>>::Unit; + //~^ ERROR lifetime may not live long enough +} + +fn test_method_call<'a, 'b>(x: MyTy<()>) { + x.method2::<Ty<'a>>(); + //~^ ERROR lifetime may not live long enough + x.trait_method::<Ty<'b>>(); + //~^ ERROR lifetime may not live long enough +} + +fn test_struct_path<'a, 'b, 'c, 'd>() { + struct Struct<T> { x: Option<T>, } + + trait Project { + type Struct; + type Enum; + } + impl<T> Project for T { + type Struct = Struct<()>; + type Enum = MyTy<()>; + } + + // Resolves to enum variant + MyTy::<Ty<'a>>::Struct {}; // without SelfTy + //~^ ERROR lifetime may not live long enough + <Ty<'b> as Project>::Enum::Struct {}; // with SelfTy + //~^ ERROR lifetime may not live long enough + + // Resolves to struct and associated type respectively + Struct::<Ty<'c>> { x: None, }; // without SelfTy + //~^ ERROR lifetime may not live long enough + <Ty<'d> as Project>::Struct { x: None, }; // with SelfTy + //~^ ERROR lifetime may not live long enough +} + +fn test_pattern<'a, 'b, 'c, 'd, 'e, 'f>() { + use MyTy::*; + match MyTy::Unit { + Struct::<Ty<'a>> {..} => {}, + //~^ ERROR lifetime may not live long enough + Tuple::<Ty<'b>> (..) => {}, + //~^ ERROR lifetime may not live long enough + Unit::<Ty<'c>> => {}, + //~^ ERROR lifetime may not live long enough + Dumb(_) => {}, + }; + match MyTy::Unit { + <Ty<'d>>::Struct {..} => {}, + //~^ ERROR lifetime may not live long enough + <Ty<'e>>::Tuple (..) => {}, + //~^ ERROR lifetime may not live long enough + <Ty<'f>>::Unit => {}, + //~^ ERROR lifetime may not live long enough + Dumb(_) => {}, + }; +} + + +fn main() {} diff --git a/tests/ui/nll/user-annotations/normalization-2.stderr b/tests/ui/nll/user-annotations/normalization-2.stderr new file mode 100644 index 000000000..5299282ea --- /dev/null +++ b/tests/ui/nll/user-annotations/normalization-2.stderr @@ -0,0 +1,296 @@ +error: lifetime may not live long enough + --> $DIR/normalization-2.rs:43:12 + | +LL | fn test_local<'a>() { + | -- lifetime `'a` defined here +LL | let _: Ty<'a> = MyTy::Unit; + | ^^^^^^ requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/normalization-2.rs:48:6 + | +LL | fn test_closure_sig<'a, 'b>() { + | -- lifetime `'a` defined here +LL | |_: Ty<'a>| {}; + | ^ requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/normalization-2.rs:50:11 + | +LL | fn test_closure_sig<'a, 'b>() { + | -- lifetime `'b` defined here +... +LL | || -> Option<Ty<'b>> { None }; + | ^^^^^^^^^^^^^^ requires that `'b` must outlive `'static` + +help: the following changes may resolve your lifetime errors + | + = help: replace `'a` with `'static` + = help: replace `'b` with `'static` + +error: lifetime may not live long enough + --> $DIR/normalization-2.rs:55:5 + | +LL | fn test_path<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h>() { + | -- lifetime `'a` defined here +LL | <Ty<'a>>::method::<Ty<'static>>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/normalization-2.rs:57:5 + | +LL | fn test_path<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h>() { + | -- lifetime `'b` defined here +... +LL | <Ty<'static>>::method::<Ty<'b>>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/normalization-2.rs:60:5 + | +LL | fn test_path<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h>() { + | -- lifetime `'c` defined here +... +LL | <Ty<'c>>::trait_method::<Ty<'static>>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'c` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/normalization-2.rs:62:5 + | +LL | fn test_path<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h>() { + | -- lifetime `'d` defined here +... +LL | <Ty<'static>>::trait_method::<Ty<'d>>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'d` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/normalization-2.rs:65:5 + | +LL | fn test_path<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h>() { + | -- lifetime `'e` defined here +... +LL | <Ty<'e>>::CONST; + | ^^^^^^^^^^^^^^^ requires that `'e` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/normalization-2.rs:67:5 + | +LL | fn test_path<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h>() { + | -- lifetime `'f` defined here +... +LL | <Ty<'f>>::TRAIT_CONST; + | ^^^^^^^^^^^^^^^^^^^^^ requires that `'f` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/normalization-2.rs:75:5 + | +LL | fn test_path<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h>() { + | -- lifetime `'g` defined here +... +LL | MyTy::Unit::<Ty<'g>>; + | ^^^^^^^^^^^^^^^^^^^^ requires that `'g` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/normalization-2.rs:77:5 + | +LL | fn test_path<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h>() { + | -- lifetime `'h` defined here +... +LL | MyTy::<Ty<'h>>::Unit; + | ^^^^^^^^^^^^^^^^^^^^ requires that `'h` must outlive `'static` + +help: the following changes may resolve your lifetime errors + | + = help: replace `'a` with `'static` + = help: replace `'b` with `'static` + = help: replace `'c` with `'static` + = help: replace `'d` with `'static` + = help: replace `'e` with `'static` + = help: replace `'f` with `'static` + = help: replace `'g` with `'static` + = help: replace `'h` with `'static` + +error: lifetime may not live long enough + --> $DIR/normalization-2.rs:82:5 + | +LL | fn test_call<'a, 'b, 'c>() { + | -- lifetime `'a` defined here +LL | <Ty<'a>>::method::<Ty<'static>>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/normalization-2.rs:84:5 + | +LL | fn test_call<'a, 'b, 'c>() { + | -- lifetime `'b` defined here +... +LL | <Ty<'static>>::method::<Ty<'b>>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'static` + +help: the following changes may resolve your lifetime errors + | + = help: replace `'a` with `'static` + = help: replace `'b` with `'static` + +error: lifetime may not live long enough + --> $DIR/normalization-2.rs:89:5 + | +LL | fn test_variants<'a, 'b, 'c>() { + | -- lifetime `'a` defined here +LL | <Ty<'a>>::Struct {}; + | ^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/normalization-2.rs:91:5 + | +LL | fn test_variants<'a, 'b, 'c>() { + | -- lifetime `'b` defined here +... +LL | <Ty<'b>>::Tuple(); + | ^^^^^^^^^^^^^^^ requires that `'b` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/normalization-2.rs:93:5 + | +LL | fn test_variants<'a, 'b, 'c>() { + | -- lifetime `'c` defined here +... +LL | <Ty<'c>>::Unit; + | ^^^^^^^^^^^^^^ requires that `'c` must outlive `'static` + +help: the following changes may resolve your lifetime errors + | + = help: replace `'a` with `'static` + = help: replace `'b` with `'static` + = help: replace `'c` with `'static` + +error: lifetime may not live long enough + --> $DIR/normalization-2.rs:98:7 + | +LL | fn test_method_call<'a, 'b>(x: MyTy<()>) { + | -- lifetime `'a` defined here +LL | x.method2::<Ty<'a>>(); + | ^^^^^^^ requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/normalization-2.rs:100:7 + | +LL | fn test_method_call<'a, 'b>(x: MyTy<()>) { + | -- lifetime `'b` defined here +... +LL | x.trait_method::<Ty<'b>>(); + | ^^^^^^^^^^^^ requires that `'b` must outlive `'static` + +help: the following changes may resolve your lifetime errors + | + = help: replace `'a` with `'static` + = help: replace `'b` with `'static` + +error: lifetime may not live long enough + --> $DIR/normalization-2.rs:117:5 + | +LL | fn test_struct_path<'a, 'b, 'c, 'd>() { + | -- lifetime `'a` defined here +... +LL | MyTy::<Ty<'a>>::Struct {}; // without SelfTy + | ^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/normalization-2.rs:119:5 + | +LL | fn test_struct_path<'a, 'b, 'c, 'd>() { + | -- lifetime `'b` defined here +... +LL | <Ty<'b> as Project>::Enum::Struct {}; // with SelfTy + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/normalization-2.rs:123:5 + | +LL | fn test_struct_path<'a, 'b, 'c, 'd>() { + | -- lifetime `'c` defined here +... +LL | Struct::<Ty<'c>> { x: None, }; // without SelfTy + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'c` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/normalization-2.rs:125:5 + | +LL | fn test_struct_path<'a, 'b, 'c, 'd>() { + | -- lifetime `'d` defined here +... +LL | <Ty<'d> as Project>::Struct { x: None, }; // with SelfTy + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'d` must outlive `'static` + +help: the following changes may resolve your lifetime errors + | + = help: replace `'a` with `'static` + = help: replace `'b` with `'static` + = help: replace `'c` with `'static` + = help: replace `'d` with `'static` + +error: lifetime may not live long enough + --> $DIR/normalization-2.rs:132:9 + | +LL | fn test_pattern<'a, 'b, 'c, 'd, 'e, 'f>() { + | -- lifetime `'a` defined here +... +LL | Struct::<Ty<'a>> {..} => {}, + | ^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/normalization-2.rs:134:9 + | +LL | fn test_pattern<'a, 'b, 'c, 'd, 'e, 'f>() { + | -- lifetime `'b` defined here +... +LL | Tuple::<Ty<'b>> (..) => {}, + | ^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/normalization-2.rs:136:9 + | +LL | fn test_pattern<'a, 'b, 'c, 'd, 'e, 'f>() { + | -- lifetime `'c` defined here +... +LL | Unit::<Ty<'c>> => {}, + | ^^^^^^^^^^^^^^ requires that `'c` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/normalization-2.rs:141:9 + | +LL | fn test_pattern<'a, 'b, 'c, 'd, 'e, 'f>() { + | -- lifetime `'d` defined here +... +LL | <Ty<'d>>::Struct {..} => {}, + | ^^^^^^^^^^^^^^^^^^^^^ requires that `'d` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/normalization-2.rs:143:9 + | +LL | fn test_pattern<'a, 'b, 'c, 'd, 'e, 'f>() { + | -- lifetime `'e` defined here +... +LL | <Ty<'e>>::Tuple (..) => {}, + | ^^^^^^^^^^^^^^^^^^^^ requires that `'e` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/normalization-2.rs:145:9 + | +LL | fn test_pattern<'a, 'b, 'c, 'd, 'e, 'f>() { + | -- lifetime `'f` defined here +... +LL | <Ty<'f>>::Unit => {}, + | ^^^^^^^^^^^^^^ requires that `'f` must outlive `'static` + +help: the following changes may resolve your lifetime errors + | + = help: replace `'a` with `'static` + = help: replace `'b` with `'static` + = help: replace `'c` with `'static` + = help: replace `'d` with `'static` + = help: replace `'e` with `'static` + = help: replace `'f` with `'static` + +error: aborting due to 28 previous errors + diff --git a/tests/ui/nll/user-annotations/normalization-default.rs b/tests/ui/nll/user-annotations/normalization-default.rs new file mode 100644 index 000000000..fa52e6d85 --- /dev/null +++ b/tests/ui/nll/user-annotations/normalization-default.rs @@ -0,0 +1,22 @@ +// check-fail + +trait Trait { type Assoc; } +impl<'a> Trait for &'a () { type Assoc = &'a (); } + +struct MyTuple<T, U = <&'static () as Trait>::Assoc>(T, U); +fn test_tuple(x: &(), y: &()) { + MyTuple::<_>((), x); + //~^ ERROR + let _: MyTuple::<_> = MyTuple((), y); + //~^ ERROR +} + +struct MyStruct<T, U = <&'static () as Trait>::Assoc> { val: (T, U), } +fn test_struct(x: &(), y: &()) { + MyStruct::<_> { val: ((), x) }; + //~^ ERROR + let _: MyStruct::<_> = MyStruct { val: ((), y) }; + //~^ ERROR +} + +fn main() {} diff --git a/tests/ui/nll/user-annotations/normalization-default.stderr b/tests/ui/nll/user-annotations/normalization-default.stderr new file mode 100644 index 000000000..6c73ac692 --- /dev/null +++ b/tests/ui/nll/user-annotations/normalization-default.stderr @@ -0,0 +1,36 @@ +error: lifetime may not live long enough + --> $DIR/normalization-default.rs:8:22 + | +LL | fn test_tuple(x: &(), y: &()) { + | - let's call the lifetime of this reference `'1` +LL | MyTuple::<_>((), x); + | ^ this usage requires that `'1` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/normalization-default.rs:10:12 + | +LL | fn test_tuple(x: &(), y: &()) { + | - let's call the lifetime of this reference `'2` +... +LL | let _: MyTuple::<_> = MyTuple((), y); + | ^^^^^^^^^^^^ type annotation requires that `'2` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/normalization-default.rs:16:26 + | +LL | fn test_struct(x: &(), y: &()) { + | - let's call the lifetime of this reference `'1` +LL | MyStruct::<_> { val: ((), x) }; + | ^^^^^^^ this usage requires that `'1` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/normalization-default.rs:18:12 + | +LL | fn test_struct(x: &(), y: &()) { + | - let's call the lifetime of this reference `'2` +... +LL | let _: MyStruct::<_> = MyStruct { val: ((), y) }; + | ^^^^^^^^^^^^^ type annotation requires that `'2` must outlive `'static` + +error: aborting due to 4 previous errors + diff --git a/tests/ui/nll/user-annotations/normalization-infer.rs b/tests/ui/nll/user-annotations/normalization-infer.rs new file mode 100644 index 000000000..8bfc272d4 --- /dev/null +++ b/tests/ui/nll/user-annotations/normalization-infer.rs @@ -0,0 +1,40 @@ +// Annnotations may contain projection types with inference variables as input. +// Make sure we don't get ambiguities when normalizing them. + +// check-fail + +// Single impl. +fn test1<A, B, C, D>(a: A, b: B, c: C) { + trait Tr { type Ty; } + impl<T: 'static> Tr for (T,) { type Ty = T; } + + let _: <(_,) as Tr>::Ty = a; //~ ERROR type `A` + Some::<<(_,) as Tr>::Ty>(b); //~ ERROR type `B` + || -> <(_,) as Tr>::Ty { c }; //~ ERROR type `C` + |d: <(_,) as Tr>::Ty| -> D { d }; //~ ERROR type `D` +} + + +// Two impls. The selected impl depends on the actual type. +fn test2<A, B, C>(a: A, b: B, c: C) { + trait Tr { type Ty; } + impl<T: 'static> Tr for (u8, T) { type Ty = T; } + impl<T> Tr for (i8, T) { type Ty = T; } + type Alias<X, Y> = (<(X, Y) as Tr>::Ty, X); + + fn temp() -> String { todo!() } + + // `u8` impl, requires static. + let _: Alias<_, _> = (a, 0u8); //~ ERROR type `A` + Some::<Alias<_, _>>((b, 0u8)); //~ ERROR type `B` + || -> Alias<_, _> { (c, 0u8) }; //~ ERROR type `C` + + let _: Alias<_, _> = (&temp(), 0u8); //~ ERROR temporary value + Some::<Alias<_, _>>((&temp(), 0u8)); //~ ERROR temporary value + + // `i8` impl, no region constraints. + let _: Alias<_, _> = (&temp(), 0i8); + Some::<Alias<_, _>>((&temp(), 0i8)); +} + +fn main() {} diff --git a/tests/ui/nll/user-annotations/normalization-infer.stderr b/tests/ui/nll/user-annotations/normalization-infer.stderr new file mode 100644 index 000000000..12854ab68 --- /dev/null +++ b/tests/ui/nll/user-annotations/normalization-infer.stderr @@ -0,0 +1,101 @@ +error[E0310]: the parameter type `A` may not live long enough + --> $DIR/normalization-infer.rs:11:12 + | +LL | let _: <(_,) as Tr>::Ty = a; + | ^^^^^^^^^^^^^^^^ ...so that the type `A` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | fn test1<A: 'static, B, C, D>(a: A, b: B, c: C) { + | +++++++++ + +error[E0310]: the parameter type `B` may not live long enough + --> $DIR/normalization-infer.rs:12:5 + | +LL | Some::<<(_,) as Tr>::Ty>(b); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `B` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | fn test1<A, B: 'static, C, D>(a: A, b: B, c: C) { + | +++++++++ + +error[E0310]: the parameter type `C` may not live long enough + --> $DIR/normalization-infer.rs:13:11 + | +LL | || -> <(_,) as Tr>::Ty { c }; + | ^^^^^^^^^^^^^^^^ ...so that the type `C` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | fn test1<A, B, C: 'static, D>(a: A, b: B, c: C) { + | +++++++++ + +error[E0310]: the parameter type `D` may not live long enough + --> $DIR/normalization-infer.rs:14:6 + | +LL | |d: <(_,) as Tr>::Ty| -> D { d }; + | ^ ...so that the type `D` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | fn test1<A, B, C, D: 'static>(a: A, b: B, c: C) { + | +++++++++ + +error[E0310]: the parameter type `A` may not live long enough + --> $DIR/normalization-infer.rs:28:12 + | +LL | let _: Alias<_, _> = (a, 0u8); + | ^^^^^^^^^^^ ...so that the type `A` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | fn test2<A: 'static, B, C>(a: A, b: B, c: C) { + | +++++++++ + +error[E0310]: the parameter type `B` may not live long enough + --> $DIR/normalization-infer.rs:29:5 + | +LL | Some::<Alias<_, _>>((b, 0u8)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `B` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | fn test2<A, B: 'static, C>(a: A, b: B, c: C) { + | +++++++++ + +error[E0310]: the parameter type `C` may not live long enough + --> $DIR/normalization-infer.rs:30:11 + | +LL | || -> Alias<_, _> { (c, 0u8) }; + | ^^^^^^^^^^^ ...so that the type `C` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | fn test2<A, B, C: 'static>(a: A, b: B, c: C) { + | +++++++++ + +error[E0716]: temporary value dropped while borrowed + --> $DIR/normalization-infer.rs:32:28 + | +LL | let _: Alias<_, _> = (&temp(), 0u8); + | ----------- ^^^^^^ creates a temporary value which is freed while still in use + | | + | type annotation requires that borrow lasts for `'static` +... +LL | } + | - temporary value is freed at the end of this statement + +error[E0716]: temporary value dropped while borrowed + --> $DIR/normalization-infer.rs:33:27 + | +LL | Some::<Alias<_, _>>((&temp(), 0u8)); + | --^^^^^^------ - temporary value is freed at the end of this statement + | | | + | | creates a temporary value which is freed while still in use + | this usage requires that borrow lasts for `'static` + +error: aborting due to 9 previous errors + +Some errors have detailed explanations: E0310, E0716. +For more information about an error, try `rustc --explain E0310`. diff --git a/tests/ui/nll/user-annotations/normalization-self.rs b/tests/ui/nll/user-annotations/normalization-self.rs new file mode 100644 index 000000000..c18760b53 --- /dev/null +++ b/tests/ui/nll/user-annotations/normalization-self.rs @@ -0,0 +1,26 @@ +// check-fail + +trait Trait { type Assoc; } +impl<'a> Trait for &'a () { type Assoc = &'a (); } + +struct MyTuple<T>(T); +impl MyTuple<<&'static () as Trait>::Assoc> { + fn test(x: &(), y: &()) { + Self(x); + //~^ ERROR + let _: Self = MyTuple(y); + //~^ ERROR + } +} + +struct MyStruct<T> { val: T, } +impl MyStruct<<&'static () as Trait>::Assoc> { + fn test(x: &(), y: &()) { + Self { val: x }; + //~^ ERROR + let _: Self = MyStruct { val: y }; + //~^ ERROR + } +} + +fn main() {} diff --git a/tests/ui/nll/user-annotations/normalization-self.stderr b/tests/ui/nll/user-annotations/normalization-self.stderr new file mode 100644 index 000000000..e231ed03c --- /dev/null +++ b/tests/ui/nll/user-annotations/normalization-self.stderr @@ -0,0 +1,36 @@ +error: lifetime may not live long enough + --> $DIR/normalization-self.rs:9:14 + | +LL | fn test(x: &(), y: &()) { + | - let's call the lifetime of this reference `'1` +LL | Self(x); + | ^ this usage requires that `'1` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/normalization-self.rs:11:16 + | +LL | fn test(x: &(), y: &()) { + | - let's call the lifetime of this reference `'2` +... +LL | let _: Self = MyTuple(y); + | ^^^^ type annotation requires that `'2` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/normalization-self.rs:19:21 + | +LL | fn test(x: &(), y: &()) { + | - let's call the lifetime of this reference `'1` +LL | Self { val: x }; + | ^ this usage requires that `'1` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/normalization-self.rs:21:16 + | +LL | fn test(x: &(), y: &()) { + | - let's call the lifetime of this reference `'2` +... +LL | let _: Self = MyStruct { val: y }; + | ^^^^ type annotation requires that `'2` must outlive `'static` + +error: aborting due to 4 previous errors + diff --git a/tests/ui/nll/user-annotations/normalization.rs b/tests/ui/nll/user-annotations/normalization.rs new file mode 100644 index 000000000..c2e892f57 --- /dev/null +++ b/tests/ui/nll/user-annotations/normalization.rs @@ -0,0 +1,17 @@ +// Test that we enforce a `&'static` requirement that is only visible +// after normalization. + +trait Foo { type Out; } +impl Foo for () { type Out = &'static u32; } +impl<'a> Foo for &'a () { type Out = &'a u32; } + +fn main() { + let a = 22; + let _: <() as Foo>::Out = &a; //~ ERROR + + let a = 22; + let _: <&'static () as Foo>::Out = &a; //~ ERROR + + let a = 22; + let _: <&'_ () as Foo>::Out = &a; +} diff --git a/tests/ui/nll/user-annotations/normalization.stderr b/tests/ui/nll/user-annotations/normalization.stderr new file mode 100644 index 000000000..975cb4b66 --- /dev/null +++ b/tests/ui/nll/user-annotations/normalization.stderr @@ -0,0 +1,25 @@ +error[E0597]: `a` does not live long enough + --> $DIR/normalization.rs:10:31 + | +LL | let _: <() as Foo>::Out = &a; + | ---------------- ^^ borrowed value does not live long enough + | | + | type annotation requires that `a` is borrowed for `'static` +... +LL | } + | - `a` dropped here while still borrowed + +error[E0597]: `a` does not live long enough + --> $DIR/normalization.rs:13:40 + | +LL | let _: <&'static () as Foo>::Out = &a; + | ------------------------- ^^ borrowed value does not live long enough + | | + | type annotation requires that `a` is borrowed for `'static` +... +LL | } + | - `a` dropped here while still borrowed + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/nll/user-annotations/normalize-self-ty.rs b/tests/ui/nll/user-annotations/normalize-self-ty.rs new file mode 100644 index 000000000..df905c878 --- /dev/null +++ b/tests/ui/nll/user-annotations/normalize-self-ty.rs @@ -0,0 +1,23 @@ +// Regression test for #55183: check a case where the self type from +// the inherent impl requires normalization to be equal to the +// user-provided type. +// +// check-pass + +trait Mirror { + type Me; +} + +impl<T> Mirror for T { + type Me = T; +} + +struct Foo<A, B>(A, B); + +impl<A> Foo<A, <A as Mirror>::Me> { + fn m(_: A) { } +} + +fn main() { + <Foo<&'static u32, &u32>>::m(&22); +} diff --git a/tests/ui/nll/user-annotations/pattern_substs_on_brace_enum_variant.rs b/tests/ui/nll/user-annotations/pattern_substs_on_brace_enum_variant.rs new file mode 100644 index 000000000..59cd69c0c --- /dev/null +++ b/tests/ui/nll/user-annotations/pattern_substs_on_brace_enum_variant.rs @@ -0,0 +1,22 @@ +enum Foo<'a> { + Bar { field: &'a u32 } +} + +fn in_let() { + let y = 22; + let foo = Foo::Bar { field: &y }; + //~^ ERROR `y` does not live long enough + let Foo::Bar::<'static> { field: _z } = foo; +} + +fn in_match() { + let y = 22; + let foo = Foo::Bar { field: &y }; + //~^ ERROR `y` does not live long enough + match foo { + Foo::Bar::<'static> { field: _z } => { + } + } +} + +fn main() { } diff --git a/tests/ui/nll/user-annotations/pattern_substs_on_brace_enum_variant.stderr b/tests/ui/nll/user-annotations/pattern_substs_on_brace_enum_variant.stderr new file mode 100644 index 000000000..a97e7a9fd --- /dev/null +++ b/tests/ui/nll/user-annotations/pattern_substs_on_brace_enum_variant.stderr @@ -0,0 +1,26 @@ +error[E0597]: `y` does not live long enough + --> $DIR/pattern_substs_on_brace_enum_variant.rs:7:33 + | +LL | let foo = Foo::Bar { field: &y }; + | ^^ borrowed value does not live long enough +LL | +LL | let Foo::Bar::<'static> { field: _z } = foo; + | --------------------------------- type annotation requires that `y` is borrowed for `'static` +LL | } + | - `y` dropped here while still borrowed + +error[E0597]: `y` does not live long enough + --> $DIR/pattern_substs_on_brace_enum_variant.rs:14:33 + | +LL | let foo = Foo::Bar { field: &y }; + | ^^ borrowed value does not live long enough +... +LL | Foo::Bar::<'static> { field: _z } => { + | --------------------------------- type annotation requires that `y` is borrowed for `'static` +... +LL | } + | - `y` dropped here while still borrowed + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/nll/user-annotations/pattern_substs_on_brace_struct.rs b/tests/ui/nll/user-annotations/pattern_substs_on_brace_struct.rs new file mode 100644 index 000000000..1586c4ea3 --- /dev/null +++ b/tests/ui/nll/user-annotations/pattern_substs_on_brace_struct.rs @@ -0,0 +1,20 @@ +struct Foo<'a> { field: &'a u32 } + +fn in_let() { + let y = 22; + let foo = Foo { field: &y }; + //~^ ERROR `y` does not live long enough + let Foo::<'static> { field: _z } = foo; +} + +fn in_main() { + let y = 22; + let foo = Foo { field: &y }; + //~^ ERROR `y` does not live long enough + match foo { + Foo::<'static> { field: _z } => { + } + } +} + +fn main() { } diff --git a/tests/ui/nll/user-annotations/pattern_substs_on_brace_struct.stderr b/tests/ui/nll/user-annotations/pattern_substs_on_brace_struct.stderr new file mode 100644 index 000000000..408d7c2a5 --- /dev/null +++ b/tests/ui/nll/user-annotations/pattern_substs_on_brace_struct.stderr @@ -0,0 +1,26 @@ +error[E0597]: `y` does not live long enough + --> $DIR/pattern_substs_on_brace_struct.rs:5:28 + | +LL | let foo = Foo { field: &y }; + | ^^ borrowed value does not live long enough +LL | +LL | let Foo::<'static> { field: _z } = foo; + | ---------------------------- type annotation requires that `y` is borrowed for `'static` +LL | } + | - `y` dropped here while still borrowed + +error[E0597]: `y` does not live long enough + --> $DIR/pattern_substs_on_brace_struct.rs:12:28 + | +LL | let foo = Foo { field: &y }; + | ^^ borrowed value does not live long enough +... +LL | Foo::<'static> { field: _z } => { + | ---------------------------- type annotation requires that `y` is borrowed for `'static` +... +LL | } + | - `y` dropped here while still borrowed + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/nll/user-annotations/pattern_substs_on_tuple_enum_variant.rs b/tests/ui/nll/user-annotations/pattern_substs_on_tuple_enum_variant.rs new file mode 100644 index 000000000..6fa59fdd8 --- /dev/null +++ b/tests/ui/nll/user-annotations/pattern_substs_on_tuple_enum_variant.rs @@ -0,0 +1,22 @@ +enum Foo<'a> { + Bar(&'a u32) +} + +fn in_let() { + let y = 22; + let foo = Foo::Bar(&y); + //~^ ERROR `y` does not live long enough + let Foo::Bar::<'static>(_z) = foo; +} + +fn in_match() { + let y = 22; + let foo = Foo::Bar(&y); + //~^ ERROR `y` does not live long enough + match foo { + Foo::Bar::<'static>(_z) => { + } + } +} + +fn main() { } diff --git a/tests/ui/nll/user-annotations/pattern_substs_on_tuple_enum_variant.stderr b/tests/ui/nll/user-annotations/pattern_substs_on_tuple_enum_variant.stderr new file mode 100644 index 000000000..920c906f6 --- /dev/null +++ b/tests/ui/nll/user-annotations/pattern_substs_on_tuple_enum_variant.stderr @@ -0,0 +1,26 @@ +error[E0597]: `y` does not live long enough + --> $DIR/pattern_substs_on_tuple_enum_variant.rs:7:24 + | +LL | let foo = Foo::Bar(&y); + | ^^ borrowed value does not live long enough +LL | +LL | let Foo::Bar::<'static>(_z) = foo; + | ----------------------- type annotation requires that `y` is borrowed for `'static` +LL | } + | - `y` dropped here while still borrowed + +error[E0597]: `y` does not live long enough + --> $DIR/pattern_substs_on_tuple_enum_variant.rs:14:24 + | +LL | let foo = Foo::Bar(&y); + | ^^ borrowed value does not live long enough +... +LL | Foo::Bar::<'static>(_z) => { + | ----------------------- type annotation requires that `y` is borrowed for `'static` +... +LL | } + | - `y` dropped here while still borrowed + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/nll/user-annotations/pattern_substs_on_tuple_struct.rs b/tests/ui/nll/user-annotations/pattern_substs_on_tuple_struct.rs new file mode 100644 index 000000000..7486aab0e --- /dev/null +++ b/tests/ui/nll/user-annotations/pattern_substs_on_tuple_struct.rs @@ -0,0 +1,20 @@ +struct Foo<'a>(&'a u32); + +fn in_let() { + let y = 22; + let foo = Foo(&y); + //~^ ERROR `y` does not live long enough + let Foo::<'static>(_z) = foo; +} + +fn in_match() { + let y = 22; + let foo = Foo(&y); + //~^ ERROR `y` does not live long enough + match foo { + Foo::<'static>(_z) => { + } + } +} + +fn main() { } diff --git a/tests/ui/nll/user-annotations/pattern_substs_on_tuple_struct.stderr b/tests/ui/nll/user-annotations/pattern_substs_on_tuple_struct.stderr new file mode 100644 index 000000000..3f01638d8 --- /dev/null +++ b/tests/ui/nll/user-annotations/pattern_substs_on_tuple_struct.stderr @@ -0,0 +1,26 @@ +error[E0597]: `y` does not live long enough + --> $DIR/pattern_substs_on_tuple_struct.rs:5:19 + | +LL | let foo = Foo(&y); + | ^^ borrowed value does not live long enough +LL | +LL | let Foo::<'static>(_z) = foo; + | ------------------ type annotation requires that `y` is borrowed for `'static` +LL | } + | - `y` dropped here while still borrowed + +error[E0597]: `y` does not live long enough + --> $DIR/pattern_substs_on_tuple_struct.rs:12:19 + | +LL | let foo = Foo(&y); + | ^^ borrowed value does not live long enough +... +LL | Foo::<'static>(_z) => { + | ------------------ type annotation requires that `y` is borrowed for `'static` +... +LL | } + | - `y` dropped here while still borrowed + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/nll/user-annotations/patterns.rs b/tests/ui/nll/user-annotations/patterns.rs new file mode 100644 index 000000000..1f635d7f5 --- /dev/null +++ b/tests/ui/nll/user-annotations/patterns.rs @@ -0,0 +1,136 @@ +// Test that various patterns also enforce types. + +fn variable_no_initializer() { + let x = 22; + let y: &'static u32; + y = &x; //~ ERROR +} + +fn tuple_no_initializer() { + + + let x = 22; + let (y, z): (&'static u32, &'static u32); + y = &x; //~ ERROR +} + +fn ref_with_ascribed_static_type() -> u32 { + // Check the behavior in some wacky cases. + let x = 22; + let y = &x; //~ ERROR + let ref z: &'static u32 = y; + **z +} + +fn ref_with_ascribed_any_type() -> u32 { + let x = 22; + let y = &x; + let ref z: &u32 = y; + **z +} + +struct Single<T> { value: T } + +fn struct_no_initializer() { + + + let x = 22; + let Single { value: y }: Single<&'static u32>; + y = &x; //~ ERROR +} + + +fn struct_no_initializer_must_normalize() { + trait Indirect { type Assoc; } + struct StaticU32; + impl Indirect for StaticU32 { type Assoc = &'static u32; } + struct Single2<T: Indirect> { value: <T as Indirect>::Assoc } + + let x = 22; + let Single2 { value: mut _y }: Single2<StaticU32>; + _y = &x; //~ ERROR +} + +fn variable_with_initializer() { + let x = 22; + let y: &'static u32 = &x; //~ ERROR +} + +fn underscore_with_initializer() { + let x = 22; + let _: &'static u32 = &x; //~ ERROR + + let _: Vec<&'static String> = vec![&String::new()]; + //~^ ERROR temporary value dropped while borrowed [E0716] + + let (_, a): (Vec<&'static String>, _) = (vec![&String::new()], 44); + //~^ ERROR temporary value dropped while borrowed [E0716] + + let (_a, b): (Vec<&'static String>, _) = (vec![&String::new()], 44); + //~^ ERROR temporary value dropped while borrowed [E0716] +} + +fn pair_underscores_with_initializer() { + let x = 22; + let (_, _): (&'static u32, u32) = (&x, 44); //~ ERROR +} + +fn pair_variable_with_initializer() { + let x = 22; + let (y, _): (&'static u32, u32) = (&x, 44); //~ ERROR +} + +fn struct_single_field_variable_with_initializer() { + let x = 22; + let Single { value: y }: Single<&'static u32> = Single { value: &x }; //~ ERROR +} + +fn struct_single_field_underscore_with_initializer() { + let x = 22; + let Single { value: _ }: Single<&'static u32> = Single { value: &x }; //~ ERROR +} + +struct Double<T> { value1: T, value2: T } + +fn struct_double_field_underscore_with_initializer() { + let x = 22; + let Double { value1: _, value2: _ }: Double<&'static u32> = Double { + value1: &x, //~ ERROR + value2: &44, + }; +} + +fn static_to_a_to_static_through_variable<'a>(x: &'a u32) -> &'static u32 { + + + + + + + let y: &'a u32 = &22; + y //~ ERROR +} + +fn static_to_a_to_static_through_tuple<'a>(x: &'a u32) -> &'static u32 { + + + + + + + + let (y, _z): (&'a u32, u32) = (&22, 44); + y //~ ERROR +} + +fn static_to_a_to_static_through_struct<'a>(_x: &'a u32) -> &'static u32 { + let Single { value: y }: Single<&'a u32> = Single { value: &22 }; + y //~ ERROR +} + +fn a_to_static_then_static<'a>(x: &'a u32) -> &'static u32 { + let (y, _z): (&'static u32, u32) = (x, 44); //~ ERROR + y +} + +fn main() { } diff --git a/tests/ui/nll/user-annotations/patterns.stderr b/tests/ui/nll/user-annotations/patterns.stderr new file mode 100644 index 000000000..de6f8f80f --- /dev/null +++ b/tests/ui/nll/user-annotations/patterns.stderr @@ -0,0 +1,189 @@ +error[E0597]: `x` does not live long enough + --> $DIR/patterns.rs:6:9 + | +LL | let y: &'static u32; + | ------------ type annotation requires that `x` is borrowed for `'static` +LL | y = &x; + | ^^ borrowed value does not live long enough +LL | } + | - `x` dropped here while still borrowed + +error[E0597]: `x` does not live long enough + --> $DIR/patterns.rs:14:9 + | +LL | let (y, z): (&'static u32, &'static u32); + | ---------------------------- type annotation requires that `x` is borrowed for `'static` +LL | y = &x; + | ^^ borrowed value does not live long enough +LL | } + | - `x` dropped here while still borrowed + +error[E0597]: `x` does not live long enough + --> $DIR/patterns.rs:20:13 + | +LL | let y = &x; + | ^^ borrowed value does not live long enough +LL | let ref z: &'static u32 = y; + | ------------ type annotation requires that `x` is borrowed for `'static` +LL | **z +LL | } + | - `x` dropped here while still borrowed + +error[E0597]: `x` does not live long enough + --> $DIR/patterns.rs:39:9 + | +LL | let Single { value: y }: Single<&'static u32>; + | -------------------- type annotation requires that `x` is borrowed for `'static` +LL | y = &x; + | ^^ borrowed value does not live long enough +LL | } + | - `x` dropped here while still borrowed + +error[E0597]: `x` does not live long enough + --> $DIR/patterns.rs:51:10 + | +LL | let Single2 { value: mut _y }: Single2<StaticU32>; + | ------------------ type annotation requires that `x` is borrowed for `'static` +LL | _y = &x; + | ^^ borrowed value does not live long enough +LL | } + | - `x` dropped here while still borrowed + +error[E0597]: `x` does not live long enough + --> $DIR/patterns.rs:56:27 + | +LL | let y: &'static u32 = &x; + | ------------ ^^ borrowed value does not live long enough + | | + | type annotation requires that `x` is borrowed for `'static` +LL | } + | - `x` dropped here while still borrowed + +error[E0597]: `x` does not live long enough + --> $DIR/patterns.rs:61:27 + | +LL | let _: &'static u32 = &x; + | ------------ ^^ borrowed value does not live long enough + | | + | type annotation requires that `x` is borrowed for `'static` +... +LL | } + | - `x` dropped here while still borrowed + +error[E0716]: temporary value dropped while borrowed + --> $DIR/patterns.rs:63:41 + | +LL | let _: Vec<&'static String> = vec![&String::new()]; + | -------------------- ^^^^^^^^^^^^^ - temporary value is freed at the end of this statement + | | | + | | creates a temporary value which is freed while still in use + | type annotation requires that borrow lasts for `'static` + +error[E0716]: temporary value dropped while borrowed + --> $DIR/patterns.rs:66:52 + | +LL | let (_, a): (Vec<&'static String>, _) = (vec![&String::new()], 44); + | ------------------------- ^^^^^^^^^^^^^ - temporary value is freed at the end of this statement + | | | + | | creates a temporary value which is freed while still in use + | type annotation requires that borrow lasts for `'static` + +error[E0716]: temporary value dropped while borrowed + --> $DIR/patterns.rs:69:53 + | +LL | let (_a, b): (Vec<&'static String>, _) = (vec![&String::new()], 44); + | ------------------------- ^^^^^^^^^^^^^ - temporary value is freed at the end of this statement + | | | + | | creates a temporary value which is freed while still in use + | type annotation requires that borrow lasts for `'static` + +error[E0597]: `x` does not live long enough + --> $DIR/patterns.rs:75:40 + | +LL | let (_, _): (&'static u32, u32) = (&x, 44); + | ------------------- ^^ borrowed value does not live long enough + | | + | type annotation requires that `x` is borrowed for `'static` +LL | } + | - `x` dropped here while still borrowed + +error[E0597]: `x` does not live long enough + --> $DIR/patterns.rs:80:40 + | +LL | let (y, _): (&'static u32, u32) = (&x, 44); + | ------------------- ^^ borrowed value does not live long enough + | | + | type annotation requires that `x` is borrowed for `'static` +LL | } + | - `x` dropped here while still borrowed + +error[E0597]: `x` does not live long enough + --> $DIR/patterns.rs:85:69 + | +LL | let Single { value: y }: Single<&'static u32> = Single { value: &x }; + | -------------------- ^^ borrowed value does not live long enough + | | + | type annotation requires that `x` is borrowed for `'static` +LL | } + | - `x` dropped here while still borrowed + +error[E0597]: `x` does not live long enough + --> $DIR/patterns.rs:90:69 + | +LL | let Single { value: _ }: Single<&'static u32> = Single { value: &x }; + | -------------------- ^^ borrowed value does not live long enough + | | + | type annotation requires that `x` is borrowed for `'static` +LL | } + | - `x` dropped here while still borrowed + +error[E0597]: `x` does not live long enough + --> $DIR/patterns.rs:98:17 + | +LL | let Double { value1: _, value2: _ }: Double<&'static u32> = Double { + | -------------------- type annotation requires that `x` is borrowed for `'static` +LL | value1: &x, + | ^^ borrowed value does not live long enough +... +LL | } + | - `x` dropped here while still borrowed + +error: lifetime may not live long enough + --> $DIR/patterns.rs:111:5 + | +LL | fn static_to_a_to_static_through_variable<'a>(x: &'a u32) -> &'static u32 { + | -- lifetime `'a` defined here +... +LL | y + | ^ returning this value requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/patterns.rs:123:5 + | +LL | fn static_to_a_to_static_through_tuple<'a>(x: &'a u32) -> &'static u32 { + | -- lifetime `'a` defined here +... +LL | y + | ^ returning this value requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/patterns.rs:128:5 + | +LL | fn static_to_a_to_static_through_struct<'a>(_x: &'a u32) -> &'static u32 { + | -- lifetime `'a` defined here +LL | let Single { value: y }: Single<&'a u32> = Single { value: &22 }; +LL | y + | ^ returning this value requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/patterns.rs:132: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); + | ^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` + +error: aborting due to 19 previous errors + +Some errors have detailed explanations: E0597, E0716. +For more information about an error, try `rustc --explain E0597`. diff --git a/tests/ui/nll/user-annotations/promoted-annotation.rs b/tests/ui/nll/user-annotations/promoted-annotation.rs new file mode 100644 index 000000000..b92f8bfd2 --- /dev/null +++ b/tests/ui/nll/user-annotations/promoted-annotation.rs @@ -0,0 +1,10 @@ +// Test that type annotations are checked in promoted constants correctly. + +fn foo<'a>() { + let x = 0; + let f = &drop::<&'a i32>; + f(&x); + //~^ ERROR `x` does not live long enough +} + +fn main() {} diff --git a/tests/ui/nll/user-annotations/promoted-annotation.stderr b/tests/ui/nll/user-annotations/promoted-annotation.stderr new file mode 100644 index 000000000..cb99a6a36 --- /dev/null +++ b/tests/ui/nll/user-annotations/promoted-annotation.stderr @@ -0,0 +1,17 @@ +error[E0597]: `x` does not live long enough + --> $DIR/promoted-annotation.rs:6:7 + | +LL | fn foo<'a>() { + | -- lifetime `'a` defined here +LL | let x = 0; +LL | let f = &drop::<&'a i32>; + | ---------------- assignment requires that `x` is borrowed for `'a` +LL | f(&x); + | ^^ borrowed value does not live long enough +LL | +LL | } + | - `x` dropped here while still borrowed + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/nll/user-annotations/type-annotation-with-hrtb.rs b/tests/ui/nll/user-annotations/type-annotation-with-hrtb.rs new file mode 100644 index 000000000..1f7c06038 --- /dev/null +++ b/tests/ui/nll/user-annotations/type-annotation-with-hrtb.rs @@ -0,0 +1,33 @@ +// Regression test for issue #69490 + +// check-pass + +pub trait Trait<T> { + const S: &'static str; +} + +impl<T> Trait<()> for T +where + T: for<'a> Trait<&'a ()>, +{ + // Use of `T::S` here caused an ICE + const S: &'static str = T::S; +} + +// Some similar cases that didn't ICE: + +impl<'a, T> Trait<()> for (T,) +where + T: Trait<&'a ()>, +{ + const S: &'static str = T::S; +} + +impl<T> Trait<()> for [T; 1] +where + T: Trait<for<'a> fn(&'a ())>, +{ + const S: &'static str = T::S; +} + +fn main() {} diff --git a/tests/ui/nll/user-annotations/type_ascription_static_lifetime.rs b/tests/ui/nll/user-annotations/type_ascription_static_lifetime.rs new file mode 100644 index 000000000..88d646dee --- /dev/null +++ b/tests/ui/nll/user-annotations/type_ascription_static_lifetime.rs @@ -0,0 +1,7 @@ +#![allow(warnings)] +#![feature(type_ascription)] + +fn main() { + let x = 22_u32; + let y: &u32 = type_ascribe!(&x, &'static u32); //~ ERROR E0597 +} diff --git a/tests/ui/nll/user-annotations/type_ascription_static_lifetime.stderr b/tests/ui/nll/user-annotations/type_ascription_static_lifetime.stderr new file mode 100644 index 000000000..ccbf3c1d9 --- /dev/null +++ b/tests/ui/nll/user-annotations/type_ascription_static_lifetime.stderr @@ -0,0 +1,14 @@ +error[E0597]: `x` does not live long enough + --> $DIR/type_ascription_static_lifetime.rs:6:33 + | +LL | let y: &u32 = type_ascribe!(&x, &'static u32); + | --------------^^--------------- + | | | + | | borrowed value does not live long enough + | type annotation requires that `x` is borrowed for `'static` +LL | } + | - `x` dropped here while still borrowed + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/nll/user-annotations/wf-self-type.rs b/tests/ui/nll/user-annotations/wf-self-type.rs new file mode 100644 index 000000000..539226aab --- /dev/null +++ b/tests/ui/nll/user-annotations/wf-self-type.rs @@ -0,0 +1,13 @@ +struct Foo<'a, 'b: 'a>(&'a &'b ()); + +impl<'a, 'b> Foo<'a, 'b> { + fn xmute(a: &'b ()) -> &'a () { + unreachable!() + } +} + +pub fn foo<'a, 'b>(u: &'b ()) -> &'a () { + Foo::xmute(u) //~ ERROR lifetime may not live long enough +} + +fn main() {} diff --git a/tests/ui/nll/user-annotations/wf-self-type.stderr b/tests/ui/nll/user-annotations/wf-self-type.stderr new file mode 100644 index 000000000..1d3ae7cfb --- /dev/null +++ b/tests/ui/nll/user-annotations/wf-self-type.stderr @@ -0,0 +1,14 @@ +error: lifetime may not live long enough + --> $DIR/wf-self-type.rs:10:5 + | +LL | pub fn foo<'a, 'b>(u: &'b ()) -> &'a () { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | Foo::xmute(u) + | ^^^^^^^^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` + | + = help: consider adding the following bound: `'b: 'a` + +error: aborting due to previous error + |