Skip to content

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

@MichaelMallaburn

Description

@MichaelMallaburn

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions