Skip to content

ICE: unexpected initial operand type. #114858

Open
@fakeshadow

Description

@fakeshadow

I tried this code:

#![feature(impl_trait_in_assoc_type)]

use std::{future::Future, convert::Infallible};

trait AsyncFn<Arg> {
    type Output;
    type Future<'f>: Future<Output = Self::Output>
    where
        Arg: 'f,
        Self: 'f;

    fn call<'s>(&'s self, arg: Arg) -> Self::Future<'s>
    where
        Arg: 's;
}

trait AsyncFn2<Arg> {
    type Output;
    type Future: Future<Output = Self::Output>;

    fn call(&self, arg: Arg) -> Self::Future;
}

impl<F, A, B, Fut> AsyncFn2<(A, B)> for F
where
    F: Fn(A, B) -> Fut,
    Fut: Future,
{
    type Output = Fut::Output;
    type Future = Fut;

    fn call(&self, (a, b): (A, B)) -> Self::Future {
        self(a, b)
    }
}

struct Func<F>(F);

impl<Arg, F, Fut> AsyncFn<Arg> for Func<F>
where
    F: Fn(Arg) -> Fut,
    Fut: Future,
{
    type Output = Fut::Output;
    type Future<'f> = impl Future<Output = Self::Output> + 'f where Arg: 'f, Self: 'f;

    fn call<'s>(&'s self, arg: Arg) -> Self::Future<'s>
    where
        Arg: 's,
    {
        async move { (self.0)(arg).await }
    }
}

struct EnclosedFn<T1, T2> {
    this: T1,
    other: T2,
}

impl<Arg, T1, T2, O> AsyncFn<Arg> for EnclosedFn<T1, T2>
where
    T1: AsyncFn<Arg>,
    T2: for<'s> AsyncFn2<(&'s T1, Arg), Output = O>,
{
    type Output = O;
    type Future<'f> = impl Future<Output = Self::Output> + 'f where Arg: 'f, Self: 'f;

    fn call<'s>(&'s self, arg: Arg) -> Self::Future<'s>
    where
        Arg: 's,
    {
        self.other.call((&self.this, arg))
    }
}

trait Enclosed<Arg>: AsyncFn<Arg> {
    fn enclosed<T>(self, other: T) -> EnclosedFn<Self, T>
    where
        T: for<'s> AsyncFn2<(&'s Self, Arg)>,
        Self: Sized,
    {
        EnclosedFn { this: self, other }
    }
}

impl<Arg, F> Enclosed<Arg> for F where F: AsyncFn<Arg> {}

fn main() {
    async fn middelware<S, Arg>(s: &S, arg: Arg) -> S::Output
    where
        S: AsyncFn<Arg>,
    {
        s.call(arg).await
    }

    let f = Func(|arg: String| async move { Ok::<_, Infallible>(arg) })
        .enclosed(middelware)
        .enclosed(middelware);

    futures::executor::block_on(f.call(String::new())).unwrap();
}

I expected to see this happen: code compile.

Instead, this happened: internal compiler error: unexpected initial operand type

Meta

rustc --version --verbose:

rustc 1.73.0-nightly (1b198b3a1 2023-08-13)
binary: rustc
commit-hash: 1b198b3a196442e14fb06978166ab46a4618d131
commit-date: 2023-08-13
host: x86_64-unknown-linux-gnu
release: 1.73.0-nightly
LLVM version: 17.0.0
Backtrace

thread 'rustc' panicked at /rustc/1b198b3a196442e14fb06978166ab46a4618d131/compiler/rustc_codegen_ssa/src/mir/locals.rs:46:21:
assertion failed: `(left == right)`
  left: `*mut [async fn body@src/main.rs:333:5: 335:6]`,
 right: `*mut [async fn body@src/main.rs:333:5: 335:6]`: unexpected initial operand type
stack backtrace:
   0: rust_begin_unwind
             at /rustc/1b198b3a196442e14fb06978166ab46a4618d131/library/std/src/panicking.rs:617:5
   1: core::panicking::panic_fmt
             at /rustc/1b198b3a196442e14fb06978166ab46a4618d131/library/core/src/panicking.rs:67:14
   2: core::panicking::assert_failed_inner
   3: core::panicking::assert_failed::<rustc_middle::ty::Ty, rustc_middle::ty::Ty>
   4: rustc_codegen_ssa::mir::codegen_mir::<rustc_codegen_llvm::builder::Builder>
   5: rustc_codegen_llvm::base::compile_codegen_unit::module_codegen
   6: <rustc_middle::dep_graph::dep_node::DepKind as rustc_query_system::dep_graph::DepKind>::with_deps::<<rustc_query_system::dep_graph::graph::DepGraphData<rustc_middle::dep_graph::dep_node::DepKind>>::with_task<rustc_middle::ty::context::TyCtxt, rustc_span::symbol::Symbol, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>::{closure#0}::{closure#0}, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>
   7: rustc_codegen_llvm::base::compile_codegen_unit
   8: rustc_codegen_ssa::base::codegen_crate::<rustc_codegen_llvm::LlvmCodegenBackend>
   9: <rustc_codegen_llvm::LlvmCodegenBackend as rustc_codegen_ssa::traits::backend::CodegenBackend>::codegen_crate
  10: <rustc_session::session::Session>::time::<alloc::boxed::Box<dyn core::any::Any>, rustc_interface::passes::start_codegen::{closure#0}>
  11: rustc_interface::passes::start_codegen
  12: <rustc_middle::ty::context::GlobalCtxt>::enter::<<rustc_interface::queries::Queries>::ongoing_codegen::{closure#0}, core::result::Result<alloc::boxed::Box<dyn core::any::Any>, rustc_span::ErrorGuaranteed>>
  13: rustc_span::set_source_map::<core::result::Result<(), rustc_span::ErrorGuaranteed>, rustc_interface::interface::run_compiler<core::result::Result<(), rustc_span::ErrorGuaranteed>, rustc_driver_impl::run_compiler::{closure#1}>::{closure#0}::{closure#0}>
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.F-impl_trait_in_assoc_type`#![feature(impl_trait_in_assoc_type)]`I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️P-highHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions