Skip to content

Failed to normalize async_fn_in_trait ICE for indirect recursion of async trait method calls #112047

Closed

Description

@rkusa

The following happens for the async_fn_in_trait feature. I guess it is caused by the indirect recursion (First::first() -> Second::second() -> First::first() -> Second::second() -> First::first() -> ...).

Code

#![feature(async_fn_in_trait)]

fn main() {
    let _ = async {
        A.first().await.second().await;
    };
}

pub trait First {
    type Second: Second;
    async fn first(self) -> Self::Second;
}

struct A;

impl First for A {
    type Second = A;
    async fn first(self) -> Self::Second {
        A
    }
}

pub trait Second {
    async fn second(self);
}

impl<C> Second for C
where
    C: First,
{
    async fn second(self) {
        self.first().await.second().await;
    }
}

Meta

rustc --version --verbose:

rustc 1.71.0-nightly (cca7ee581 2023-05-27)
binary: rustc
commit-hash: cca7ee58110726983951a19d5fb7316d9243925d
commit-date: 2023-05-27
host: aarch64-apple-darwin
release: 1.71.0-nightly
LLVM version: 16.0.4

Error output

error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:195:90: Failed to normalize [async block@src/main.rs:4:13: 6:6], maybe try to call `try_normalize_erasing_regions` instead
Backtrace

thread 'rustc' panicked at 'Box<dyn Any>', /rustc/cca7ee58110726983951a19d5fb7316d9243925d/compiler/rustc_errors/src/lib.rs:1651:9
stack backtrace:
   0: std::panicking::begin_panic::<rustc_errors::ExplicitBug>
   1: <rustc_errors::HandlerInner>::bug::<alloc::string::String>
   2: <rustc_errors::Handler>::bug::<alloc::string::String>
   3: rustc_middle::util::bug::opt_span_bug_fmt::<rustc_span::span_encoding::Span>::{closure#0}
   4: rustc_middle::ty::context::tls::with_opt::<rustc_middle::util::bug::opt_span_bug_fmt<rustc_span::span_encoding::Span>::{closure#0}, !>::{closure#0}
   5: rustc_middle::ty::context::tls::with_context_opt::<rustc_middle::ty::context::tls::with_opt<rustc_middle::util::bug::opt_span_bug_fmt<rustc_span::span_encoding::Span>::{closure#0}, !>::{closure#0}, !>
   6: rustc_middle::util::bug::bug_fmt
   7: <rustc_middle::ty::normalize_erasing_regions::NormalizeAfterErasingRegionsFolder as rustc_type_ir::fold::TypeFolder<rustc_middle::ty::context::TyCtxt>>::fold_ty
   8: <rustc_monomorphize::collector::MirNeighborCollector as rustc_middle::mir::visit::Visitor>::visit_terminator
   9: rustc_monomorphize::collector::collect_neighbours
  10: rustc_monomorphize::collector::collect_items_rec
  11: <core::panic::unwind_safe::AssertUnwindSafe<rustc_data_structures::sync::par_for_each_in<alloc::vec::Vec<rustc_middle::mir::mono::MonoItem>, rustc_monomorphize::collector::collect_crate_mono_items::{closure#1}::{closure#0}>::{closure#0}::{closure#0}> as core::ops::function::FnOnce<()>>::call_once
  12: rustc_data_structures::sync::par_for_each_in::<alloc::vec::Vec<rustc_middle::mir::mono::MonoItem>, rustc_monomorphize::collector::collect_crate_mono_items::{closure#1}::{closure#0}>
  13: <rustc_session::session::Session>::time::<(), rustc_monomorphize::collector::collect_crate_mono_items::{closure#1}>
  14: rustc_monomorphize::collector::collect_crate_mono_items
  15: rustc_monomorphize::partitioning::collect_and_partition_mono_items
  16: rustc_codegen_ssa::base::codegen_crate::<rustc_codegen_llvm::LlvmCodegenBackend>
  17: <rustc_codegen_llvm::LlvmCodegenBackend as rustc_codegen_ssa::traits::backend::CodegenBackend>::codegen_crate
  18: rustc_interface::passes::start_codegen
  19: <rustc_middle::ty::context::GlobalCtxt>::enter::<<rustc_interface::queries::Queries>::ongoing_codegen::{closure#0}::{closure#0}, core::result::Result<alloc::boxed::Box<dyn core::any::Any>, rustc_span::ErrorGuaranteed>>
  20: <rustc_interface::queries::Queries>::ongoing_codegen
  21: <rustc_interface::interface::Compiler>::enter::<rustc_driver_impl::run_compiler::{closure#1}::{closure#2}, core::result::Result<core::option::Option<rustc_interface::queries::Linker>, rustc_span::ErrorGuaranteed>>
  22: 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}>
  23: <scoped_tls::ScopedKey<rustc_span::SessionGlobals>>::set::<rustc_interface::interface::run_compiler<core::result::Result<(), rustc_span::ErrorGuaranteed>, rustc_driver_impl::run_compiler::{closure#1}>::{closure#0}, core::result::Result<(), rustc_span::ErrorGuaranteed>>
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md

note: rustc 1.71.0-nightly (cca7ee581 2023-05-27) running on aarch64-apple-darwin

note: compiler flags: --crate-type bin -C embed-bitcode=no -C split-debuginfo=unpacked -C debuginfo=2 -C incremental=[REDACTED]

note: some of the compiler flags provided by cargo are hidden

query stack during panic:
#0 [collect_and_partition_mono_items] collect_and_partition_mono_items
end of query stack

Activity

  1. added
    C-bugCategory: This is a bug.
    I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on May 28, 2023
  2. matthiaskrgr commented on Jun 11, 2023

    @matthiaskrgr
    Member

    Regression in nightly-2022-09-24

  3. compiler-errors commented on Jun 26, 2023

    @compiler-errors
    Contributor

    This is reproducible with type alias impl trait (well, impl trait in assoc ty) similarly:

    #![feature(impl_trait_in_assoc_type)]
    
    use core::future::Future;
    
    trait Recur {
        type Recur: Future<Output = ()>;
        
        fn recur(self) -> Self::Recur;
    }
    
    async fn recur(t: impl Recur) {
        t.recur().await;
    }
    
    impl Recur for () {
        type Recur = impl Future<Output = ()>;
        
        fn recur(self) -> Self::Recur {
            async move { recur(self).await; }
        }
    }
    
    fn main() {
        recur(());
    }

    I consider this to be somewhat concerning, because both of these features introduce a new kind of post-monomorphization error that (afaict) can't be reproduced with associated types on stable rust.

  4. added a commit that references this issue on Sep 19, 2023
    0060db7
  5. added a commit that references this issue on Sep 19, 2023
    64d2330
  6. added a commit that references this issue on Oct 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-codegenArea: Code generationC-bugCategory: This is a bug.F-async_fn_in_traitStatic async fn in traitsF-type_alias_impl_trait`#[feature(type_alias_impl_trait)]`I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.glacierICE tracked in rust-lang/glacier.

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions