Stop generating inference vars for nested impl trait and let type equality handle it.

This means we stop supporting the case where a locally defined trait has only a single impl so we can always use that impl (see nested-tait-inference.rs).
This commit is contained in:
Oli Scherer 2022-01-26 13:02:45 +00:00
parent 7bce50c01a
commit a745797142
9 changed files with 70 additions and 50 deletions

View File

@ -1,4 +1,3 @@
use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use crate::infer::{InferCtxt, InferOk};
use crate::traits::{self, PredicateObligation, PredicateObligations};
use hir::def_id::{DefId, LocalDefId};
@ -604,20 +603,6 @@ struct Instantiator<'a, 'tcx> {
}
impl<'a, 'tcx> Instantiator<'a, 'tcx> {
#[instrument(level = "trace", skip(self))]
fn instantiate_opaque_types(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
if let Some(ty) = self.fold_opaque_ty_new(ty, |infcx, span| {
infcx.next_ty_var(TypeVariableOrigin {
kind: TypeVariableOriginKind::TypeInference,
span,
})
}) {
return ty;
}
ty
}
fn fold_opaque_ty_new(
&mut self,
ty: Ty<'tcx>,
@ -720,7 +705,6 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
ty::Opaque(def_id2, substs2) if def_id == def_id2 && substs == substs2 => {
ty_var
}
ty::Opaque(..) => self.instantiate_opaque_types(ty),
_ => ty,
},
lt_op: |lt| lt,

View File

@ -4,6 +4,7 @@ fn fine(x: impl Into<u32>) -> impl Into<u32> { x }
fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
//~^ ERROR nested `impl Trait` is not allowed
//~| ERROR `impl Into<u32>` doesn't implement `Debug`
fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {}
//~^ ERROR nested `impl Trait` is not allowed
@ -16,6 +17,7 @@ struct X;
impl X {
fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
//~^ ERROR nested `impl Trait` is not allowed
//~| ERROR `impl Into<u32>` doesn't implement `Debug`
}
fn allowed_in_assoc_type() -> impl Iterator<Item=impl Fn()> {

View File

@ -8,7 +8,7 @@ LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
| outer `impl Trait`
error[E0666]: nested `impl Trait` is not allowed
--> $DIR/nested_impl_trait.rs:8:42
--> $DIR/nested_impl_trait.rs:9:42
|
LL | fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {}
| ----------^^^^^^^^^^-
@ -17,7 +17,7 @@ LL | fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {}
| outer `impl Trait`
error[E0666]: nested `impl Trait` is not allowed
--> $DIR/nested_impl_trait.rs:12:37
--> $DIR/nested_impl_trait.rs:13:37
|
LL | fn bad_in_arg_position(_: impl Into<impl Debug>) { }
| ----------^^^^^^^^^^-
@ -26,7 +26,7 @@ LL | fn bad_in_arg_position(_: impl Into<impl Debug>) { }
| outer `impl Trait`
error[E0666]: nested `impl Trait` is not allowed
--> $DIR/nested_impl_trait.rs:17:44
--> $DIR/nested_impl_trait.rs:18:44
|
LL | fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
| ----------^^^^^^^^^^-
@ -35,18 +35,40 @@ LL | fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
| outer `impl Trait`
error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/nested_impl_trait.rs:8:32
--> $DIR/nested_impl_trait.rs:9:32
|
LL | fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {}
| ^^^^^^^^^^^^^^^^^^^^^
error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/nested_impl_trait.rs:25:42
--> $DIR/nested_impl_trait.rs:27:42
|
LL | fn allowed_in_ret_type() -> impl Fn() -> impl Into<u32> {
| ^^^^^^^^^^^^^^
error: aborting due to 6 previous errors
error[E0277]: `impl Into<u32>` doesn't implement `Debug`
--> $DIR/nested_impl_trait.rs:5:70
|
LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
| ^ `impl Into<u32>` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
help: consider further restricting this bound
|
LL | fn bad_in_ret_position(x: impl Into<u32> + std::fmt::Debug) -> impl Into<impl Debug> { x }
| +++++++++++++++++
Some errors have detailed explanations: E0562, E0666.
For more information about an error, try `rustc --explain E0562`.
error[E0277]: `impl Into<u32>` doesn't implement `Debug`
--> $DIR/nested_impl_trait.rs:18:58
|
LL | fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
| ^ `impl Into<u32>` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
help: consider further restricting this bound
|
LL | fn bad(x: impl Into<u32> + std::fmt::Debug) -> impl Into<impl Debug> { x }
| +++++++++++++++++
error: aborting due to 8 previous errors
Some errors have detailed explanations: E0277, E0562, E0666.
For more information about an error, try `rustc --explain E0277`.

View File

@ -15,5 +15,5 @@ impl<W> Trait<W> for () {}
fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
()
//~^ ERROR type annotations needed
//~^ ERROR non-defining opaque type use
}

View File

@ -1,8 +1,14 @@
error[E0282]: type annotations needed
error: non-defining opaque type use in defining scope
--> $DIR/bound_reduction2.rs:17:5
|
LL | ()
| ^^ cannot infer type
| ^^
|
note: used non-generic type `<T as TraitWithAssoc>::Assoc` for generic parameter
--> $DIR/bound_reduction2.rs:9:10
|
LL | type Foo<V> = impl Trait<V>;
| ^
error: could not find defining uses
--> $DIR/bound_reduction2.rs:9:15
@ -12,4 +18,3 @@ LL | type Foo<V> = impl Trait<V>;
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0282`.

View File

@ -1,18 +1,19 @@
#![feature(type_alias_impl_trait)]
#![allow(dead_code)]
// check-pass
use std::fmt::Debug;
type FooX = impl Debug;
//~^ ERROR could not find defining uses
trait Foo<A> { }
impl Foo<()> for () { }
fn foo() -> impl Foo<FooX> {
// FIXME(type-alias-impl-trait): We could probably make this work.
()
//~^ ERROR: the trait bound `(): Foo<impl Debug>` is not satisfied
}
fn main() { }

View File

@ -0,0 +1,18 @@
error[E0277]: the trait bound `(): Foo<impl Debug>` is not satisfied
--> $DIR/nested-tait-inference.rs:15:5
|
LL | ()
| ^^ the trait `Foo<impl Debug>` is not implemented for `()`
|
= help: the following implementations were found:
<() as Foo<()>>
error: could not find defining uses
--> $DIR/nested-tait-inference.rs:6:13
|
LL | type FooX = impl Debug;
| ^^^^^^^^^^
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0277`.

View File

@ -13,8 +13,7 @@ impl Foo<u32> for () {}
fn foo() -> impl Foo<FooX> {
()
//~^ ERROR: type annotations needed
//~| ERROR: type annotations needed
//~^ ERROR: the trait bound `(): Foo<impl Debug>` is not satisfied
}
fn main() {}

View File

@ -1,22 +1,12 @@
error[E0282]: type annotations needed
error[E0277]: the trait bound `(): Foo<impl Debug>` is not satisfied
--> $DIR/nested-tait-inference2.rs:15:5
|
LL | ()
| ^^ cannot infer type
error[E0283]: type annotations needed
--> $DIR/nested-tait-inference2.rs:15:5
| ^^ the trait `Foo<impl Debug>` is not implemented for `()`
|
LL | ()
| ^^ cannot infer type
|
note: multiple `impl`s satisfying `(): Foo<_>` found
--> $DIR/nested-tait-inference2.rs:11:1
|
LL | impl Foo<()> for () {}
| ^^^^^^^^^^^^^^^^^^^
LL | impl Foo<u32> for () {}
| ^^^^^^^^^^^^^^^^^^^^
= help: the following implementations were found:
<() as Foo<()>>
<() as Foo<u32>>
error: could not find defining uses
--> $DIR/nested-tait-inference2.rs:6:13
@ -24,7 +14,6 @@ error: could not find defining uses
LL | type FooX = impl Debug;
| ^^^^^^^^^^
error: aborting due to 3 previous errors
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0282, E0283.
For more information about an error, try `rustc --explain E0282`.
For more information about this error, try `rustc --explain E0277`.