diff options
| author | Oliver Schneider <git-spam-no-reply9815368754983@oli-obk.de> | 2018-02-06 14:05:06 +0100 |
|---|---|---|
| committer | Oliver Schneider <git-spam-no-reply9815368754983@oli-obk.de> | 2018-03-08 08:34:17 +0100 |
| commit | f68dc0190a369b6ce9bcfaae26d1b07941028da0 (patch) | |
| tree | 55cb3c70c9fa3f1a340297fcb33e0a07b3e21cf0 | |
| parent | 0a1278aea808ddfe2178fdc49b96ccc0e9e608b6 (diff) | |
Add a test for transmuting via unions in constants
| -rw-r--r-- | src/test/ui/const-eval/const_transmute.rs | 62 | ||||
| -rw-r--r-- | src/test/ui/const-eval/const_transmute.stderr | 0 |
2 files changed, 62 insertions, 0 deletions
diff --git a/src/test/ui/const-eval/const_transmute.rs b/src/test/ui/const-eval/const_transmute.rs new file mode 100644 index 00000000000..a64a1d212ab --- /dev/null +++ b/src/test/ui/const-eval/const_transmute.rs @@ -0,0 +1,62 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// must-compile-successfully +// run-pass + +union Transmute<T: Copy, U: Copy> { + t: T, + u: U, +} + +trait Bar { + fn bar(&self) -> u32; +} + +struct Foo { + foo: u32, + bar: bool, +} + +impl Bar for Foo { + fn bar(&self) -> u32 { + self.foo + } +} + +impl Drop for Foo { + fn drop(&mut self) { + assert!(!self.bar); + self.bar = true; + println!("dropping Foo"); + } +} + +#[derive(Copy, Clone)] +struct Fat<'a>(&'a Foo, &'static VTable); + +struct VTable { + drop: Option<for<'a> fn(&'a mut Foo)>, + size: usize, + align: usize, + bar: for<'a> fn(&'a Foo) -> u32, +} + +const FOO: &Bar = &Foo { foo: 128, bar: false }; +const G: Fat = unsafe { Transmute { t: FOO }.u }; +const F: Option<for<'a> fn(&'a mut Foo)> = G.1.drop; +const H: for<'a> fn(&'a Foo) -> u32 = G.1.bar; + +fn main() { + let mut foo = Foo { foo: 99, bar: false }; + (F.unwrap())(&mut foo); + std::mem::forget(foo); // already ran the drop impl + assert_eq!(H(&Foo { foo: 42, bar: false }), 42); +} diff --git a/src/test/ui/const-eval/const_transmute.stderr b/src/test/ui/const-eval/const_transmute.stderr new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/src/test/ui/const-eval/const_transmute.stderr |
