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

Compile Bug: unexpected dereferenceable type #22992

Closed
laijs opened this issue Mar 3, 2015 · 3 comments
Closed

Compile Bug: unexpected dereferenceable type #22992

laijs opened this issue Mar 3, 2015 · 3 comments
Labels
E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️

Comments

@laijs
Copy link

laijs commented Mar 3, 2015

When I was compiling the code of What are Rust's exact auto-dereferencing rules?, it resulted a bug.

The code:

struct X { val: i32 }
impl std::ops::Deref for X {
    type Target = i32;
    fn deref(&self) -> &i32 { &self.val }
}


trait            M                   { fn m(self); }
impl             M for i32           { fn m(self) { println!("i32::m()"); } }
impl             M for X             { fn m(self) { println!("X::m()"); } }
impl<'a>         M for &'a X         { fn m(self) { println!("&X::m()"); } }
impl<'a, 'b>     M for &'a &'b X     { fn m(self) { println!("&&X::m()"); } }
impl<'a, 'b, 'c> M for &'a &'b &'c X { fn m(self) { println!("&&&X::m()"); } }

trait            RefM                   { fn refm(&self); }
impl             RefM for i32           { fn refm(&self) { println!("i32::refm()"); } }
impl             RefM for X             { fn refm(&self) { println!("X::refm()"); } }
impl<'a>         RefM for &'a X         { fn refm(&self) { println!("&X::refm()"); } }
impl<'a, 'b>     RefM for &'a &'b X     { fn refm(&self) { println!("&&X::refm()"); } }
impl<'a, 'b, 'c> RefM for &'a &'b &'c X { fn refm(&self) { println!("&&&X::refm()"); } }

struct Y { val: i32 }
impl std::ops::Deref for Y {
    type Target = i32;
    fn deref(&self) -> &i32 { &self.val }
}

struct Z { val: Y }
impl std::ops::Deref for Z {
    type Target = Y;
    fn deref(&self) -> &Y { &self.val }
}

struct A;
impl std::marker::Copy for A {}
impl             M for             A { fn m(self) { println!("A::m()"); } }
impl<'a, 'b, 'c> M for &'a &'b &'c A { fn m(self) { println!("&&&A::m()"); } }
impl             RefM for             A { fn refm(&self) { println!("A::refm()"); } }
impl<'a, 'b, 'c> RefM for &'a &'b &'c A { fn refm(&self) { println!("&&&A::refm()"); } }

fn main() {
    // I'll use @ to denote left side of the dot operator
    (*X{val:42}).m();        // i32::refm() , self == @
    X{val:42}.m();           // X::m()      , self == @
    (&X{val:42}).m();        // &X::m()     , self == @
    (&&X{val:42}).m();       // &&X::m()    , self == @
    (&&&X{val:42}).m();      // &&&X:m()    , self == @
    (&&&&X{val:42}).m();     // &&&X::m()   , self == *@
    (&&&&&X{val:42}).m();    // &&&X::m()   , self == **@

    (*X{val:42}).refm();     // i32::refm() , self == @
    X{val:42}.refm();        // X::refm()   , self == @
    (&X{val:42}).refm();     // X::refm()   , self == *@
    (&&X{val:42}).refm();    // &X::refm()  , self == *@
    (&&&X{val:42}).refm();   // &&X::refm() , self == *@
    (&&&&X{val:42}).refm();  // &&&X::refm(), self == *@
    (&&&&&X{val:42}).refm(); // &&&X::refm(), self == **@

    Y{val:42}.refm();        // i32::refm() , self == *@
    Z{val:Y{val:42}}.refm(); // i32::refm() , self == **@

    A.m();                   // A::m()      , self == @
    // without the Copy trait, (&A).m() would be a compilation error:
    // cannot move out of borrowed content
    (&A).m();                // A::m()      , self == *@
    (&&A).m();               // &&&A::m()   , self == &@
    (&&&A).m();              // &&&A::m()   , self == @
    A.refm();                // A::refm()   , self == @
    (&A).refm();             // A::refm()   , self == *@
    (&&A).refm();            // A::refm()   , self == **@
    (&&&A).refm();           // &&&A::refm(), self == @
}

And the rustc resulted:

# rustc --version
rustc 1.0.0-dev (b4c965ee8 2015-03-02) (built 2015-03-03)

