rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
97.98k stars 12.68k forks source link

FulfilmentError ICE with trait-provided method implementations and -Clink-dead-code #90992

Closed nagisa closed 1 year ago

nagisa commented 2 years ago

The following code ICEs from 1.24.0 onwards when built with -Clink-dead-code (godbolt):

struct Banana<'a>(&'a ());

pub trait Peach: Sized {
    fn chaenomeles() -> Self;
    fn apple() -> Self {
        Self::chaenomeles()
    }
}

impl <'a> Peach for Banana<'a>
where &'a (): Peach {
     fn chaenomeles() -> Banana<'a> {
        unimplemented!()
    }
}

In this example, the where &'a (): Peach bound is never satisfied and it is indeed reported as such by the compiler when attempting to call Banana::<'static>::apple explicitly:

error[E0599]: the function or associated item `apple` exists for struct `Banana<'static>`, but its trait bounds were not satisfied
  --> <source>:18:24
   |
1  | struct Banana<'a>(&'a ());
   | --------------------------
   | |
   | function or associated item `apple` not found for this
   | doesn't satisfy `Banana<'_>: Peach`
...
18 |     Banana::<'static>::apple();
   |                        ^^^^^ function or associated item cannot be called on `Banana<'static>` due to unsatisfied trait bounds
   |
   = note: the following trait bounds were not satisfied:
           `&(): Peach`
           which is required by `Banana<'_>: Peach`
   = help: items from traits can only be used if the trait is implemented and in scope
note: `Peach` defines an item `apple`, perhaps you need to implement it
  --> <source>:3:1
   |
3  | pub trait Peach: Sized {
   | ^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

However in absence of calls to Banana::apple there is nothing to “force” typeck to report this error and yet -Clink-dead-code causes codegen to attempt to codegen the method anyway, despite the where clause not being satisfied.

The correct fix here would probably to make sure that the monomorphization collector in -Clink-dead-code mode does not collect items with unsatisfied bounds?

Additionally, I feel like a lint warning along the lines of

warning: this where clause is never satisfied
     where &'a (): Peach
           ^^^^^^^^^^^^^

could be useful

cjgillot commented 1 year ago

Fixed by https://github.com/rust-lang/rust/pull/109321