Skip to content

Mir undefined behaviour false positive when comparing Option<&T> #55454

Closed
@jesskfullwood

Description

@jesskfullwood

I discovered this bug while tinkering with the frunk crate.

#[derive(PartialEq, Debug)]
struct Cons<H, T: Hlist> {
    head: H,
    tail: T
}

#[derive(PartialEq, Debug)]
struct Nil;

trait Hlist {}
impl<H, T: Hlist> Hlist for Cons<H, T> {}
impl Hlist for Nil {}

fn main() {

    // This part works fine
    let x = Cons {head: Some(&0), tail: Nil};
    let y = Cons {head: Some(&0), tail: Nil};
    assert_eq!(x, y);

    // This apparently-equivalent code fails to compile (passes cargo-check but not cargo-build)
    assert_eq!(
        Cons {head: Some(&0), tail: Nil},
        Cons {head: Some(&0), tail: Nil}
    );
}

This code compiles and runs on stable.

➜  rustup default stable
info: using existing install for 'stable-x86_64-unknown-linux-gnu'
info: default toolchain set to 'stable-x86_64-unknown-linux-gnu'

  stable-x86_64-unknown-linux-gnu unchanged - rustc 1.30.0 (da5f414c2 2018-10-24)

➜ cargo build
    Finished dev [unoptimized + debuginfo] target(s) in 0.12s    

But fails on nightly

➜  rustup default nightly
info: using existing install for 'nightly-x86_64-unknown-linux-gnu'
info: default toolchain set to 'nightly-x86_64-unknown-linux-gnu'

  nightly-x86_64-unknown-linux-gnu unchanged - rustc 1.31.0-nightly (cae6efc37 2018-10-27)

➜  cargo build
   Compiling typeck v0.1.0                                               
error[E0080]: it is undefined behavior to use this value                                                
  --> src/main.rs:15:1                                                                                  
   |                                                                                                    
15 | / fn main() {                                                                                      
16 | |                                                                                                  
17 | |     // This part works fine                                                                      
18 | |     let x = Cons {head: Some(&0), tail: Nil};                                                    
...  |                                                                                                  
26 | |     );                                                                                           
27 | | }                                                                                                
   | |_^ type validation failed: encountered a pointer, but expected something that cannot possibly be outside the (wrapping) range 1..=0
   |                                                                                                    
   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
                                                                                                        
error: aborting due to previous error                                                                   
                                                                                                        
For more information about this error, try `rustc --explain E0080`.                                     
error: Could not compile `typeck`.                                                                      

To learn more, run the command again with --verbose.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions