Closed
Description
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>