about summary refs log tree commit diff
path: root/tests/ui/lifetimes/lifetime-errors
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/lifetimes/lifetime-errors')
-rw-r--r--tests/ui/lifetimes/lifetime-errors/42701_one_named_and_one_anonymous.rs14
-rw-r--r--tests/ui/lifetimes/lifetime-errors/42701_one_named_and_one_anonymous.stderr12
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.rs20
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.stderr12
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-2.rs5
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-2.stderr11
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-3.rs5
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-3.stderr11
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.rs8
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.stderr11
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.rs14
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr12
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.rs18
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.stderr13
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else.rs5
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else.stderr11
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.rs15
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr13
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.rs14
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr13
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.rs5
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr15
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-2.rs9
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-2.stderr11
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-early-bound.rs11
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-early-bound.stderr12
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name.rs9
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name.stderr11
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex2b-push-no-existing-names.rs10
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex2b-push-no-existing-names.stderr12
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex2c-push-inference-variable.rs11
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex2c-push-inference-variable.stderr15
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex2d-push-inference-variable-2.rs12
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex2d-push-inference-variable-2.stderr15
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex2e-push-inference-variable-3.rs12
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex2e-push-inference-variable-3.stderr15
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.rs6
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.stderr17
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.rs7
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.stderr32
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.rs11
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.stderr12
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.rs11
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.stderr13
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.rs13
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.stderr15
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.rs10
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.stderr14
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs.rs10
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs.stderr12
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-latebound-regions.rs6
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-latebound-regions.stderr14
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.rs9
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.stderr21
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.rs8
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.stderr12
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.rs8
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.stderr12
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct.rs11
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct.stderr12
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.rs12
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr17
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.rs12
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr17
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.rs7
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.stderr29
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.rs10
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.stderr17
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.rs7
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.stderr29
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.rs6
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.stderr17
-rw-r--r--tests/ui/lifetimes/lifetime-errors/issue_74400.rs16
-rw-r--r--tests/ui/lifetimes/lifetime-errors/issue_74400.stderr38
-rw-r--r--tests/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.rs37
-rw-r--r--tests/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.stderr46
76 files changed, 1035 insertions, 0 deletions
diff --git a/tests/ui/lifetimes/lifetime-errors/42701_one_named_and_one_anonymous.rs b/tests/ui/lifetimes/lifetime-errors/42701_one_named_and_one_anonymous.rs
new file mode 100644
index 00000000000..b0c09c7514e
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/42701_one_named_and_one_anonymous.rs
@@ -0,0 +1,14 @@
+struct Foo {
+    field: i32,
+}
+
+fn foo2<'a>(a: &'a Foo, x: &i32) -> &'a i32 {
+    if true {
+        let p: &i32 = &a.field;
+        &*p
+    } else {
+        &*x //~ ERROR explicit lifetime
+    }
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/42701_one_named_and_one_anonymous.stderr b/tests/ui/lifetimes/lifetime-errors/42701_one_named_and_one_anonymous.stderr
new file mode 100644
index 00000000000..63d00875dd3
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/42701_one_named_and_one_anonymous.stderr
@@ -0,0 +1,12 @@
+error[E0621]: explicit lifetime required in the type of `x`
+  --> $DIR/42701_one_named_and_one_anonymous.rs:10:9
+   |
+LL | fn foo2<'a>(a: &'a Foo, x: &i32) -> &'a i32 {
+   |                            ---- help: add explicit lifetime `'a` to the type of `x`: `&'a i32`
+...
+LL |         &*x
+   |         ^^^ lifetime `'a` required
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0621`.
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.rs b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.rs
new file mode 100644
index 00000000000..35f70dd1982
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.rs
@@ -0,0 +1,20 @@
+#[derive(Clone)]
+enum Foo<'a> {
+    Bar(&'a str),
+}
+
+impl<'a> Foo<'a> {
+    fn bar(&self, other: Foo) -> Foo<'a> {
+        match *self {
+            Foo::Bar(s) => {
+                if s == "test" {
+                    other //~ ERROR explicit lifetime
+                } else {
+                    self.clone()
+                }
+            }
+        }
+    }
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.stderr b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.stderr
new file mode 100644
index 00000000000..64aa8361cd5
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.stderr
@@ -0,0 +1,12 @@
+error[E0621]: explicit lifetime required in the type of `other`
+  --> $DIR/ex1-return-one-existing-name-early-bound-in-struct.rs:11:21
+   |
+LL |     fn bar(&self, other: Foo) -> Foo<'a> {
+   |                          --- help: add explicit lifetime `'a` to the type of `other`: `Foo<'a>`
+...
+LL |                     other
+   |                     ^^^^^ lifetime `'a` required
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0621`.
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-2.rs b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-2.rs
new file mode 100644
index 00000000000..9b15b378dc1
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-2.rs
@@ -0,0 +1,5 @@
+fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32 {
+    if x > y { x } else { y } //~ ERROR explicit lifetime
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-2.stderr b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-2.stderr
new file mode 100644
index 00000000000..b40481ecdc4
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-2.stderr
@@ -0,0 +1,11 @@
+error[E0621]: explicit lifetime required in the type of `x`
+  --> $DIR/ex1-return-one-existing-name-if-else-2.rs:2:16
+   |
+LL | fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32 {
+   |               ---- help: add explicit lifetime `'a` to the type of `x`: `&'a i32`
+LL |     if x > y { x } else { y }
+   |                ^ lifetime `'a` required
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0621`.
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-3.rs b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-3.rs
new file mode 100644
index 00000000000..6b062125cc0
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-3.rs
@@ -0,0 +1,5 @@
+fn foo<'a>((x, y): (&'a i32, &i32)) -> &'a i32 {
+    if x > y { x } else { y } //~ ERROR explicit lifetime
+}
+
+fn main () { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-3.stderr b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-3.stderr
new file mode 100644
index 00000000000..194fd95891e
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-3.stderr
@@ -0,0 +1,11 @@
+error[E0621]: explicit lifetime required in parameter type
+  --> $DIR/ex1-return-one-existing-name-if-else-3.rs:2:27
+   |
+LL | fn foo<'a>((x, y): (&'a i32, &i32)) -> &'a i32 {
+   |                    --------------- help: add explicit lifetime `'a` to type: `(&'a i32, &'a i32)`
+LL |     if x > y { x } else { y }
+   |                           ^ lifetime `'a` required
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0621`.
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.rs b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.rs
new file mode 100644
index 00000000000..7bc3fa623ee
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.rs
@@ -0,0 +1,8 @@
+trait Foo {
+
+fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32 {
+   if x > y { x } else { y } //~ ERROR explicit lifetime
+   }
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.stderr b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.stderr
new file mode 100644
index 00000000000..64f4bd0fc70
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.stderr
@@ -0,0 +1,11 @@
+error[E0621]: explicit lifetime required in the type of `x`
+  --> $DIR/ex1-return-one-existing-name-if-else-using-impl-2.rs:4:15
+   |
+LL | fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32 {
+   |               ---- help: add explicit lifetime `'a` to the type of `x`: `&'a i32`
+LL |    if x > y { x } else { y }
+   |               ^ lifetime `'a` required
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0621`.
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.rs b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.rs
new file mode 100644
index 00000000000..a1126d6bb15
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.rs
@@ -0,0 +1,14 @@
+struct Foo {
+  field: i32
+}
+
+impl Foo {
+  fn foo<'a>(&'a self, x: &i32) -> &i32 {
+
+    if true { &self.field } else { x } //~ ERROR explicit lifetime
+
+  }
+
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr
new file mode 100644
index 00000000000..961f9de6614
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr
@@ -0,0 +1,12 @@
+error[E0621]: explicit lifetime required in the type of `x`
+  --> $DIR/ex1-return-one-existing-name-if-else-using-impl-3.rs:8:36
+   |
+LL |   fn foo<'a>(&'a self, x: &i32) -> &i32 {
+   |                           ---- help: add explicit lifetime `'a` to the type of `x`: `&'a i32`
+LL |
+LL |     if true { &self.field } else { x }
+   |                                    ^ lifetime `'a` required
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0621`.
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.rs b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.rs
new file mode 100644
index 00000000000..f0d73deb3cc
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.rs
@@ -0,0 +1,18 @@
+trait Foo {
+
+    fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32;
+
+}
+
+impl Foo for () {
+
+    fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32 {
+
+        if x > y { x } else { y }
+        //~^ ERROR lifetime may not live long enough
+
+    }
+
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.stderr b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.stderr
new file mode 100644
index 00000000000..5bb76381332
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.stderr
@@ -0,0 +1,13 @@
+error: lifetime may not live long enough
+  --> $DIR/ex1-return-one-existing-name-if-else-using-impl.rs:11:20
+   |
+LL |     fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32 {
+   |            --     - let's call the lifetime of this reference `'1`
+   |            |
+   |            lifetime `'a` defined here
+LL |
+LL |         if x > y { x } else { y }
+   |                    ^ associated function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else.rs b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else.rs
new file mode 100644
index 00000000000..f72d567bbd8
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else.rs
@@ -0,0 +1,5 @@
+fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 {
+    if x > y { x } else { y } //~ ERROR explicit lifetime
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else.stderr b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else.stderr
new file mode 100644
index 00000000000..29a70695710
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else.stderr
@@ -0,0 +1,11 @@
+error[E0621]: explicit lifetime required in the type of `y`
+  --> $DIR/ex1-return-one-existing-name-if-else.rs:2:27
+   |
+LL | fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 {
+   |                           ---- help: add explicit lifetime `'a` to the type of `y`: `&'a i32`
+LL |     if x > y { x } else { y }
+   |                           ^ lifetime `'a` required
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0621`.
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.rs b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.rs
new file mode 100644
index 00000000000..49993aca3ca
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.rs
@@ -0,0 +1,15 @@
+struct Foo {
+  field: i32
+}
+
+impl Foo {
+  fn foo<'a>(&self, x: &'a i32) -> &i32 {
+
+    x
+    //~^ ERROR lifetime may not live long enough
+
+  }
+
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr
new file mode 100644
index 00000000000..4bcd7cf9578
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr
@@ -0,0 +1,13 @@
+error: lifetime may not live long enough
+  --> $DIR/ex1-return-one-existing-name-return-type-is-anon.rs:8:5
+   |
+LL |   fn foo<'a>(&self, x: &'a i32) -> &i32 {
+   |          --  - let's call the lifetime of this reference `'1`
+   |          |
+   |          lifetime `'a` defined here
+LL |
+LL |     x
+   |     ^ associated function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.rs b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.rs
new file mode 100644
index 00000000000..63d81a57d5d
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.rs
@@ -0,0 +1,14 @@
+struct Foo {
+    field: i32,
+}
+
+impl Foo {
+    fn foo<'a>(&self, x: &'a Foo) -> &'a Foo {
+
+        if true { x } else { self }
+        //~^ ERROR lifetime may not live long enough
+
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr
new file mode 100644
index 00000000000..34a64f8a63e
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr
@@ -0,0 +1,13 @@
+error: lifetime may not live long enough
+  --> $DIR/ex1-return-one-existing-name-self-is-anon.rs:8:30
+   |
+LL |     fn foo<'a>(&self, x: &'a Foo) -> &'a Foo {
+   |            --  - let's call the lifetime of this reference `'1`
+   |            |
+   |            lifetime `'a` defined here
+LL |
+LL |         if true { x } else { self }
+   |                              ^^^^ associated function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.rs b/tests/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.rs
new file mode 100644
index 00000000000..d6c918843c7
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.rs
@@ -0,0 +1,5 @@
+fn foo(x: &i32, y: &i32) -> &i32 { //~ ERROR missing lifetime
+    if x > y { x } else { y }
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr b/tests/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr
new file mode 100644
index 00000000000..bcc3e9510ac
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr
@@ -0,0 +1,15 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/ex1b-return-no-names-if-else.rs:1:29
+   |
+LL | fn foo(x: &i32, y: &i32) -> &i32 {
+   |           ----     ----     ^ expected named lifetime parameter
+   |
+   = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y`
+help: consider introducing a named lifetime parameter
+   |
+LL | fn foo<'a>(x: &'a i32, y: &'a i32) -> &'a i32 {
+   |       ++++     ++          ++          ++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-2.rs b/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-2.rs
new file mode 100644
index 00000000000..998a48ce20c
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-2.rs
@@ -0,0 +1,9 @@
+struct Ref<'a, T: 'a> {
+    data: &'a T
+}
+
+fn foo<'a>(x: Ref<i32>, y: &mut Vec<Ref<'a, i32>>) {
+    y.push(x); //~ ERROR explicit lifetime
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-2.stderr b/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-2.stderr
new file mode 100644
index 00000000000..90d4754ebab
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-2.stderr
@@ -0,0 +1,11 @@
+error[E0621]: explicit lifetime required in the type of `x`
+  --> $DIR/ex2a-push-one-existing-name-2.rs:6:5
+   |
+LL | fn foo<'a>(x: Ref<i32>, y: &mut Vec<Ref<'a, i32>>) {
+   |               -------- help: add explicit lifetime `'a` to the type of `x`: `Ref<'a, i32>`
+LL |     y.push(x);
+   |     ^^^^^^^^^ lifetime `'a` required
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0621`.
diff --git a/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-early-bound.rs b/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-early-bound.rs
new file mode 100644
index 00000000000..d18b50d0d0c
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-early-bound.rs
@@ -0,0 +1,11 @@
+trait Foo<'a> {}
+impl<'a, T> Foo<'a> for T {}
+
+fn baz<'a, 'b, T>(x: &mut Vec<&'a T>, y: &T)
+    where i32: Foo<'a>,
+          u32: Foo<'b>
+{
+    x.push(y); //~ ERROR explicit lifetime required
+}
+fn main() {
+}
diff --git a/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-early-bound.stderr b/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-early-bound.stderr
new file mode 100644
index 00000000000..a03e16b3b79
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-early-bound.stderr
@@ -0,0 +1,12 @@
+error[E0621]: explicit lifetime required in the type of `y`
+  --> $DIR/ex2a-push-one-existing-name-early-bound.rs:8:5
+   |
+LL | fn baz<'a, 'b, T>(x: &mut Vec<&'a T>, y: &T)
+   |                                          -- help: add explicit lifetime `'a` to the type of `y`: `&'a T`
+...
+LL |     x.push(y);
+   |     ^^^^^^^^^ lifetime `'a` required
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0621`.
diff --git a/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name.rs b/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name.rs
new file mode 100644
index 00000000000..5188ea1cc9c
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name.rs
@@ -0,0 +1,9 @@
+struct Ref<'a, T: 'a> {
+    data: &'a T
+}
+
+fn foo<'a>(x: &mut Vec<Ref<'a, i32>>, y: Ref<i32>) {
+    x.push(y); //~ ERROR explicit lifetime
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name.stderr b/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name.stderr
new file mode 100644
index 00000000000..487b34e3d18
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name.stderr
@@ -0,0 +1,11 @@
+error[E0621]: explicit lifetime required in the type of `y`
+  --> $DIR/ex2a-push-one-existing-name.rs:6:5
+   |
+LL | fn foo<'a>(x: &mut Vec<Ref<'a, i32>>, y: Ref<i32>) {
+   |                                          -------- help: add explicit lifetime `'a` to the type of `y`: `Ref<'a, i32>`
+LL |     x.push(y);
+   |     ^^^^^^^^^ lifetime `'a` required
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0621`.
diff --git a/tests/ui/lifetimes/lifetime-errors/ex2b-push-no-existing-names.rs b/tests/ui/lifetimes/lifetime-errors/ex2b-push-no-existing-names.rs
new file mode 100644
index 00000000000..27424d79bc0
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex2b-push-no-existing-names.rs
@@ -0,0 +1,10 @@
+struct Ref<'a, T: 'a> {
+    data: &'a T
+}
+
+fn foo(x: &mut Vec<Ref<i32>>, y: Ref<i32>) {
+    x.push(y);
+    //~^ ERROR lifetime may not live long enough
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex2b-push-no-existing-names.stderr b/tests/ui/lifetimes/lifetime-errors/ex2b-push-no-existing-names.stderr
new file mode 100644
index 00000000000..1622ce42290
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex2b-push-no-existing-names.stderr
@@ -0,0 +1,12 @@
+error: lifetime may not live long enough
+  --> $DIR/ex2b-push-no-existing-names.rs:6:5
+   |
+LL | fn foo(x: &mut Vec<Ref<i32>>, y: Ref<i32>) {
+   |        -                      - has type `Ref<'1, i32>`
+   |        |
+   |        has type `&mut Vec<Ref<'2, i32>>`
+LL |     x.push(y);
+   |     ^^^^^^^^^ argument requires that `'1` must outlive `'2`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex2c-push-inference-variable.rs b/tests/ui/lifetimes/lifetime-errors/ex2c-push-inference-variable.rs
new file mode 100644
index 00000000000..2236d78ef4b
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex2c-push-inference-variable.rs
@@ -0,0 +1,11 @@
+struct Ref<'a, T: 'a> {
+    data: &'a T
+}
+
+fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
+    let z = Ref { data: y.data };
+    x.push(z);
+    //~^ ERROR lifetime may not live long enough
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex2c-push-inference-variable.stderr b/tests/ui/lifetimes/lifetime-errors/ex2c-push-inference-variable.stderr
new file mode 100644
index 00000000000..99fab4631a2
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex2c-push-inference-variable.stderr
@@ -0,0 +1,15 @@
+error: lifetime may not live long enough
+  --> $DIR/ex2c-push-inference-variable.rs:7:5
+   |
+LL | fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
+   |            --  -- lifetime `'c` defined here
+   |            |
+   |            lifetime `'b` defined here
+LL |     let z = Ref { data: y.data };
+LL |     x.push(z);
+   |     ^^^^^^^^^ argument requires that `'c` must outlive `'b`
+   |
+   = help: consider adding the following bound: `'c: 'b`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex2d-push-inference-variable-2.rs b/tests/ui/lifetimes/lifetime-errors/ex2d-push-inference-variable-2.rs
new file mode 100644
index 00000000000..f573230293e
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex2d-push-inference-variable-2.rs
@@ -0,0 +1,12 @@
+struct Ref<'a, T: 'a> {
+    data: &'a T
+}
+
+fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
+    let a: &mut Vec<Ref<i32>> = x;
+    let b = Ref { data: y.data };
+    a.push(b);
+    //~^ ERROR lifetime may not live long enough
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex2d-push-inference-variable-2.stderr b/tests/ui/lifetimes/lifetime-errors/ex2d-push-inference-variable-2.stderr
new file mode 100644
index 00000000000..52c5752f6ea
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex2d-push-inference-variable-2.stderr
@@ -0,0 +1,15 @@
+error: lifetime may not live long enough
+  --> $DIR/ex2d-push-inference-variable-2.rs:8:5
+   |
+LL | fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
+   |            --  -- lifetime `'c` defined here
+   |            |
+   |            lifetime `'b` defined here
+...
+LL |     a.push(b);
+   |     ^^^^^^^^^ argument requires that `'c` must outlive `'b`
+   |
+   = help: consider adding the following bound: `'c: 'b`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex2e-push-inference-variable-3.rs b/tests/ui/lifetimes/lifetime-errors/ex2e-push-inference-variable-3.rs
new file mode 100644
index 00000000000..4a934bbf080
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex2e-push-inference-variable-3.rs
@@ -0,0 +1,12 @@
+struct Ref<'a, T: 'a> {
+    data: &'a T
+}
+
+fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
+    let a: &mut Vec<Ref<i32>> = x;
+    let b = Ref { data: y.data };
+    Vec::push(a, b);
+    //~^ ERROR lifetime may not live long enough
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex2e-push-inference-variable-3.stderr b/tests/ui/lifetimes/lifetime-errors/ex2e-push-inference-variable-3.stderr
new file mode 100644
index 00000000000..e90c81ee3e1
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex2e-push-inference-variable-3.stderr
@@ -0,0 +1,15 @@
+error: lifetime may not live long enough
+  --> $DIR/ex2e-push-inference-variable-3.rs:8:5
+   |
+LL | fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
+   |            --  -- lifetime `'c` defined here
+   |            |
+   |            lifetime `'b` defined here
+...
+LL |     Vec::push(a, b);
+   |     ^^^^^^^^^^^^^^^ argument requires that `'c` must outlive `'b`
+   |
+   = help: consider adding the following bound: `'c: 'b`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.rs
new file mode 100644
index 00000000000..09ee9accccd
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.rs
@@ -0,0 +1,6 @@
+fn foo(&mut (ref mut v, w): &mut (&u8, &u8), x: &u8) {
+    *v = x;
+    //~^ ERROR lifetime may not live long enough
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.stderr
new file mode 100644
index 00000000000..5a23f1e0e9d
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.stderr
@@ -0,0 +1,17 @@
+error: lifetime may not live long enough
+  --> $DIR/ex3-both-anon-regions-2.rs:2:5
+   |
+LL | fn foo(&mut (ref mut v, w): &mut (&u8, &u8), x: &u8) {
+   |                                   -             - let's call the lifetime of this reference `'1`
+   |                                   |
+   |                                   let's call the lifetime of this reference `'2`
+LL |     *v = x;
+   |     ^^^^^^ assignment requires that `'1` must outlive `'2`
+   |
+help: consider introducing a named lifetime parameter
+   |
+LL | fn foo<'a>(&mut (ref mut v, w): &mut (&'a u8, &u8), x: &'a u8) {
+   |       ++++                             ++               ++
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.rs
new file mode 100644
index 00000000000..b3106db776f
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.rs
@@ -0,0 +1,7 @@
+fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) {
+    z.push((x,y));
+    //~^ ERROR lifetime may not live long enough
+    //~| ERROR lifetime may not live long enough
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.stderr
new file mode 100644
index 00000000000..6ba130308a3
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.stderr
@@ -0,0 +1,32 @@
+error: lifetime may not live long enough
+  --> $DIR/ex3-both-anon-regions-3.rs:2:5
+   |
+LL | fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) {
+   |                     -                   - let's call the lifetime of this reference `'1`
+   |                     |
+   |                     let's call the lifetime of this reference `'2`
+LL |     z.push((x,y));
+   |     ^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
+   |
+help: consider introducing a named lifetime parameter
+   |
+LL | fn foo<'a>(z: &mut Vec<(&'a u8,&u8)>, (x, y): (&'a u8, &u8)) {
+   |       ++++               ++                     ++
+
+error: lifetime may not live long enough
+  --> $DIR/ex3-both-anon-regions-3.rs:2:5
+   |
+LL | fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) {
+   |                         -                    - let's call the lifetime of this reference `'3`
+   |                         |
+   |                         let's call the lifetime of this reference `'4`
+LL |     z.push((x,y));
+   |     ^^^^^^^^^^^^^ argument requires that `'3` must outlive `'4`
+   |
+help: consider introducing a named lifetime parameter
+   |
+LL | fn foo<'a>(z: &mut Vec<(&u8,&'a u8)>, (x, y): (&u8, &'a u8)) {
+   |       ++++                   ++                      ++
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.rs
new file mode 100644
index 00000000000..5d0367783b8
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.rs
@@ -0,0 +1,11 @@
+struct Ref<'a, 'b> {
+    a: &'a u32,
+    b: &'b u32,
+}
+
+fn foo(mut x: Ref, y: Ref) {
+    x.b = y.b;
+    //~^ ERROR lifetime may not live long enough
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.stderr
new file mode 100644
index 00000000000..4c0ffe5c090
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.stderr
@@ -0,0 +1,12 @@
+error: lifetime may not live long enough
+  --> $DIR/ex3-both-anon-regions-both-are-structs-2.rs:7:5
+   |
+LL | fn foo(mut x: Ref, y: Ref) {
+   |        -----       - has type `Ref<'_, '1>`
+   |        |
+   |        has type `Ref<'_, '2>`
+LL |     x.b = y.b;
+   |     ^^^^^^^^^ assignment requires that `'1` must outlive `'2`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.rs
new file mode 100644
index 00000000000..4a479f19c72
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.rs
@@ -0,0 +1,11 @@
+struct Ref<'a, 'b> {
+    a: &'a u32,
+    b: &'b u32,
+}
+
+fn foo(mut x: Ref) {
+    x.a = x.b;
+    //~^ ERROR lifetime may not live long enough
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.stderr
new file mode 100644
index 00000000000..97c665347f6
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.stderr
@@ -0,0 +1,13 @@
+error: lifetime may not live long enough
+  --> $DIR/ex3-both-anon-regions-both-are-structs-3.rs:7:5
+   |
+LL | fn foo(mut x: Ref) {
+   |        -----
+   |        |
+   |        has type `Ref<'_, '1>`
+   |        has type `Ref<'2, '_>`
+LL |     x.a = x.b;
+   |     ^^^^^^^^^ assignment requires that `'1` must outlive `'2`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.rs
new file mode 100644
index 00000000000..9b8cfe670e6
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.rs
@@ -0,0 +1,13 @@
+struct Ref<'a> {
+    x: &'a u32,
+}
+
+fn foo<'a, 'b>(mut x: Vec<Ref<'a>>, y: Ref<'b>)
+    where &'a (): Sized,
+          &'b u32: Sized
+{
+    x.push(y);
+    //~^ ERROR lifetime may not live long enough
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.stderr
new file mode 100644
index 00000000000..b3d0bc2b882
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.stderr
@@ -0,0 +1,15 @@
+error: lifetime may not live long enough
+  --> $DIR/ex3-both-anon-regions-both-are-structs-earlybound-regions.rs:9:5
+   |
+LL | fn foo<'a, 'b>(mut x: Vec<Ref<'a>>, y: Ref<'b>)
+   |        --  -- lifetime `'b` defined here
+   |        |
+   |        lifetime `'a` defined here
+...
+LL |     x.push(y);
+   |     ^^^^^^^^^ argument requires that `'b` must outlive `'a`
+   |
+   = help: consider adding the following bound: `'b: 'a`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.rs
new file mode 100644
index 00000000000..db934a0bede
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.rs
@@ -0,0 +1,10 @@
+struct Ref<'a> {
+    x: &'a u32,
+}
+
+fn foo<'a, 'b>(mut x: Vec<Ref<'a>>, y: Ref<'b>) {
+    x.push(y);
+    //~^ ERROR lifetime may not live long enough
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.stderr
new file mode 100644
index 00000000000..fbe98a4263e
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.stderr
@@ -0,0 +1,14 @@
+error: lifetime may not live long enough
+  --> $DIR/ex3-both-anon-regions-both-are-structs-latebound-regions.rs:6:5
+   |
+LL | fn foo<'a, 'b>(mut x: Vec<Ref<'a>>, y: Ref<'b>) {
+   |        --  -- lifetime `'b` defined here
+   |        |
+   |        lifetime `'a` defined here
+LL |     x.push(y);
+   |     ^^^^^^^^^ argument requires that `'b` must outlive `'a`
+   |
+   = help: consider adding the following bound: `'b: 'a`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs.rs
new file mode 100644
index 00000000000..4bf5db41f4e
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs.rs
@@ -0,0 +1,10 @@
+struct Ref<'a> {
+    x: &'a u32,
+}
+
+fn foo(mut x: Vec<Ref>, y: Ref) {
+    x.push(y);
+    //~^ ERROR lifetime may not live long enough
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs.stderr
new file mode 100644
index 00000000000..9630729d0ee
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs.stderr
@@ -0,0 +1,12 @@
+error: lifetime may not live long enough
+  --> $DIR/ex3-both-anon-regions-both-are-structs.rs:6:5
+   |
+LL | fn foo(mut x: Vec<Ref>, y: Ref) {
+   |        -----            - has type `Ref<'1>`
+   |        |
+   |        has type `Vec<Ref<'2>>`
+LL |     x.push(y);
+   |     ^^^^^^^^^ argument requires that `'1` must outlive `'2`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-latebound-regions.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-latebound-regions.rs
new file mode 100644
index 00000000000..8dcb814b28b
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-latebound-regions.rs
@@ -0,0 +1,6 @@
+fn foo<'a,'b>(x: &mut Vec<&'a u8>, y: &'b u8) {
+    x.push(y);
+    //~^ ERROR lifetime may not live long enough
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-latebound-regions.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-latebound-regions.stderr
new file mode 100644
index 00000000000..1e24032fc1c
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-latebound-regions.stderr
@@ -0,0 +1,14 @@
+error: lifetime may not live long enough
+  --> $DIR/ex3-both-anon-regions-latebound-regions.rs:2:5
+   |
+LL | fn foo<'a,'b>(x: &mut Vec<&'a u8>, y: &'b u8) {
+   |        -- -- lifetime `'b` defined here
+   |        |
+   |        lifetime `'a` defined here
+LL |     x.push(y);
+   |     ^^^^^^^^^ argument requires that `'b` must outlive `'a`
+   |
+   = help: consider adding the following bound: `'b: 'a`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.rs
new file mode 100644
index 00000000000..e4df870bc00
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.rs
@@ -0,0 +1,9 @@
+struct Ref<'a, 'b> { a: &'a u32, b: &'b u32 }
+
+fn foo(mut x: Ref, y: &u32) {
+    y = x.b;
+    //~^ ERROR lifetime may not live long enough
+    //~| ERROR cannot assign to immutable argument
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.stderr
new file mode 100644
index 00000000000..bbd62902d9f
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.stderr
@@ -0,0 +1,21 @@
+error: lifetime may not live long enough
+  --> $DIR/ex3-both-anon-regions-one-is-struct-2.rs:4:5
+   |
+LL | fn foo(mut x: Ref, y: &u32) {
+   |        -----          - let's call the lifetime of this reference `'2`
+   |        |
+   |        has type `Ref<'_, '1>`
+LL |     y = x.b;
+   |     ^^^^^^^ assignment requires that `'1` must outlive `'2`
+
+error[E0384]: cannot assign to immutable argument `y`
+  --> $DIR/ex3-both-anon-regions-one-is-struct-2.rs:4:5
+   |
+LL | fn foo(mut x: Ref, y: &u32) {
+   |                    - help: consider making this binding mutable: `mut y`
+LL |     y = x.b;
+   |     ^^^^^^^ cannot assign to immutable argument
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0384`.
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.rs
new file mode 100644
index 00000000000..00de48278b2
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.rs
@@ -0,0 +1,8 @@
+struct Ref<'a, 'b> { a: &'a u32, b: &'b u32 }
+
+fn foo(mut y: Ref, x: &u32) {
+    y.b = x;
+    //~^ ERROR lifetime may not live long enough
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.stderr
new file mode 100644
index 00000000000..79e7e8e157d
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.stderr
@@ -0,0 +1,12 @@
+error: lifetime may not live long enough
+  --> $DIR/ex3-both-anon-regions-one-is-struct-3.rs:4:5
+   |
+LL | fn foo(mut y: Ref, x: &u32) {
+   |        -----          - let's call the lifetime of this reference `'1`
+   |        |
+   |        has type `Ref<'_, '2>`
+LL |     y.b = x;
+   |     ^^^^^^^ assignment requires that `'1` must outlive `'2`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.rs
new file mode 100644
index 00000000000..00de48278b2
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.rs
@@ -0,0 +1,8 @@
+struct Ref<'a, 'b> { a: &'a u32, b: &'b u32 }
+
+fn foo(mut y: Ref, x: &u32) {
+    y.b = x;
+    //~^ ERROR lifetime may not live long enough
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.stderr
new file mode 100644
index 00000000000..53615fd1aba
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.stderr
@@ -0,0 +1,12 @@
+error: lifetime may not live long enough
+  --> $DIR/ex3-both-anon-regions-one-is-struct-4.rs:4:5
+   |
+LL | fn foo(mut y: Ref, x: &u32) {
+   |        -----          - let's call the lifetime of this reference `'1`
+   |        |
+   |        has type `Ref<'_, '2>`
+LL |     y.b = x;
+   |     ^^^^^^^ assignment requires that `'1` must outlive `'2`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct.rs
new file mode 100644
index 00000000000..5bb0e28d46f
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct.rs
@@ -0,0 +1,11 @@
+struct Ref<'a, 'b> {
+    a: &'a u32,
+    b: &'b u32,
+}
+
+fn foo(mut x: Ref, y: &u32) {
+    x.b = y;
+    //~^ ERROR lifetime may not live long enough
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct.stderr
new file mode 100644
index 00000000000..6ff44116737
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct.stderr
@@ -0,0 +1,12 @@
+error: lifetime may not live long enough
+  --> $DIR/ex3-both-anon-regions-one-is-struct.rs:7:5
+   |
+LL | fn foo(mut x: Ref, y: &u32) {
+   |        -----          - let's call the lifetime of this reference `'1`
+   |        |
+   |        has type `Ref<'_, '2>`
+LL |     x.b = y;
+   |     ^^^^^^^ assignment requires that `'1` must outlive `'2`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.rs
new file mode 100644
index 00000000000..3ffd7be4e73
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.rs
@@ -0,0 +1,12 @@
+struct Foo {
+  field: i32
+}
+
+impl Foo {
+  fn foo<'a>(&self, x: &i32) -> &i32 {
+    x
+    //~^ ERROR lifetime may not live long enough
+  }
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr
new file mode 100644
index 00000000000..5601335d275
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr
@@ -0,0 +1,17 @@
+error: lifetime may not live long enough
+  --> $DIR/ex3-both-anon-regions-return-type-is-anon.rs:7:5
+   |
+LL |   fn foo<'a>(&self, x: &i32) -> &i32 {
+   |              -         - let's call the lifetime of this reference `'1`
+   |              |
+   |              let's call the lifetime of this reference `'2`
+LL |     x
+   |     ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |   fn foo<'a>(&'a self, x: &'a i32) -> &i32 {
+   |               ++           ++
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.rs
new file mode 100644
index 00000000000..9b67a774264
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.rs
@@ -0,0 +1,12 @@
+struct Foo {
+    field: i32,
+}
+
+impl Foo {
+    fn foo<'a>(&self, x: &Foo) -> &Foo {
+        if true { x } else { self }
+        //~^ ERROR lifetime may not live long enough
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr
new file mode 100644
index 00000000000..e221902c4a9
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr
@@ -0,0 +1,17 @@
+error: lifetime may not live long enough
+  --> $DIR/ex3-both-anon-regions-self-is-anon.rs:7:19
+   |
+LL |     fn foo<'a>(&self, x: &Foo) -> &Foo {
+   |                -         - let's call the lifetime of this reference `'1`
+   |                |
+   |                let's call the lifetime of this reference `'2`
+LL |         if true { x } else { self }
+   |                   ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |     fn foo<'a>(&'a self, x: &'a Foo) -> &Foo {
+   |                 ++           ++
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.rs
new file mode 100644
index 00000000000..2f67750d89b
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.rs
@@ -0,0 +1,7 @@
+fn foo(x:fn(&u8, &u8), y: Vec<&u8>, z: &u8) {
+  y.push(z);
+  //~^ ERROR lifetime may not live long enough
+  //~| ERROR cannot borrow
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.stderr
new file mode 100644
index 00000000000..cc2447b1877
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.stderr
@@ -0,0 +1,29 @@
+error: lifetime may not live long enough
+  --> $DIR/ex3-both-anon-regions-using-fn-items.rs:2:3
+   |
+LL | fn foo(x:fn(&u8, &u8), y: Vec<&u8>, z: &u8) {
+   |                               -        - let's call the lifetime of this reference `'1`
+   |                               |
+   |                               let's call the lifetime of this reference `'2`
+LL |   y.push(z);
+   |   ^^^^^^^^^ argument requires that `'1` must outlive `'2`
+   |
+help: consider introducing a named lifetime parameter
+   |
+LL | fn foo<'a>(x:fn(&u8, &u8), y: Vec<&'a u8>, z: &'a u8) {
+   |       ++++                         ++          ++
+
+error[E0596]: cannot borrow `y` as mutable, as it is not declared as mutable
+  --> $DIR/ex3-both-anon-regions-using-fn-items.rs:2:3
+   |
+LL |   y.push(z);
+   |   ^^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL | fn foo(x:fn(&u8, &u8), mut y: Vec<&u8>, z: &u8) {
+   |                        +++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.rs
new file mode 100644
index 00000000000..73e1789f225
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.rs
@@ -0,0 +1,10 @@
+trait Foo {
+    fn foo<'a>(x: &mut Vec<&u8>, y: &u8);
+}
+impl Foo for () {
+    fn foo(x: &mut Vec<&u8>, y: &u8) {
+        x.push(y);
+        //~^ ERROR lifetime may not live long enough
+    }
+}
+fn main() {}
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.stderr
new file mode 100644
index 00000000000..9661f1e5144
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.stderr
@@ -0,0 +1,17 @@
+error: lifetime may not live long enough
+  --> $DIR/ex3-both-anon-regions-using-impl-items.rs:6:9
+   |
+LL |     fn foo(x: &mut Vec<&u8>, y: &u8) {
+   |                        -        - let's call the lifetime of this reference `'1`
+   |                        |
+   |                        let's call the lifetime of this reference `'2`
+LL |         x.push(y);
+   |         ^^^^^^^^^ argument requires that `'1` must outlive `'2`
+   |
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |     fn foo<'a>(x: &mut Vec<&'a u8>, y: &'a u8) {
+   |           ++++              ++          ++
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.rs
new file mode 100644
index 00000000000..97fa9ef914f
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.rs
@@ -0,0 +1,7 @@
+fn foo(x:Box<dyn Fn(&u8, &u8)> , y: Vec<&u8>, z: &u8) {
+  y.push(z);
+  //~^ ERROR lifetime may not live long enough
+  //~| ERROR cannot borrow
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.stderr
new file mode 100644
index 00000000000..2ba5afa808d
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.stderr
@@ -0,0 +1,29 @@
+error: lifetime may not live long enough
+  --> $DIR/ex3-both-anon-regions-using-trait-objects.rs:2:3
+   |
+LL | fn foo(x:Box<dyn Fn(&u8, &u8)> , y: Vec<&u8>, z: &u8) {
+   |                                         -        - let's call the lifetime of this reference `'1`
+   |                                         |
+   |                                         let's call the lifetime of this reference `'2`
+LL |   y.push(z);
+   |   ^^^^^^^^^ argument requires that `'1` must outlive `'2`
+   |
+help: consider introducing a named lifetime parameter
+   |
+LL | fn foo<'a>(x:Box<dyn Fn(&u8, &u8)> , y: Vec<&'a u8>, z: &'a u8) {
+   |       ++++                                   ++          ++
+
+error[E0596]: cannot borrow `y` as mutable, as it is not declared as mutable
+  --> $DIR/ex3-both-anon-regions-using-trait-objects.rs:2:3
+   |
+LL |   y.push(z);
+   |   ^^^^^^^^^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL | fn foo(x:Box<dyn Fn(&u8, &u8)> , mut y: Vec<&u8>, z: &u8) {
+   |                                  +++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.rs
new file mode 100644
index 00000000000..ca0feaba851
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.rs
@@ -0,0 +1,6 @@
+fn foo(x: &mut Vec<&u8>, y: &u8) {
+    x.push(y);
+    //~^ ERROR lifetime may not live long enough
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.stderr
new file mode 100644
index 00000000000..ec9fac0c288
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.stderr
@@ -0,0 +1,17 @@
+error: lifetime may not live long enough
+  --> $DIR/ex3-both-anon-regions.rs:2:5
+   |
+LL | fn foo(x: &mut Vec<&u8>, y: &u8) {
+   |                    -        - let's call the lifetime of this reference `'1`
+   |                    |
+   |                    let's call the lifetime of this reference `'2`
+LL |     x.push(y);
+   |     ^^^^^^^^^ argument requires that `'1` must outlive `'2`
+   |
+help: consider introducing a named lifetime parameter
+   |
+LL | fn foo<'a>(x: &mut Vec<&'a u8>, y: &'a u8) {
+   |       ++++              ++          ++
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/issue_74400.rs b/tests/ui/lifetimes/lifetime-errors/issue_74400.rs
new file mode 100644
index 00000000000..ddb8bacce8f
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/issue_74400.rs
@@ -0,0 +1,16 @@
+//! Regression test for #74400: Type mismatch in function arguments E0631, E0271 are falsely
+//! recognized as E0308 mismatched types.
+
+use std::convert::identity;
+
+fn main() {}
+
+fn f<T, S>(data: &[T], key: impl Fn(&T) -> S) {
+}
+
+fn g<T>(data: &[T]) {
+    f(data, identity)
+    //~^ ERROR the parameter type
+    //~| ERROR mismatched types
+    //~| ERROR implementation of `FnOnce` is not general
+}
diff --git a/tests/ui/lifetimes/lifetime-errors/issue_74400.stderr b/tests/ui/lifetimes/lifetime-errors/issue_74400.stderr
new file mode 100644
index 00000000000..7049f28e2f6
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/issue_74400.stderr
@@ -0,0 +1,38 @@
+error[E0310]: the parameter type `T` may not live long enough
+  --> $DIR/issue_74400.rs:12:5
+   |
+LL |     f(data, identity)
+   |     ^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
+   |
+help: consider adding an explicit lifetime bound...
+   |
+LL | fn g<T: 'static>(data: &[T]) {
+   |       +++++++++
+
+error[E0308]: mismatched types
+  --> $DIR/issue_74400.rs:12:5
+   |
+LL |     f(data, identity)
+   |     ^^^^^^^^^^^^^^^^^ one type is more general than the other
+   |
+   = note: expected trait `for<'a> Fn<(&'a T,)>`
+              found trait `Fn<(&T,)>`
+note: the lifetime requirement is introduced here
+  --> $DIR/issue_74400.rs:8:34
+   |
+LL | fn f<T, S>(data: &[T], key: impl Fn(&T) -> S) {
+   |                                  ^^^^^^^^^^^
+
+error: implementation of `FnOnce` is not general enough
+  --> $DIR/issue_74400.rs:12:5
+   |
+LL |     f(data, identity)
+   |     ^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
+   |
+   = note: `fn(&'2 T) -> &'2 T {identity::<&'2 T>}` must implement `FnOnce<(&'1 T,)>`, for any lifetime `'1`...
+   = note: ...but it actually implements `FnOnce<(&'2 T,)>`, for some specific lifetime `'2`
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0308, E0310.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.rs b/tests/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.rs
new file mode 100644
index 00000000000..81a20c58776
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.rs
@@ -0,0 +1,37 @@
+// Check notes are placed on an assignment that can actually precede the current assignment
+// Don't emit a first assignment for assignment in a loop.
+
+fn test() {
+    let x;
+    if true {
+        x = 1;
+    } else {
+        x = 2;
+        x = 3;      //~ ERROR [E0384]
+    }
+}
+
+fn test_in_loop() {
+    loop {
+        let x;
+        if true {
+            x = 1;
+        } else {
+            x = 2;
+            x = 3;      //~ ERROR [E0384]
+        }
+    }
+}
+
+fn test_using_loop() {
+    let x;
+    loop {
+        if true {
+            x = 1;      //~ ERROR [E0384]
+        } else {
+            x = 2;      //~ ERROR [E0384]
+        }
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.stderr b/tests/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.stderr
new file mode 100644
index 00000000000..b47a47d631e
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.stderr
@@ -0,0 +1,46 @@
+error[E0384]: cannot assign twice to immutable variable `x`
+  --> $DIR/liveness-assign-imm-local-notes.rs:10:9
+   |
+LL |     let x;
+   |         - help: consider making this binding mutable: `mut x`
+...
+LL |         x = 2;
+   |         ----- first assignment to `x`
+LL |         x = 3;
+   |         ^^^^^ cannot assign twice to immutable variable
+
+error[E0384]: cannot assign twice to immutable variable `x`
+  --> $DIR/liveness-assign-imm-local-notes.rs:21:13
+   |
+LL |         let x;
+   |             - help: consider making this binding mutable: `mut x`
+...
+LL |             x = 2;
+   |             ----- first assignment to `x`
+LL |             x = 3;
+   |             ^^^^^ cannot assign twice to immutable variable
+
+error[E0384]: cannot assign twice to immutable variable `x`
+  --> $DIR/liveness-assign-imm-local-notes.rs:30:13
+   |
+LL |     let x;
+   |         - help: consider making this binding mutable: `mut x`
+...
+LL |             x = 1;
+   |             ^^^^^ cannot assign twice to immutable variable
+
+error[E0384]: cannot assign twice to immutable variable `x`
+  --> $DIR/liveness-assign-imm-local-notes.rs:32:13
+   |
+LL |     let x;
+   |         - help: consider making this binding mutable: `mut x`
+...
+LL |             x = 1;
+   |             ----- first assignment to `x`
+LL |         } else {
+LL |             x = 2;
+   |             ^^^^^ cannot assign twice to immutable variable
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0384`.