Skip to content
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

Codegen bug: dest == expr::Ignore || bcx.unreachable.get() #11709

Closed
alexcrichton opened this issue Jan 21, 2014 · 10 comments · Fixed by #12095
Closed

Codegen bug: dest == expr::Ignore || bcx.unreachable.get() #11709

alexcrichton opened this issue Jan 21, 2014 · 10 comments · Fixed by #12095
Labels
A-codegen Area: Code generation

Comments

@alexcrichton
Copy link
Member

Was trying to find another bug, found this bug!

#[inline(never)]                                             
fn function(slot: &mut Option<proc() -> proc()>, f: proc()) {
  let a = slot.take();                                       
  let a = match a {                                          
    Some(a) => { let _a = a(); },                            
    None => (),                                              
  };                                                         
  //a();                                                     
}                                                            
fn main() {                                                  
  let mut slot = None;                                       
  function(&mut slot, proc() {});                            
}                                                            

That code will fail with

[~/rust/valgrind[master]] $ rustc foo.rs -O && valgrind ./foo                                                                                                                        [alex@arch-vm]
foo.rs:2:50: 2:51 warning: unused variable: `f`, #[warn(unused_variable)] on by default
foo.rs:2 fn function(slot: &mut Option<proc() -> proc()>, f: proc()) {
                                                          ^
foo.rs:4:7: 4:8 warning: unused variable: `a`, #[warn(unused_variable)] on by default
foo.rs:4   let a = match a {
               ^
error: internal compiler error: unexpected failure
This message reflects a bug in the Rust compiler. 
We would appreciate a bug report: http://static.rust-lang.org/doc/master/complement-bugreport.html
note: the compiler hit an unexpected failure path. this is a bug
task 'rustc' failed at 'assertion failed: dest == expr::Ignore || bcx.unreachable.get()', /build/rust-git/src/rust/src/librustc/middle/trans/controlflow.rs:91

@flaper87
Copy link
Contributor

I'll take it

@Kimundi
Copy link
Member

Kimundi commented Jan 24, 2014

Different testcases:

rusti: let v = [1, 2, 3, 4]; println!("{:?}", v.chunks(2).to_owned_vec());
rusti: use std::rand::random; struct RandIter; impl Iterator<u8> for RandIter { fn next(&mut self) -> Option<u8> { Some(random()) } }

EDIT: Found more testcases

@flaper87
Copy link
Contributor

Interesting. I'm looking into it. Not sure what is causing this, though.

@huonw
Copy link
Member

huonw commented Jan 26, 2014

Another testcase:

fn main() { let _r = { box(GC) ~&1; }; }

(The {} and _r are both necessary.)

@flaper87
Copy link
Contributor

Even simpler example:

fn main() { let _r = { 1; }; }

Debug Log

trans_block(bcx=[block 0x7f38a41a8f50], b=15, dest=Ignore)
trans_stmt(stmt(14: let _r = { 1; };))
trans_block(bcx=[block 0x7f38a41a8f50], b=11, dest=SaveIn(({}*:  %_r = alloca {})))
trans_stmt(stmt(10: 1;))

EDIT:

Making the block {1;} return {1} doesn't raise this issue.

@eddyb
Copy link
Member

eddyb commented Feb 1, 2014

My final testcase:

 fn main() { let _r = {}; }

@jrupac
Copy link

jrupac commented Feb 2, 2014

Could this be related to the no-argument version of lambda block expressions that were used in do foo {...} syntax? Looking in libsyntax/parse/parser.rs, there's a comment to this form of lambda expressions used with do. As far as why {1} doesn't raise the issue, maybe that's parsed as a block expression instead?

@eddyb
Copy link
Member

eddyb commented Feb 3, 2014

@jrupac I don't see how it could be related. The error here has to do with a () (or just zero-sized? I'm not sure) result of a block being stored somewhere. I'm not even sure the assert needs to be that strict.

@bstrie
Copy link
Contributor

bstrie commented Feb 7, 2014

Yet another test case to consider:

struct S {x:()}

fn main(){
    let s : S  = S{x: {println!("a");} };
}

@flaper87
Copy link
Contributor

flaper87 commented Feb 7, 2014

@bstrie thanks! I'll get back to debug this in a bit

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-codegen Area: Code generation
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants