Skip to content

Commit

Permalink
Rollup merge of rust-lang#120558 - oli-obk:missing_impl_item_ice, r=e…
Browse files Browse the repository at this point in the history
…stebank

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.
  • Loading branch information
matthiaskrgr authored Feb 4, 2024
2 parents 1bc76ef + 32b44ec commit c1cecc9
Show file tree
Hide file tree
Showing 48 changed files with 497 additions and 137 deletions.
4 changes: 4 additions & 0 deletions compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1964,6 +1964,10 @@ pub(super) fn check_type_bounds<'tcx>(
impl_ty: ty::AssocItem,
impl_trait_ref: ty::TraitRef<'tcx>,
) -> Result<(), ErrorGuaranteed> {
// Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
// other `Foo` impls are incoherent.
tcx.ensure().coherent_trait(impl_trait_ref.def_id)?;

let param_env = tcx.param_env(impl_ty.def_id);
debug!(?param_env);

Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1006,6 +1006,10 @@ fn check_associated_item(
enter_wf_checking_ctxt(tcx, span, item_id, |wfcx| {
let item = tcx.associated_item(item_id);

// Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
// other `Foo` impls are incoherent.
tcx.ensure().coherent_trait(tcx.local_parent(item_id))?;

let self_ty = match item.container {
ty::TraitContainer => tcx.types.self_param,
ty::ImplContainer => tcx.type_of(item.container_id(tcx)).instantiate_identity(),
Expand Down Expand Up @@ -1292,6 +1296,9 @@ fn check_impl<'tcx>(
// therefore don't need to be WF (the trait's `Self: Trait` predicate
// won't hold).
let trait_ref = tcx.impl_trait_ref(item.owner_id).unwrap().instantiate_identity();
// Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
// other `Foo` impls are incoherent.
tcx.ensure().coherent_trait(trait_ref.def_id)?;
let trait_ref = wfcx.normalize(
ast_trait_ref.path.span,
Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)),
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,11 +169,11 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {

tcx.sess.time("coherence_checking", || {
// Check impls constrain their parameters
let mut res =
let res =
tcx.hir().try_par_for_each_module(|module| tcx.ensure().check_mod_impl_wf(module));

for &trait_def_id in tcx.all_local_trait_impls(()).keys() {
res = res.and(tcx.ensure().coherent_trait(trait_def_id));
let _ = tcx.ensure().coherent_trait(trait_def_id);
}
// these queries are executed for side-effects (error reporting):
res.and(tcx.ensure().crate_inherent_impls(()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2364,6 +2364,12 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
return e;
}

if let Err(guar) = self.tcx.ensure().coherent_trait(trait_ref.def_id()) {
// Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
// other `Foo` impls are incoherent.
return guar;
}

// This is kind of a hack: it frequently happens that some earlier
// error prevents types from being fully inferred, and then we get
// a bunch of uninteresting errors saying something like "<generic
Expand Down Expand Up @@ -2659,6 +2665,14 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
if let Some(e) = self.tainted_by_errors() {
return e;
}

if let Err(guar) =
self.tcx.ensure().coherent_trait(self.tcx.parent(data.projection_ty.def_id))
{
// Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
// other `Foo` impls are incoherent.
return guar;
}
let subst = data
.projection_ty
.args
Expand Down
36 changes: 0 additions & 36 deletions library/core/src/primitive_docs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -448,22 +448,6 @@ mod prim_unit {}
#[doc(hidden)]
impl () {}

// Fake impl that's only really used for docs.
#[cfg(doc)]
#[stable(feature = "rust1", since = "1.0.0")]
impl Clone for () {
fn clone(&self) -> Self {
loop {}
}
}

// Fake impl that's only really used for docs.
#[cfg(doc)]
#[stable(feature = "rust1", since = "1.0.0")]
impl Copy for () {
// empty
}

#[rustc_doc_primitive = "pointer"]
#[doc(alias = "ptr")]
#[doc(alias = "*")]
Expand Down Expand Up @@ -1690,23 +1674,3 @@ mod prim_fn {}
// See src/librustdoc/passes/collect_trait_impls.rs:collect_trait_impls
#[doc(hidden)]
impl<Ret, T> fn(T) -> Ret {}

// Fake impl that's only really used for docs.
#[cfg(doc)]
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(fake_variadic)]
/// This trait is implemented on function pointers with any number of arguments.
impl<Ret, T> Clone for fn(T) -> Ret {
fn clone(&self) -> Self {
loop {}
}
}

// Fake impl that's only really used for docs.
#[cfg(doc)]
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(fake_variadic)]
/// This trait is implemented on function pointers with any number of arguments.
impl<Ret, T> Copy for fn(T) -> Ret {
// empty
}
1 change: 1 addition & 0 deletions tests/ui/associated-consts/issue-105330.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ fn foo<A: TraitWAssocConst<A=32>>() { //~ ERROR E0658

fn main<A: TraitWAssocConst<A=32>>() {
//~^ ERROR E0658
//~| ERROR E0131
foo::<Demo>();
}
12 changes: 9 additions & 3 deletions tests/ui/associated-consts/issue-105330.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,13 @@ LL | impl TraitWAssocConst for impl Demo {
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods

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

error: aborting due to 6 previous errors

Some errors have detailed explanations: E0404, E0562, E0658.
For more information about an error, try `rustc --explain E0404`.
Some errors have detailed explanations: E0131, E0404, E0562, E0658.
For more information about an error, try `rustc --explain E0131`.
2 changes: 0 additions & 2 deletions tests/ui/async-await/in-trait/coherence-constrained.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,13 @@ impl Foo for Bar {
type T = ();

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

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

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

fn main() {}
19 changes: 3 additions & 16 deletions tests/ui/async-await/in-trait/coherence-constrained.stderr
Original file line number Diff line number Diff line change
@@ -1,25 +1,12 @@
error[E0284]: type annotations needed: cannot satisfy `<Bar as Foo>::T == ()`
--> $DIR/coherence-constrained.rs:14:5
|
LL | async fn foo(&self) {}
| ^^^^^^^^^^^^^^^^^^^ cannot satisfy `<Bar as Foo>::T == ()`

error[E0284]: type annotations needed: cannot satisfy `<Bar as Foo>::T == ()`
--> $DIR/coherence-constrained.rs:22:5
|
LL | async fn foo(&self) {}
| ^^^^^^^^^^^^^^^^^^^ cannot satisfy `<Bar as Foo>::T == ()`

error[E0119]: conflicting implementations of trait `Foo` for type `Bar`
--> $DIR/coherence-constrained.rs:18:1
--> $DIR/coherence-constrained.rs:17:1
|
LL | impl Foo for Bar {
| ---------------- first implementation here
...
LL | impl Foo for Bar {
| ^^^^^^^^^^^^^^^^ conflicting implementation for `Bar`

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

Some errors have detailed explanations: E0119, E0284.
For more information about an error, try `rustc --explain E0119`.
For more information about this error, try `rustc --explain E0119`.
20 changes: 20 additions & 0 deletions tests/ui/coherence/associated-type2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//! A regression test for #120343. The overlap error was previously
//! silenced in coherence because projecting `<() as ToUnit>::Unit`
//! failed. Then then silenced the missing items error in the `ToUnit`
//! impl, causing us to not emit any errors and ICEing due to a
//! `span_delay_bug`.
trait ToUnit {
type Unit;
}

impl<T> ToUnit for *const T {}
//~^ ERROR: not all trait items implemented

trait Overlap<T> {}

impl<T> Overlap<T> for T {}

impl<T> Overlap<<*const T as ToUnit>::Unit> for T {}

fn main() {}
12 changes: 12 additions & 0 deletions tests/ui/coherence/associated-type2.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error[E0046]: not all trait items implemented, missing: `Unit`
--> $DIR/associated-type2.rs:11:1
|
LL | type Unit;
| --------- `Unit` from trait
...
LL | impl<T> ToUnit for *const T {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Unit` in implementation

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0046`.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ struct MyType {
impl MyTrait<MyType> for MyType {
//~^ ERROR E0119
fn get(&self) -> usize { (*self).clone() }
//~^ ERROR incompatible type
}

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

error: aborting due to 1 previous error
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: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0119`.
Some errors have detailed explanations: E0053, E0119.
For more information about an error, try `rustc --explain E0053`.
3 changes: 3 additions & 0 deletions tests/ui/coherence/coherence-orphan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@ 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
//~^ WARNING
Expand Down
33 changes: 29 additions & 4 deletions tests/ui/coherence/coherence-orphan.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ LL | impl TheTrait<usize> for isize { }
= note: define and implement a trait or new type instead

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

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

error: aborting due to 2 previous errors; 1 warning emitted
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: aborting due to 5 previous errors; 1 warning emitted

For more information about this error, try `rustc --explain E0117`.
Some errors have detailed explanations: E0046, E0117.
For more information about an error, try `rustc --explain E0046`.
5 changes: 5 additions & 0 deletions tests/ui/coherence/deep-bad-copy-reason.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ extern "Rust" {
}

pub struct ListS<T> {
//~^ NOTE: required because it appears within the type
len: usize,
data: [T; 0],
opaque: OpaqueListContents,
}

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

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

impl<'tcx, T> Clone for List<'tcx, T> {
fn clone(&self) -> Self {
Expand Down
31 changes: 27 additions & 4 deletions tests/ui/coherence/deep-bad-copy-reason.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0204]: the trait `Copy` cannot be implemented for this type
--> $DIR/deep-bad-copy-reason.rs:33:24
--> $DIR/deep-bad-copy-reason.rs:38:24
|
LL | pub struct List<'tcx, T>(Interned<'tcx, ListS<T>>);
| ------------------------ this field does not implement `Copy`
Expand All @@ -8,11 +8,34 @@ LL | impl<'tcx, T> Copy for List<'tcx, T> {}
| ^^^^^^^^^^^^^
|
note: the `Copy` impl for `Interned<'tcx, ListS<T>>` requires that `OpaqueListContents: Sized`
--> $DIR/deep-bad-copy-reason.rs:23:26
--> $DIR/deep-bad-copy-reason.rs:26:26
|
LL | pub struct List<'tcx, T>(Interned<'tcx, ListS<T>>);
| ^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 1 previous error
error[E0277]: the size for values of type `OpaqueListContents` cannot be known at compilation time
--> $DIR/deep-bad-copy-reason.rs:26:26
|
LL | pub struct List<'tcx, T>(Interned<'tcx, ListS<T>>);
| ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: within `ListS<T>`, the trait `Sized` is not implemented for `OpaqueListContents`, which is required by `ListS<T>: Sized`
note: required because it appears within the type `ListS<T>`
--> $DIR/deep-bad-copy-reason.rs:7:12
|
LL | pub struct ListS<T> {
| ^^^^^
note: required by a bound in `Interned`
--> $DIR/deep-bad-copy-reason.rs:14:25
|
LL | pub struct Interned<'a, T>(&'a T);
| ^ required by this bound in `Interned`
help: consider relaxing the implicit `Sized` restriction
|
LL | pub struct Interned<'a, T: ?Sized>(&'a T);
| ++++++++

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0204`.
Some errors have detailed explanations: E0204, E0277.
For more information about an error, try `rustc --explain E0204`.
Loading

0 comments on commit c1cecc9

Please sign in to comment.