Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Silence some follow-up errors on trait impls in case the trait has conflicting or otherwise incoherent impls #123674

Merged
merged 2 commits into from
Apr 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -534,8 +534,14 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
}
DefKind::Impl { of_trait } => {
if of_trait && let Some(impl_trait_header) = tcx.impl_trait_header(def_id) {
check_impl_items_against_trait(tcx, def_id, impl_trait_header);
check_on_unimplemented(tcx, def_id);
if tcx
.ensure()
.coherent_trait(impl_trait_header.trait_ref.instantiate_identity().def_id)
.is_ok()
{
check_impl_items_against_trait(tcx, def_id, impl_trait_header);
check_on_unimplemented(tcx, def_id);
}
}
}
DefKind::Trait => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ struct MyType {
impl MyTrait<MyType> for MyType {
//~^ ERROR E0119
fn get(&self) -> usize { (*self).clone() }
//~^ ERROR incompatible type
//~| ERROR mismatched types
//~^ ERROR mismatched types
}

fn main() { }
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,6 @@ LL | impl<T> MyTrait<T> for T {
LL | impl MyTrait<MyType> for MyType {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `MyType`

error[E0053]: method `get` has an incompatible type for trait
--> $DIR/coherence-blanket-conflicts-with-specific-multidispatch.rs:24:22
|
LL | fn get(&self) -> usize { (*self).clone() }
| ^^^^^
| |
| expected `MyType`, found `usize`
| help: change the output type to match the trait: `MyType`
|
note: type in trait
--> $DIR/coherence-blanket-conflicts-with-specific-multidispatch.rs:8:22
|
LL | fn get(&self) -> T;
| ^
= note: expected signature `fn(&MyType) -> MyType`
found signature `fn(&MyType) -> usize`

error[E0308]: mismatched types
--> $DIR/coherence-blanket-conflicts-with-specific-multidispatch.rs:24:30
|
Expand All @@ -32,7 +15,7 @@ LL | fn get(&self) -> usize { (*self).clone() }
| |
| expected `usize` because of return type

error: aborting due to 3 previous errors
error: aborting due to 2 previous errors

Some errors have detailed explanations: E0053, E0119, E0308.
For more information about an error, try `rustc --explain E0053`.
Some errors have detailed explanations: E0119, E0308.
For more information about an error, try `rustc --explain E0119`.
3 changes: 0 additions & 3 deletions tests/ui/coherence/coherence-orphan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,10 @@ struct TheType;

impl TheTrait<usize> for isize {}
//~^ ERROR E0117
//~| ERROR not all trait items implemented

impl TheTrait<TheType> for isize {}
//~^ ERROR not all trait items implemented

impl TheTrait<isize> for TheType {}
//~^ ERROR not all trait items implemented

impl !Send for Vec<isize> {} //~ ERROR E0117

Expand Down
31 changes: 3 additions & 28 deletions tests/ui/coherence/coherence-orphan.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,32 +10,8 @@ LL | impl TheTrait<usize> for isize {}
|
= note: define and implement a trait or new type instead

error[E0046]: not all trait items implemented, missing: `the_fn`
--> $DIR/coherence-orphan.rs:10:1
|
LL | impl TheTrait<usize> for isize {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `the_fn` in implementation
|
= help: implement the missing item: `fn the_fn(&self) { todo!() }`

error[E0046]: not all trait items implemented, missing: `the_fn`
--> $DIR/coherence-orphan.rs:14:1
|
LL | impl TheTrait<TheType> for isize {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `the_fn` in implementation
|
= help: implement the missing item: `fn the_fn(&self) { todo!() }`

error[E0046]: not all trait items implemented, missing: `the_fn`
--> $DIR/coherence-orphan.rs:17:1
|
LL | impl TheTrait<isize> for TheType {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `the_fn` in implementation
|
= help: implement the missing item: `fn the_fn(&self) { todo!() }`

error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
--> $DIR/coherence-orphan.rs:20:1
--> $DIR/coherence-orphan.rs:17:1
|
LL | impl !Send for Vec<isize> {}
| ^^^^^^^^^^^^^^^----------
Expand All @@ -45,7 +21,6 @@ LL | impl !Send for Vec<isize> {}
|
= note: define and implement a trait or new type instead

error: aborting due to 5 previous errors
error: aborting due to 2 previous errors

Some errors have detailed explanations: E0046, E0117.
For more information about an error, try `rustc --explain E0046`.
For more information about this error, try `rustc --explain E0117`.
1 change: 0 additions & 1 deletion tests/ui/error-codes/E0117.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
impl Drop for u32 {} //~ ERROR E0117
//~| ERROR the `Drop` trait may only be implemented for local structs, enums, and unions
//~| ERROR not all trait items implemented

fn main() {}
14 changes: 3 additions & 11 deletions tests/ui/error-codes/E0117.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,7 @@ error[E0120]: the `Drop` trait may only be implemented for local structs, enums,
LL | impl Drop for u32 {}
| ^^^ must be a struct, enum, or union in the current crate

error[E0046]: not all trait items implemented, missing: `drop`
--> $DIR/E0117.rs:1:1
|
LL | impl Drop for u32 {}
| ^^^^^^^^^^^^^^^^^ missing `drop` in implementation
|
= help: implement the missing item: `fn drop(&mut self) { todo!() }`

error: aborting due to 3 previous errors
error: aborting due to 2 previous errors

Some errors have detailed explanations: E0046, E0117, E0120.
For more information about an error, try `rustc --explain E0046`.
Some errors have detailed explanations: E0117, E0120.
For more information about an error, try `rustc --explain E0117`.
6 changes: 3 additions & 3 deletions tests/ui/issues/issue-67535.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@ fn main() {}

impl std::ops::AddAssign for () {
//~^ ERROR only traits defined in the current crate can be implemented for arbitrary types
fn add_assign(&self, other: ()) -> () { //~ ERROR incompatible type
fn add_assign(&self, other: ()) -> () {
()
}
}

impl std::ops::AddAssign for [(); 1] {
//~^ ERROR only traits defined in the current crate can be implemented for arbitrary types
fn add_assign(&self, other: [(); 1]) -> [(); 1] { //~ ERROR incompatible type
fn add_assign(&self, other: [(); 1]) -> [(); 1] {
[()]
}
}

impl std::ops::AddAssign for &[u8] {
//~^ ERROR only traits defined in the current crate can be implemented for arbitrary types
fn add_assign(&self, other: &[u8]) -> &[u8] { //~ ERROR incompatible type
fn add_assign(&self, other: &[u8]) -> &[u8] {
self
}
}
41 changes: 2 additions & 39 deletions tests/ui/issues/issue-67535.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -34,43 +34,6 @@ LL | impl std::ops::AddAssign for &[u8] {
|
= note: define and implement a trait or new type instead

error[E0053]: method `add_assign` has an incompatible type for trait
--> $DIR/issue-67535.rs:5:19
|
LL | fn add_assign(&self, other: ()) -> () {
| ^^^^^
| |
| types differ in mutability
| help: change the self-receiver type to match the trait: `&mut self`
|
= note: expected signature `fn(&mut (), ())`
found signature `fn(&(), ())`

error[E0053]: method `add_assign` has an incompatible type for trait
--> $DIR/issue-67535.rs:12:19
|
LL | fn add_assign(&self, other: [(); 1]) -> [(); 1] {
| ^^^^^
| |
| types differ in mutability
| help: change the self-receiver type to match the trait: `&mut self`
|
= note: expected signature `fn(&mut _, _)`
found signature `fn(&_, _) -> [(); 1]`

error[E0053]: method `add_assign` has an incompatible type for trait
--> $DIR/issue-67535.rs:19:19
|
LL | fn add_assign(&self, other: &[u8]) -> &[u8] {
| ^^^^^
| |
| types differ in mutability
| help: change the self-receiver type to match the trait: `&mut self`
|
= note: expected signature `fn(&mut &_, &_)`
found signature `fn(&&_, &_) -> &[u8]`

error: aborting due to 6 previous errors
error: aborting due to 3 previous errors

Some errors have detailed explanations: E0053, E0117.
For more information about an error, try `rustc --explain E0053`.
For more information about this error, try `rustc --explain E0117`.
20 changes: 20 additions & 0 deletions tests/ui/wf/conflicting-impls.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//@ edition: 2021

struct Ty;

impl TryFrom<Ty> for u8 {
type Error = Ty;
fn try_from(_: Ty) -> Result<Self, Self::Error> {
loop {}
}
}

impl TryFrom<Ty> for u8 {
//~^ ERROR conflicting implementations of trait
type Error = Ty;
fn try_from(_: Ty) -> Result<Self, Self::Error> {
loop {}
}
}

fn main() {}
12 changes: 12 additions & 0 deletions tests/ui/wf/conflicting-impls.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error[E0119]: conflicting implementations of trait `TryFrom<Ty>` for type `u8`
--> $DIR/conflicting-impls.rs:12:1
|
LL | impl TryFrom<Ty> for u8 {
| ----------------------- first implementation here
...
LL | impl TryFrom<Ty> for u8 {
| ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u8`

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0119`.
Loading