Skip to content

Specialized impl for a type with const generics in another crate causes a stack overflow in rustc #68104

Closed
@stbowers

Description

@stbowers

Currently with const generics you can create a "specialized" implementation, such as:

pub struct MyStruct<const N: usize> {
    _data: [usize; N],
}

impl<const N: usize> MyStruct<N> {
    pub fn new() -> MyStruct<N> {
        return MyStruct {
            _data: unsafe { std::mem::uninitialized() },
        };
    }

    pub fn test_generic(&self) {
        println!("There are {} elements!", N);
    }
}

// Specialized implementation when N == 3
impl MyStruct<3> {
    pub fn test_three(&self) {
        println!("There are 3 elements! Do something cool with this special case!");
    }
}

fn main() {
    let my_struct: MyStruct<3> = MyStruct::new();
    
    my_struct.test_generic();
    my_struct.test_three();
}

Which has the following output:

There are 3 elements!
There are 3 elements! Do something cool with this special case!

(playground link: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=c5c862b1590029a6c785ec6feddd6da8)

However, when using such a type in another crate this causes a stack overflow in the compiler. For example, with the following code (full example: https://github.com/stbowers/const-generics-test):

// main.rs
use test_lib::*;

fn main() {
    let my_struct: MyStruct<3> = MyStruct::new();

    my_struct.test_generic();
    my_struct.test_three(); // If this line is commented out it will compile correctly
}
// lib.rs (in another crate)
pub struct MyStruct<const N: usize> {
    data: [usize; N],
}

impl<const N: usize> MyStruct<N> {
    pub fn new() -> MyStruct<N> {
        return MyStruct {
            data: unsafe { std::mem::uninitialized() },
        };
    }

    pub fn test_generic(&self) {
        println!("There are {} elements!", N);
    }
}

impl MyStruct<3> {
    pub fn test_three(&self) {
        println!("There are 3 elements! Do something cool with this special case!");
    }
}

I would expect it to produce the same output as the playground link above, however it produces the following:

$ cargo +nightly run
Compiling test_lib v0.1.0 (/home/sean/Documents/Projects/rust_test/lib/test_lib)
Compiling rust_test v0.1.0 (/home/sean/Documents/Projects/rust_test)

thread 'rustc' has overflowed its stack
fatal runtime error: stack overflow
error: could not compile `rust_test`.

Caused by:
process didn't exit successfully: `rustc --crate-name rust_test --edition=2018 src/main.rs --error-format=json --json=diagnostic-rendered-ansi --crate-type bin --emit=dep-info,link -C debuginfo=2 -C metadata=9b6d50326f9f810d -C extra-filename=-9b6d50326f9f810d --out-dir /home/sean/Documents/Projects/rust_test/target/debug/deps -C incremental=/home/sean/Documents/Projects/rust_test/target/debug/incremental -L dependency=/home/sean/Documents/Projects/rust_test/target/debug/deps --extern test_lib=/home/sean/Documents/Projects/rust_test/target/debug/deps/libtest_lib-36dbf7eb695dbec6.rlib` (signal: 6, SIGABRT: process abort signal)

Meta

$ cargo +nightly rustc -- --version --verbose
rustc 1.42.0-nightly (72b2bd55e 2020-01-09)
binary: rustc
commit-hash: 72b2bd55edbb1e63a930c5ddd08b25e4f9044786
commit-date: 2020-01-09
host: x86_64-unknown-linux-gnu
release: 1.42.0-nightly
LLVM version: 9.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-const-genericsArea: const generics (parameters and arguments)C-bugCategory: This is a bug.E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.F-const_generics`#![feature(const_generics)]`I-crashIssue: The compiler crashes (SIGSEGV, SIGABRT, etc). Use I-ICE instead when the compiler panics.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.requires-nightlyThis issue requires a nightly compiler in some way.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions