When checking whether an impl applies, constrain hidden types of opaque types.
We already handle this case this way on the coherence side, and it matches the new solver's behaviour. While there is some breakage around type-alias-impl-trait (see new "type annotations needed" in tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs), no stable code breaks, and no new stable code is accepted.
This commit is contained in:
parent
dc8d1bc373
commit
29a630eb72
23 changed files with 126 additions and 115 deletions
|
@ -2539,7 +2539,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
||||||
let InferOk { obligations, .. } = self
|
let InferOk { obligations, .. } = self
|
||||||
.infcx
|
.infcx
|
||||||
.at(&cause, obligation.param_env)
|
.at(&cause, obligation.param_env)
|
||||||
.eq(DefineOpaqueTypes::No, placeholder_obligation_trait_ref, impl_trait_ref)
|
.eq(DefineOpaqueTypes::Yes, placeholder_obligation_trait_ref, impl_trait_ref)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
debug!("match_impl: failed eq_trait_refs due to `{}`", e.to_string(self.tcx()))
|
debug!("match_impl: failed eq_trait_refs due to `{}`", e.to_string(self.tcx()))
|
||||||
})?;
|
})?;
|
||||||
|
|
|
@ -22,7 +22,7 @@ fn sum_to(n: u32) -> impl Foo {
|
||||||
0
|
0
|
||||||
} else {
|
} else {
|
||||||
n + sum_to(n - 1)
|
n + sum_to(n - 1)
|
||||||
//~^ ERROR cannot add `impl Foo` to `u32`
|
//~^ ERROR cannot satisfy `<u32 as Add<impl Foo>>::Output == i32`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,12 +32,15 @@ trait Leak: Sized {
|
||||||
}
|
}
|
||||||
impl<T> Leak for T {
|
impl<T> Leak for T {
|
||||||
default type T = ();
|
default type T = ();
|
||||||
default fn leak(self) -> Self::T { panic!() }
|
default fn leak(self) -> Self::T {
|
||||||
|
panic!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
impl Leak for i32 {
|
impl Leak for i32 {
|
||||||
type T = i32;
|
type T = i32;
|
||||||
fn leak(self) -> i32 { self }
|
fn leak(self) -> i32 {
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {}
|
||||||
}
|
|
||||||
|
|
|
@ -22,20 +22,13 @@ help: change the type of the numeric literal from `u32` to `i32`
|
||||||
LL | 0_i32
|
LL | 0_i32
|
||||||
| ~~~
|
| ~~~
|
||||||
|
|
||||||
error[E0277]: cannot add `impl Foo` to `u32`
|
error[E0284]: type annotations needed: cannot satisfy `<u32 as Add<impl Foo>>::Output == i32`
|
||||||
--> $DIR/equality.rs:24:11
|
--> $DIR/equality.rs:24:11
|
||||||
|
|
|
|
||||||
LL | n + sum_to(n - 1)
|
LL | n + sum_to(n - 1)
|
||||||
| ^ no implementation for `u32 + impl Foo`
|
| ^ cannot satisfy `<u32 as Add<impl Foo>>::Output == i32`
|
||||||
|
|
|
||||||
= help: the trait `Add<impl Foo>` is not implemented for `u32`
|
|
||||||
= help: the following other types implement trait `Add<Rhs>`:
|
|
||||||
<&'a u32 as Add<u32>>
|
|
||||||
<&u32 as Add<&u32>>
|
|
||||||
<u32 as Add<&u32>>
|
|
||||||
<u32 as Add>
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors; 1 warning emitted
|
error: aborting due to 2 previous errors; 1 warning emitted
|
||||||
|
|
||||||
Some errors have detailed explanations: E0277, E0308.
|
Some errors have detailed explanations: E0284, E0308.
|
||||||
For more information about an error, try `rustc --explain E0277`.
|
For more information about an error, try `rustc --explain E0284`.
|
||||||
|
|
|
@ -46,19 +46,23 @@ error[E0277]: the trait bound `impl Into<u32>: Into<impl Debug>` is not satisfie
|
||||||
--> $DIR/nested_impl_trait.rs:6:46
|
--> $DIR/nested_impl_trait.rs:6:46
|
||||||
|
|
|
|
||||||
LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
|
LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Into<u32>`, which is required by `impl Into<u32>: Into<impl Debug>`
|
| ^^^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `impl Into<u32>`
|
||||||
|
|
|
|
||||||
= help: the trait `Into<U>` is implemented for `T`
|
help: consider further restricting this bound
|
||||||
= note: required for `impl Into<u32>` to implement `Into<impl Debug>`
|
|
|
||||||
|
LL | fn bad_in_ret_position(x: impl Into<u32> + std::fmt::Debug) -> impl Into<impl Debug> { x }
|
||||||
|
| +++++++++++++++++
|
||||||
|
|
||||||
error[E0277]: the trait bound `impl Into<u32>: Into<impl Debug>` is not satisfied
|
error[E0277]: the trait bound `impl Into<u32>: Into<impl Debug>` is not satisfied
|
||||||
--> $DIR/nested_impl_trait.rs:19:34
|
--> $DIR/nested_impl_trait.rs:19:34
|
||||||
|
|
|
|
||||||
LL | fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
|
LL | fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Into<u32>`, which is required by `impl Into<u32>: Into<impl Debug>`
|
| ^^^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `impl Into<u32>`
|
||||||
|
|
|
|
||||||
= help: the trait `Into<U>` is implemented for `T`
|
help: consider further restricting this bound
|
||||||
= note: required for `impl Into<u32>` to implement `Into<impl Debug>`
|
|
|
||||||
|
LL | fn bad(x: impl Into<u32> + std::fmt::Debug) -> impl Into<impl Debug> { x }
|
||||||
|
| +++++++++++++++++
|
||||||
|
|
||||||
error: aborting due to 7 previous errors
|
error: aborting due to 7 previous errors
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ impl PartialEq<(Bar, i32)> for Bar {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn foo() -> Foo {
|
fn foo() -> Foo {
|
||||||
//~^ ERROR can't compare `Bar` with `(Foo, i32)`
|
//~^ ERROR overflow evaluating the requirement `Bar: PartialEq<(Foo, i32)>`
|
||||||
Bar
|
Bar
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,9 @@
|
||||||
error[E0277]: can't compare `Bar` with `(Foo, i32)`
|
error[E0275]: overflow evaluating the requirement `Bar: PartialEq<(Foo, i32)>`
|
||||||
--> $DIR/recursive-type-alias-impl-trait-declaration.rs:13:13
|
--> $DIR/recursive-type-alias-impl-trait-declaration.rs:13:13
|
||||||
|
|
|
|
||||||
LL | fn foo() -> Foo {
|
LL | fn foo() -> Foo {
|
||||||
| ^^^ no implementation for `Bar == (Foo, i32)`
|
| ^^^
|
||||||
LL |
|
|
||||||
LL | Bar
|
|
||||||
| --- return type was inferred to be `Bar` here
|
|
||||||
|
|
|
||||||
= help: the trait `PartialEq<(Foo, i32)>` is not implemented for `Bar`
|
|
||||||
= help: the trait `PartialEq<(Bar, i32)>` is implemented for `Bar`
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0275`.
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
error[E0277]: the trait bound `Foo: Trait<Bar>` is not satisfied
|
|
||||||
--> $DIR/constrain_in_projection.rs:24:14
|
|
||||||
|
|
|
||||||
LL | let x = <Foo as Trait<Bar>>::Assoc::default();
|
|
||||||
| ^^^ the trait `Trait<Bar>` is not implemented for `Foo`
|
|
||||||
|
|
|
||||||
= help: the trait `Trait<()>` is implemented for `Foo`
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
|
|
@ -4,7 +4,7 @@
|
||||||
//@ revisions: current next
|
//@ revisions: current next
|
||||||
//@ ignore-compare-mode-next-solver (explicit revisions)
|
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||||
//@[next] compile-flags: -Znext-solver
|
//@[next] compile-flags: -Znext-solver
|
||||||
//@[next]check-pass
|
//@check-pass
|
||||||
|
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
|
@ -22,7 +22,6 @@ impl Trait<()> for Foo {
|
||||||
|
|
||||||
fn bop(_: Bar) {
|
fn bop(_: Bar) {
|
||||||
let x = <Foo as Trait<Bar>>::Assoc::default();
|
let x = <Foo as Trait<Bar>>::Assoc::default();
|
||||||
//[current]~^ `Foo: Trait<Bar>` is not satisfied
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,13 +1,19 @@
|
||||||
error[E0277]: the trait bound `Foo: Trait<Bar>` is not satisfied
|
error[E0283]: type annotations needed: cannot satisfy `Foo: Trait<Bar>`
|
||||||
--> $DIR/constrain_in_projection2.rs:27:14
|
--> $DIR/constrain_in_projection2.rs:27:14
|
||||||
|
|
|
|
||||||
LL | let x = <Foo as Trait<Bar>>::Assoc::default();
|
LL | let x = <Foo as Trait<Bar>>::Assoc::default();
|
||||||
| ^^^ the trait `Trait<Bar>` is not implemented for `Foo`
|
| ^^^ help: use the fully qualified path to an implementation: `<Type as Trait>::Assoc`
|
||||||
|
|
|
|
||||||
= help: the following other types implement trait `Trait<T>`:
|
note: multiple `impl`s satisfying `Foo: Trait<Bar>` found
|
||||||
<Foo as Trait<()>>
|
--> $DIR/constrain_in_projection2.rs:18:1
|
||||||
<Foo as Trait<u32>>
|
|
|
||||||
|
LL | impl Trait<()> for Foo {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
...
|
||||||
|
LL | impl Trait<u32> for Foo {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
= note: associated types cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl`
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0283`.
|
||||||
|
|
|
@ -25,8 +25,7 @@ impl Trait<u32> for Foo {
|
||||||
|
|
||||||
fn bop(_: Bar) {
|
fn bop(_: Bar) {
|
||||||
let x = <Foo as Trait<Bar>>::Assoc::default();
|
let x = <Foo as Trait<Bar>>::Assoc::default();
|
||||||
//[next]~^ ERROR: cannot satisfy `Foo: Trait<Bar>`
|
//~^ ERROR: cannot satisfy `Foo: Trait<Bar>`
|
||||||
//[current]~^^ ERROR: `Foo: Trait<Bar>` is not satisfied
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0119]: conflicting implementations of trait `Trait<Bar, _>`
|
error[E0119]: conflicting implementations of trait `Trait<Bar, _>`
|
||||||
--> $DIR/issue-84660-unsoundness.rs:23:1
|
--> $DIR/issue-84660-unsoundness.rs:28:1
|
||||||
|
|
|
|
||||||
LL | impl<In, Out> Trait<Bar, In> for Out {
|
LL | impl<In, Out> Trait<Bar, In> for Out {
|
||||||
| ------------------------------------ first implementation here
|
| ------------------------------------ first implementation here
|
|
@ -0,0 +1,23 @@
|
||||||
|
error[E0284]: type annotations needed: cannot satisfy `<Out as Trait<Bar, In>>::Out == ()`
|
||||||
|
--> $DIR/issue-84660-unsoundness.rs:22:37
|
||||||
|
|
|
||||||
|
LL | fn convert(_i: In) -> Self::Out {
|
||||||
|
| _____________________________________^
|
||||||
|
LL | |
|
||||||
|
LL | | unreachable!();
|
||||||
|
LL | | }
|
||||||
|
| |_____^ cannot satisfy `<Out as Trait<Bar, In>>::Out == ()`
|
||||||
|
|
||||||
|
error[E0119]: conflicting implementations of trait `Trait<Bar, _>`
|
||||||
|
--> $DIR/issue-84660-unsoundness.rs:28:1
|
||||||
|
|
|
||||||
|
LL | impl<In, Out> Trait<Bar, In> for Out {
|
||||||
|
| ------------------------------------ first implementation here
|
||||||
|
...
|
||||||
|
LL | impl<In, Out> Trait<(), In> for Out {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0119, E0284.
|
||||||
|
For more information about an error, try `rustc --explain E0119`.
|
|
@ -1,6 +1,10 @@
|
||||||
// Another example from issue #84660, this time weaponized as a safe transmute: an opaque type in an
|
// Another example from issue #84660, this time weaponized as a safe transmute: an opaque type in an
|
||||||
// impl header being accepted was used to create unsoundness.
|
// impl header being accepted was used to create unsoundness.
|
||||||
|
|
||||||
|
//@ revisions: current next
|
||||||
|
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||||
|
//@[next] compile-flags: -Znext-solver
|
||||||
|
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
trait Foo {}
|
trait Foo {}
|
||||||
|
@ -16,11 +20,13 @@ trait Trait<T, In> {
|
||||||
impl<In, Out> Trait<Bar, In> for Out {
|
impl<In, Out> Trait<Bar, In> for Out {
|
||||||
type Out = Out;
|
type Out = Out;
|
||||||
fn convert(_i: In) -> Self::Out {
|
fn convert(_i: In) -> Self::Out {
|
||||||
|
//[next]~^ ERROR: type annotations needed
|
||||||
unreachable!();
|
unreachable!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<In, Out> Trait<(), In> for Out { //~ ERROR conflicting implementations of trait `Trait<Bar, _>`
|
impl<In, Out> Trait<(), In> for Out {
|
||||||
|
//~^ ERROR conflicting implementations of trait `Trait<Bar, _>`
|
||||||
type Out = In;
|
type Out = In;
|
||||||
fn convert(i: In) -> Self::Out {
|
fn convert(i: In) -> Self::Out {
|
||||||
i
|
i
|
||||||
|
|
|
@ -1,18 +1,21 @@
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
//@ revisions: current next
|
||||||
|
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||||
|
//@[next] compile-flags: -Znext-solver
|
||||||
|
//@check-pass
|
||||||
|
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
type FooX = impl Debug;
|
type FooX = impl Debug;
|
||||||
|
|
||||||
trait Foo<A> { }
|
trait Foo<A> {}
|
||||||
|
|
||||||
impl Foo<()> for () { }
|
impl Foo<()> for () {}
|
||||||
|
|
||||||
fn foo() -> impl Foo<FooX> {
|
fn foo() -> impl Foo<FooX> {
|
||||||
//~^ ERROR: the trait bound `(): Foo<FooX>` is not satisfied
|
|
||||||
// FIXME(type-alias-impl-trait): We could probably make this work.
|
|
||||||
()
|
()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() { }
|
fn main() {}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
error[E0283]: type annotations needed: cannot satisfy `(): Foo<FooX>`
|
||||||
|
--> $DIR/nested-tait-inference2.rs:17:13
|
||||||
|
|
|
||||||
|
LL | fn foo() -> impl Foo<FooX> {
|
||||||
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: multiple `impl`s satisfying `(): Foo<FooX>` found
|
||||||
|
--> $DIR/nested-tait-inference2.rs:14:1
|
||||||
|
|
|
||||||
|
LL | impl Foo<()> for () {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
LL | impl Foo<u32> for () {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0283`.
|
|
@ -0,0 +1,9 @@
|
||||||
|
error[E0284]: type annotations needed: cannot satisfy `impl Foo<FooX> == ()`
|
||||||
|
--> $DIR/nested-tait-inference2.rs:19:5
|
||||||
|
|
|
||||||
|
LL | ()
|
||||||
|
| ^^ cannot satisfy `impl Foo<FooX> == ()`
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0284`.
|
|
@ -1,6 +1,10 @@
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
//@ revisions: current next
|
||||||
|
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||||
|
//@[next] compile-flags: -Znext-solver
|
||||||
|
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
type FooX = impl Debug;
|
type FooX = impl Debug;
|
||||||
|
@ -11,8 +15,9 @@ impl Foo<()> for () {}
|
||||||
impl Foo<u32> for () {}
|
impl Foo<u32> for () {}
|
||||||
|
|
||||||
fn foo() -> impl Foo<FooX> {
|
fn foo() -> impl Foo<FooX> {
|
||||||
//~^ ERROR: the trait bound `(): Foo<FooX>` is not satisfied
|
//[current]~^ ERROR: cannot satisfy `(): Foo<FooX>`
|
||||||
()
|
()
|
||||||
|
//[next]~^ ERROR: cannot satisfy `impl Foo<FooX> == ()`
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
error[E0277]: the trait bound `(): Foo<FooX>` is not satisfied
|
|
||||||
--> $DIR/nested-tait-inference2.rs:13:13
|
|
||||||
|
|
|
||||||
LL | fn foo() -> impl Foo<FooX> {
|
|
||||||
| ^^^^^^^^^^^^^^ the trait `Foo<FooX>` is not implemented for `()`
|
|
||||||
LL |
|
|
||||||
LL | ()
|
|
||||||
| -- return type was inferred to be `()` here
|
|
||||||
|
|
|
||||||
= help: the following other types implement trait `Foo<A>`:
|
|
||||||
<() as Foo<()>>
|
|
||||||
<() as Foo<u32>>
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
|
|
@ -22,21 +22,17 @@ note: previous use here
|
||||||
LL | fn define_1() -> Opaque { dyn_hoops::<_>(0) }
|
LL | fn define_1() -> Opaque { dyn_hoops::<_>(0) }
|
||||||
| ^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error: concrete type differs from previous defining opaque type use
|
||||||
--> $DIR/normalize-hidden-types.rs:43:25
|
--> $DIR/normalize-hidden-types.rs:43:25
|
||||||
|
|
|
|
||||||
LL | type Opaque = impl Sized;
|
|
||||||
| ---------- the expected opaque type
|
|
||||||
...
|
|
||||||
LL | let _: Opaque = dyn_hoops::<u8>(0);
|
LL | let _: Opaque = dyn_hoops::<u8>(0);
|
||||||
| ------ ^^^^^^^^^^^^^^^^^^ expected opaque type, found `*const dyn FnOnce(())`
|
| ^^^^^^^^^^^^^^^^^^ expected `*const (dyn FnOnce(()) + 'static)`, got `*const dyn for<'a> FnOnce(<u8 as Trait>::Gat<'a>)`
|
||||||
| |
|
|
||||||
| expected due to this
|
|
||||||
|
|
|
|
||||||
= note: expected opaque type `typeck::Opaque`
|
note: previous use here
|
||||||
found raw pointer `*const (dyn FnOnce(()) + 'static)`
|
--> $DIR/normalize-hidden-types.rs:44:9
|
||||||
= help: consider constraining the associated type `<u8 as Trait>::Gat<'_>` to `()` or calling a method that returns `<u8 as Trait>::Gat<'_>`
|
|
|
||||||
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
|
LL | None
|
||||||
|
| ^^^^
|
||||||
|
|
||||||
error: concrete type differs from previous defining opaque type use
|
error: concrete type differs from previous defining opaque type use
|
||||||
--> $DIR/normalize-hidden-types.rs:52:25
|
--> $DIR/normalize-hidden-types.rs:52:25
|
||||||
|
@ -52,4 +48,3 @@ LL | None
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0308`.
|
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
error[E0277]: can't compare `i32` with `Foo`
|
|
||||||
--> $DIR/self-referential-2.rs:10:13
|
|
||||||
|
|
|
||||||
LL | fn bar() -> Bar {
|
|
||||||
| ^^^ no implementation for `i32 == Foo`
|
|
||||||
LL | 42_i32
|
|
||||||
| ------ return type was inferred to be `i32` here
|
|
||||||
|
|
|
||||||
= help: the trait `PartialEq<Foo>` is not implemented for `i32`
|
|
||||||
= help: the trait `PartialEq` is implemented for `i32`
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
|
|
@ -1,14 +1,14 @@
|
||||||
//@ revisions: current next
|
//@ revisions: current next
|
||||||
//@ ignore-compare-mode-next-solver (explicit revisions)
|
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||||
//@[next] compile-flags: -Znext-solver
|
//@[next] compile-flags: -Znext-solver
|
||||||
//@[next] check-pass
|
//@ check-pass
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
type Foo = impl std::fmt::Debug;
|
type Foo = impl std::fmt::Debug;
|
||||||
type Bar = impl PartialEq<Foo>;
|
type Bar = impl PartialEq<Foo>;
|
||||||
|
|
||||||
fn bar() -> Bar {
|
fn bar() -> Bar {
|
||||||
42_i32 //[current]~^ ERROR can't compare `i32` with `Foo`
|
42_i32
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
type Bar<'a, 'b> = impl PartialEq<Bar<'a, 'b>> + std::fmt::Debug;
|
type Bar<'a, 'b> = impl PartialEq<Bar<'a, 'b>> + std::fmt::Debug;
|
||||||
|
|
||||||
fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> {
|
fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> {
|
||||||
//~^ ERROR can't compare `&i32` with `Bar<'a, 'b>`
|
//~^ ERROR overflow normalizing the type alias `Bar<'a, 'b>`
|
||||||
i
|
i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,11 @@
|
||||||
error[E0277]: can't compare `&i32` with `Bar<'a, 'b>`
|
error[E0275]: overflow normalizing the type alias `Bar<'a, 'b>`
|
||||||
--> $DIR/self-referential-3.rs:7:31
|
--> $DIR/self-referential-3.rs:7:31
|
||||||
|
|
|
|
||||||
LL | fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> {
|
LL | fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> {
|
||||||
| ^^^^^^^^^^^ no implementation for `&i32 == Bar<'a, 'b>`
|
| ^^^^^^^^^^^
|
||||||
LL |
|
|
||||||
LL | i
|
|
||||||
| - return type was inferred to be `&i32` here
|
|
||||||
|
|
|
|
||||||
= help: the trait `PartialEq<Bar<'a, 'b>>` is not implemented for `&i32`
|
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead
|
||||||
= help: the trait `PartialEq` is implemented for `i32`
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0275`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue