rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
98.76k stars 12.76k forks source link

Compilation of invalid return type succeeds in FromIterator impl on a newtype over Vec #133302

Closed MichaelMallaburn closed 23 hours ago

MichaelMallaburn commented 23 hours ago

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> (iter=...) at src/main.rs:7 7 fn from_iter>(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.

MichaelMallaburn commented 23 hours ago

Closed as I realised I got exactly what I asked for: an infinite recursion. Sorry for the noise.