summary refs log tree commit diff
path: root/src/test/ui/impl-trait
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-11-19 13:10:17 +0100
committerGitHub <noreply@github.com>2019-11-19 13:10:17 +0100
commitee535a0f95f40513b130d7bcf0a2d77477b1b7b4 (patch)
tree4b5e021b18f4095da692f7e794d9d87749a6e8aa /src/test/ui/impl-trait
parent95b9766e0a43b4c527d3de62a781a2f5418655c6 (diff)
parenta11abe0d6b0f1a7a7bb4bdfde1dedfd89b357732 (diff)
downloadrust-ee535a0f95f40513b130d7bcf0a2d77477b1b7b4.tar.gz
rust-ee535a0f95f40513b130d7bcf0a2d77477b1b7b4.zip
Rollup merge of #66431 - Aaron1011:fix/opaque-type-infer, r=varkor
Fix 'type annotations needed' error with opaque types

Related: #66426

This commit adds handling for opaque types during inference variable
fallback. Type variables generated from the instantiation of opaque
types now fallback to the opaque type itself.

Normally, the type variable for an instantiated opaque type is either
unified with the concrete type, or with the opaque type itself (e.g when
a function returns an opaque type by calling another function).

However, it's possible for the type variable to be left completely
unconstrained. This can occur in code like this:

```rust
pub type Foo = impl Copy;
fn produce() -> Option<Foo> {
    None
}
```

Here, we'll instantatiate the `Foo` in `Option<Foo>` to a fresh type
variable, but we will never unify it with anything due to the fact
that we return a `None`.

This results in the error message:
```
type annotations needed: cannot resolve `_: std::marker::Copy
```

pointing at `pub type Foo = impl Copy`.

This message is not only confusing, it's incorrect. When an opaque type
inference variable is completely unconstrained, we can always fall back
to using the opaque type itself. This effectively turns that particular
use of the opaque type into a non-defining use, even if it appears in a
defining scope.
Diffstat (limited to 'src/test/ui/impl-trait')
-rw-r--r--src/test/ui/impl-trait/where-allowed-2.rs9
-rw-r--r--src/test/ui/impl-trait/where-allowed-2.stderr11
-rw-r--r--src/test/ui/impl-trait/where-allowed.rs5
-rw-r--r--src/test/ui/impl-trait/where-allowed.stderr102
4 files changed, 65 insertions, 62 deletions
diff --git a/src/test/ui/impl-trait/where-allowed-2.rs b/src/test/ui/impl-trait/where-allowed-2.rs
new file mode 100644
index 00000000000..f7744ef1b3e
--- /dev/null
+++ b/src/test/ui/impl-trait/where-allowed-2.rs
@@ -0,0 +1,9 @@
+//! Ideally, these tests would go in `where-allowed.rs`, but we bail out
+//! too early to display them.
+use std::fmt::Debug;
+
+// Disallowed
+fn in_adt_in_return() -> Vec<impl Debug> { panic!() }
+//~^ ERROR opaque type expands to a recursive type
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/where-allowed-2.stderr b/src/test/ui/impl-trait/where-allowed-2.stderr
new file mode 100644
index 00000000000..1de15014c1f
--- /dev/null
+++ b/src/test/ui/impl-trait/where-allowed-2.stderr
@@ -0,0 +1,11 @@
+error[E0720]: opaque type expands to a recursive type
+  --> $DIR/where-allowed-2.rs:6:30
+   |
+LL | fn in_adt_in_return() -> Vec<impl Debug> { panic!() }
+   |                              ^^^^^^^^^^ expands to a recursive type
+   |
+   = note: type resolves to itself
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0720`.
diff --git a/src/test/ui/impl-trait/where-allowed.rs b/src/test/ui/impl-trait/where-allowed.rs
index 5ab74e02e0e..211a14ed4dd 100644
--- a/src/test/ui/impl-trait/where-allowed.rs
+++ b/src/test/ui/impl-trait/where-allowed.rs
@@ -12,10 +12,6 @@ fn in_return() -> impl Debug { panic!() }
 fn in_adt_in_parameters(_: Vec<impl Debug>) { panic!() }
 
 // Disallowed
-fn in_adt_in_return() -> Vec<impl Debug> { panic!() }
-//~^ ERROR type annotations needed
-
-// Disallowed
 fn in_fn_parameter_in_parameters(_: fn(impl Debug)) { panic!() }
 //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
 
@@ -60,7 +56,6 @@ fn in_impl_Fn_return_in_parameters(_: &impl Fn() -> impl Debug) { panic!() }
 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
-//~| ERROR type annotations needed
 
 // Disallowed
 fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { panic!() }
diff --git a/src/test/ui/impl-trait/where-allowed.stderr b/src/test/ui/impl-trait/where-allowed.stderr
index fcd4c357afd..e5d2feff51c 100644
--- a/src/test/ui/impl-trait/where-allowed.stderr
+++ b/src/test/ui/impl-trait/where-allowed.stderr
@@ -1,5 +1,5 @@
 error[E0666]: nested `impl Trait` is not allowed
-  --> $DIR/where-allowed.rs:51:51
+  --> $DIR/where-allowed.rs:47:51
    |
 LL | fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() }
    |                                           --------^^^^^^^^^^-
@@ -8,7 +8,7 @@ LL | fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() }
    |                                           outer `impl Trait`
 
 error[E0666]: nested `impl Trait` is not allowed
-  --> $DIR/where-allowed.rs:60:57
+  --> $DIR/where-allowed.rs:56:57
    |
 LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() }
    |                                                 --------^^^^^^^^^^-
