From d43683f2e905d34ab289882c16124deb5ed09edd Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 18 Jun 2023 22:10:07 +0000 Subject: [PATCH] Treat TAIT equation as always ambiguous in coherence --- compiler/rustc_infer/src/infer/combine.rs | 11 +++---- .../tests/ui/from_over_into_unfixable.rs | 6 ---- .../tests/ui/from_over_into_unfixable.stderr | 33 ++++++++++++++----- ...coherence-treats-tait-ambig.current.stderr | 13 ++++++++ .../coherence-treats-tait-ambig.next.stderr | 13 ++++++++ .../impl-trait/coherence-treats-tait-ambig.rs | 19 +++++++++++ 6 files changed, 74 insertions(+), 21 deletions(-) create mode 100644 tests/ui/impl-trait/coherence-treats-tait-ambig.current.stderr create mode 100644 tests/ui/impl-trait/coherence-treats-tait-ambig.next.stderr create mode 100644 tests/ui/impl-trait/coherence-treats-tait-ambig.rs diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 152c56572b691..12cb86d7d72bd 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -124,13 +124,10 @@ impl<'tcx> InferCtxt<'tcx> { } // During coherence, opaque types should be treated as *possibly* - // equal to each other, even if their generic params differ, as - // they could resolve to the same hidden type, even for different - // generic params. - ( - &ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, .. }), - &ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }), - ) if self.intercrate && a_def_id == b_def_id => { + // equal to any other type (except for possibly itself). This is an + // extremely heavy hammer, but can be relaxed in a fowards-compatible + // way later. + (&ty::Alias(ty::Opaque, _), _) | (_, &ty::Alias(ty::Opaque, _)) if self.intercrate => { relation.register_predicates([ty::Binder::dummy(ty::PredicateKind::Ambiguous)]); Ok(a) } diff --git a/src/tools/clippy/tests/ui/from_over_into_unfixable.rs b/src/tools/clippy/tests/ui/from_over_into_unfixable.rs index bd62c655216e8..3b280b7488ae7 100644 --- a/src/tools/clippy/tests/ui/from_over_into_unfixable.rs +++ b/src/tools/clippy/tests/ui/from_over_into_unfixable.rs @@ -32,10 +32,4 @@ impl Into for ContainsVal { } } -type Opaque = impl Sized; -struct IntoOpaque; -impl Into for IntoOpaque { - fn into(self) -> Opaque {} -} - fn main() {} diff --git a/src/tools/clippy/tests/ui/from_over_into_unfixable.stderr b/src/tools/clippy/tests/ui/from_over_into_unfixable.stderr index bb966af4b0ffd..251f1d84e74e3 100644 --- a/src/tools/clippy/tests/ui/from_over_into_unfixable.stderr +++ b/src/tools/clippy/tests/ui/from_over_into_unfixable.stderr @@ -1,12 +1,29 @@ -error[E0658]: `impl Trait` in type aliases is unstable - --> $DIR/from_over_into_unfixable.rs:35:15 +error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true + --> $DIR/from_over_into_unfixable.rs:11:1 | -LL | type Opaque = impl Sized; - | ^^^^^^^^^^ +LL | impl Into for String { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: see issue #63063 for more information - = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable + = help: replace the `Into` implementation with `From` + = note: `-D clippy::from-over-into` implied by `-D warnings` -error: aborting due to previous error +error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true + --> $DIR/from_over_into_unfixable.rs:19:1 + | +LL | impl Into for &'static [u8] { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: replace the `Into` implementation with `From<&'static [u8]>` + +error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true + --> $DIR/from_over_into_unfixable.rs:28:1 + | +LL | impl Into for ContainsVal { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `impl From for Foreign` is allowed by the orphan rules, for more information see + https://doc.rust-lang.org/reference/items/implementations.html#trait-implementation-coherence + = help: replace the `Into` implementation with `From` + +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/impl-trait/coherence-treats-tait-ambig.current.stderr b/tests/ui/impl-trait/coherence-treats-tait-ambig.current.stderr new file mode 100644 index 0000000000000..61fed16294b4e --- /dev/null +++ b/tests/ui/impl-trait/coherence-treats-tait-ambig.current.stderr @@ -0,0 +1,13 @@ +error[E0119]: conflicting implementations of trait `Into` for type `Foo` + --> $DIR/coherence-treats-tait-ambig.rs:10:1 + | +LL | impl Into for Foo { + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `core`: + - impl Into for T + where U: From; + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/impl-trait/coherence-treats-tait-ambig.next.stderr b/tests/ui/impl-trait/coherence-treats-tait-ambig.next.stderr new file mode 100644 index 0000000000000..61fed16294b4e --- /dev/null +++ b/tests/ui/impl-trait/coherence-treats-tait-ambig.next.stderr @@ -0,0 +1,13 @@ +error[E0119]: conflicting implementations of trait `Into` for type `Foo` + --> $DIR/coherence-treats-tait-ambig.rs:10:1 + | +LL | impl Into for Foo { + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `core`: + - impl Into for T + where U: From; + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/impl-trait/coherence-treats-tait-ambig.rs b/tests/ui/impl-trait/coherence-treats-tait-ambig.rs new file mode 100644 index 0000000000000..156a7eb0e23d7 --- /dev/null +++ b/tests/ui/impl-trait/coherence-treats-tait-ambig.rs @@ -0,0 +1,19 @@ +// revisions: current next +//[next] compile-flags: -Ztrait-solver=next + +#![feature(type_alias_impl_trait)] + +type T = impl Sized; + +struct Foo; + +impl Into for Foo { +//~^ ERROR conflicting implementations of trait `Into` for type `Foo` + fn into(self) -> T { + Foo + } +} + +fn main() { + let _: T = Foo.into(); +}