summaryrefslogtreecommitdiffstats
path: root/src/test/ui/underscore-lifetime
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui/underscore-lifetime')
-rw-r--r--src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.rs12
-rw-r--r--src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr15
-rw-r--r--src/test/ui/underscore-lifetime/dyn-trait-underscore.rs20
-rw-r--r--src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr16
-rw-r--r--src/test/ui/underscore-lifetime/in-binder.rs35
-rw-r--r--src/test/ui/underscore-lifetime/in-binder.stderr39
-rw-r--r--src/test/ui/underscore-lifetime/in-fn-return-illegal.rs7
-rw-r--r--src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr15
-rw-r--r--src/test/ui/underscore-lifetime/in-struct.rs13
-rw-r--r--src/test/ui/underscore-lifetime/in-struct.stderr27
-rw-r--r--src/test/ui/underscore-lifetime/underscore-lifetime-binders.rs22
-rw-r--r--src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr51
-rw-r--r--src/test/ui/underscore-lifetime/underscore-lifetime-elison-mismatch.rs4
-rw-r--r--src/test/ui/underscore-lifetime/underscore-lifetime-elison-mismatch.stderr16
-rw-r--r--src/test/ui/underscore-lifetime/underscore-outlives-bounds.rs8
-rw-r--r--src/test/ui/underscore-lifetime/underscore-outlives-bounds.stderr9
-rw-r--r--src/test/ui/underscore-lifetime/where-clause-inherent-impl-ampersand.rs18
-rw-r--r--src/test/ui/underscore-lifetime/where-clause-inherent-impl-ampersand.rust2015.stderr9
-rw-r--r--src/test/ui/underscore-lifetime/where-clause-inherent-impl-ampersand.rust2018.stderr9
-rw-r--r--src/test/ui/underscore-lifetime/where-clause-inherent-impl-underscore.rs17
-rw-r--r--src/test/ui/underscore-lifetime/where-clause-inherent-impl-underscore.rust2015.stderr9
-rw-r--r--src/test/ui/underscore-lifetime/where-clause-inherent-impl-underscore.rust2018.stderr9
-rw-r--r--src/test/ui/underscore-lifetime/where-clause-trait-impl-region.rs15
-rw-r--r--src/test/ui/underscore-lifetime/where-clause-trait-impl-region.rust2015.stderr9
-rw-r--r--src/test/ui/underscore-lifetime/where-clause-trait-impl-region.rust2018.stderr9
-rw-r--r--src/test/ui/underscore-lifetime/where-clause-trait-impl-underscore.rs15
-rw-r--r--src/test/ui/underscore-lifetime/where-clause-trait-impl-underscore.rust2015.stderr9
-rw-r--r--src/test/ui/underscore-lifetime/where-clause-trait-impl-underscore.rust2018.stderr9
-rw-r--r--src/test/ui/underscore-lifetime/where-clauses.rs7
-rw-r--r--src/test/ui/underscore-lifetime/where-clauses.stderr15
30 files changed, 468 insertions, 0 deletions
diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.rs b/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.rs
new file mode 100644
index 000000000..e1deab736
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.rs
@@ -0,0 +1,12 @@
+// Check that the `'_` in `dyn Trait + '_` acts like ordinary elision,
+// and not like an object lifetime default.
+//
+// cc #48468
+
+use std::fmt::Debug;
+
+struct Foo {
+ x: Box<dyn Debug + '_>, //~ ERROR missing lifetime specifier
+}
+
+fn main() {}
diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr
new file mode 100644
index 000000000..fd0860028
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr
@@ -0,0 +1,15 @@
+error[E0106]: missing lifetime specifier
+ --> $DIR/dyn-trait-underscore-in-struct.rs:9:24
+ |
+LL | x: Box<dyn Debug + '_>,
+ | ^^ expected named lifetime parameter
+ |
+help: consider introducing a named lifetime parameter
+ |
+LL ~ struct Foo<'a> {
+LL ~ x: Box<dyn Debug + 'a>,
+ |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.rs b/src/test/ui/underscore-lifetime/dyn-trait-underscore.rs
new file mode 100644
index 000000000..fa6e65c7d
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.rs
@@ -0,0 +1,20 @@
+// Check that the `'_` in `dyn Trait + '_` acts like ordinary elision,
+// and not like an object lifetime default.
+//
+// cc #48468
+
+fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
+ // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
+ Box::new(items.iter())
+ //~^ ERROR lifetime may not live long enough
+}
+
+fn b<T>(items: &[T]) -> Box<dyn Iterator<Item=&T> + '_> {
+ Box::new(items.iter()) // OK, equivalent to c
+}
+
+fn c<'a, T>(items: &'a [T]) -> Box<dyn Iterator<Item=&'a T> + 'a> {
+ Box::new(items.iter()) // OK, equivalent to b
+}
+
+fn main() { }
diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr
new file mode 100644
index 000000000..60b0b3ee7
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr
@@ -0,0 +1,16 @@
+error: lifetime may not live long enough
+ --> $DIR/dyn-trait-underscore.rs:8:5
+ |
+LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
+ | - let's call the lifetime of this reference `'1`
+LL | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
+LL | Box::new(items.iter())
+ | ^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static`
+ |
+help: to declare that the trait object captures data from argument `items`, you can add an explicit `'_` lifetime bound
+ |
+LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T> + '_> {
+ | ++++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/underscore-lifetime/in-binder.rs b/src/test/ui/underscore-lifetime/in-binder.rs
new file mode 100644
index 000000000..74dc331b0
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/in-binder.rs
@@ -0,0 +1,35 @@
+// Check that we error when `'_` appears as the name of a lifetime parameter.
+//
+// Regression test for #52098.
+
+struct IceCube<'a> {
+ v: Vec<&'a char>
+}
+
+impl<'_> IceCube<'_> {}
+//~^ ERROR `'_` cannot be used here
+
+struct Struct<'_> {
+ //~^ ERROR `'_` cannot be used here
+ v: Vec<&'static char>
+}
+
+enum Enum<'_> {
+ //~^ ERROR `'_` cannot be used here
+ Variant
+}
+
+union Union<'_> {
+ //~^ ERROR `'_` cannot be used here
+ a: u32
+}
+
+trait Trait<'_> {
+ //~^ ERROR `'_` cannot be used here
+}
+
+fn foo<'_>() {
+ //~^ ERROR `'_` cannot be used here
+}
+
+fn main() {}
diff --git a/src/test/ui/underscore-lifetime/in-binder.stderr b/src/test/ui/underscore-lifetime/in-binder.stderr
new file mode 100644
index 000000000..fcd7eddb5
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/in-binder.stderr
@@ -0,0 +1,39 @@
+error[E0637]: `'_` cannot be used here
+ --> $DIR/in-binder.rs:9:6
+ |
+LL | impl<'_> IceCube<'_> {}
+ | ^^ `'_` is a reserved lifetime name
+
+error[E0637]: `'_` cannot be used here
+ --> $DIR/in-binder.rs:12:15
+ |
+LL | struct Struct<'_> {
+ | ^^ `'_` is a reserved lifetime name
+
+error[E0637]: `'_` cannot be used here
+ --> $DIR/in-binder.rs:17:11
+ |
+LL | enum Enum<'_> {
+ | ^^ `'_` is a reserved lifetime name
+
+error[E0637]: `'_` cannot be used here
+ --> $DIR/in-binder.rs:22:13
+ |
+LL | union Union<'_> {
+ | ^^ `'_` is a reserved lifetime name
+
+error[E0637]: `'_` cannot be used here
+ --> $DIR/in-binder.rs:27:13
+ |
+LL | trait Trait<'_> {
+ | ^^ `'_` is a reserved lifetime name
+
+error[E0637]: `'_` cannot be used here
+ --> $DIR/in-binder.rs:31:8
+ |
+LL | fn foo<'_>() {
+ | ^^ `'_` is a reserved lifetime name
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0637`.
diff --git a/src/test/ui/underscore-lifetime/in-fn-return-illegal.rs b/src/test/ui/underscore-lifetime/in-fn-return-illegal.rs
new file mode 100644
index 000000000..a46ece7d4
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/in-fn-return-illegal.rs
@@ -0,0 +1,7 @@
+// Check that the `'_` used in structs/enums gives an error.
+
+use std::fmt::Debug;
+
+fn foo(x: &u32, y: &u32) -> &'_ u32 { loop { } } //~ ERROR missing lifetime specifier
+
+fn main() { }
diff --git a/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr b/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr
new file mode 100644
index 000000000..6a104e8f9
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr
@@ -0,0 +1,15 @@
+error[E0106]: missing lifetime specifier
+ --> $DIR/in-fn-return-illegal.rs:5:30
+ |
+LL | fn foo(x: &u32, y: &u32) -> &'_ u32 { loop { } }
+ | ---- ---- ^^ 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 u32, y: &'a u32) -> &'a u32 { loop { } }
+ | ++++ ++ ++ ~~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/underscore-lifetime/in-struct.rs b/src/test/ui/underscore-lifetime/in-struct.rs
new file mode 100644
index 000000000..bed89c7dc
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/in-struct.rs
@@ -0,0 +1,13 @@
+// Check that the `'_` used in structs/enums gives an error.
+
+use std::fmt::Debug;
+
+struct Foo {
+ x: &'_ u32, //~ ERROR missing lifetime specifier
+}
+
+enum Bar {
+ Variant(&'_ u32), //~ ERROR missing lifetime specifier
+}
+
+fn main() { }
diff --git a/src/test/ui/underscore-lifetime/in-struct.stderr b/src/test/ui/underscore-lifetime/in-struct.stderr
new file mode 100644
index 000000000..84183f61e
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/in-struct.stderr
@@ -0,0 +1,27 @@
+error[E0106]: missing lifetime specifier
+ --> $DIR/in-struct.rs:6:9
+ |
+LL | x: &'_ u32,
+ | ^^ expected named lifetime parameter
+ |
+help: consider introducing a named lifetime parameter
+ |
+LL ~ struct Foo<'a> {
+LL ~ x: &'a u32,
+ |
+
+error[E0106]: missing lifetime specifier
+ --> $DIR/in-struct.rs:10:14
+ |
+LL | Variant(&'_ u32),
+ | ^^ expected named lifetime parameter
+ |
+help: consider introducing a named lifetime parameter
+ |
+LL ~ enum Bar<'a> {
+LL ~ Variant(&'a u32),
+ |
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.rs b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.rs
new file mode 100644
index 000000000..3d049cc56
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.rs
@@ -0,0 +1,22 @@
+struct Foo<'a>(&'a u8);
+struct Baz<'a>(&'_ &'a u8); //~ ERROR missing lifetime specifier
+
+fn foo<'_> //~ ERROR cannot be used here
+(_: Foo<'_>) {}
+
+trait Meh<'a> {}
+impl<'a> Meh<'a> for u8 {}
+
+fn meh() -> Box<dyn for<'_> Meh<'_>> //~ ERROR cannot be used here
+//~^ ERROR missing lifetime specifier
+{
+ Box::new(5u8)
+}
+
+fn foo2(_: &'_ u8, y: &'_ u8) -> &'_ u8 { y } //~ ERROR missing lifetime specifier
+
+fn main() {
+ let x = 5;
+ foo(Foo(&x));
+ let _ = meh();
+}
diff --git a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr
new file mode 100644
index 000000000..50401791e
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr
@@ -0,0 +1,51 @@
+error[E0106]: missing lifetime specifier
+ --> $DIR/underscore-lifetime-binders.rs:2:17
+ |
+LL | struct Baz<'a>(&'_ &'a u8);
+ | ^^ expected named lifetime parameter
+ |
+help: consider using the `'a` lifetime
+ |
+LL | struct Baz<'a>(&'a &'a u8);
+ | ~~
+
+error[E0637]: `'_` cannot be used here
+ --> $DIR/underscore-lifetime-binders.rs:4:8
+ |
+LL | fn foo<'_>
+ | ^^ `'_` is a reserved lifetime name
+
+error[E0637]: `'_` cannot be used here
+ --> $DIR/underscore-lifetime-binders.rs:10:25
+ |
+LL | fn meh() -> Box<dyn for<'_> Meh<'_>>
+ | ^^ `'_` is a reserved lifetime name
+
+error[E0106]: missing lifetime specifier
+ --> $DIR/underscore-lifetime-binders.rs:10:33
+ |
+LL | fn meh() -> Box<dyn for<'_> Meh<'_>>
+ | ^^ expected named lifetime parameter
+ |
+ = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+ |
+LL | fn meh() -> Box<dyn for<'_> Meh<'static>>
+ | ~~~~~~~
+
+error[E0106]: missing lifetime specifier
+ --> $DIR/underscore-lifetime-binders.rs:16:35
+ |
+LL | fn foo2(_: &'_ u8, y: &'_ u8) -> &'_ u8 { y }
+ | ------ ------ ^^ 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 argument 1 or `y`
+help: consider introducing a named lifetime parameter
+ |
+LL | fn foo2<'a>(_: &'a u8, y: &'a u8) -> &'a u8 { y }
+ | ++++ ~~ ~~ ~~
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0106, E0637.
+For more information about an error, try `rustc --explain E0106`.
diff --git a/src/test/ui/underscore-lifetime/underscore-lifetime-elison-mismatch.rs b/src/test/ui/underscore-lifetime/underscore-lifetime-elison-mismatch.rs
new file mode 100644
index 000000000..c61126884
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/underscore-lifetime-elison-mismatch.rs
@@ -0,0 +1,4 @@
+fn foo(x: &mut Vec<&'_ u8>, y: &'_ u8) { x.push(y); }
+//~^ ERROR lifetime may not live long enough
+
+fn main() {}
diff --git a/src/test/ui/underscore-lifetime/underscore-lifetime-elison-mismatch.stderr b/src/test/ui/underscore-lifetime/underscore-lifetime-elison-mismatch.stderr
new file mode 100644
index 000000000..2b34f0c55
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/underscore-lifetime-elison-mismatch.stderr
@@ -0,0 +1,16 @@
+error: lifetime may not live long enough
+ --> $DIR/underscore-lifetime-elison-mismatch.rs:1:42
+ |
+LL | fn foo(x: &mut Vec<&'_ u8>, y: &'_ u8) { x.push(y); }
+ | - - ^^^^^^^^^ argument requires that `'1` must outlive `'2`
+ | | |
+ | | let's call the lifetime of this reference `'1`
+ | let's call the lifetime of this reference `'2`
+ |
+help: consider introducing a named lifetime parameter
+ |
+LL | fn foo<'a>(x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); }
+ | ++++ ~~ ~~
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/underscore-lifetime/underscore-outlives-bounds.rs b/src/test/ui/underscore-lifetime/underscore-outlives-bounds.rs
new file mode 100644
index 000000000..567cc7a3f
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/underscore-outlives-bounds.rs
@@ -0,0 +1,8 @@
+// Regression test to check that `'b: '_` gets an error, because it's
+// basically useless.
+//
+// #54902
+
+trait Foo<'a> {}
+impl<'b: '_> Foo<'b> for i32 {} //~ ERROR `'_` cannot be used here
+fn main() { }
diff --git a/src/test/ui/underscore-lifetime/underscore-outlives-bounds.stderr b/src/test/ui/underscore-lifetime/underscore-outlives-bounds.stderr
new file mode 100644
index 000000000..4b38a26f9
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/underscore-outlives-bounds.stderr
@@ -0,0 +1,9 @@
+error[E0637]: `'_` cannot be used here
+ --> $DIR/underscore-outlives-bounds.rs:7:10
+ |
+LL | impl<'b: '_> Foo<'b> for i32 {}
+ | ^^ `'_` is a reserved lifetime name
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0637`.
diff --git a/src/test/ui/underscore-lifetime/where-clause-inherent-impl-ampersand.rs b/src/test/ui/underscore-lifetime/where-clause-inherent-impl-ampersand.rs
new file mode 100644
index 000000000..43de30944
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/where-clause-inherent-impl-ampersand.rs
@@ -0,0 +1,18 @@
+// revisions: rust2015 rust2018
+//[rust2018] edition:2018
+
+trait WithType<T> {}
+trait WithRegion<'a> { }
+
+struct Foo<T> {
+ t: T
+}
+
+impl<T> Foo<T>
+where
+ T: WithType<&u32>
+//[rust2015]~^ ERROR `&` without an explicit lifetime name cannot be used here
+//[rust2018]~^^ ERROR `&` without an explicit lifetime name cannot be used here
+{ }
+
+fn main() {}
diff --git a/src/test/ui/underscore-lifetime/where-clause-inherent-impl-ampersand.rust2015.stderr b/src/test/ui/underscore-lifetime/where-clause-inherent-impl-ampersand.rust2015.stderr
new file mode 100644
index 000000000..fe726cb49
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/where-clause-inherent-impl-ampersand.rust2015.stderr
@@ -0,0 +1,9 @@
+error[E0637]: `&` without an explicit lifetime name cannot be used here
+ --> $DIR/where-clause-inherent-impl-ampersand.rs:13:17
+ |
+LL | T: WithType<&u32>
+ | ^ explicit lifetime name needed here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0637`.
diff --git a/src/test/ui/underscore-lifetime/where-clause-inherent-impl-ampersand.rust2018.stderr b/src/test/ui/underscore-lifetime/where-clause-inherent-impl-ampersand.rust2018.stderr
new file mode 100644
index 000000000..fe726cb49
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/where-clause-inherent-impl-ampersand.rust2018.stderr
@@ -0,0 +1,9 @@
+error[E0637]: `&` without an explicit lifetime name cannot be used here
+ --> $DIR/where-clause-inherent-impl-ampersand.rs:13:17
+ |
+LL | T: WithType<&u32>
+ | ^ explicit lifetime name needed here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0637`.
diff --git a/src/test/ui/underscore-lifetime/where-clause-inherent-impl-underscore.rs b/src/test/ui/underscore-lifetime/where-clause-inherent-impl-underscore.rs
new file mode 100644
index 000000000..38189816d
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/where-clause-inherent-impl-underscore.rs
@@ -0,0 +1,17 @@
+// revisions: rust2015 rust2018
+//[rust2018] edition:2018
+
+trait WithType<T> {}
+trait WithRegion<'a> { }
+
+struct Foo<T> {
+ t: T
+}
+
+impl<T> Foo<T>
+where
+ T: WithRegion<'_>
+//[rust2015,rust2018]~^ ERROR `'_` cannot be used here
+{ }
+
+fn main() {}
diff --git a/src/test/ui/underscore-lifetime/where-clause-inherent-impl-underscore.rust2015.stderr b/src/test/ui/underscore-lifetime/where-clause-inherent-impl-underscore.rust2015.stderr
new file mode 100644
index 000000000..95939fd6b
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/where-clause-inherent-impl-underscore.rust2015.stderr
@@ -0,0 +1,9 @@
+error[E0637]: `'_` cannot be used here
+ --> $DIR/where-clause-inherent-impl-underscore.rs:13:19
+ |
+LL | T: WithRegion<'_>
+ | ^^ `'_` is a reserved lifetime name
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0637`.
diff --git a/src/test/ui/underscore-lifetime/where-clause-inherent-impl-underscore.rust2018.stderr b/src/test/ui/underscore-lifetime/where-clause-inherent-impl-underscore.rust2018.stderr
new file mode 100644
index 000000000..95939fd6b
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/where-clause-inherent-impl-underscore.rust2018.stderr
@@ -0,0 +1,9 @@
+error[E0637]: `'_` cannot be used here
+ --> $DIR/where-clause-inherent-impl-underscore.rs:13:19
+ |
+LL | T: WithRegion<'_>
+ | ^^ `'_` is a reserved lifetime name
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0637`.
diff --git a/src/test/ui/underscore-lifetime/where-clause-trait-impl-region.rs b/src/test/ui/underscore-lifetime/where-clause-trait-impl-region.rs
new file mode 100644
index 000000000..09e5bbd84
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/where-clause-trait-impl-region.rs
@@ -0,0 +1,15 @@
+// revisions: rust2015 rust2018
+//[rust2018] edition:2018
+
+trait WithType<T> {}
+trait WithRegion<'a> { }
+
+trait Foo { }
+
+impl<T> Foo for Vec<T>
+where
+ T: WithType<&u32>
+//[rust2015,rust2018]~^ ERROR `&` without an explicit lifetime name cannot be used here
+{ }
+
+fn main() {}
diff --git a/src/test/ui/underscore-lifetime/where-clause-trait-impl-region.rust2015.stderr b/src/test/ui/underscore-lifetime/where-clause-trait-impl-region.rust2015.stderr
new file mode 100644
index 000000000..fbd14de21
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/where-clause-trait-impl-region.rust2015.stderr
@@ -0,0 +1,9 @@
+error[E0637]: `&` without an explicit lifetime name cannot be used here
+ --> $DIR/where-clause-trait-impl-region.rs:11:17
+ |
+LL | T: WithType<&u32>
+ | ^ explicit lifetime name needed here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0637`.
diff --git a/src/test/ui/underscore-lifetime/where-clause-trait-impl-region.rust2018.stderr b/src/test/ui/underscore-lifetime/where-clause-trait-impl-region.rust2018.stderr
new file mode 100644
index 000000000..fbd14de21
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/where-clause-trait-impl-region.rust2018.stderr
@@ -0,0 +1,9 @@
+error[E0637]: `&` without an explicit lifetime name cannot be used here
+ --> $DIR/where-clause-trait-impl-region.rs:11:17
+ |
+LL | T: WithType<&u32>
+ | ^ explicit lifetime name needed here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0637`.
diff --git a/src/test/ui/underscore-lifetime/where-clause-trait-impl-underscore.rs b/src/test/ui/underscore-lifetime/where-clause-trait-impl-underscore.rs
new file mode 100644
index 000000000..371d2e4ba
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/where-clause-trait-impl-underscore.rs
@@ -0,0 +1,15 @@
+// revisions: rust2015 rust2018
+//[rust2018] edition:2018
+
+trait WithType<T> {}
+trait WithRegion<'a> { }
+
+trait Foo { }
+
+impl<T> Foo for Vec<T>
+where
+ T: WithRegion<'_>
+//[rust2015,rust2018]~^ ERROR `'_` cannot be used here
+{ }
+
+fn main() {}
diff --git a/src/test/ui/underscore-lifetime/where-clause-trait-impl-underscore.rust2015.stderr b/src/test/ui/underscore-lifetime/where-clause-trait-impl-underscore.rust2015.stderr
new file mode 100644
index 000000000..92caff0dc
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/where-clause-trait-impl-underscore.rust2015.stderr
@@ -0,0 +1,9 @@
+error[E0637]: `'_` cannot be used here
+ --> $DIR/where-clause-trait-impl-underscore.rs:11:19
+ |
+LL | T: WithRegion<'_>
+ | ^^ `'_` is a reserved lifetime name
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0637`.
diff --git a/src/test/ui/underscore-lifetime/where-clause-trait-impl-underscore.rust2018.stderr b/src/test/ui/underscore-lifetime/where-clause-trait-impl-underscore.rust2018.stderr
new file mode 100644
index 000000000..92caff0dc
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/where-clause-trait-impl-underscore.rust2018.stderr
@@ -0,0 +1,9 @@
+error[E0637]: `'_` cannot be used here
+ --> $DIR/where-clause-trait-impl-underscore.rs:11:19
+ |
+LL | T: WithRegion<'_>
+ | ^^ `'_` is a reserved lifetime name
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0637`.
diff --git a/src/test/ui/underscore-lifetime/where-clauses.rs b/src/test/ui/underscore-lifetime/where-clauses.rs
new file mode 100644
index 000000000..ee6823b80
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/where-clauses.rs
@@ -0,0 +1,7 @@
+trait Foo<'a> {}
+
+impl<'b: '_> Foo<'b> for i32 {} //~ ERROR `'_` cannot be used here
+
+impl<T: '_> Foo<'static> for Vec<T> {} //~ ERROR `'_` cannot be used here
+
+fn main() { }
diff --git a/src/test/ui/underscore-lifetime/where-clauses.stderr b/src/test/ui/underscore-lifetime/where-clauses.stderr
new file mode 100644
index 000000000..1a3ea4af7
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/where-clauses.stderr
@@ -0,0 +1,15 @@
+error[E0637]: `'_` cannot be used here
+ --> $DIR/where-clauses.rs:3:10
+ |
+LL | impl<'b: '_> Foo<'b> for i32 {}
+ | ^^ `'_` is a reserved lifetime name
+
+error[E0637]: `'_` cannot be used here
+ --> $DIR/where-clauses.rs:5:9
+ |
+LL | impl<T: '_> Foo<'static> for Vec<T> {}
+ | ^^ `'_` is a reserved lifetime name
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0637`.