-
Notifications
You must be signed in to change notification settings - Fork 13.9k
Description
Code
use std::iter::FromIterator;
#[allow(dead_code)]
struct NewVec<T>(Vec<T>);
impl<T> FromIterator<T> for NewVec<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
// Note the incorrect return type not caught by the compiler.
// In debug mode, this overflows the main stack.
// In release mode it causes an infinite* loop.
// *Not tested for more than a minute or so.
iter.into_iter().collect()
// Using Self(...) as return works as expected.
}
}
fn main() {
let _ = [0].into_iter()
.collect::<NewVec<_>>();
}
Meta
rustc --version --verbose
:
rustc 1.79.0 (129f3b996 2024-06-10)
binary: rustc
commit-hash: 129f3b9964af4d4a709d1383930ade12dfe7c081
commit-date: 2024-06-10
host: x86_64-unknown-linux-gnu
release: 1.79.0
LLVM version: 18.1.7
NB/ Also tested 1.82.0 2021 version stable on rust playground, and 2024 version latest nightly (tested on 2024-11-21).
Error output
Build is successful.
On running a debug build (release just hangs):
thread 'main' has overflowed its stack
fatal runtime error: stack overflow
Cannot get rust to produce backtrace as stack overflow aborts.
GDB output:
Backtrace
Starting program: /home/mm/newvec/target/debug/newvec
warning: opening /proc/PID/mem file for lwp 1623.1623 failed: No such file or directory (2)
Failed to read a valid object file image from memory.
Program received signal SIGSEGV, Segmentation fault.
0x00000000080086b4 in newvec::{impl#0}::from_iter<i32, core::array::iter::IntoIter<i32, 1>> (iter=...) at src/main.rs:7
7 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
Hello. I have encountered what I believe to be a compiler bug, allowing an incorrect program to be compiled.
When implementing FromIterator for a newtype over a Vec, it is possible to compile code that returns a Vec, when the function signature declares the return type to be that of the newtype (whether Self or NewVec explicitly).
The code is compiled without error and fails at runtime.
I would have expected the compiler to recognise the incorrect return type and complain, ideally with a hint that I need to wrap the return in Self(...)
.
Link to rust playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=4367dfdb1f1fd4f92b92e50cfe49a863
Update/
On second thought, this is likely not a compiler bug, just a silly infinite recursion error.