about summary refs log tree commit diff
path: root/src/test/ui/compile-fail-migration/impl-trait
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui/compile-fail-migration/impl-trait')
-rw-r--r--src/test/ui/compile-fail-migration/impl-trait/impl-generic-mismatch-ab.rs22
-rw-r--r--src/test/ui/compile-fail-migration/impl-trait/impl-generic-mismatch-ab.stderr15
-rw-r--r--src/test/ui/compile-fail-migration/impl-trait/infinite-impl-trait-issue-38064.rs37
-rw-r--r--src/test/ui/compile-fail-migration/impl-trait/infinite-impl-trait-issue-38064.stderr7
-rw-r--r--src/test/ui/compile-fail-migration/impl-trait/must_outlive_least_region_or_bound.nll.stderr73
-rw-r--r--src/test/ui/compile-fail-migration/impl-trait/must_outlive_least_region_or_bound.rs37
-rw-r--r--src/test/ui/compile-fail-migration/impl-trait/must_outlive_least_region_or_bound.stderr71
-rw-r--r--src/test/ui/compile-fail-migration/impl-trait/needs_least_region_or_bound.rs21
-rw-r--r--src/test/ui/compile-fail-migration/impl-trait/needs_least_region_or_bound.stderr8
-rw-r--r--src/test/ui/compile-fail-migration/impl-trait/no-trait.rs13
-rw-r--r--src/test/ui/compile-fail-migration/impl-trait/no-trait.stderr8
-rw-r--r--src/test/ui/compile-fail-migration/impl-trait/type_parameters_captured.nll.stderr17
-rw-r--r--src/test/ui/compile-fail-migration/impl-trait/type_parameters_captured.rs22
-rw-r--r--src/test/ui/compile-fail-migration/impl-trait/type_parameters_captured.stderr17
-rw-r--r--src/test/ui/compile-fail-migration/impl-trait/where-allowed.rs235
-rw-r--r--src/test/ui/compile-fail-migration/impl-trait/where-allowed.stderr244
16 files changed, 847 insertions, 0 deletions
diff --git a/src/test/ui/compile-fail-migration/impl-trait/impl-generic-mismatch-ab.rs b/src/test/ui/compile-fail-migration/impl-trait/impl-generic-mismatch-ab.rs
new file mode 100644
index 00000000000..23549918ff1
--- /dev/null
+++ b/src/test/ui/compile-fail-migration/impl-trait/impl-generic-mismatch-ab.rs
@@ -0,0 +1,22 @@
+// Copyright 2017 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.
+
+use std::fmt::Debug;
+
+trait Foo {
+    fn foo<A: Debug>(&self, a: &A, b: &impl Debug);
+}
+
+impl Foo for () {
+    fn foo<B: Debug>(&self, a: &impl Debug, b: &B) { }
+    //~^ ERROR method `foo` has an incompatible type for trait
+}
+
+fn main() {}
diff --git a/src/test/ui/compile-fail-migration/impl-trait/impl-generic-mismatch-ab.stderr b/src/test/ui/compile-fail-migration/impl-trait/impl-generic-mismatch-ab.stderr
new file mode 100644
index 00000000000..77ecdf2f5ac
--- /dev/null
+++ b/src/test/ui/compile-fail-migration/impl-trait/impl-generic-mismatch-ab.stderr
@@ -0,0 +1,15 @@
+error[E0053]: method `foo` has an incompatible type for trait
+  --> $DIR/impl-generic-mismatch-ab.rs:18:32
+   |
+LL |     fn foo<A: Debug>(&self, a: &A, b: &impl Debug);
+   |                                -- type in trait
+...
+LL |     fn foo<B: Debug>(&self, a: &impl Debug, b: &B) { }
+   |                                ^^^^^^^^^^^ expected type parameter, found a different type parameter
+   |
+   = note: expected type `fn(&(), &B, &impl Debug)`
+              found type `fn(&(), &impl Debug, &B)`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0053`.
diff --git a/src/test/ui/compile-fail-migration/impl-trait/infinite-impl-trait-issue-38064.rs b/src/test/ui/compile-fail-migration/impl-trait/infinite-impl-trait-issue-38064.rs
new file mode 100644
index 00000000000..653ef1723e0
--- /dev/null
+++ b/src/test/ui/compile-fail-migration/impl-trait/infinite-impl-trait-issue-38064.rs
@@ -0,0 +1,37 @@
+// Copyright 2016 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.
+
+// Test that attempts to construct infinite types via impl trait fail
+// in a graceful way.
+//
+// Regression test for #38064.
+
+// error-pattern:overflow evaluating the requirement `impl Quux`
+
+trait Quux {}
+
+fn foo() -> impl Quux {
+    struct Foo<T>(T);
+    impl<T> Quux for Foo<T> {}
+    Foo(bar())
+}
+
+fn bar() -> impl Quux {
+    struct Bar<T>(T);
+    impl<T> Quux for Bar<T> {}
+    Bar(foo())
+}
+
+// effectively:
+//     struct Foo(Bar);
+//     struct Bar(Foo);
+// should produce an error about infinite size
+
+fn main() { foo(); }
diff --git a/src/test/ui/compile-fail-migration/impl-trait/infinite-impl-trait-issue-38064.stderr b/src/test/ui/compile-fail-migration/impl-trait/infinite-impl-trait-issue-38064.stderr
new file mode 100644
index 00000000000..f260cce647b
--- /dev/null
+++ b/src/test/ui/compile-fail-migration/impl-trait/infinite-impl-trait-issue-38064.stderr
@@ -0,0 +1,7 @@
+error[E0275]: overflow evaluating the requirement `impl Quux`
+   |
+   = help: consider adding a `#![recursion_limit="128"]` attribute to your crate
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/src/test/ui/compile-fail-migration/impl-trait/must_outlive_least_region_or_bound.nll.stderr b/src/test/ui/compile-fail-migration/impl-trait/must_outlive_least_region_or_bound.nll.stderr
new file mode 100644
index 00000000000..6d581952ac9
--- /dev/null
+++ b/src/test/ui/compile-fail-migration/impl-trait/must_outlive_least_region_or_bound.nll.stderr
@@ -0,0 +1,73 @@
+warning: not reporting region error due to nll
+  --> $DIR/must_outlive_least_region_or_bound.rs:13:35
+   |
+LL | fn elided(x: &i32) -> impl Copy { x }
+   |                                   ^
+
+warning: not reporting region error due to nll
+  --> $DIR/must_outlive_least_region_or_bound.rs:16:44
+   |
+LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x }
+   |                                            ^
+
+warning: not reporting region error due to nll
+  --> $DIR/must_outlive_least_region_or_bound.rs:22:69
+   |
+LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
+   |                                                                     ^
+
+warning: not reporting region error due to nll
+  --> $DIR/must_outlive_least_region_or_bound.rs:29:5
+   |
+LL |     move |_| println!("{}", y)
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: not reporting region error due to nll
+  --> $DIR/must_outlive_least_region_or_bound.rs:32:51
+   |
+LL | fn ty_param_wont_outlive_static<T:Debug>(x: T) -> impl Debug + 'static {
+   |                                                   ^^^^^^^^^^^^^^^^^^^^
+
+error[E0621]: explicit lifetime required in the type of `x`
+  --> $DIR/must_outlive_least_region_or_bound.rs:13:35
+   |
+LL | fn elided(x: &i32) -> impl Copy { x }
+   |              ----                 ^ lifetime `'static` required
+   |              |
+   |              help: add explicit lifetime `'static` to the type of `x`: `&'static i32`
+
+error: unsatisfied lifetime constraints
+  --> $DIR/must_outlive_least_region_or_bound.rs:16:44
+   |
+LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x }
+   |             -- lifetime `'a` defined here  ^ return requires that `'a` must outlive `'static`
+
+error: unsatisfied lifetime constraints
+  --> $DIR/must_outlive_least_region_or_bound.rs:22:69
+   |
+LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
+   |               -- lifetime `'a` defined here                         ^ return requires that `'a` must outlive `'static`
+
+error: unsatisfied lifetime constraints
+  --> $DIR/must_outlive_least_region_or_bound.rs:29:5
+   |
+LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) {
+   |                          --  -- lifetime `'b` defined here
+   |                          |
+   |                          lifetime `'a` defined here
+LL |     //~^ ERROR lifetime mismatch
+LL |     move |_| println!("{}", y)
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+
+error[E0310]: the parameter type `T` may not live long enough
+  --> $DIR/must_outlive_least_region_or_bound.rs:34:5
+   |
+LL |     x
+   |     ^
+   |
+   = help: consider adding an explicit lifetime bound `T: 'static`...
+
+error: aborting due to 5 previous errors
+
+Some errors occurred: E0310, E0621.
+For more information about an error, try `rustc --explain E0310`.
diff --git a/src/test/ui/compile-fail-migration/impl-trait/must_outlive_least_region_or_bound.rs b/src/test/ui/compile-fail-migration/impl-trait/must_outlive_least_region_or_bound.rs
new file mode 100644
index 00000000000..537fc975bcf
--- /dev/null
+++ b/src/test/ui/compile-fail-migration/impl-trait/must_outlive_least_region_or_bound.rs
@@ -0,0 +1,37 @@
+// Copyright 2017 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.
+
+use std::fmt::Debug;
+
+fn elided(x: &i32) -> impl Copy { x }
+//~^ ERROR explicit lifetime required in the type of `x` [E0621]
+
+fn explicit<'a>(x: &'a i32) -> impl Copy { x }
+//~^ ERROR cannot infer an appropriate lifetime
+
+trait LifetimeTrait<'a> {}
+impl<'a> LifetimeTrait<'a> for &'a i32 {}
+
+fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
+//~^ ERROR cannot infer an appropriate lifetime
+
+// Tests that a closure type contianing 'b cannot be returned from a type where
+// only 'a was expected.
+fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) {
+    //~^ ERROR lifetime mismatch
+    move |_| println!("{}", y)
+}
+
+fn ty_param_wont_outlive_static<T:Debug>(x: T) -> impl Debug + 'static {
+    //~^ ERROR the parameter type `T` may not live long enough
+    x
+}
+
+fn main() {}
diff --git a/src/test/ui/compile-fail-migration/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/compile-fail-migration/impl-trait/must_outlive_least_region_or_bound.stderr
new file mode 100644
index 00000000000..48686cbcaf2
--- /dev/null
+++ b/src/test/ui/compile-fail-migration/impl-trait/must_outlive_least_region_or_bound.stderr
@@ -0,0 +1,71 @@
+error[E0621]: explicit lifetime required in the type of `x`
+  --> $DIR/must_outlive_least_region_or_bound.rs:13:23
+   |
+LL | fn elided(x: &i32) -> impl Copy { x }
+   |              ----     ^^^^^^^^^ lifetime `'static` required
+   |              |
+   |              help: add explicit lifetime `'static` to the type of `x`: `&'static i32`
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/must_outlive_least_region_or_bound.rs:16:44
+   |
+LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x }
+   |                                ---------   ^ ...but this borrow...
+   |                                |
+   |                                this return type evaluates to the `'static` lifetime...
+   |
+note: ...can't outlive the lifetime 'a as defined on the function body at 16:13
+  --> $DIR/must_outlive_least_region_or_bound.rs:16:13
+   |
+LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x }
+   |             ^^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime 'a as defined on the function body at 16:13
+   |
+LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x }
+   |                                ^^^^^^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/must_outlive_least_region_or_bound.rs:22:69
+   |
+LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
+   |                                  --------------------------------   ^ ...but this borrow...
+   |                                  |
+   |                                  this return type evaluates to the `'static` lifetime...
+   |
+note: ...can't outlive the lifetime 'a as defined on the function body at 22:15
+  --> $DIR/must_outlive_least_region_or_bound.rs:22:15
+   |
+LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
+   |               ^^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime 'a as defined on the function body at 22:15
+   |
+LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static + 'a { x }
+   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0623]: lifetime mismatch
+  --> $DIR/must_outlive_least_region_or_bound.rs:27:61
+   |
+LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) {
+   |                                                 -------     ^^^^^^^^^^^^^^^^
+   |                                                 |           |
+   |                                                 |           ...but data from `y` is returned here
+   |                                                 this parameter and the return type are declared with different lifetimes...
+
+error[E0310]: the parameter type `T` may not live long enough
+  --> $DIR/must_outlive_least_region_or_bound.rs:32:51
+   |
+LL | fn ty_param_wont_outlive_static<T:Debug>(x: T) -> impl Debug + 'static {
+   |                                 --                ^^^^^^^^^^^^^^^^^^^^
+   |                                 |
+   |                                 help: consider adding an explicit lifetime bound `T: 'static`...
+   |
+note: ...so that the type `T` will meet its required lifetime bounds
+  --> $DIR/must_outlive_least_region_or_bound.rs:32:51
+   |
+LL | fn ty_param_wont_outlive_static<T:Debug>(x: T) -> impl Debug + 'static {
+   |                                                   ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 5 previous errors
+
+Some errors occurred: E0310, E0621, E0623.
+For more information about an error, try `rustc --explain E0310`.
diff --git a/src/test/ui/compile-fail-migration/impl-trait/needs_least_region_or_bound.rs b/src/test/ui/compile-fail-migration/impl-trait/needs_least_region_or_bound.rs
new file mode 100644
index 00000000000..6c0a0b800ce
--- /dev/null
+++ b/src/test/ui/compile-fail-migration/impl-trait/needs_least_region_or_bound.rs
@@ -0,0 +1,21 @@
+// Copyright 2017 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.
+
+use std::fmt::Debug;
+
+trait MultiRegionTrait<'a, 'b> {}
+impl<'a, 'b> MultiRegionTrait<'a, 'b> for (&'a u32, &'b u32) {}
+
+fn no_least_region<'a, 'b>(x: &'a u32, y: &'b u32) -> impl MultiRegionTrait<'a, 'b> {
+//~^ ERROR ambiguous lifetime bound
+    (x, y)
+}
+
+fn main() {}
diff --git a/src/test/ui/compile-fail-migration/impl-trait/needs_least_region_or_bound.stderr b/src/test/ui/compile-fail-migration/impl-trait/needs_least_region_or_bound.stderr
new file mode 100644
index 00000000000..fd2665dc762
--- /dev/null
+++ b/src/test/ui/compile-fail-migration/impl-trait/needs_least_region_or_bound.stderr
@@ -0,0 +1,8 @@
+error: ambiguous lifetime bound in `impl Trait`
+  --> $DIR/needs_least_region_or_bound.rs:16:55
+   |
+LL | fn no_least_region<'a, 'b>(x: &'a u32, y: &'b u32) -> impl MultiRegionTrait<'a, 'b> {
+   |                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ neither `'a` nor `'b` outlives the other
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/compile-fail-migration/impl-trait/no-trait.rs b/src/test/ui/compile-fail-migration/impl-trait/no-trait.rs
new file mode 100644
index 00000000000..5299ba297d0
--- /dev/null
+++ b/src/test/ui/compile-fail-migration/impl-trait/no-trait.rs
@@ -0,0 +1,13 @@
+// Copyright 2017 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.
+
+fn f() -> impl 'static {} //~ ERROR at least one trait must be specified
+
+fn main() {}
diff --git a/src/test/ui/compile-fail-migration/impl-trait/no-trait.stderr b/src/test/ui/compile-fail-migration/impl-trait/no-trait.stderr
new file mode 100644
index 00000000000..fdd01c87d1c
--- /dev/null
+++ b/src/test/ui/compile-fail-migration/impl-trait/no-trait.stderr
@@ -0,0 +1,8 @@
+error: at least one trait must be specified
+  --> $DIR/no-trait.rs:11:11
+   |
+LL | fn f() -> impl 'static {} //~ ERROR at least one trait must be specified
+   |           ^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/compile-fail-migration/impl-trait/type_parameters_captured.nll.stderr b/src/test/ui/compile-fail-migration/impl-trait/type_parameters_captured.nll.stderr
new file mode 100644
index 00000000000..823ee446729
--- /dev/null
+++ b/src/test/ui/compile-fail-migration/impl-trait/type_parameters_captured.nll.stderr
@@ -0,0 +1,17 @@
+warning: not reporting region error due to nll
+  --> $DIR/type_parameters_captured.rs:17:20
+   |
+LL | fn foo<T>(x: T) -> impl Any + 'static {
+   |                    ^^^^^^^^^^^^^^^^^^
+
+error[E0310]: the parameter type `T` may not live long enough
+  --> $DIR/type_parameters_captured.rs:19:5
+   |
+LL |     x
+   |     ^
+   |
+   = help: consider adding an explicit lifetime bound `T: 'static`...
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0310`.
diff --git a/src/test/ui/compile-fail-migration/impl-trait/type_parameters_captured.rs b/src/test/ui/compile-fail-migration/impl-trait/type_parameters_captured.rs
new file mode 100644
index 00000000000..7c3430ab90e
--- /dev/null
+++ b/src/test/ui/compile-fail-migration/impl-trait/type_parameters_captured.rs
@@ -0,0 +1,22 @@
+// Copyright 2017 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.
+
+use std::fmt::Debug;
+
+trait Any {}
+impl<T> Any for T {}
+
+// Check that type parameters are captured and not considered 'static
+fn foo<T>(x: T) -> impl Any + 'static {
+    //~^ ERROR the parameter type `T` may not live long enough
+    x
+}
+
+fn main() {}
diff --git a/src/test/ui/compile-fail-migration/impl-trait/type_parameters_captured.stderr b/src/test/ui/compile-fail-migration/impl-trait/type_parameters_captured.stderr
new file mode 100644
index 00000000000..3b9b0e08a45
--- /dev/null
+++ b/src/test/ui/compile-fail-migration/impl-trait/type_parameters_captured.stderr
@@ -0,0 +1,17 @@
+error[E0310]: the parameter type `T` may not live long enough
+  --> $DIR/type_parameters_captured.rs:17:20
+   |
+LL | fn foo<T>(x: T) -> impl Any + 'static {
+   |        -           ^^^^^^^^^^^^^^^^^^
+   |        |
+   |        help: consider adding an explicit lifetime bound `T: 'static`...
+   |
+note: ...so that the type `T` will meet its required lifetime bounds
+  --> $DIR/type_parameters_captured.rs:17:20
+   |
+LL | fn foo<T>(x: T) -> impl Any + 'static {
+   |                    ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0310`.
diff --git a/src/test/ui/compile-fail-migration/impl-trait/where-allowed.rs b/src/test/ui/compile-fail-migration/impl-trait/where-allowed.rs
new file mode 100644
index 00000000000..2891cd59e3e
--- /dev/null
+++ b/src/test/ui/compile-fail-migration/impl-trait/where-allowed.rs
@@ -0,0 +1,235 @@
+// Copyright 2017 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.
+
+//! A simple test for testing many permutations of allowedness of
+//! impl Trait
+use std::fmt::Debug;
+
+// Allowed
+fn in_parameters(_: impl Debug) { panic!() }
+
+// Allowed
+fn in_return() -> impl Debug { panic!() }
+
+// Allowed
+fn in_adt_in_parameters(_: Vec<impl Debug>) { panic!() }
+
+// Allowed
+fn in_adt_in_return() -> Vec<impl Debug> { panic!() }
+
+// Disallowed
+fn in_fn_parameter_in_parameters(_: fn(impl Debug)) { panic!() }
+//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+
+// Disallowed
+fn in_fn_return_in_parameters(_: fn() -> impl Debug) { panic!() }
+//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+
+// Disallowed
+fn in_fn_parameter_in_return() -> fn(impl Debug) { panic!() }
+//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+
+// Disallowed
+fn in_fn_return_in_return() -> fn() -> impl Debug { panic!() }
+//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+
+// Disallowed
+fn in_dyn_Fn_parameter_in_parameters(_: &dyn Fn(impl Debug)) { panic!() }
+//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+
+// Disallowed
+fn in_dyn_Fn_return_in_parameters(_: &dyn Fn() -> impl Debug) { panic!() }
+//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+
+// Disallowed
+fn in_dyn_Fn_parameter_in_return() -> &'static dyn Fn(impl Debug) { panic!() }
+//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+
+// Disallowed
+fn in_dyn_Fn_return_in_return() -> &'static dyn Fn() -> impl Debug { panic!() }
+//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+
+// Disallowed
+fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() }
+//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^^ ERROR nested `impl Trait` is not allowed
+
+// Disallowed
+fn in_impl_Fn_return_in_parameters(_: &impl Fn() -> impl Debug) { panic!() }
+//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+
+// Disallowed
+fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() }
+//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^^ ERROR nested `impl Trait` is not allowed
+
+// Disallowed
+fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { panic!() }
+//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+
+// Disallowed
+fn in_Fn_parameter_in_generics<F: Fn(impl Debug)> (_: F) { panic!() }
+//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+
+// Disallowed
+fn in_Fn_return_in_generics<F: Fn() -> impl Debug> (_: F) { panic!() }
+//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+
+
+// Allowed
+fn in_impl_Trait_in_parameters(_: impl Iterator<Item = impl Iterator>) { panic!() }
+
+// Allowed
+fn in_impl_Trait_in_return() -> impl IntoIterator<Item = impl IntoIterator> {
+    vec![vec![0; 10], vec![12; 7], vec![8; 3]]
+}
+
+// Disallowed
+struct InBraceStructField { x: impl Debug }
+//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+
+// Disallowed
+struct InAdtInBraceStructField { x: Vec<impl Debug> }
+//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+
+// Disallowed
+struct InTupleStructField(impl Debug);
+//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+
+// Disallowed
+enum InEnum {
+    InBraceVariant { x: impl Debug },
+    //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+    InTupleVariant(impl Debug),
+    //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+}
+
+// Allowed
+trait InTraitDefnParameters {
+    fn in_parameters(_: impl Debug);
+}
+
+// Disallowed
+trait InTraitDefnReturn {
+    fn in_return() -> impl Debug;
+    //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+}
+
+// Allowed and disallowed in trait impls
+trait DummyTrait {
+    type Out;
+    fn in_trait_impl_parameter(impl Debug);
+    fn in_trait_impl_return() -> Self::Out;
+}
+impl DummyTrait for () {
+    type Out = impl Debug;
+    //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+
+    fn in_trait_impl_parameter(_: impl Debug) { }
+    // Allowed
+
+    fn in_trait_impl_return() -> impl Debug { () }
+    //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+}
+
+// Allowed
+struct DummyType;
+impl DummyType {
+    fn in_inherent_impl_parameters(_: impl Debug) { }
+    fn in_inherent_impl_return() -> impl Debug { () }
+}
+
+// Disallowed
+extern "C" {
+    fn in_foreign_parameters(_: impl Debug);
+    //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+
+    fn in_foreign_return() -> impl Debug;
+    //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+}
+
+// Allowed
+extern "C" fn in_extern_fn_parameters(_: impl Debug) {
+}
+
+// Allowed
+extern "C" fn in_extern_fn_return() -> impl Debug {
+    22
+}
+
+type InTypeAlias<R> = impl Debug;
+//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+
+type InReturnInTypeAlias<R> = fn() -> impl Debug;
+//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+
+// Disallowed in impl headers
+impl PartialEq<impl Debug> for () {
+    //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+}
+
+// Disallowed in impl headers
+impl PartialEq<()> for impl Debug {
+    //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+}
+
+// Disallowed in inherent impls
+impl impl Debug {
+    //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+}
+
+// Disallowed in inherent impls
+struct InInherentImplAdt<T> { t: T }
+impl InInherentImplAdt<impl Debug> {
+    //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+}
+
+// Disallowed in where clauses
+fn in_fn_where_clause()
+    where impl Debug: Debug
+//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+{
+}
+
+// Disallowed in where clauses
+fn in_adt_in_fn_where_clause()
+    where Vec<impl Debug>: Debug
+//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+{
+}
+
+// Disallowed
+fn in_trait_parameter_in_fn_where_clause<T>()
+    where T: PartialEq<impl Debug>
+//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+{
+}
+
+// Disallowed
+fn in_Fn_parameter_in_fn_where_clause<T>()
+    where T: Fn(impl Debug)
+//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+{
+}
+
+// Disallowed
+fn in_Fn_return_in_fn_where_clause<T>()
+    where T: Fn() -> impl Debug
+//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+{
+}
+
+fn main() {
+    let _in_local_variable: impl Fn() = || {};
+    //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+    let _in_return_in_local_variable = || -> impl Fn() { || {} };
+    //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+}
+
diff --git a/src/test/ui/compile-fail-migration/impl-trait/where-allowed.stderr b/src/test/ui/compile-fail-migration/impl-trait/where-allowed.stderr
new file mode 100644
index 00000000000..b15893e7c28
--- /dev/null
+++ b/src/test/ui/compile-fail-migration/impl-trait/where-allowed.stderr
@@ -0,0 +1,244 @@
+error[E0666]: nested `impl Trait` is not allowed
+  --> $DIR/where-allowed.rs:60:51
+   |
+LL | fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() }
+   |                                           --------^^^^^^^^^^-
+   |                                           |       |
+   |                                           |       nested `impl Trait` here
+   |                                           outer `impl Trait`
+
+error[E0666]: nested `impl Trait` is not allowed
+  --> $DIR/where-allowed.rs:69:57
+   |
+LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() }
+   |                                                 --------^^^^^^^^^^-
+   |                                                 |       |
+   |                                                 |       nested `impl Trait` here
+   |                                                 outer `impl Trait`
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:28:40
+   |
+LL | fn in_fn_parameter_in_parameters(_: fn(impl Debug)) { panic!() }
+   |                                        ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:32:42
+   |
+LL | fn in_fn_return_in_parameters(_: fn() -> impl Debug) { panic!() }
+   |                                          ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:36:38
+   |
+LL | fn in_fn_parameter_in_return() -> fn(impl Debug) { panic!() }
+   |                                      ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:40:40
+   |
+LL | fn in_fn_return_in_return() -> fn() -> impl Debug { panic!() }
+   |                                        ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:44:49
+   |
+LL | fn in_dyn_Fn_parameter_in_parameters(_: &dyn Fn(impl Debug)) { panic!() }
+   |                                                 ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:48:51
+   |
+LL | fn in_dyn_Fn_return_in_parameters(_: &dyn Fn() -> impl Debug) { panic!() }
+   |                                                   ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:52:55
+   |
+LL | fn in_dyn_Fn_parameter_in_return() -> &'static dyn Fn(impl Debug) { panic!() }
+   |                                                       ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:56:57
+   |
+LL | fn in_dyn_Fn_return_in_return() -> &'static dyn Fn() -> impl Debug { panic!() }
+   |                                                         ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:60:51
+   |
+LL | fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() }
+   |                                                   ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:65:53
+   |
+LL | fn in_impl_Fn_return_in_parameters(_: &impl Fn() -> impl Debug) { panic!() }
+   |                                                     ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:69:57
+   |
+LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() }
+   |                                                         ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:74:59
+   |
+LL | fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { panic!() }
+   |                                                           ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:78:38
+   |
+LL | fn in_Fn_parameter_in_generics<F: Fn(impl Debug)> (_: F) { panic!() }
+   |                                      ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:82:40
+   |
+LL | fn in_Fn_return_in_generics<F: Fn() -> impl Debug> (_: F) { panic!() }
+   |                                        ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:95:32
+   |
+LL | struct InBraceStructField { x: impl Debug }
+   |                                ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:99:41
+   |
+LL | struct InAdtInBraceStructField { x: Vec<impl Debug> }
+   |                                         ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:103:27
+   |
+LL | struct InTupleStructField(impl Debug);
+   |                           ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:108:25
+   |
+LL |     InBraceVariant { x: impl Debug },
+   |                         ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:110:20
+   |
+LL |     InTupleVariant(impl Debug),
+   |                    ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:121:23
+   |
+LL |     fn in_return() -> impl Debug;
+   |                       ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:132:16
+   |
+LL |     type Out = impl Debug;
+   |                ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:138:34
+   |
+LL |     fn in_trait_impl_return() -> impl Debug { () }
+   |                                  ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:151:33
+   |
+LL |     fn in_foreign_parameters(_: impl Debug);
+   |                                 ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:154:31
+   |
+LL |     fn in_foreign_return() -> impl Debug;
+   |                               ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:167:23
+   |
+LL | type InTypeAlias<R> = impl Debug;
+   |                       ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:170:39
+   |
+LL | type InReturnInTypeAlias<R> = fn() -> impl Debug;
+   |                                       ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:174:16
+   |
+LL | impl PartialEq<impl Debug> for () {
+   |                ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:179:24
+   |
+LL | impl PartialEq<()> for impl Debug {
+   |                        ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:184:6
+   |
+LL | impl impl Debug {
+   |      ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:190:24
+   |
+LL | impl InInherentImplAdt<impl Debug> {
+   |                        ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:196:11
+   |
+LL |     where impl Debug: Debug
+   |           ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:203:15
+   |
+LL |     where Vec<impl Debug>: Debug
+   |               ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:210:24
+   |
+LL |     where T: PartialEq<impl Debug>
+   |                        ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:217:17
+   |
+LL |     where T: Fn(impl Debug)
+   |                 ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:224:22
+   |
+LL |     where T: Fn() -> impl Debug
+   |                      ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:230:29
+   |
+LL |     let _in_local_variable: impl Fn() = || {};
+   |                             ^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/where-allowed.rs:232:46
+   |
+LL |     let _in_return_in_local_variable = || -> impl Fn() { || {} };
+   |                                              ^^^^^^^^^
+
+error: aborting due to 39 previous errors
+
+Some errors occurred: E0562, E0666.
+For more information about an error, try `rustc --explain E0562`.