Skip to content

Commit 965da3a

Browse files
committed
Stop bailing out from compilation just because there were incoherent traits
1 parent fe8c4ed commit 965da3a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+480
-83
lines changed

compiler/rustc_hir_analysis/src/check/compare_impl_item.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1990,6 +1990,10 @@ pub(super) fn check_type_bounds<'tcx>(
19901990
impl_ty: ty::AssocItem,
19911991
impl_trait_ref: ty::TraitRef<'tcx>,
19921992
) -> Result<(), ErrorGuaranteed> {
1993+
// Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
1994+
// other `Foo` impls are incoherent.
1995+
tcx.ensure().coherent_trait(impl_trait_ref.def_id)?;
1996+
19931997
let param_env = tcx.param_env(impl_ty.def_id);
19941998
debug!(?param_env);
19951999

compiler/rustc_hir_analysis/src/check/wfcheck.rs

+7
Original file line numberDiff line numberDiff line change
@@ -1006,6 +1006,10 @@ fn check_associated_item(
10061006
enter_wf_checking_ctxt(tcx, span, item_id, |wfcx| {
10071007
let item = tcx.associated_item(item_id);
10081008

1009+
// Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
1010+
// other `Foo` impls are incoherent.
1011+
tcx.ensure().coherent_trait(tcx.local_parent(item_id))?;
1012+
10091013
let self_ty = match item.container {
10101014
ty::TraitContainer => tcx.types.self_param,
10111015
ty::ImplContainer => tcx.type_of(item.container_id(tcx)).instantiate_identity(),
@@ -1292,6 +1296,9 @@ fn check_impl<'tcx>(
12921296
// therefore don't need to be WF (the trait's `Self: Trait` predicate
12931297
// won't hold).
12941298
let trait_ref = tcx.impl_trait_ref(item.owner_id).unwrap().instantiate_identity();
1299+
// Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
1300+
// other `Foo` impls are incoherent.
1301+
tcx.ensure().coherent_trait(trait_ref.def_id)?;
12951302
let trait_ref = wfcx.normalize(
12961303
ast_trait_ref.path.span,
12971304
Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)),

compiler/rustc_hir_analysis/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -169,11 +169,11 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
169169

170170
tcx.sess.time("coherence_checking", || {
171171
// Check impls constrain their parameters
172-
let mut res =
172+
let res =
173173
tcx.hir().try_par_for_each_module(|module| tcx.ensure().check_mod_impl_wf(module));
174174

175175
for &trait_def_id in tcx.all_local_trait_impls(()).keys() {
176-
res = res.and(tcx.ensure().coherent_trait(trait_def_id));
176+
let _ = tcx.ensure().coherent_trait(trait_def_id);
177177
}
178178
// these queries are executed for side-effects (error reporting):
179179
res.and(tcx.ensure().crate_inherent_impls(()))

tests/ui/associated-consts/issue-105330.rs

+1
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,6 @@ fn foo<A: TraitWAssocConst<A=32>>() { //~ ERROR E0658
1414

1515
fn main<A: TraitWAssocConst<A=32>>() {
1616
//~^ ERROR E0658
17+
//~| ERROR E0131
1718
foo::<Demo>();
1819
}

tests/ui/associated-consts/issue-105330.stderr

+9-3
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,13 @@ LL | impl TraitWAssocConst for impl Demo {
4343
|
4444
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
4545

46-
error: aborting due to 5 previous errors
46+
error[E0131]: `main` function is not allowed to have generic parameters
47+
--> $DIR/issue-105330.rs:15:8
48+
|
49+
LL | fn main<A: TraitWAssocConst<A=32>>() {
50+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `main` cannot have generic parameters
51+
52+
error: aborting due to 6 previous errors
4753

48-
Some errors have detailed explanations: E0404, E0562, E0658.
49-
For more information about an error, try `rustc --explain E0404`.
54+
Some errors have detailed explanations: E0131, E0404, E0562, E0658.
55+
For more information about an error, try `rustc --explain E0131`.
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//! A regression test for #120343. The overlap error was previously
2+
//! silenced in coherence because projecting `<() as ToUnit>::Unit`
3+
//! failed. Then then silenced the missing items error in the `ToUnit`
4+
//! impl, causing us to not emit any errors and ICEing due to a
5+
//! `span_delay_bug`.
6+
7+
trait ToUnit {
8+
type Unit;
9+
}
10+
11+
impl<T> ToUnit for *const T {}
12+
//~^ ERROR: not all trait items implemented
13+
14+
trait Overlap<T> {}
15+
16+
impl<T> Overlap<T> for T {}
17+
18+
impl<T> Overlap<<*const T as ToUnit>::Unit> for T {}
19+
20+
fn main() {}
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0046]: not all trait items implemented, missing: `Unit`
2+
--> $DIR/associated-type2.rs:11:1
3+
|
4+
LL | type Unit;
5+
| --------- `Unit` from trait
6+
...
7+
LL | impl<T> ToUnit for *const T {}
8+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Unit` in implementation
9+
10+
error: aborting due to 1 previous error
11+
12+
For more information about this error, try `rustc --explain E0046`.

tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ struct MyType {
2222
impl MyTrait<MyType> for MyType {
2323
//~^ ERROR E0119
2424
fn get(&self) -> usize { (*self).clone() }
25+
//~^ ERROR incompatible type
2526
}
2627

2728
fn main() { }

tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.stderr

+20-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,24 @@ LL | impl<T> MyTrait<T> for T {
77
LL | impl MyTrait<MyType> for MyType {
88
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `MyType`
99

10-
error: aborting due to 1 previous error
10+
error[E0053]: method `get` has an incompatible type for trait
11+
--> $DIR/coherence-blanket-conflicts-with-specific-multidispatch.rs:24:22
12+
|
13+
LL | fn get(&self) -> usize { (*self).clone() }
14+
| ^^^^^
15+
| |
16+
| expected `MyType`, found `usize`
17+
| help: change the output type to match the trait: `MyType`
18+
|
19+
note: type in trait
20+
--> $DIR/coherence-blanket-conflicts-with-specific-multidispatch.rs:8:22
21+
|
22+
LL | fn get(&self) -> T;
23+
| ^
24+
= note: expected signature `fn(&MyType) -> MyType`
25+
found signature `fn(&MyType) -> usize`
26+
27+
error: aborting due to 2 previous errors
1128

12-
For more information about this error, try `rustc --explain E0119`.
29+
Some errors have detailed explanations: E0053, E0119.
30+
For more information about an error, try `rustc --explain E0053`.

tests/ui/coherence/coherence-orphan.rs

+3
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,13 @@ struct TheType;
99

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

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

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

1720
impl !Send for Vec<isize> { } //~ ERROR E0117
1821
//~^ WARNING

tests/ui/coherence/coherence-orphan.stderr

+29-4
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ LL | impl TheTrait<usize> for isize { }
1111
= note: define and implement a trait or new type instead
1212

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

2424
warning: cross-crate traits with a default impl, like `Send`, should not be specialized
25-
--> $DIR/coherence-orphan.rs:17:1
25+
--> $DIR/coherence-orphan.rs:20:1
2626
|
2727
LL | impl !Send for Vec<isize> { }
2828
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -34,6 +34,31 @@ note: try using the same sequence of generic parameters as the struct definition
3434
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
3535
= note: `#[warn(suspicious_auto_trait_impls)]` on by default
3636

37-
error: aborting due to 2 previous errors; 1 warning emitted
37+
error[E0046]: not all trait items implemented, missing: `the_fn`
38+
--> $DIR/coherence-orphan.rs:10:1
39+
|
40+
LL | impl TheTrait<usize> for isize { }
41+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `the_fn` in implementation
42+
|
43+
= help: implement the missing item: `fn the_fn(&self) { todo!() }`
44+
45+
error[E0046]: not all trait items implemented, missing: `the_fn`
46+
--> $DIR/coherence-orphan.rs:14:1
47+
|
48+
LL | impl TheTrait<TheType> for isize { }
49+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `the_fn` in implementation
50+
|
51+
= help: implement the missing item: `fn the_fn(&self) { todo!() }`
52+
53+
error[E0046]: not all trait items implemented, missing: `the_fn`
54+
--> $DIR/coherence-orphan.rs:17:1
55+
|
56+
LL | impl TheTrait<isize> for TheType { }
57+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `the_fn` in implementation
58+
|
59+
= help: implement the missing item: `fn the_fn(&self) { todo!() }`
60+
61+
error: aborting due to 5 previous errors; 1 warning emitted
3862

39-
For more information about this error, try `rustc --explain E0117`.
63+
Some errors have detailed explanations: E0046, E0117.
64+
For more information about an error, try `rustc --explain E0046`.

tests/ui/coherence/deep-bad-copy-reason.rs

+5
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@ extern "Rust" {
55
}
66

77
pub struct ListS<T> {
8+
//~^ NOTE: required because it appears within the type
89
len: usize,
910
data: [T; 0],
1011
opaque: OpaqueListContents,
1112
}
1213

1314
pub struct Interned<'a, T>(&'a T);
15+
//~^ NOTE: required by this bound
16+
//~| NOTE: required by a bound
1417

1518
impl<'a, T> Clone for Interned<'a, T> {
1619
fn clone(&self) -> Self {
@@ -23,6 +26,8 @@ impl<'a, T> Copy for Interned<'a, T> {}
2326
pub struct List<'tcx, T>(Interned<'tcx, ListS<T>>);
2427
//~^ NOTE this field does not implement `Copy`
2528
//~| NOTE the `Copy` impl for `Interned<'tcx, ListS<T>>` requires that `OpaqueListContents: Sized`
29+
//~| NOTE: doesn't have a size known at compile-time
30+
//~| ERROR: cannot be known at compilation time
2631

2732
impl<'tcx, T> Clone for List<'tcx, T> {
2833
fn clone(&self) -> Self {
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0204]: the trait `Copy` cannot be implemented for this type
2-
--> $DIR/deep-bad-copy-reason.rs:33:24
2+
--> $DIR/deep-bad-copy-reason.rs:38:24
33
|
44
LL | pub struct List<'tcx, T>(Interned<'tcx, ListS<T>>);
55
| ------------------------ this field does not implement `Copy`
@@ -8,11 +8,34 @@ LL | impl<'tcx, T> Copy for List<'tcx, T> {}
88
| ^^^^^^^^^^^^^
99
|
1010
note: the `Copy` impl for `Interned<'tcx, ListS<T>>` requires that `OpaqueListContents: Sized`
11-
--> $DIR/deep-bad-copy-reason.rs:23:26
11+
--> $DIR/deep-bad-copy-reason.rs:26:26
1212
|
1313
LL | pub struct List<'tcx, T>(Interned<'tcx, ListS<T>>);
1414
| ^^^^^^^^^^^^^^^^^^^^^^^^
1515

16-
error: aborting due to 1 previous error
16+
error[E0277]: the size for values of type `OpaqueListContents` cannot be known at compilation time
17+
--> $DIR/deep-bad-copy-reason.rs:26:26
18+
|
19+
LL | pub struct List<'tcx, T>(Interned<'tcx, ListS<T>>);
20+
| ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
21+
|
22+
= help: within `ListS<T>`, the trait `Sized` is not implemented for `OpaqueListContents`, which is required by `ListS<T>: Sized`
23+
note: required because it appears within the type `ListS<T>`
24+
--> $DIR/deep-bad-copy-reason.rs:7:12
25+
|
26+
LL | pub struct ListS<T> {
27+
| ^^^^^
28+
note: required by a bound in `Interned`
29+
--> $DIR/deep-bad-copy-reason.rs:14:25
30+
|
31+
LL | pub struct Interned<'a, T>(&'a T);
32+
| ^ required by this bound in `Interned`
33+
help: consider relaxing the implicit `Sized` restriction
34+
|
35+
LL | pub struct Interned<'a, T: ?Sized>(&'a T);
36+
| ++++++++
37+
38+
error: aborting due to 2 previous errors
1739

18-
For more information about this error, try `rustc --explain E0204`.
40+
Some errors have detailed explanations: E0204, E0277.
41+
For more information about an error, try `rustc --explain E0204`.
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
error[E0119]: conflicting implementations of trait `Trait<Alias<_>>` for type `Alias<_>`
2-
--> $DIR/opaques.rs:29:1
2+
--> $DIR/opaques.rs:30:1
33
|
44
LL | impl<T> Trait<T> for T {
55
| ---------------------- first implementation here
66
...
77
LL | impl<T> Trait<T> for defining_scope::Alias<T> {
88
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Alias<_>`
99

10-
error: aborting due to 1 previous error
10+
error[E0282]: type annotations needed
11+
--> $DIR/opaques.rs:13:20
12+
|
13+
LL | pub fn cast<T>(x: Container<Alias<T>, T>) -> Container<T, T> {
14+
| ^ cannot infer type for struct `Container<Alias<T>, T>`
15+
16+
error: aborting due to 2 previous errors
1117

12-
For more information about this error, try `rustc --explain E0119`.
18+
Some errors have detailed explanations: E0119, E0282.
19+
For more information about an error, try `rustc --explain E0119`.

tests/ui/coherence/occurs-check/opaques.rs

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ mod defining_scope {
1111
pub type Alias<T> = impl Sized;
1212

1313
pub fn cast<T>(x: Container<Alias<T>, T>) -> Container<T, T> {
14+
//[next]~^ ERROR type annotations needed
1415
x
1516
}
1617
}

tests/ui/error-codes/E0117.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
impl Drop for u32 {} //~ ERROR E0117
22
//~| ERROR the `Drop` trait may only be implemented for local structs, enums, and unions
3+
//~| ERROR not all trait items implemented
34

45
fn main() {}

tests/ui/error-codes/E0117.stderr

+11-3
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,15 @@ error[E0120]: the `Drop` trait may only be implemented for local structs, enums,
1515
LL | impl Drop for u32 {}
1616
| ^^^ must be a struct, enum, or union in the current crate
1717

18-
error: aborting due to 2 previous errors
18+
error[E0046]: not all trait items implemented, missing: `drop`
19+
--> $DIR/E0117.rs:1:1
20+
|
21+
LL | impl Drop for u32 {}
22+
| ^^^^^^^^^^^^^^^^^ missing `drop` in implementation
23+
|
24+
= help: implement the missing item: `fn drop(&mut self) { todo!() }`
25+
26+
error: aborting due to 3 previous errors
1927

20-
Some errors have detailed explanations: E0117, E0120.
21-
For more information about an error, try `rustc --explain E0117`.
28+
Some errors have detailed explanations: E0046, E0117, E0120.
29+
For more information about an error, try `rustc --explain E0046`.

tests/ui/error-codes/E0120.rs

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ trait MyTrait { fn foo() {} }
33
impl Drop for dyn MyTrait {
44
//~^ ERROR E0120
55
fn drop(&mut self) {}
6+
//~^ ERROR E0038
7+
68
}
79

810
fn main() {}

tests/ui/error-codes/E0120.stderr

+25-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,29 @@ error[E0120]: the `Drop` trait may only be implemented for local structs, enums,
44
LL | impl Drop for dyn MyTrait {
55
| ^^^^^^^^^^^ must be a struct, enum, or union in the current crate
66

7-
error: aborting due to 1 previous error
7+
error[E0038]: the trait `MyTrait` cannot be made into an object
8+
--> $DIR/E0120.rs:5:18
9+
|
10+
LL | fn drop(&mut self) {}
11+
| ^^^^ `MyTrait` cannot be made into an object
12+
|
13+
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
14+
--> $DIR/E0120.rs:1:20
15+
|
16+
LL | trait MyTrait { fn foo() {} }
17+
| ------- ^^^ ...because associated function `foo` has no `self` parameter
18+
| |
19+
| this trait cannot be made into an object...
20+
help: consider turning `foo` into a method by giving it a `&self` argument
21+
|
22+
LL | trait MyTrait { fn foo(&self) {} }
23+
| +++++
24+
help: alternatively, consider constraining `foo` so it does not apply to trait objects
25+
|
26+
LL | trait MyTrait { fn foo() where Self: Sized {} }
27+
| +++++++++++++++++
28+
29+
error: aborting due to 2 previous errors
830

9-
For more information about this error, try `rustc --explain E0120`.
31+
Some errors have detailed explanations: E0038, E0120.
32+
For more information about an error, try `rustc --explain E0038`.

tests/ui/error-codes/E0374.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#![feature(coerce_unsized)]
22
use std::ops::CoerceUnsized;
33

4-
struct Foo<T: ?Sized> {
4+
struct Foo<T: ?Sized> { //~ ERROR `T` is never used
55
a: i32,
66
}
77

tests/ui/error-codes/E0374.stderr

+11-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@ LL | | where T: CoerceUnsized<U> {}
77
|
88
= note: expected a single field to be coerced, none found
99

10-
error: aborting due to 1 previous error
10+
error[E0392]: parameter `T` is never used
11+
--> $DIR/E0374.rs:4:12
12+
|
13+
LL | struct Foo<T: ?Sized> {
14+
| ^ unused parameter
15+
|
16+
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
17+
18+
error: aborting due to 2 previous errors
1119

12-
For more information about this error, try `rustc --explain E0374`.
20+
Some errors have detailed explanations: E0374, E0392.
21+
For more information about an error, try `rustc --explain E0374`.

0 commit comments

Comments
 (0)