@@ -17,7 +17,7 @@ LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic
    |                                                 outer `impl Trait`
 
 error[E0658]: `impl Trait` in type aliases is unstable
-  --> $DIR/where-allowed.rs:124:16
+  --> $DIR/where-allowed.rs:119:16
    |
 LL |     type Out = impl Debug;
    |                ^^^^^^^^^^
@@ -26,7 +26,7 @@ LL |     type Out = impl Debug;
    = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
 
 error[E0658]: `impl Trait` in type aliases is unstable
-  --> $DIR/where-allowed.rs:160:23
+  --> $DIR/where-allowed.rs:155:23
    |
 LL | type InTypeAlias<R> = impl Debug;
    |                       ^^^^^^^^^^
@@ -35,7 +35,7 @@ LL | type InTypeAlias<R> = impl Debug;
    = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
 
 error[E0658]: `impl Trait` in type aliases is unstable
-  --> $DIR/where-allowed.rs:164:39
+  --> $DIR/where-allowed.rs:159:39
    |
 LL | type InReturnInTypeAlias<R> = fn() -> impl Debug;
    |                                       ^^^^^^^^^^
@@ -44,205 +44,205 @@ LL | type InReturnInTypeAlias<R> = fn() -> impl Debug;
    = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:19:40
+  --> $DIR/where-allowed.rs:15: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:23:42
+  --> $DIR/where-allowed.rs:19: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:27:38
+  --> $DIR/where-allowed.rs:23: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:31:40
+  --> $DIR/where-allowed.rs:27: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:35:49
+  --> $DIR/where-allowed.rs:31: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:39:51
+  --> $DIR/where-allowed.rs:35: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:43:55
+  --> $DIR/where-allowed.rs:39: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:47:57
+  --> $DIR/where-allowed.rs:43: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:51:51
+  --> $DIR/where-allowed.rs:47: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:56:53
+  --> $DIR/where-allowed.rs:52: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:60:57
+  --> $DIR/where-allowed.rs:56: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:66:59
+  --> $DIR/where-allowed.rs:61: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:70:38
+  --> $DIR/where-allowed.rs:65: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:74:40
+  --> $DIR/where-allowed.rs:69: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:87:32
+  --> $DIR/where-allowed.rs:82: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:91:41
+  --> $DIR/where-allowed.rs:86: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:95:27
+  --> $DIR/where-allowed.rs:90:27
    |
 LL | struct InTupleStructField(impl Debug);
    |                           ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:100:25
+  --> $DIR/where-allowed.rs:95:25
    |
 LL |     InBraceVariant { x: impl Debug },
    |                         ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:102:20
+  --> $DIR/where-allowed.rs:97:20
    |
 LL |     InTupleVariant(impl Debug),
    |                    ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:113:23
+  --> $DIR/where-allowed.rs:108: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:131:34
+  --> $DIR/where-allowed.rs:126: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:144:33
+  --> $DIR/where-allowed.rs:139: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:147:31
+  --> $DIR/where-allowed.rs:142: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:164:39
+  --> $DIR/where-allowed.rs:159: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:169:16
+  --> $DIR/where-allowed.rs:164: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:174:24
+  --> $DIR/where-allowed.rs:169: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:179:6
+  --> $DIR/where-allowed.rs:174:6
    |
 LL | impl impl Debug {
    |      ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:185:24
+  --> $DIR/where-allowed.rs:180:24
    |
 LL | impl InInherentImplAdt<impl Debug> {
    |                        ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:191:11
+  --> $DIR/where-allowed.rs:186:11
    |
 LL |     where impl Debug: Debug
    |           ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:198:15
+  --> $DIR/where-allowed.rs:193: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:205:24
+  --> $DIR/where-allowed.rs:200: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:212:17
+  --> $DIR/where-allowed.rs:207: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:219:22
+  --> $DIR/where-allowed.rs:214: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:225:29
+  --> $DIR/where-allowed.rs:220:29
    |
 LL |     let _in_local_variable: impl Fn() = || {};
    |                             ^^^^^^^^^
@@ -250,36 +250,24 @@ LL |     let _in_local_variable: impl Fn() = || {};
    = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:227:46
+  --> $DIR/where-allowed.rs:222:46
    |
 LL |     let _in_return_in_local_variable = || -> impl Fn() { || {} };
    |                                              ^^^^^^^^^
 
-error[E0282]: type annotations needed
-  --> $DIR/where-allowed.rs:15:30
-   |
-LL | fn in_adt_in_return() -> Vec<impl Debug> { panic!() }
-   |                              ^^^^^^^^^^ cannot infer type
-
-error[E0282]: type annotations needed
-  --> $DIR/where-allowed.rs:60:49
-   |
-LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() }
-   |                                                 ^^^^^^^^^^^^^^^^^^^ cannot infer type
-
 error: could not find defining uses
-  --> $DIR/where-allowed.rs:160:1
+  --> $DIR/where-allowed.rs:155:1
    |
 LL | type InTypeAlias<R> = impl Debug;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: could not find defining uses
-  --> $DIR/where-allowed.rs:124:5
+  --> $DIR/where-allowed.rs:119:5
    |
 LL |     type Out = impl Debug;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 44 previous errors
+error: aborting due to 42 previous errors
 
-Some errors have detailed explanations: E0282, E0562, E0658, E0666.
-For more information about an error, try `rustc --explain E0282`.
+Some errors have detailed explanations: E0562, E0658, E0666.
+For more information about an error, try `rustc --explain E0562`.