Skip to content

Commit 83738a9

Browse files
committed
Stop bailing out from compilation just because there were incoherent traits
1 parent 7f1d523 commit 83738a9

Some content is hidden

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

46 files changed

+473
-92
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

+8
Original file line numberDiff line numberDiff line change
@@ -1005,6 +1005,11 @@ fn check_associated_item(
10051005
enter_wf_checking_ctxt(tcx, span, item_id, |wfcx| {
10061006
let item = tcx.associated_item(item_id);
10071007

1008+
// Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
1009+
// other `Foo` impls are incoherent.
1010+
tcx.ensure()
1011+
.coherent_trait(tcx.parent(item.trait_item_def_id.unwrap_or(item_id.into())))?;
1012+
10081013
let self_ty = match item.container {
10091014
ty::TraitContainer => tcx.types.self_param,
10101015
ty::ImplContainer => tcx.type_of(item.container_id(tcx)).instantiate_identity(),
@@ -1291,6 +1296,9 @@ fn check_impl<'tcx>(
12911296
// therefore don't need to be WF (the trait's `Self: Trait` predicate
12921297
// won't hold).
12931298
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)?;
12941302
let trait_ref = wfcx.normalize(
12951303
ast_trait_ref.path.span,
12961304
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(()))

compiler/rustc_hir_typeck/src/callee.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ pub fn check_legal_trait_for_method_call(
4141
receiver: Option<Span>,
4242
expr_span: Span,
4343
trait_id: DefId,
44-
) {
44+
) -> Result<(), ErrorGuaranteed> {
4545
if tcx.lang_items().drop_trait() == Some(trait_id) {
4646
let sugg = if let Some(receiver) = receiver.filter(|s| !s.is_empty()) {
4747
errors::ExplicitDestructorCallSugg::Snippet {
@@ -51,8 +51,9 @@ pub fn check_legal_trait_for_method_call(
5151
} else {
5252
errors::ExplicitDestructorCallSugg::Empty(span)
5353
};
54-
tcx.dcx().emit_err(errors::ExplicitDestructorCall { span, sugg });
54+
return Err(tcx.dcx().emit_err(errors::ExplicitDestructorCall { span, sugg }));
5555
}
56+
tcx.coherent_trait(trait_id)
5657
}
5758

5859
#[derive(Debug)]

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

+11-7
Original file line numberDiff line numberDiff line change
@@ -1105,13 +1105,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11051105
let container_id = assoc_item.container_id(tcx);
11061106
debug!(?def_id, ?container, ?container_id);
11071107
match container {
1108-
ty::TraitContainer => callee::check_legal_trait_for_method_call(
1109-
tcx,
1110-
path_span,
1111-
None,
1112-
span,
1113-
container_id,
1114-
),
1108+
ty::TraitContainer => {
1109+
if let Err(e) = callee::check_legal_trait_for_method_call(
1110+
tcx,
1111+
path_span,
1112+
None,
1113+
span,
1114+
container_id,
1115+
) {
1116+
self.set_tainted_by_errors(e);
1117+
}
1118+
}
11151119
ty::ImplContainer => {
11161120
if segments.len() == 1 {
11171121
// `<T>::assoc` will end up here, and so

compiler/rustc_hir_typeck/src/method/confirm.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -630,13 +630,15 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
630630
fn enforce_illegal_method_limitations(&self, pick: &probe::Pick<'_>) {
631631
// Disallow calls to the method `drop` defined in the `Drop` trait.
632632
if let Some(trait_def_id) = pick.item.trait_container(self.tcx) {
633-
callee::check_legal_trait_for_method_call(
633+
if let Err(e) = callee::check_legal_trait_for_method_call(
634634
self.tcx,
635635
self.span,
636636
Some(self.self_expr.span),
637637
self.call_expr.span,
638638
trait_def_id,
639-
)
639+
) {
640+
self.set_tainted_by_errors(e);
641+
}
640642
}
641643
}
642644

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 an implicit `Sized`
16+
//~| NOTE: required by the implicit `Sized`
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 an implicit `Sized` 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 the implicit `Sized` requirement on this type parameter 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`.

0 commit comments

Comments
 (0)