Skip to content

Commit

Permalink
Rollup merge of #112780 - compiler-errors:tait-is-ambig, r=lcnr
Browse files Browse the repository at this point in the history
Treat TAIT equation as always ambiguous in coherence

Not sure why we weren't treating all TAIT equality as ambiguous -- this behavior combined with `DefineOpaqueTypes::No` leads to coherence overlap failures, since we incorrectly consider impls as not overlapping because the obligation `T: From<Foo>` doesn't hold.

Fixes #112765
  • Loading branch information
matthiaskrgr committed Jun 19, 2023
2 parents 68f2f1e + d43683f commit 263635b
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 21 deletions.
11 changes: 4 additions & 7 deletions compiler/rustc_infer/src/infer/combine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
6 changes: 0 additions & 6 deletions src/tools/clippy/tests/ui/from_over_into_unfixable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,4 @@ impl Into<u8> for ContainsVal {
}
}

type Opaque = impl Sized;
struct IntoOpaque;
impl Into<Opaque> for IntoOpaque {
fn into(self) -> Opaque {}
}

fn main() {}
33 changes: 25 additions & 8 deletions src/tools/clippy/tests/ui/from_over_into_unfixable.stderr
Original file line number Diff line number Diff line change
@@ -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<InMacro> for String {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
= help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
= help: replace the `Into` implementation with `From<std::string::String>`
= 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<WeirdUpperSelf> 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<u8> for ContainsVal {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: `impl From<Local> 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<ContainsVal>`

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0658`.
13 changes: 13 additions & 0 deletions tests/ui/impl-trait/coherence-treats-tait-ambig.current.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
error[E0119]: conflicting implementations of trait `Into<T>` for type `Foo`
--> $DIR/coherence-treats-tait-ambig.rs:10:1
|
LL | impl Into<T> for Foo {
| ^^^^^^^^^^^^^^^^^^^^
|
= note: conflicting implementation in crate `core`:
- impl<T, U> Into<U> for T
where U: From<T>;

error: aborting due to previous error

For more information about this error, try `rustc --explain E0119`.
13 changes: 13 additions & 0 deletions tests/ui/impl-trait/coherence-treats-tait-ambig.next.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
error[E0119]: conflicting implementations of trait `Into<T>` for type `Foo`
--> $DIR/coherence-treats-tait-ambig.rs:10:1
|
LL | impl Into<T> for Foo {
| ^^^^^^^^^^^^^^^^^^^^
|
= note: conflicting implementation in crate `core`:
- impl<T, U> Into<U> for T
where U: From<T>;

error: aborting due to previous error

For more information about this error, try `rustc --explain E0119`.
19 changes: 19 additions & 0 deletions tests/ui/impl-trait/coherence-treats-tait-ambig.rs
Original file line number Diff line number Diff line change
@@ -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<T> for Foo {
//~^ ERROR conflicting implementations of trait `Into<T>` for type `Foo`
fn into(self) -> T {
Foo
}
}

fn main() {
let _: T = Foo.into();
}

0 comments on commit 263635b

Please sign in to comment.