about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-10-19 22:54:14 +0000
committerbors <bors@rust-lang.org>2018-10-19 22:54:14 +0000
commit42dde960f95222ffd8c356e0f7841cd22294a6c9 (patch)
tree315f1c52471fc775ee057c987a0c5d69f20a4b05 /src/test
parent78ff609d7375ee2a2c6d0222776ac612eb1b75be (diff)
parentc294ec640be6b4cdd3b4922a622a6c12f6078b1d (diff)
Auto merge of #55162 - nikomatsakis:issue-54902-underscore-bound, r=tmandry
handle underscore bounds in unexpected places

Per the discussion on #54902, I made it a hard error to use lifetime bounds in various places where they used to be permitted:

- `where Foo: Bar<'_>` for example

I also moved error reporting to HIR lowering and added `Error` variants to let us suppress downstream errors that result.

I (imo) improved the error message wording to be clearer, as well.

In the process, I fixed the ICE in #52098.

Fixes #54902
Fixes #52098
Diffstat (limited to 'src/test')
-rw-r--r--src/test/ui/error-codes/E0637.rs6
-rw-r--r--src/test/ui/error-codes/E0637.stderr12
-rw-r--r--src/test/ui/underscore-lifetime/in-binder.Rust2015.stderr46
-rw-r--r--src/test/ui/underscore-lifetime/in-binder.Rust2018.stderr39
-rw-r--r--src/test/ui/underscore-lifetime/in-binder.rs45
-rw-r--r--src/test/ui/underscore-lifetime/in-fn-return-illegal.rs17
-rw-r--r--src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr11
-rw-r--r--src/test/ui/underscore-lifetime/in-struct.rs23
-rw-r--r--src/test/ui/underscore-lifetime/in-struct.stderr15
-rw-r--r--src/test/ui/underscore-lifetime/underscore-lifetime-binders.rs4
-rw-r--r--src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr28
-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.rs18
-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.rs16
-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.rs16
-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
27 files changed, 400 insertions, 25 deletions
diff --git a/src/test/ui/error-codes/E0637.rs b/src/test/ui/error-codes/E0637.rs
index ee6a978d169..b4f769a749f 100644
--- a/src/test/ui/error-codes/E0637.rs
+++ b/src/test/ui/error-codes/E0637.rs
@@ -8,11 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Foo<'a: '_>(&'a u8); //~ ERROR invalid lifetime bound name: `'_`
-fn foo<'a: '_>(_: &'a u8) {} //~ ERROR invalid lifetime bound name: `'_`
+struct Foo<'a: '_>(&'a u8); //~ ERROR cannot be used here
+fn foo<'a: '_>(_: &'a u8) {} //~ ERROR cannot be used here
 
 struct Bar<'a>(&'a u8);
-impl<'a: '_> Bar<'a> { //~ ERROR invalid lifetime bound name: `'_`
+impl<'a: '_> Bar<'a> { //~ ERROR cannot be used here
   fn bar() {}
 }
 
diff --git a/src/test/ui/error-codes/E0637.stderr b/src/test/ui/error-codes/E0637.stderr
index 245729376df..2a4545fc43d 100644
--- a/src/test/ui/error-codes/E0637.stderr
+++ b/src/test/ui/error-codes/E0637.stderr
@@ -1,19 +1,19 @@
-error[E0637]: invalid lifetime bound name: `'_`
+error[E0637]: `'_` cannot be used here
   --> $DIR/E0637.rs:11:16
    |
-LL | struct Foo<'a: '_>(&'a u8); //~ ERROR invalid lifetime bound name: `'_`
+LL | struct Foo<'a: '_>(&'a u8); //~ ERROR cannot be used here
    |                ^^ `'_` is a reserved lifetime name
 
-error[E0637]: invalid lifetime bound name: `'_`
+error[E0637]: `'_` cannot be used here
   --> $DIR/E0637.rs:12:12
    |
-LL | fn foo<'a: '_>(_: &'a u8) {} //~ ERROR invalid lifetime bound name: `'_`
+LL | fn foo<'a: '_>(_: &'a u8) {} //~ ERROR cannot be used here
    |            ^^ `'_` is a reserved lifetime name
 
-error[E0637]: invalid lifetime bound name: `'_`
+error[E0637]: `'_` cannot be used here
   --> $DIR/E0637.rs:15:10
    |
-LL | impl<'a: '_> Bar<'a> { //~ ERROR invalid lifetime bound name: `'_`
+LL | impl<'a: '_> Bar<'a> { //~ ERROR cannot be used here
    |          ^^ `'_` is a reserved lifetime name
 
 error: aborting due to 3 previous errors
diff --git a/src/test/ui/underscore-lifetime/in-binder.Rust2015.stderr b/src/test/ui/underscore-lifetime/in-binder.Rust2015.stderr
new file mode 100644
index 00000000000..a851e6b2071
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/in-binder.Rust2015.stderr
@@ -0,0 +1,46 @@
+error[E0637]: `'_` cannot be used here
+  --> $DIR/in-binder.rs:12:6
+   |
+LL | impl<'_> IceCube<'_> {}
+   |      ^^ `'_` is a reserved lifetime name
+
+error[E0637]: `'_` cannot be used here
+  --> $DIR/in-binder.rs:17:15
+   |
+LL | struct Struct<'_> {
+   |               ^^ `'_` is a reserved lifetime name
+
+error[E0637]: `'_` cannot be used here
+  --> $DIR/in-binder.rs:23:11
+   |
+LL | enum Enum<'_> {
+   |           ^^ `'_` is a reserved lifetime name
+
+error[E0637]: `'_` cannot be used here
+  --> $DIR/in-binder.rs:29:13
+   |
+LL | union Union<'_> {
+   |             ^^ `'_` is a reserved lifetime name
+
+error[E0637]: `'_` cannot be used here
+  --> $DIR/in-binder.rs:35:13
+   |
+LL | trait Trait<'_> {
+   |             ^^ `'_` is a reserved lifetime name
+
+error[E0637]: `'_` cannot be used here
+  --> $DIR/in-binder.rs:40:8
+   |
+LL | fn foo<'_>() {
+   |        ^^ `'_` is a reserved lifetime name
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/in-binder.rs:12:18
+   |
+LL | impl<'_> IceCube<'_> {}
+   |                  ^^ expected lifetime parameter
+
+error: aborting due to 7 previous errors
+
+Some errors occurred: E0106, E0637.
+For more information about an error, try `rustc --explain E0106`.
diff --git a/src/test/ui/underscore-lifetime/in-binder.Rust2018.stderr b/src/test/ui/underscore-lifetime/in-binder.Rust2018.stderr
new file mode 100644
index 00000000000..77da3038724
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/in-binder.Rust2018.stderr
@@ -0,0 +1,39 @@
+error[E0637]: `'_` cannot be used here
+  --> $DIR/in-binder.rs:12:6
+   |
+LL | impl<'_> IceCube<'_> {}
+   |      ^^ `'_` is a reserved lifetime name
+
+error[E0637]: `'_` cannot be used here
+  --> $DIR/in-binder.rs:17:15
+   |
+LL | struct Struct<'_> {
+   |               ^^ `'_` is a reserved lifetime name
+
+error[E0637]: `'_` cannot be used here
+  --> $DIR/in-binder.rs:23:11
+   |
+LL | enum Enum<'_> {
+   |           ^^ `'_` is a reserved lifetime name
+
+error[E0637]: `'_` cannot be used here
+  --> $DIR/in-binder.rs:29:13
+   |
+LL | union Union<'_> {
+   |             ^^ `'_` is a reserved lifetime name
+
+error[E0637]: `'_` cannot be used here
+  --> $DIR/in-binder.rs:35:13
+   |
+LL | trait Trait<'_> {
+   |             ^^ `'_` is a reserved lifetime name
+
+error[E0637]: `'_` cannot be used here
+  --> $DIR/in-binder.rs:40: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-binder.rs b/src/test/ui/underscore-lifetime/in-binder.rs
new file mode 100644
index 00000000000..c94947d1eab
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/in-binder.rs
@@ -0,0 +1,45 @@
+// Check that we error when `'_` appears as the name of a lifetime parameter.
+//
+// Regression test for #52098.
+
+// revisions: Rust2015 Rust2018
+//[Rust2018] edition:2018
+
+struct IceCube<'a> {
+    v: Vec<&'a char>
+}
+
+impl<'_> IceCube<'_> {}
+//[Rust2015]~^ ERROR `'_` cannot be used here
+//[Rust2015]~| ERROR missing lifetime specifier
+//[Rust2018]~^^^ ERROR `'_` cannot be used here
+
+struct Struct<'_> {
+//[Rust2015]~^ ERROR `'_` cannot be used here
+//[Rust2018]~^^ ERROR `'_` cannot be used here
+    v: Vec<&'static char>
+}
+
+enum Enum<'_> {
+//[Rust2015]~^ ERROR `'_` cannot be used here
+//[Rust2018]~^^ ERROR `'_` cannot be used here
+    Variant
+}
+
+union Union<'_> {
+//[Rust2015]~^ ERROR `'_` cannot be used here
+//[Rust2018]~^^ ERROR `'_` cannot be used here
+    a: u32
+}
+
+trait Trait<'_> {
+//[Rust2015]~^ ERROR `'_` cannot be used here
+//[Rust2018]~^^ ERROR `'_` cannot be used here
+}
+
+fn foo<'_>() {
+    //[Rust2015]~^ ERROR `'_` cannot be used here
+    //[Rust2018]~^^ ERROR `'_` cannot be used here
+}
+
+fn main() {}
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 00000000000..09f3abd9135
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/in-fn-return-illegal.rs
@@ -0,0 +1,17 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// 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 00000000000..f3ba3e52924
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr
@@ -0,0 +1,11 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/in-fn-return-illegal.rs:15:30
+   |
+LL | fn foo(x: &u32, y: &u32) -> &'_ u32 { loop { } } //~ ERROR missing lifetime specifier
+   |                              ^^ expected 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`
+
+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 00000000000..1c1a9ef62d5
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/in-struct.rs
@@ -0,0 +1,23 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// 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 00000000000..d288995d4bb
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/in-struct.stderr
@@ -0,0 +1,15 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/in-struct.rs:16:9
+   |
+LL |     x: &'_ u32, //~ ERROR missing lifetime specifier
+   |         ^^ expected lifetime parameter
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/in-struct.rs:20:14
+   |
+LL |     Variant(&'_ u32), //~ ERROR missing lifetime specifier
+   |              ^^ expected lifetime parameter
+
+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
index 6a6698957d9..2652fc62bb6 100644
--- a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.rs
+++ b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.rs
@@ -15,13 +15,13 @@ impl Foo<'_> { //~ ERROR missing lifetime specifier
     fn x() {}
 }
 
-fn foo<'_> //~ ERROR invalid lifetime parameter name: `'_`
+fn foo<'_> //~ ERROR cannot be used here
 (_: Foo<'_>) {}
 
 trait Meh<'a> {}
 impl<'a> Meh<'a> for u8 {}
 
-fn meh() -> Box<for<'_> Meh<'_>> //~ ERROR invalid lifetime parameter name: `'_`
+fn meh() -> Box<for<'_> Meh<'_>> //~ ERROR cannot be used here
 //~^ ERROR missing lifetime specifier
 {
   Box::new(5u8)
diff --git a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr
index 4917c2795e3..fc9f3e642d4 100644
--- a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr
+++ b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr
@@ -1,3 +1,15 @@
+error[E0637]: `'_` cannot be used here
+  --> $DIR/underscore-lifetime-binders.rs:18:8
+   |
+LL | fn foo<'_> //~ ERROR cannot be used here
+   |        ^^ `'_` is a reserved lifetime name
+
+error[E0637]: `'_` cannot be used here
+  --> $DIR/underscore-lifetime-binders.rs:24:21
+   |
+LL | fn meh() -> Box<for<'_> Meh<'_>> //~ ERROR cannot be used here
+   |                     ^^ `'_` is a reserved lifetime name
+
 error[E0106]: missing lifetime specifier
   --> $DIR/underscore-lifetime-binders.rs:12:17
    |
@@ -10,22 +22,10 @@ error[E0106]: missing lifetime specifier
 LL | impl Foo<'_> { //~ ERROR missing lifetime specifier
    |          ^^ expected lifetime parameter
 
-error[E0262]: invalid lifetime parameter name: `'_`
-  --> $DIR/underscore-lifetime-binders.rs:18:8
-   |
-LL | fn foo<'_> //~ ERROR invalid lifetime parameter name: `'_`
-   |        ^^ '_ is a reserved lifetime name
-
-error[E0262]: invalid lifetime parameter name: `'_`
-  --> $DIR/underscore-lifetime-binders.rs:24:21
-   |
-LL | fn meh() -> Box<for<'_> Meh<'_>> //~ ERROR invalid lifetime parameter name: `'_`
-   |                     ^^ '_ is a reserved lifetime name
-
 error[E0106]: missing lifetime specifier
   --> $DIR/underscore-lifetime-binders.rs:24:29
    |
-LL | fn meh() -> Box<for<'_> Meh<'_>> //~ ERROR invalid lifetime parameter name: `'_`
+LL | fn meh() -> Box<for<'_> Meh<'_>> //~ ERROR cannot be used here
    |                             ^^ expected lifetime parameter
    |
    = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
@@ -41,5 +41,5 @@ LL | fn foo2(_: &'_ u8, y: &'_ u8) -> &'_ u8 { y } //~ ERROR missing lifetime sp
 
 error: aborting due to 6 previous errors
 
-Some errors occurred: E0106, E0262.
+Some errors occurred: E0106, E0637.
 For more information about an error, try `rustc --explain E0106`.
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 00000000000..b514ff43860
--- /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 {}
+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 00000000000..4b38a26f957
--- /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 00000000000..43de30944ca
--- /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 00000000000..fe726cb49c7
--- /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 00000000000..fe726cb49c7
--- /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 00000000000..b50cce335bd
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/where-clause-inherent-impl-underscore.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: WithRegion<'_>
+//[rust2015]~^ ERROR `'_` cannot be used here
+//[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 00000000000..95939fd6b7e
--- /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 00000000000..95939fd6b7e
--- /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 00000000000..f2d483e66e0
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/where-clause-trait-impl-region.rs
@@ -0,0 +1,16 @@
+// 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]~^ 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-trait-impl-region.rust2015.stderr b/src/test/ui/underscore-lifetime/where-clause-trait-impl-region.rust2015.stderr
new file mode 100644
index 00000000000..fbd14de2107
--- /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 00000000000..fbd14de2107
--- /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 00000000000..94e4426e822
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/where-clause-trait-impl-underscore.rs
@@ -0,0 +1,16 @@
+// revisions: rust2015 rust2018
+//[rust2018] edition:2018
+
+trait WithType<T> {}
+trait WithRegion<'a> { }
+
+trait Foo { }
+
+impl<T> Foo for Vec<T>
+where
+    T: WithRegion<'_>
+//[rust2015]~^ ERROR `'_` cannot be used here
+//[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 00000000000..92caff0dcde
--- /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 00000000000..92caff0dcde
--- /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 00000000000..ee6823b8047
--- /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 00000000000..57fe2456f4c
--- /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 {} //~ ERROR `'_` cannot be used here
+   |          ^^ `'_` 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> {} //~ ERROR `'_` cannot be used here
+   |         ^^ `'_` is a reserved lifetime name
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0637`.