Repository: rust
Issue: ICE while re-compiling trait-heavy inferences.
Labels: I-ICE,T-compiler,C-bug

<!--
Thank you for finding an Internal Compiler Error! 🧊  If possible, try to provide
a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for
how to create smaller examples.
http://blog.pnkfx.org/blog/2019/11/18/rust-bug-minimization-patterns/
-->

### Code

The code is, uh, quite expansive if not complex. I copied the probably relevant traits below, but I don't have the time to narrow it down right now.

I also can't reproduce it on demand, so I think it has to do with incremental compilation. This does happen whenever I adjust the types implementing the following traits.

```Rust
pub struct P {}
impl FocusedProcessor<A> for P {}
impl FocusedProcessor<B> for P {}

fn p() -> impl FullyCapableProcessor {
    P{}
}
```

```Rust
impl Request for A {}
impl Request for B {}
pub trait FullyCapableProcessor: Processor<A> + Processor<B> {} // And so on.
impl <P> FullyCapableProcessor for P where P: Processor<A> + Processor<B> {} // Matching above
```

```Rust
//! Contains the basic trait that will need to be implemented.
//!
//! The usual way to implement `Processor` for a request is to:
//! - Implement `Contextual`.
//! - Implement `FocusedProcessor` for each request.
//! - Return the struct as a `request::FullyCapableProcessor` to verify that all requests are
//!   handled.

use std::{fmt::Debug, any::type_name_of_val};

use async_trait::async_trait;
use dbt::id::{DiscordUserId, DiscordChannelId};
use tracing::Instrument;

pub trait Contextual {
    type Value<'a>: tracing::Value where Self: 'a;

    fn ui<'a>(&'a self) -> &'a str;
    fn ui_context(&self) -> Self::Value<'_>;
}

#[async_trait]
pub trait FocusedProcessor<Req: Request + Send + Debug + Sized> {
    async fn process_only(&self, req: Req) -> Req::Output where Req: 'async_trait;
}

// TODO Consider removing Debug bound.
#[async_trait]
pub trait Processor<Req: Request + Send + Debug + Sized>: Sized + Sync {
    /// Processes a request with logging. Delegates to FocusedProcessor.
    async fn process(&self, req: Req) -> Req::Output
        where Req: 'async_trait;
}

#[async_trait]
impl <Req: Sized + Send + Debug + Request, P: Sized + Sync + FocusedProcessor<Req> + Contextual> Processor<Req> for P {
    /// Processes a request with logging. Delegates to process_request.
    async fn process(&self, req: Req) -> Req::Output
        where Req: 'async_trait
    {
        let req_name = type_name_of_val(&req);
        log::info!("REQUEST-STARTED req={req_name}");
        let start = chrono::Utc::now();
        let output = self.process_only(req)
            .instrument(tracing::span!(
                tracing::Level::INFO,
                "REQUEST",
                ui = self.ui(),
                context = self.ui_context(),
            ))
            .await;
        let end = chrono::Utc::now();
        output.log(req_name);
        let diff = end - start;
        let diff_ns = diff.num_nanoseconds().unwrap_or(-1);
        let diff_ms = diff.num_milliseconds();
        log::info!("REQUEST-TIMING req={req_name} duration={diff_ns}ns human={diff_ms}ms");
        output
    }
}

#[async_trait]
pub trait Request {
    type Output: CompletionLoggable;
}

pub trait CompletionLoggable: Sized {
    /// Once execution returns a value of this type, runs this.
    ///
    /// This function should only log.
    fn log(&self, req_name: &'static str) {
        log::info!("REQUEST-COMPLETE req={req_name}");
    }
}
```


### Meta
<!--
If you're using the stable version of the compiler, you should also check if the
bug also exists in the beta or nightly versions.
-->

(pulled from further down)
`rustc --version --verbose`:
```
rustc 1.71.0-nightly (fec9adcdb 2023-04-21)
x86_64-unknown-linux-gnu
```

(Yeah, not up to date, but I've seen it pop up. That plus not being really regularly reproducible kind of makes it hard to updated and see the same error again.)