Address comments and add requested tests
This commit is contained in:
parent
e67c2282af
commit
93067ca089
47 changed files with 582 additions and 61 deletions
|
|
@ -10,7 +10,11 @@
|
|||
|
||||
#![feature(untagged_unions)]
|
||||
|
||||
fn union() {}
|
||||
|
||||
fn main() {
|
||||
union();
|
||||
|
||||
let union = 10;
|
||||
|
||||
union;
|
||||
47
src/test/run-pass/union/union-c-interop.rs
Normal file
47
src/test/run-pass/union/union-c-interop.rs
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
// Copyright 2016 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.
|
||||
|
||||
#![feature(untagged_unions)]
|
||||
|
||||
#[derive(Copy)]
|
||||
#[repr(C)]
|
||||
struct LARGE_INTEGER_U {
|
||||
LowPart: u32,
|
||||
HighPart: u32,
|
||||
}
|
||||
|
||||
#[derive(Copy)]
|
||||
#[repr(C)]
|
||||
union LARGE_INTEGER {
|
||||
__unnamed__: LARGE_INTEGER_U,
|
||||
u: LARGE_INTEGER_U,
|
||||
QuadPart: u64,
|
||||
}
|
||||
|
||||
impl Clone for LARGE_INTEGER_U { fn clone(&self) -> Self { *self } }
|
||||
impl Clone for LARGE_INTEGER { fn clone(&self) -> Self { *self } }
|
||||
|
||||
#[link(name = "rust_test_helpers")]
|
||||
extern "C" {
|
||||
fn increment_all_parts(_: LARGE_INTEGER) -> LARGE_INTEGER;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
let mut li = LARGE_INTEGER { QuadPart: 0 };
|
||||
let li_c = increment_all_parts(li);
|
||||
li.__unnamed__.LowPart += 1;
|
||||
li.__unnamed__.HighPart += 1;
|
||||
li.u.LowPart += 1;
|
||||
li.u.HighPart += 1;
|
||||
li.QuadPart += 1;
|
||||
assert_eq!(li.QuadPart, li_c.QuadPart);
|
||||
}
|
||||
}
|
||||
43
src/test/run-pass/union/union-generic.rs
Normal file
43
src/test/run-pass/union/union-generic.rs
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
// Copyright 2016 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.
|
||||
|
||||
#![feature(untagged_unions)]
|
||||
|
||||
union MaybeItem<T: Iterator> {
|
||||
elem: T::Item,
|
||||
none: (),
|
||||
}
|
||||
|
||||
union U<A, B> {
|
||||
a: A,
|
||||
b: B,
|
||||
}
|
||||
|
||||
unsafe fn union_transmute<A, B>(a: A) -> B {
|
||||
U { a: a }.b
|
||||
}
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
let u = U::<String, Vec<u8>> { a: String::from("abcd") };
|
||||
|
||||
assert_eq!(u.b.len(), 4);
|
||||
assert_eq!(u.b[0], b'a');
|
||||
|
||||
let b = union_transmute::<(u8, u8), u16>((1, 1));
|
||||
assert_eq!(b, (1 << 8) + 1);
|
||||
|
||||
let v: Vec<u8> = vec![1, 2, 3];
|
||||
let mut i = v.iter();
|
||||
i.next();
|
||||
let mi = MaybeItem::<std::slice::Iter<_>> { elem: i.next().unwrap() };
|
||||
assert_eq!(*mi.elem, 2);
|
||||
}
|
||||
}
|
||||
24
src/test/run-pass/union/union-inherent-method.rs
Normal file
24
src/test/run-pass/union/union-inherent-method.rs
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright 2016 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.
|
||||
|
||||
#![feature(untagged_unions)]
|
||||
|
||||
union U {
|
||||
a: u8,
|
||||
}
|
||||
|
||||
impl U {
|
||||
fn method(&self) -> u8 { unsafe { self.a } }
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let u = U { a: 10 };
|
||||
assert_eq!(u.method(), 10);
|
||||
}
|
||||
33
src/test/run-pass/union/union-macro.rs
Normal file
33
src/test/run-pass/union/union-macro.rs
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright 2016 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.
|
||||
|
||||
#![feature(untagged_unions)]
|
||||
|
||||
macro_rules! duplicate {
|
||||
($i: item) => {
|
||||
mod m1 {
|
||||
$i
|
||||
}
|
||||
mod m2 {
|
||||
$i
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
duplicate! {
|
||||
pub union U {
|
||||
pub a: u8
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let u1 = m1::U { a: 0 };
|
||||
let u2 = m2::U { a: 0 };
|
||||
}
|
||||
80
src/test/run-pass/union/union-overwrite.rs
Normal file
80
src/test/run-pass/union/union-overwrite.rs
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
// Copyright 2016 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.
|
||||
|
||||
#![feature(untagged_unions)]
|
||||
|
||||
#[repr(C)]
|
||||
struct Pair<T, U>(T, U);
|
||||
#[repr(C)]
|
||||
struct Triple<T>(T, T, T);
|
||||
|
||||
#[repr(C)]
|
||||
union U<A, B> {
|
||||
a: Pair<A, A>,
|
||||
b: B,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
union W<A, B> {
|
||||
a: A,
|
||||
b: B,
|
||||
}
|
||||
|
||||
#[cfg(target_endian = "little")]
|
||||
unsafe fn check() {
|
||||
let mut u = U::<u8, u16> { b: 0xDE_DE };
|
||||
u.a.0 = 0xBE;
|
||||
assert_eq!(u.b, 0xDE_BE);
|
||||
|
||||
let mut u = U::<u16, u32> { b: 0xDEAD_DEAD };
|
||||
u.a.0 = 0xBEEF;
|
||||
assert_eq!(u.b, 0xDEAD_BEEF);
|
||||
|
||||
let mut u = U::<u32, u64> { b: 0xDEADBEEF_DEADBEEF };
|
||||
u.a.0 = 0xBAADF00D;
|
||||
assert_eq!(u.b, 0xDEADBEEF_BAADF00D);
|
||||
|
||||
let mut w = W::<Pair<Triple<u8>, u8>, u32> { b: 0xDEAD_DEAD };
|
||||
w.a.0 = Triple(0, 0, 0);
|
||||
assert_eq!(w.b, 0xDE00_0000);
|
||||
|
||||
let mut w = W::<Pair<u8, Triple<u8>>, u32> { b: 0xDEAD_DEAD };
|
||||
w.a.1 = Triple(0, 0, 0);
|
||||
assert_eq!(w.b, 0x0000_00AD);
|
||||
}
|
||||
|
||||
#[cfg(target_endian = "big")]
|
||||
unsafe fn check() {
|
||||
let mut u = U::<u8, u16> { b: 0xDE_DE };
|
||||
u.a.0 = 0xBE;
|
||||
assert_eq!(u.b, 0xBE_DE);
|
||||
|
||||
let mut u = U::<u16, u32> { b: 0xDEAD_DEAD };
|
||||
u.a.0 = 0xBEEF;
|
||||
assert_eq!(u.b, 0xBEEF_DEAD);
|
||||
|
||||
let mut u = U::<u32, u64> { b: 0xDEADBEEF_DEADBEEF };
|
||||
u.a.0 = 0xBAADF00D;
|
||||
assert_eq!(u.b, 0xBAADF00D_DEADBEEF);
|
||||
|
||||
let mut w = W::<Pair<Triple<u8>, u8>, u32> { b: 0xDEAD_DEAD };
|
||||
w.a.0 = Triple(0, 0, 0);
|
||||
assert_eq!(w.b, 0x0000_00AD);
|
||||
|
||||
let mut w = W::<Pair<u8, Triple<u8>>, u32> { b: 0xDEAD_DEAD };
|
||||
w.a.1 = Triple(0, 0, 0);
|
||||
assert_eq!(w.b, 0xDE00_0000);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
check();
|
||||
}
|
||||
}
|
||||
|
|
@ -71,4 +71,34 @@ fn main() {
|
|||
assert_eq!(align_of::<Up>(), 1);
|
||||
assert_eq!(align_of_val(&up), 1);
|
||||
assert_eq!(align_of_val(&CUP), 1);
|
||||
|
||||
hybrid::check_hybrid();
|
||||
}
|
||||
|
||||
mod hybrid {
|
||||
use std::mem::size_of;
|
||||
|
||||
#[repr(packed)]
|
||||
struct S1 {
|
||||
a: u16,
|
||||
b: u8,
|
||||
}
|
||||
|
||||
#[repr(packed)]
|
||||
union U {
|
||||
s: S1,
|
||||
c: u16,
|
||||
}
|
||||
|
||||
#[repr(packed)]
|
||||
struct S2 {
|
||||
d: u8,
|
||||
u: U,
|
||||
}
|
||||
|
||||
pub fn check_hybrid() {
|
||||
assert_eq!(size_of::<S1>(), 3);
|
||||
assert_eq!(size_of::<U>(), 3);
|
||||
assert_eq!(size_of::<S2>(), 4);
|
||||
}
|
||||
}
|
||||
27
src/test/run-pass/union/union-trait-impl.rs
Normal file
27
src/test/run-pass/union/union-trait-impl.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright 2016 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.
|
||||
|
||||
#![feature(untagged_unions)]
|
||||
|
||||
use std::fmt;
|
||||
|
||||
union U {
|
||||
a: u8
|
||||
}
|
||||
|
||||
impl fmt::Display for U {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
unsafe { write!(f, "Oh hai {}", self.a) }
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(U { a: 2 }.to_string(), "Oh hai 2");
|
||||
}
|
||||
42
src/test/run-pass/union/union-with-drop-fields-lint.rs
Normal file
42
src/test/run-pass/union/union-with-drop-fields-lint.rs
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
// Copyright 2016 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.
|
||||
|
||||
// ignore-pretty
|
||||
|
||||
#![feature(untagged_unions)]
|
||||
#![allow(dead_code)]
|
||||
#![allow(unions_with_drop_fields)]
|
||||
|
||||
union U {
|
||||
a: u8, // OK
|
||||
}
|
||||
|
||||
union W {
|
||||
a: String, // OK
|
||||
b: String, // OK
|
||||
}
|
||||
|
||||
struct S(String);
|
||||
|
||||
// `S` doesn't implement `Drop` trait, but still has non-trivial destructor
|
||||
union Y {
|
||||
a: S, // OK
|
||||
}
|
||||
|
||||
// We don't know if `T` is trivially-destructable or not until trans
|
||||
union J<T> {
|
||||
a: T, // OK
|
||||
}
|
||||
|
||||
union H<T: Copy> {
|
||||
a: T, // OK
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
Loading…
Add table
Add a link
Reference in a new issue