From c8f6e03c1570200dbb99587fb257d371aa7447b3 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 9 Apr 2024 10:19:48 +0000 Subject: [PATCH 1/2] Add regression test --- tests/ui/wf/conflicting-impls.rs | 22 +++++++++++++++ tests/ui/wf/conflicting-impls.stderr | 41 ++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 tests/ui/wf/conflicting-impls.rs create mode 100644 tests/ui/wf/conflicting-impls.stderr diff --git a/tests/ui/wf/conflicting-impls.rs b/tests/ui/wf/conflicting-impls.rs new file mode 100644 index 0000000000000..c387199a8bf14 --- /dev/null +++ b/tests/ui/wf/conflicting-impls.rs @@ -0,0 +1,22 @@ +//@ edition: 2021 + +struct Ty; + +impl TryFrom for u8 { + type Error = Ty; + fn try_from(_: Ty) -> Result { + //~^ ERROR type annotations needed + loop {} + } +} + +impl TryFrom for u8 { + //~^ ERROR conflicting implementations of trait + type Error = Ty; + fn try_from(_: Ty) -> Result { + //~^ ERROR type annotations needed + loop {} + } +} + +fn main() {} diff --git a/tests/ui/wf/conflicting-impls.stderr b/tests/ui/wf/conflicting-impls.stderr new file mode 100644 index 0000000000000..69f48f69bfbfc --- /dev/null +++ b/tests/ui/wf/conflicting-impls.stderr @@ -0,0 +1,41 @@ +error[E0119]: conflicting implementations of trait `TryFrom` for type `u8` + --> $DIR/conflicting-impls.rs:12:1 + | +LL | impl TryFrom for u8 { + | ----------------------- first implementation here +... +LL | impl TryFrom for u8 { + | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u8` + +error[E0282]: type annotations needed + --> $DIR/conflicting-impls.rs:7:5 + | +LL | fn try_from(_: Ty) -> Result { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type + | +note: the requirement `_ <: _` appears on the `impl`'s method `try_from` but not on the corresponding trait's method + --> $SRC_DIR/core/src/convert/mod.rs:LL:COL + | + = note: in this trait + ::: $SRC_DIR/core/src/convert/mod.rs:LL:COL + | + = note: this trait's method doesn't have the requirement `_ <: _` + +error[E0282]: type annotations needed + --> $DIR/conflicting-impls.rs:14:5 + | +LL | fn try_from(_: Ty) -> Result { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type + | +note: the requirement `_ <: _` appears on the `impl`'s method `try_from` but not on the corresponding trait's method + --> $SRC_DIR/core/src/convert/mod.rs:LL:COL + | + = note: in this trait + ::: $SRC_DIR/core/src/convert/mod.rs:LL:COL + | + = note: this trait's method doesn't have the requirement `_ <: _` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0119, E0282. +For more information about an error, try `rustc --explain E0119`. From c0a9c8c9549662ec9199112cb59592ef2c617412 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 9 Apr 2024 10:23:58 +0000 Subject: [PATCH 2/2] Silence some follow-up errors on trait impls in case the trait has conflicting or otherwise incoherent impls --- .../rustc_hir_analysis/src/check/check.rs | 10 ++++- ...t-conflicts-with-specific-multidispatch.rs | 3 +- ...nflicts-with-specific-multidispatch.stderr | 23 ++--------- tests/ui/coherence/coherence-orphan.rs | 3 -- tests/ui/coherence/coherence-orphan.stderr | 31 ++------------ tests/ui/error-codes/E0117.rs | 1 - tests/ui/error-codes/E0117.stderr | 14 ++----- tests/ui/issues/issue-67535.rs | 6 +-- tests/ui/issues/issue-67535.stderr | 41 +------------------ tests/ui/wf/conflicting-impls.rs | 2 - tests/ui/wf/conflicting-impls.stderr | 33 +-------------- 11 files changed, 25 insertions(+), 142 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 8d4ae10d4bfe6..b223c590bff6c 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -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 => { diff --git a/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs b/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs index 8426748fd52ee..fd54fe2b0e8a8 100644 --- a/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs +++ b/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs @@ -22,8 +22,7 @@ struct MyType { impl MyTrait for MyType { //~^ ERROR E0119 fn get(&self) -> usize { (*self).clone() } - //~^ ERROR incompatible type - //~| ERROR mismatched types + //~^ ERROR mismatched types } fn main() { } diff --git a/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.stderr b/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.stderr index 0653009409c5b..fc6250dfa0266 100644 --- a/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.stderr +++ b/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.stderr @@ -7,23 +7,6 @@ LL | impl MyTrait for T { LL | impl MyTrait 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 | @@ -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`. diff --git a/tests/ui/coherence/coherence-orphan.rs b/tests/ui/coherence/coherence-orphan.rs index 9c96958f21a12..aee6647a78819 100644 --- a/tests/ui/coherence/coherence-orphan.rs +++ b/tests/ui/coherence/coherence-orphan.rs @@ -9,13 +9,10 @@ struct TheType; impl TheTrait for isize {} //~^ ERROR E0117 -//~| ERROR not all trait items implemented impl TheTrait for isize {} -//~^ ERROR not all trait items implemented impl TheTrait for TheType {} -//~^ ERROR not all trait items implemented impl !Send for Vec {} //~ ERROR E0117 diff --git a/tests/ui/coherence/coherence-orphan.stderr b/tests/ui/coherence/coherence-orphan.stderr index 48843f7cd1818..f6ffae342908a 100644 --- a/tests/ui/coherence/coherence-orphan.stderr +++ b/tests/ui/coherence/coherence-orphan.stderr @@ -10,32 +10,8 @@ LL | impl TheTrait 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 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 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 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 {} | ^^^^^^^^^^^^^^^---------- @@ -45,7 +21,6 @@ LL | impl !Send for Vec {} | = 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`. diff --git a/tests/ui/error-codes/E0117.rs b/tests/ui/error-codes/E0117.rs index 32b9863806c04..406d24e366614 100644 --- a/tests/ui/error-codes/E0117.rs +++ b/tests/ui/error-codes/E0117.rs @@ -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() {} diff --git a/tests/ui/error-codes/E0117.stderr b/tests/ui/error-codes/E0117.stderr index 058a64b20d171..f144aa9f72c13 100644 --- a/tests/ui/error-codes/E0117.stderr +++ b/tests/ui/error-codes/E0117.stderr @@ -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`. diff --git a/tests/ui/issues/issue-67535.rs b/tests/ui/issues/issue-67535.rs index 153b95a167434..24f50621310f1 100644 --- a/tests/ui/issues/issue-67535.rs +++ b/tests/ui/issues/issue-67535.rs @@ -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 } } diff --git a/tests/ui/issues/issue-67535.stderr b/tests/ui/issues/issue-67535.stderr index c8bde2cb88c77..4d7a02a50969f 100644 --- a/tests/ui/issues/issue-67535.stderr +++ b/tests/ui/issues/issue-67535.stderr @@ -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`. diff --git a/tests/ui/wf/conflicting-impls.rs b/tests/ui/wf/conflicting-impls.rs index c387199a8bf14..8054eb7c59436 100644 --- a/tests/ui/wf/conflicting-impls.rs +++ b/tests/ui/wf/conflicting-impls.rs @@ -5,7 +5,6 @@ struct Ty; impl TryFrom for u8 { type Error = Ty; fn try_from(_: Ty) -> Result { - //~^ ERROR type annotations needed loop {} } } @@ -14,7 +13,6 @@ impl TryFrom for u8 { //~^ ERROR conflicting implementations of trait type Error = Ty; fn try_from(_: Ty) -> Result { - //~^ ERROR type annotations needed loop {} } } diff --git a/tests/ui/wf/conflicting-impls.stderr b/tests/ui/wf/conflicting-impls.stderr index 69f48f69bfbfc..d31ae17aa8f7d 100644 --- a/tests/ui/wf/conflicting-impls.stderr +++ b/tests/ui/wf/conflicting-impls.stderr @@ -7,35 +7,6 @@ LL | impl TryFrom for u8 { LL | impl TryFrom for u8 { | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u8` -error[E0282]: type annotations needed - --> $DIR/conflicting-impls.rs:7:5 - | -LL | fn try_from(_: Ty) -> Result { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type - | -note: the requirement `_ <: _` appears on the `impl`'s method `try_from` but not on the corresponding trait's method - --> $SRC_DIR/core/src/convert/mod.rs:LL:COL - | - = note: in this trait - ::: $SRC_DIR/core/src/convert/mod.rs:LL:COL - | - = note: this trait's method doesn't have the requirement `_ <: _` - -error[E0282]: type annotations needed - --> $DIR/conflicting-impls.rs:14:5 - | -LL | fn try_from(_: Ty) -> Result { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type - | -note: the requirement `_ <: _` appears on the `impl`'s method `try_from` but not on the corresponding trait's method - --> $SRC_DIR/core/src/convert/mod.rs:LL:COL - | - = note: in this trait - ::: $SRC_DIR/core/src/convert/mod.rs:LL:COL - | - = note: this trait's method doesn't have the requirement `_ <: _` - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0119, E0282. -For more information about an error, try `rustc --explain E0119`. +For more information about this error, try `rustc --explain E0119`.