summaryrefslogtreecommitdiffstats
path: root/tests/ui/nll/user-annotations
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:18:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:18:58 +0000
commita4b7ed7a42c716ab9f05e351f003d589124fd55d (patch)
treeb620cd3f223850b28716e474e80c58059dca5dd4 /tests/ui/nll/user-annotations
parentAdding upstream version 1.67.1+dfsg1. (diff)
downloadrustc-a4b7ed7a42c716ab9f05e351f003d589124fd55d.tar.xz
rustc-a4b7ed7a42c716ab9f05e351f003d589124fd55d.zip
Adding upstream version 1.68.2+dfsg1.upstream/1.68.2+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/ui/nll/user-annotations')
-rw-r--r--tests/ui/nll/user-annotations/adt-brace-enums.rs50
-rw-r--r--tests/ui/nll/user-annotations/adt-brace-enums.stderr42
-rw-r--r--tests/ui/nll/user-annotations/adt-brace-structs.rs48
-rw-r--r--tests/ui/nll/user-annotations/adt-brace-structs.stderr42
-rw-r--r--tests/ui/nll/user-annotations/adt-nullary-enums.rs69
-rw-r--r--tests/ui/nll/user-annotations/adt-nullary-enums.stderr45
-rw-r--r--tests/ui/nll/user-annotations/adt-tuple-enums.rs53
-rw-r--r--tests/ui/nll/user-annotations/adt-tuple-enums.stderr42
-rw-r--r--tests/ui/nll/user-annotations/adt-tuple-struct-calls.rs71
-rw-r--r--tests/ui/nll/user-annotations/adt-tuple-struct-calls.stderr56
-rw-r--r--tests/ui/nll/user-annotations/adt-tuple-struct.rs48
-rw-r--r--tests/ui/nll/user-annotations/adt-tuple-struct.stderr42
-rw-r--r--tests/ui/nll/user-annotations/ascribed-type-wf.rs17
-rw-r--r--tests/ui/nll/user-annotations/ascribed-type-wf.stderr10
-rw-r--r--tests/ui/nll/user-annotations/cast_static_lifetime.rs6
-rw-r--r--tests/ui/nll/user-annotations/cast_static_lifetime.stderr14
-rw-r--r--tests/ui/nll/user-annotations/closure-sig.rs15
-rw-r--r--tests/ui/nll/user-annotations/closure-substs.polonius.stderr61
-rw-r--r--tests/ui/nll/user-annotations/closure-substs.rs31
-rw-r--r--tests/ui/nll/user-annotations/closure-substs.stderr42
-rw-r--r--tests/ui/nll/user-annotations/constant-in-expr-inherent-1.rs12
-rw-r--r--tests/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr10
-rw-r--r--tests/ui/nll/user-annotations/constant-in-expr-inherent-2.rs27
-rw-r--r--tests/ui/nll/user-annotations/constant-in-expr-inherent-2.stderr50
-rw-r--r--tests/ui/nll/user-annotations/constant-in-expr-normalize.rs22
-rw-r--r--tests/ui/nll/user-annotations/constant-in-expr-normalize.stderr10
-rw-r--r--tests/ui/nll/user-annotations/constant-in-expr-trait-item-1.rs14
-rw-r--r--tests/ui/nll/user-annotations/constant-in-expr-trait-item-1.stderr10
-rw-r--r--tests/ui/nll/user-annotations/constant-in-expr-trait-item-2.rs14
-rw-r--r--tests/ui/nll/user-annotations/constant-in-expr-trait-item-2.stderr10
-rw-r--r--tests/ui/nll/user-annotations/constant-in-expr-trait-item-3.rs14
-rw-r--r--tests/ui/nll/user-annotations/constant-in-expr-trait-item-3.stderr10
-rw-r--r--tests/ui/nll/user-annotations/downcast-infer.rs11
-rw-r--r--tests/ui/nll/user-annotations/dump-adt-brace-struct.rs20
-rw-r--r--tests/ui/nll/user-annotations/dump-adt-brace-struct.stderr8
-rw-r--r--tests/ui/nll/user-annotations/dump-fn-method.rs57
-rw-r--r--tests/ui/nll/user-annotations/dump-fn-method.stderr26
-rw-r--r--tests/ui/nll/user-annotations/fns.rs48
-rw-r--r--tests/ui/nll/user-annotations/fns.stderr42
-rw-r--r--tests/ui/nll/user-annotations/inherent-associated-constants.rs15
-rw-r--r--tests/ui/nll/user-annotations/inherent-associated-constants.stderr10
-rw-r--r--tests/ui/nll/user-annotations/issue-54124.rs8
-rw-r--r--tests/ui/nll/user-annotations/issue-54124.stderr20
-rw-r--r--tests/ui/nll/user-annotations/issue-54570-bootstrapping.rs30
-rw-r--r--tests/ui/nll/user-annotations/issue-55219.rs18
-rw-r--r--tests/ui/nll/user-annotations/issue-55241.rs26
-rw-r--r--tests/ui/nll/user-annotations/issue-55748-pat-types-constrain-bindings.rs68
-rw-r--r--tests/ui/nll/user-annotations/issue-55748-pat-types-constrain-bindings.stderr29
-rw-r--r--tests/ui/nll/user-annotations/issue-57731-ascibed-coupled-types.rs40
-rw-r--r--tests/ui/nll/user-annotations/issue-57731-ascibed-coupled-types.stderr38
-rw-r--r--tests/ui/nll/user-annotations/method-call.rs69
-rw-r--r--tests/ui/nll/user-annotations/method-call.stderr42
-rw-r--r--tests/ui/nll/user-annotations/method-ufcs-1.rs63
-rw-r--r--tests/ui/nll/user-annotations/method-ufcs-1.stderr46
-rw-r--r--tests/ui/nll/user-annotations/method-ufcs-2.rs63
-rw-r--r--tests/ui/nll/user-annotations/method-ufcs-2.stderr46
-rw-r--r--tests/ui/nll/user-annotations/method-ufcs-3.rs69
-rw-r--r--tests/ui/nll/user-annotations/method-ufcs-3.stderr42
-rw-r--r--tests/ui/nll/user-annotations/method-ufcs-inherent-1.rs18
-rw-r--r--tests/ui/nll/user-annotations/method-ufcs-inherent-1.stderr18
-rw-r--r--tests/ui/nll/user-annotations/method-ufcs-inherent-2.rs19
-rw-r--r--tests/ui/nll/user-annotations/method-ufcs-inherent-2.stderr33
-rw-r--r--tests/ui/nll/user-annotations/method-ufcs-inherent-3.rs18
-rw-r--r--tests/ui/nll/user-annotations/method-ufcs-inherent-3.stderr18
-rw-r--r--tests/ui/nll/user-annotations/method-ufcs-inherent-4.rs20
-rw-r--r--tests/ui/nll/user-annotations/method-ufcs-inherent-4.stderr33
-rw-r--r--tests/ui/nll/user-annotations/normalization-2.rs152
-rw-r--r--tests/ui/nll/user-annotations/normalization-2.stderr296
-rw-r--r--tests/ui/nll/user-annotations/normalization-default.rs22
-rw-r--r--tests/ui/nll/user-annotations/normalization-default.stderr36
-rw-r--r--tests/ui/nll/user-annotations/normalization-infer.rs40
-rw-r--r--tests/ui/nll/user-annotations/normalization-infer.stderr101
-rw-r--r--tests/ui/nll/user-annotations/normalization-self.rs26
-rw-r--r--tests/ui/nll/user-annotations/normalization-self.stderr36
-rw-r--r--tests/ui/nll/user-annotations/normalization.rs17
-rw-r--r--tests/ui/nll/user-annotations/normalization.stderr25
-rw-r--r--tests/ui/nll/user-annotations/normalize-self-ty.rs23
-rw-r--r--tests/ui/nll/user-annotations/pattern_substs_on_brace_enum_variant.rs22
-rw-r--r--tests/ui/nll/user-annotations/pattern_substs_on_brace_enum_variant.stderr26
-rw-r--r--tests/ui/nll/user-annotations/pattern_substs_on_brace_struct.rs20
-rw-r--r--tests/ui/nll/user-annotations/pattern_substs_on_brace_struct.stderr26
-rw-r--r--tests/ui/nll/user-annotations/pattern_substs_on_tuple_enum_variant.rs22
-rw-r--r--tests/ui/nll/user-annotations/pattern_substs_on_tuple_enum_variant.stderr26
-rw-r--r--tests/ui/nll/user-annotations/pattern_substs_on_tuple_struct.rs20
-rw-r--r--tests/ui/nll/user-annotations/pattern_substs_on_tuple_struct.stderr26
-rw-r--r--tests/ui/nll/user-annotations/patterns.rs136
-rw-r--r--tests/ui/nll/user-annotations/patterns.stderr189
-rw-r--r--tests/ui/nll/user-annotations/promoted-annotation.rs10
-rw-r--r--tests/ui/nll/user-annotations/promoted-annotation.stderr17
-rw-r--r--tests/ui/nll/user-annotations/type-annotation-with-hrtb.rs33
-rw-r--r--tests/ui/nll/user-annotations/type_ascription_static_lifetime.rs7
-rw-r--r--tests/ui/nll/user-annotations/type_ascription_static_lifetime.stderr14
-rw-r--r--tests/ui/nll/user-annotations/wf-self-type.rs13
-rw-r--r--tests/ui/nll/user-annotations/wf-self-type.stderr14
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
+