| // Various tests ensuring that underscore patterns really just construct the place, but don't check its contents. |
| #![feature(never_type)] |
| |
| use std::ptr; |
| |
| fn main() { |
| dangling_match(); |
| invalid_match(); |
| dangling_let(); |
| invalid_let(); |
| dangling_let_type_annotation(); |
| invalid_let_type_annotation(); |
| never(); |
| } |
| |
| fn dangling_match() { |
| let p = { |
| let b = Box::new(42); |
| &*b as *const i32 |
| }; |
| unsafe { |
| match *p { |
| _ => {} |
| } |
| } |
| } |
| |
| fn invalid_match() { |
| union Uninit<T: Copy> { |
| value: T, |
| uninit: (), |
| } |
| unsafe { |
| let x: Uninit<bool> = Uninit { uninit: () }; |
| match x.value { |
| _ => {} |
| } |
| } |
| |
| unsafe { |
| let x: Uninit<!> = Uninit { uninit: () }; |
| match x.value { |
| _ => {} |
| } |
| } |
| } |
| |
| fn dangling_let() { |
| unsafe { |
| let ptr = ptr::without_provenance::<bool>(0x40); |
| let _ = *ptr; |
| } |
| |
| unsafe { |
| let ptr = ptr::without_provenance::<!>(0x40); |
| let _ = *ptr; |
| } |
| } |
| |
| fn invalid_let() { |
| unsafe { |
| let val = 3u8; |
| let ptr = ptr::addr_of!(val).cast::<bool>(); |
| let _ = *ptr; |
| } |
| |
| unsafe { |
| let val = 3u8; |
| let ptr = ptr::addr_of!(val).cast::<!>(); |
| let _ = *ptr; |
| } |
| } |
| |
| // Adding a type annotation used to change how MIR is generated, make sure we cover both cases. |
| fn dangling_let_type_annotation() { |
| unsafe { |
| let ptr = ptr::without_provenance::<bool>(0x40); |
| let _: bool = *ptr; |
| } |
| |
| unsafe { |
| let ptr = ptr::without_provenance::<!>(0x40); |
| let _: ! = *ptr; |
| } |
| } |
| |
| fn invalid_let_type_annotation() { |
| unsafe { |
| let val = 3u8; |
| let ptr = ptr::addr_of!(val).cast::<bool>(); |
| let _: bool = *ptr; |
| } |
| |
| unsafe { |
| let val = 3u8; |
| let ptr = ptr::addr_of!(val).cast::<!>(); |
| let _: ! = *ptr; |
| } |
| } |
| |
| // Regression test from <https://github.com/rust-lang/rust/issues/117288>. |
| fn never() { |
| unsafe { |
| let x = 3u8; |
| let x: *const ! = &x as *const u8 as *const _; |
| let _: ! = *x; |
| } |
| |
| // Without a type annotation, make sure we don't implicitly coerce `!` to `()` |
| // when we do the noop `*x` (as that would require a `!` *value*, creating |
| // which is UB). |
| unsafe { |
| let x = 3u8; |
| let x: *const ! = &x as *const u8 as *const _; |
| let _ = *x; |
| } |
| } |