Skip to content

Commit 6b71dd2

Browse files
committed
Auto merge of rust-lang#120558 - oli-obk:missing_impl_item_ice, r=estebank
Stop bailing out from compilation just because there were incoherent traits fixes rust-lang#120343 but also has a lot of "type annotations needed" fallout. Some are fixed in the second commit.
2 parents d4f6f9e + a59a1e7 commit 6b71dd2

File tree

50 files changed

+490
-146
lines changed

Some content is hidden

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

50 files changed

+490
-146
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

compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs

+14
Original file line numberDiff line numberDiff line change
@@ -2371,6 +2371,12 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
23712371
return e;
23722372
}
23732373

2374+
if let Err(guar) = self.tcx.ensure().coherent_trait(trait_ref.def_id()) {
2375+
// Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
2376+
// other `Foo` impls are incoherent.
2377+
return guar;
2378+
}
2379+
23742380
// This is kind of a hack: it frequently happens that some earlier
23752381
// error prevents types from being fully inferred, and then we get
23762382
// a bunch of uninteresting errors saying something like "<generic
@@ -2666,6 +2672,14 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
26662672
if let Some(e) = self.tainted_by_errors() {
26672673
return e;
26682674
}
2675+
2676+
if let Err(guar) =
2677+
self.tcx.ensure().coherent_trait(self.tcx.parent(data.projection_ty.def_id))
2678+
{
2679+
// Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
2680+
// other `Foo` impls are incoherent.
2681+
return guar;
2682+
}
26692683
let subst = data
26702684
.projection_ty
26712685
.args

library/core/src/primitive_docs.rs

-36
Original file line numberDiff line numberDiff line change
@@ -448,22 +448,6 @@ mod prim_unit {}
448448
#[doc(hidden)]
449449
impl () {}
450450

451-
// Fake impl that's only really used for docs.
452-
#[cfg(doc)]
453-
#[stable(feature = "rust1", since = "1.0.0")]
454-
impl Clone for () {
455-
fn clone(&self) -> Self {
456-
loop {}
457-
}
458-
}
459-
460-
// Fake impl that's only really used for docs.
461-
#[cfg(doc)]
462-
#[stable(feature = "rust1", since = "1.0.0")]
463-
impl Copy for () {
464-
// empty
465-
}
466-
467451
#[rustc_doc_primitive = "pointer"]
468452
#[doc(alias = "ptr")]
469453
#[doc(alias = "*")]
@@ -1690,23 +1674,3 @@ mod prim_fn {}
16901674
// See src/librustdoc/passes/collect_trait_impls.rs:collect_trait_impls
16911675
#[doc(hidden)]
16921676
impl<Ret, T> fn(T) -> Ret {}
1693-
1694-
// Fake impl that's only really used for docs.
1695-
#[cfg(doc)]
1696-
#[stable(feature = "rust1", since = "1.0.0")]
1697-
#[doc(fake_variadic)]
1698-
/// This trait is implemented on function pointers with any number of arguments.
1699-
impl<Ret, T> Clone for fn(T) -> Ret {
1700-
fn clone(&self) -> Self {
1701-
loop {}
1702-
}
1703-
}
1704-
1705-
// Fake impl that's only really used for docs.
1706-
#[cfg(doc)]
1707-
#[stable(feature = "rust1", since = "1.0.0")]
1708-
#[doc(fake_variadic)]
1709-
/// This trait is implemented on function pointers with any number of arguments.
1710-
impl<Ret, T> Copy for fn(T) -> Ret {
1711-
// empty
1712-
}

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`.

tests/ui/async-await/in-trait/coherence-constrained.rs

-2
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,13 @@ impl Foo for Bar {
1212
type T = ();
1313

1414
async fn foo(&self) {}
15-
//~^ ERROR type annotations needed: cannot satisfy `<Bar as Foo>::T == ()`
1615
}
1716

1817
impl Foo for Bar {
1918
//~^ ERROR conflicting implementations of trait `Foo` for type `Bar`
2019
type T = ();
2120

2221
async fn foo(&self) {}
23-
//~^ ERROR type annotations needed: cannot satisfy `<Bar as Foo>::T == ()`
2422
}
2523

2624
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,12 @@
1-
error[E0284]: type annotations needed: cannot satisfy `<Bar as Foo>::T == ()`
2-
--> $DIR/coherence-constrained.rs:14:5
3-
|
4-
LL | async fn foo(&self) {}
5-
| ^^^^^^^^^^^^^^^^^^^ cannot satisfy `<Bar as Foo>::T == ()`
6-
7-
error[E0284]: type annotations needed: cannot satisfy `<Bar as Foo>::T == ()`
8-
--> $DIR/coherence-constrained.rs:22:5
9-
|
10-
LL | async fn foo(&self) {}
11-
| ^^^^^^^^^^^^^^^^^^^ cannot satisfy `<Bar as Foo>::T == ()`
12-
131
error[E0119]: conflicting implementations of trait `Foo` for type `Bar`
14-
--> $DIR/coherence-constrained.rs:18:1
2+
--> $DIR/coherence-constrained.rs:17:1
153
|
164
LL | impl Foo for Bar {
175
| ---------------- first implementation here
186
...
197
LL | impl Foo for Bar {
208
| ^^^^^^^^^^^^^^^^ conflicting implementation for `Bar`
219

22-
error: aborting due to 3 previous errors
10+
error: aborting due to 1 previous error
2311

24-
Some errors have detailed explanations: E0119, E0284.
25-
For more information about an error, try `rustc --explain E0119`.
12+
For more information about this error, try `rustc --explain E0119`.
+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`.

0 commit comments

Comments
 (0)