Closed
Description
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
Labels
Area: const generics (parameters and arguments)Category: This is a bug.Call for participation: An issue has been fixed and does not reproduce, but no test has been added.`#![feature(const_generics)]`Issue: The compiler crashes (SIGSEGV, SIGABRT, etc). Use I-ICE instead when the compiler panics.Relevant to the compiler team, which will review and decide on the PR/issue.This issue requires a nightly compiler in some way.