# RUST_BACKTRACE=1 rustc deref.rs 
error: internal compiler error: unexpected dereferenceable type Y
note: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports
note: run with `RUST_BACKTRACE=1` for a backtrace
thread 'rustc' panicked at 'Box<Any>', /home/laijs/work/rust-for-install/src/libsyntax/diagnostic.rs:189

stack backtrace:
   1:     0x7fcbf38f28ff - sys::backtrace::write::h577e1c6361768c02QyA
   2:     0x7fcbf391b432 - panicking::on_panic::hef3a5ce737f27c37FDJ
   3:     0x7fcbf385618a - rt::unwind::begin_unwind_inner::h51b5b5b16031b3c28jJ
   4:     0x7fcbf0b6d9ed - rt::unwind::begin_unwind::h2713391746432164638
   5:     0x7fcbf0b6e225 - diagnostic::Handler::bug::hfe31e16b8d71f021BHD
   6:     0x7fcbf168f43b - session::Session::bug::h96f42bebaeb8e73fqup
   7:     0x7fcbf3015677 - trans::consts::const_expr::hb0b128b357663b3c4vn
   8:     0x7fcbf2faa3ae - trans::consts::get_const_expr_as_global::h21a61339d5edfef7ftn
   9:     0x7fcbf2f64130 - trans::expr::trans::h0937a1423c3712b8Tth
  10:     0x7fcbf2f9c817 - trans::callee::trans_args::hc57b3e614890b9dfz1g
  11:     0x7fcbf2fa47e2 - trans::callee::trans_call_inner::h14447778500323265516
  12:     0x7fcbf2fac8fc - trans::expr::trans_rvalue_dps_unadjusted::hb70513e148b158edgAi
  13:     0x7fcbf2f62f5e - trans::expr::trans_into::h1fb70f0657f02021Lnh
  14:     0x7fcbf2f61f74 - trans::controlflow::trans_stmt_semi::h3484c46defdec968n4d
  15:     0x7fcbf2f63970 - trans::controlflow::trans_block::hda388713e3e88977a5d
  16:     0x7fcbf302f26f - trans::base::trans_closure::hd3b6ad6febef58aaVct
  17:     0x7fcbf2f4fff8 - trans::base::trans_fn::h63c86b5ef9723009Ont
  18:     0x7fcbf2f4bb76 - trans::base::trans_item::hac26f7be10d65cfeGLt
  19:     0x7fcbf3035d7c - trans::base::trans_crate::hff2787f0626d8852QHu
  20:     0x7fcbf3f8cba2 - driver::phase_4_translate_to_llvm::hbc0b6a58c8ee4f80rNa
  21:     0x7fcbf3f68198 - driver::compile_input::h9de6f092c5dfb6ebIba
  22:     0x7fcbf4032a0e - run_compiler::hb5e94b85ec6e83edF5b
  23:     0x7fcbf40305bc - thunk::F.Invoke<A, R>::invoke::h17784488277762929069
  24:     0x7fcbf402f310 - rt::unwind::try::try_fn::h12687093362529061390
  25:     0x7fcbf398fd08 - rust_try_inner
  26:     0x7fcbf398fcf5 - rust_try
  27:     0x7fcbf402f9fc - thunk::F.Invoke<A, R>::invoke::h5447655687859444331
  28:     0x7fcbf3906f85 - sys::thread::thread_start::h8973b07a174c8c31j5E
  29:     0x7fcbed77f529 - start_thread
  30:     0x7fcbf34da77c - clone
  31: 0xffffffffffffffff - <unknown>
@jdm jdm added the I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ label Mar 3, 2015
@tomaka
Copy link
Contributor

tomaka commented Apr 16, 2015

This code triggers it as well on 1.0.0-beta:

struct Foo {
    value: u32
}

impl std::ops::Deref for Foo {
    type Target = u32;
    fn deref(&self) -> &u32 { &self.value }
}

fn foo(_: &u32) {} 

fn main() {
    foo(&Foo { value: 5 });
}

@bombless
Copy link
Contributor

struct A(B);
struct B;

use std::ops::Deref;

impl Deref for A {
    type Target = B;
    fn deref(&self)->&B { &self.0 }
}

impl B {
    fn foo(&self){}
}

fn main() {
    A(B).foo()
}

Same issue here.

@pmarcelll
Copy link
Contributor

This compiles and runs on nightly.

@alexcrichton alexcrichton added the E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. label Sep 1, 2015
bors added a commit that referenced this issue Sep 9, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️
Projects
None yet
Development

No branches or pull requests

6 participants