Skip to content

for loops allow moving out of references #16205

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
steveklabnik opened this issue Aug 2, 2014 · 7 comments · Fixed by #16458
Closed

for loops allow moving out of references #16205

steveklabnik opened this issue Aug 2, 2014 · 7 comments · Fixed by #16458
Milestone

Comments

@steveklabnik
Copy link
Member

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...

steveklabnik/dining_philosophers@52ca036

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
Copy link

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
Copy link
Member

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
Copy link

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 alexcrichton changed the title segfault with channels for loops allow moving out of fixed size arrays Aug 4, 2014
@alexcrichton
Copy link
Member

Ah, found it.

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

@pnkfelix
Copy link
Member

pnkfelix commented Aug 7, 2014

Assigning P-backcompat-lang, 1.0 milestone.

@pnkfelix pnkfelix added this to the 1.0 milestone Aug 7, 2014
@huonw
Copy link
Member

huonw commented Aug 7, 2014

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

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

@huonw huonw changed the title for loops allow moving out of fixed size arrays for loops allow moving out of references Aug 7, 2014
@reem
Copy link
Contributor

reem commented Aug 7, 2014

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.

pcwalton added a commit to pcwalton/rust that referenced this issue Aug 12, 2014
`for` loop heads.

This breaks code like:

    let x = Some(box 1i);
        for &a in x.iter() {
    }

Change this code to obey the borrow checking rules. For example:

    let x = Some(box 1i);
        for &ref a in x.iter() {
    }

Closes rust-lang#16205.

[breaking-change]
bors added a commit that referenced this issue Aug 13, 2014
`for` loop heads.

This breaks code like:

    let x = Some(box 1i);
    for &a in x.iter() {
    }

Change this code to obey the borrow checking rules. For example:

    let x = Some(box 1i);
    for &ref a in x.iter() {
    }

Closes #16205.

[breaking-change]

r? @nikomatsakis
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants