rust-lang / rust

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

`for` loops allow moving out of references #16205

Closed steveklabnik closed 10 years ago

steveklabnik commented 10 years ago

Updated description

for loops allow moving out of fixed size arrays. This code compiles and should not compile.

struct Foo {
    a: [Box<int>, ..3],
}

fn main() {
    let f = Foo { a: [box 3, box 4, box 5] };
    for &a in f.a.iter() {
    }
}

Original description

segfault with channels

I don't know how to make this test case smaller, but...

https://github.com/steveklabnik/dining_philosophers/commit/52ca03637a750f603f70c1d3b17d4326a2ae5eaa

This commit introduces a segfault.

steve@computer:~/src/dining_philosophers$ cargo run
   Compiling dining_philosophers v0.0.1 (file:/home/steve/src/dining_philosophers)
     Running `target/dining_philosophers`
Baruch Spinoza has sat down to eat.
An unknown error occurred

To learn more, run the command again with --verbose.  
steve@computer:~/src/dining_philosophers$ ./target/dining_philosophers 
Karl Marx has sat down to eat.
Karl Marx is thinking.
Baruch Spinoza has sat down to eat.
Baruch Spinoza is thinking.
Segmentation fault (core dumped)
steve@computer:~/src/dining_philosophers$

Seems bad.

JCRPaquin commented 10 years ago

From what I'm seeing here(debugger wise) the problem looks to stem from the call to channel.try_recv in the have_dinner function.

Inside try_recv we enter the loop, make it through the first unsafe match and then the problem appears to occur in the Oneshot branch when we try to match again.

alexcrichton commented 10 years ago

Can you describe the system that you're running on as well as the cargo/rustc versions you're using? I've been unable to reproduce the segfault on the most recent nightly on both linux and osx.

JCRPaquin commented 10 years ago

Oh sorry, I'm running Windows here. Latest installer version.

C:\Windows\System32>rustc --version
rustc 0.12.0-pre-nightly (d7cfc34a2 2014-08-02 00:31:03 +0000)

After restarting into Xubuntu and updating I recompiled there and got a segfault. I get rust from the hansjorg/rust PPA.

magisun@magimobile-ubuntu:~$ rustc --version
rustc 0.12.0-pre

I'm running off of a Toshiba Satellite L875D-S7210 with an AMD A6-4400M APU. Windows is 64bit and Xubuntu is 32bit.

alexcrichton commented 10 years ago

Ah, found it.

Nominating and cc @pcwalton, this seems bad and related to the recent removal of for-loop desugaring.

pnkfelix commented 10 years ago

Assigning P-backcompat-lang, 1.0 milestone.

huonw commented 10 years ago

Simpler reproduction (it's not related to fixed sized arrays, updating title):

fn main() {
    let x = Some(box 1i);
    for &a in x.iter() {
    }
}
reem commented 10 years ago

If you want to see a segfault you have to do something in the loop and iterate twice:

fn main() {
    let x = [box 1i, box 2i];
    for &a in x.iter() {
        println!("{}", a);
    }
    for &a in x.iter() {
        println!("{}", a);
    }
}

This prints 1 and 2, then stalls a bit, then segfaults.