Skip to content

Compiler stack overflow when calling function on generic struct with TAIT resolving to lambda #136390

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
Elekrisk opened this issue Feb 1, 2025 · 4 comments
Labels
C-bug Category: This is a bug. I-crash Issue: The compiler crashes (SIGSEGV, SIGABRT, etc). Use I-ICE instead when the compiler panics. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@Elekrisk
Copy link

Elekrisk commented Feb 1, 2025

I tried this code:

#![feature(type_alias_impl_trait)]

type X = impl FnOnce();

struct S<F>(F);

impl S<X> {
    fn new() -> Self {
        Self(|| {})
    }
}

fn main() {
    S::new();
}

I expected to see this happen: Compilation succeeds.

Instead, this happened: Compiler crashes with a stack overflow, although only in debug mode.

I ran this through cargo bisect-rustc and got the following:

Regression in rust-lang-ci@89bc42c
The PR introducing the regression in this rollup is #134081: Try to evaluate constants in legacy mangling

searched nightlies: from nightly-2024-10-11 to nightly-2025-02-01
regressed nightly: nightly-2024-12-15
searched commit range: 327c7ee...0aeaa5e
regressed commit: f1ec5d6

bisected with cargo-bisect-rustc v0.6.9

Host triple: x86_64-unknown-linux-gnu
Reproduce with:

cargo bisect-rustc --start=2024-10-11 

I am guessing that the TAIT being in the symbol path of new messes something up with creating the mangled symbol name.

Meta

rustc --version --verbose:

rustc 1.86.0-nightly (854f22563 2025-01-31)
binary: rustc
commit-hash: 854f22563c8daf92709fae18ee6aed52953835cd
commit-date: 2025-01-31
host: x86_64-unknown-linux-gnu
release: 1.86.0-nightly
LLVM version: 19.1.7
Backtrace

/home/elekrisk/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/librustc_driver-8cb71fa651fbc0f4.so(+0x37a6cc3) [0x705d645a6cc3]
/usr/lib/libc.so.6(+0x3d1d0) [0x705d60c4c1d0]
/home/elekrisk/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/librustc_driver-8cb71fa651fbc0f4.so(+0x5521865) [0x705d66321865]

### cycle encountered after 3 frames with period 5
/home/elekrisk/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/librustc_driver-8cb71fa651fbc0f4.so(+0x5520108) [0x705d66320108]
/home/elekrisk/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/librustc_driver-8cb71fa651fbc0f4.so(+0x55228a1) [0x705d663228a1]
/home/elekrisk/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/librustc_driver-8cb71fa651fbc0f4.so(+0x5521a2b) [0x705d66321a2b]
/home/elekrisk/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/librustc_driver-8cb71fa651fbc0f4.so(+0x5521a2b) [0x705d66321a2b]
/home/elekrisk/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/librustc_driver-8cb71fa651fbc0f4.so(+0x5522183) [0x705d66322183]
### recursed 50 times

/home/elekrisk/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/librustc_driver-8cb71fa651fbc0f4.so(+0x5520108) [0x705d66320108]
/home/elekrisk/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/librustc_driver-8cb71fa651fbc0f4.so(+0x55228a1) [0x705d663228a1]
/home/elekrisk/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/librustc_driver-8cb71fa651fbc0f4.so(+0x5521a2b) [0x705d66321a2b]

@Elekrisk Elekrisk added the C-bug Category: This is a bug. label Feb 1, 2025
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Feb 1, 2025
@Elekrisk
Copy link
Author

Elekrisk commented Feb 1, 2025

It seems to be specifically when the TAIT is resolved to a lambda function.

#![feature(type_alias_impl_trait)]

trait T {}
impl<F: Fn()> T for F {}
impl T for bool {}

type A = impl T;
type B = impl T;
type C = impl T;

struct S<F>(F);

impl S<A> {
    // causes crash if called
    fn new_a() -> Self {
        Self(|| {})
    }
}
impl S<B> {
    // does not cause crash if called
    fn new_b() -> Self {
        Self(main)
    }
}
impl S<C> {
    // does not cause crash if called
    fn new_c() -> Self {
        Self(true)
    }
}

fn main() {
    S::new_a(); // Uncommenting this makes the compiler not crash
    S::new_b();
    S::new_c();
}

@Elekrisk Elekrisk changed the title Compiler stack overflow when calling function on generic struct with TAIT Compiler stack overflow when calling function on generic struct with TAIT resolving to lambda Feb 1, 2025
@saethlin saethlin added I-crash Issue: The compiler crashes (SIGSEGV, SIGABRT, etc). Use I-ICE instead when the compiler panics. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Feb 1, 2025
@matthiaskrgr
Copy link
Member

bisects to #134081 cc @oli-obk 🤔

@oli-obk
Copy link
Contributor

oli-obk commented Feb 2, 2025

The closure has a generic parameter X that used to be just the opaque. Now it gets normalized to the closure itself. Then trying to print the closure prints its generics, which contain the closure, ... 💥

@oli-obk
Copy link
Contributor

oli-obk commented Feb 2, 2025

#![feature(type_alias_impl_trait)]

type C = impl Sized;

struct S<F>(F);

impl S<C> {
    fn new_c() -> Self {
        Self(Self::new_c)
    }
}

fn main() {
    S::new_c();
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. I-crash Issue: The compiler crashes (SIGSEGV, SIGABRT, etc). Use I-ICE instead when the compiler panics. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants