Format tests with rustfmt (51-100 of 300)
This commit is contained in:
parent
b2616ced5c
commit
619813500b
@ -2,9 +2,11 @@
|
||||
fn manual_alignment() {
|
||||
let x = &mut [0u8; 3];
|
||||
let base_addr = x as *mut _ as usize;
|
||||
let base_addr_aligned = if base_addr % 2 == 0 { base_addr } else { base_addr+1 };
|
||||
let base_addr_aligned = if base_addr % 2 == 0 { base_addr } else { base_addr + 1 };
|
||||
let u16_ptr = base_addr_aligned as *mut u16;
|
||||
unsafe { *u16_ptr = 2; }
|
||||
unsafe {
|
||||
*u16_ptr = 2;
|
||||
}
|
||||
}
|
||||
|
||||
/// Test standard library `align_to`.
|
||||
@ -12,7 +14,7 @@ fn align_to() {
|
||||
const LEN: usize = 128;
|
||||
let buf = &[0u8; LEN];
|
||||
let (l, m, r) = unsafe { buf.align_to::<i32>() };
|
||||
assert!(m.len()*4 >= LEN-4);
|
||||
assert!(m.len() * 4 >= LEN - 4);
|
||||
assert!(l.len() + r.len() <= 4);
|
||||
}
|
||||
|
||||
|
@ -36,31 +36,32 @@ fn test_align_to() {
|
||||
{
|
||||
let (l, m, r) = unsafe { s[1..].align_to::<u32>() };
|
||||
assert_eq!(l.len(), 3);
|
||||
assert_eq!(m.len(), N-1);
|
||||
assert_eq!(m.len(), N - 1);
|
||||
assert_eq!(r.len(), 0);
|
||||
assert_eq!(raw.wrapping_offset(4), m.as_ptr() as *const u8);
|
||||
}
|
||||
|
||||
{
|
||||
let (l, m, r) = unsafe { s[..4*N - 1].align_to::<u32>() };
|
||||
let (l, m, r) = unsafe { s[..4 * N - 1].align_to::<u32>() };
|
||||
assert_eq!(l.len(), 0);
|
||||
assert_eq!(m.len(), N-1);
|
||||
assert_eq!(m.len(), N - 1);
|
||||
assert_eq!(r.len(), 3);
|
||||
assert_eq!(raw, m.as_ptr() as *const u8);
|
||||
}
|
||||
|
||||
{
|
||||
let (l, m, r) = unsafe { s[1..4*N - 1].align_to::<u32>() };
|
||||
let (l, m, r) = unsafe { s[1..4 * N - 1].align_to::<u32>() };
|
||||
assert_eq!(l.len(), 3);
|
||||
assert_eq!(m.len(), N-2);
|
||||
assert_eq!(m.len(), N - 2);
|
||||
assert_eq!(r.len(), 3);
|
||||
assert_eq!(raw.wrapping_offset(4), m.as_ptr() as *const u8);
|
||||
}
|
||||
|
||||
{
|
||||
#[repr(align(8))] struct Align8(u64);
|
||||
#[repr(align(8))]
|
||||
struct Align8(u64);
|
||||
let (l, m, r) = unsafe { s.align_to::<Align8>() }; // requested alignment higher than allocation alignment
|
||||
assert_eq!(l.len(), 4*N);
|
||||
assert_eq!(l.len(), 4 * N);
|
||||
assert_eq!(r.len(), 0);
|
||||
assert_eq!(m.len(), 0);
|
||||
}
|
||||
|
@ -1,14 +1,28 @@
|
||||
// normalize-stderr-test: "::<.*>" -> ""
|
||||
|
||||
#[inline(never)] fn func_a() -> Box<[*mut ()]> { func_b::<u8>() }
|
||||
#[inline(never)] fn func_b<T>() -> Box<[*mut ()]> { func_c() }
|
||||
|
||||
macro_rules! invoke_func_d {
|
||||
() => { func_d() }
|
||||
#[inline(never)]
|
||||
fn func_a() -> Box<[*mut ()]> {
|
||||
func_b::<u8>()
|
||||
}
|
||||
#[inline(never)]
|
||||
fn func_b<T>() -> Box<[*mut ()]> {
|
||||
func_c()
|
||||
}
|
||||
|
||||
#[inline(never)] fn func_c() -> Box<[*mut ()]> { invoke_func_d!() }
|
||||
#[inline(never)] fn func_d() -> Box<[*mut ()]> { unsafe { miri_get_backtrace(0) } }
|
||||
macro_rules! invoke_func_d {
|
||||
() => {
|
||||
func_d()
|
||||
};
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
fn func_c() -> Box<[*mut ()]> {
|
||||
invoke_func_d!()
|
||||
}
|
||||
#[inline(never)]
|
||||
fn func_d() -> Box<[*mut ()]> {
|
||||
unsafe { miri_get_backtrace(0) }
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut seen_main = false;
|
||||
@ -51,4 +65,3 @@ struct MiriFrame {
|
||||
colno: u32,
|
||||
fn_ptr: *mut (),
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,33 @@
|
||||
// normalize-stderr-test: "::<.*>" -> ""
|
||||
|
||||
#[inline(never)] fn func_a() -> Box<[*mut ()]> { func_b::<u8>() }
|
||||
#[inline(never)] fn func_b<T>() -> Box<[*mut ()]> { func_c() }
|
||||
|
||||
macro_rules! invoke_func_d {
|
||||
() => { func_d() }
|
||||
#[inline(never)]
|
||||
fn func_a() -> Box<[*mut ()]> {
|
||||
func_b::<u8>()
|
||||
}
|
||||
#[inline(never)]
|
||||
fn func_b<T>() -> Box<[*mut ()]> {
|
||||
func_c()
|
||||
}
|
||||
|
||||
#[inline(never)] fn func_c() -> Box<[*mut ()]> { invoke_func_d!() }
|
||||
#[inline(never)] fn func_d() -> Box<[*mut ()]> { unsafe { let count = miri_backtrace_size(0); let mut buf = vec![std::ptr::null_mut(); count]; miri_get_backtrace(1, buf.as_mut_ptr()); buf.into() } }
|
||||
macro_rules! invoke_func_d {
|
||||
() => {
|
||||
func_d()
|
||||
};
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
fn func_c() -> Box<[*mut ()]> {
|
||||
invoke_func_d!()
|
||||
}
|
||||
#[inline(never)]
|
||||
fn func_d() -> Box<[*mut ()]> {
|
||||
unsafe {
|
||||
let count = miri_backtrace_size(0);
|
||||
let mut buf = vec![std::ptr::null_mut(); count];
|
||||
miri_get_backtrace(1, buf.as_mut_ptr());
|
||||
buf.into()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut seen_main = false;
|
||||
|
@ -4,15 +4,29 @@
|
||||
|
||||
use std::backtrace::Backtrace;
|
||||
|
||||
#[inline(never)] fn func_a() -> Backtrace { func_b::<u8>() }
|
||||
#[inline(never)] fn func_b<T>() -> Backtrace { func_c() }
|
||||
|
||||
macro_rules! invoke_func_d {
|
||||
() => { func_d() }
|
||||
#[inline(never)]
|
||||
fn func_a() -> Backtrace {
|
||||
func_b::<u8>()
|
||||
}
|
||||
#[inline(never)]
|
||||
fn func_b<T>() -> Backtrace {
|
||||
func_c()
|
||||
}
|
||||
|
||||
#[inline(never)] fn func_c() -> Backtrace { invoke_func_d!() }
|
||||
#[inline(never)] fn func_d() -> Backtrace { Backtrace::capture() }
|
||||
macro_rules! invoke_func_d {
|
||||
() => {
|
||||
func_d()
|
||||
};
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
fn func_c() -> Backtrace {
|
||||
invoke_func_d!()
|
||||
}
|
||||
#[inline(never)]
|
||||
fn func_d() -> Backtrace {
|
||||
Backtrace::capture()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
eprint!("{}", func_a());
|
||||
|
@ -26,7 +26,7 @@ fn drain() {
|
||||
for x in heap.drain() {
|
||||
sum += x;
|
||||
}
|
||||
assert_eq!(sum, 127*128/2);
|
||||
assert_eq!(sum, 127 * 128 / 2);
|
||||
|
||||
assert!(heap.is_empty());
|
||||
}
|
||||
|
@ -56,21 +56,18 @@ struct P {
|
||||
}
|
||||
|
||||
fn p(x: isize, y: isize) -> P {
|
||||
P {
|
||||
x: x,
|
||||
y: y
|
||||
}
|
||||
P { x: x, y: y }
|
||||
}
|
||||
|
||||
fn test_class() {
|
||||
let q = p(1, 2);
|
||||
let mut r = p(1, 2);
|
||||
let q = p(1, 2);
|
||||
let mut r = p(1, 2);
|
||||
|
||||
assert_eq!(q, r);
|
||||
r.y = 17;
|
||||
assert!((r.y != q.y));
|
||||
assert_eq!(r.y, 17);
|
||||
assert!((q != r));
|
||||
assert_eq!(q, r);
|
||||
r.y = 17;
|
||||
assert!((r.y != q.y));
|
||||
assert_eq!(r.y, 17);
|
||||
assert!((q != r));
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
|
@ -6,30 +6,34 @@ fn main() {
|
||||
boxed_pair_to_vec();
|
||||
}
|
||||
|
||||
fn into_raw() { unsafe {
|
||||
let b = Box::new(4i32);
|
||||
let r = Box::into_raw(b);
|
||||
fn into_raw() {
|
||||
unsafe {
|
||||
let b = Box::new(4i32);
|
||||
let r = Box::into_raw(b);
|
||||
|
||||
// "lose the tag"
|
||||
let r2 = ((r as usize)+0) as *mut i32;
|
||||
*(&mut *r2) = 7;
|
||||
// "lose the tag"
|
||||
let r2 = ((r as usize) + 0) as *mut i32;
|
||||
*(&mut *r2) = 7;
|
||||
|
||||
// Use original ptr again
|
||||
*(&mut *r) = 17;
|
||||
drop(Box::from_raw(r));
|
||||
}}
|
||||
// Use original ptr again
|
||||
*(&mut *r) = 17;
|
||||
drop(Box::from_raw(r));
|
||||
}
|
||||
}
|
||||
|
||||
fn into_unique() { unsafe {
|
||||
let b = Box::new(4i32);
|
||||
let u = Box::into_unique(b).0;
|
||||
fn into_unique() {
|
||||
unsafe {
|
||||
let b = Box::new(4i32);
|
||||
let u = Box::into_unique(b).0;
|
||||
|
||||
// "lose the tag"
|
||||
let r = ((u.as_ptr() as usize)+0) as *mut i32;
|
||||
*(&mut *r) = 7;
|
||||
// "lose the tag"
|
||||
let r = ((u.as_ptr() as usize) + 0) as *mut i32;
|
||||
*(&mut *r) = 7;
|
||||
|
||||
// Use original ptr again.
|
||||
drop(Box::from_raw(u.as_ptr()));
|
||||
}}
|
||||
// Use original ptr again.
|
||||
drop(Box::from_raw(u.as_ptr()));
|
||||
}
|
||||
}
|
||||
|
||||
fn boxed_pair_to_vec() {
|
||||
#[repr(C)]
|
||||
@ -44,15 +48,10 @@ fn boxed_pair_to_vec() {
|
||||
fn reinterstruct(box_pair: Box<PairFoo>) -> Vec<Foo> {
|
||||
let ref_pair = Box::leak(box_pair) as *mut PairFoo;
|
||||
let ptr_foo = unsafe { &mut (*ref_pair).fst as *mut Foo };
|
||||
unsafe {
|
||||
Vec::from_raw_parts(ptr_foo, 2, 2)
|
||||
}
|
||||
unsafe { Vec::from_raw_parts(ptr_foo, 2, 2) }
|
||||
}
|
||||
|
||||
let pair_foo = Box::new(PairFoo {
|
||||
fst: Foo(42),
|
||||
snd: Foo(1337),
|
||||
});
|
||||
let pair_foo = Box::new(PairFoo { fst: Foo(42), snd: Foo(1337) });
|
||||
println!("pair_foo = {:?}", pair_foo);
|
||||
for (n, foo) in reinterstruct(pair_foo).into_iter().enumerate() {
|
||||
println!("foo #{} = {:?}", n, foo);
|
||||
|
@ -7,17 +7,15 @@ fn call() -> i32 {
|
||||
|
||||
fn factorial_recursive() -> i64 {
|
||||
fn fact(n: i64) -> i64 {
|
||||
if n == 0 {
|
||||
1
|
||||
} else {
|
||||
n * fact(n - 1)
|
||||
}
|
||||
if n == 0 { 1 } else { n * fact(n - 1) }
|
||||
}
|
||||
fact(10)
|
||||
}
|
||||
|
||||
fn call_generic() -> (i16, bool) {
|
||||
fn id<T>(t: T) -> T { t }
|
||||
fn id<T>(t: T) -> T {
|
||||
t
|
||||
}
|
||||
(id(42), id(true))
|
||||
}
|
||||
|
||||
@ -26,7 +24,9 @@ fn cross_crate_fn_call() -> i64 {
|
||||
if 1i32.is_positive() { 1 } else { 0 }
|
||||
}
|
||||
|
||||
const fn foo(i: i64) -> i64 { *&i + 1 }
|
||||
const fn foo(i: i64) -> i64 {
|
||||
*&i + 1
|
||||
}
|
||||
|
||||
fn const_fn_call() -> i64 {
|
||||
let x = 5 + foo(5);
|
||||
|
@ -2,44 +2,52 @@
|
||||
// whose vtable have the same kind (both lengths, or both trait pointers).
|
||||
|
||||
trait Foo<T> {
|
||||
fn foo(&self, _: T) -> u32 { 42 }
|
||||
fn foo(&self, _: T) -> u32 {
|
||||
42
|
||||
}
|
||||
}
|
||||
|
||||
trait Bar {
|
||||
fn bar(&self) { println!("Bar!"); }
|
||||
fn bar(&self) {
|
||||
println!("Bar!");
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Foo<T> for () {}
|
||||
impl Foo<u32> for u32 { fn foo(&self, _: u32) -> u32 { self+43 } }
|
||||
impl Foo<u32> for u32 {
|
||||
fn foo(&self, _: u32) -> u32 {
|
||||
self + 43
|
||||
}
|
||||
}
|
||||
impl Bar for () {}
|
||||
|
||||
unsafe fn round_trip_and_call<'a>(t: *const (dyn Foo<u32>+'a)) -> u32 {
|
||||
let foo_e : *const dyn Foo<u16> = t as *const _;
|
||||
unsafe fn round_trip_and_call<'a>(t: *const (dyn Foo<u32> + 'a)) -> u32 {
|
||||
let foo_e: *const dyn Foo<u16> = t as *const _;
|
||||
let r_1 = foo_e as *mut dyn Foo<u32>;
|
||||
|
||||
(&*r_1).foo(0)
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
struct FooS<T:?Sized>(T);
|
||||
struct FooS<T: ?Sized>(T);
|
||||
#[repr(C)]
|
||||
struct BarS<T:?Sized>(T);
|
||||
struct BarS<T: ?Sized>(T);
|
||||
|
||||
fn foo_to_bar<T:?Sized>(u: *const FooS<T>) -> *const BarS<T> {
|
||||
fn foo_to_bar<T: ?Sized>(u: *const FooS<T>) -> *const BarS<T> {
|
||||
u as *const BarS<T>
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = 4u32;
|
||||
let y : &dyn Foo<u32> = &x;
|
||||
let y: &dyn Foo<u32> = &x;
|
||||
let fl = unsafe { round_trip_and_call(y as *const dyn Foo<u32>) };
|
||||
assert_eq!(fl, (43+4));
|
||||
assert_eq!(fl, (43 + 4));
|
||||
|
||||
let s = FooS([0,1,2]);
|
||||
let s = FooS([0, 1, 2]);
|
||||
let u: &FooS<[u32]> = &s;
|
||||
let u: *const FooS<[u32]> = u;
|
||||
let bar_ref : *const BarS<[u32]> = foo_to_bar(u);
|
||||
let z : &BarS<[u32]> = unsafe{&*bar_ref};
|
||||
assert_eq!(&z.0, &[0,1,2]);
|
||||
let bar_ref: *const BarS<[u32]> = foo_to_bar(u);
|
||||
let z: &BarS<[u32]> = unsafe { &*bar_ref };
|
||||
assert_eq!(&z.0, &[0, 1, 2]);
|
||||
// If validation fails here, that's likely because an immutable suspension is recovered mutably.
|
||||
}
|
||||
|
@ -1,9 +1,7 @@
|
||||
fn main() {
|
||||
fn f(_: *const u8) {}
|
||||
|
||||
let g = unsafe {
|
||||
std::mem::transmute::<fn(*const u8), fn(*const i32)>(f)
|
||||
};
|
||||
let g = unsafe { std::mem::transmute::<fn(*const u8), fn(*const i32)>(f) };
|
||||
|
||||
g(&42 as *const _);
|
||||
}
|
||||
|
@ -2,6 +2,8 @@ use std::panic::{catch_unwind, AssertUnwindSafe};
|
||||
|
||||
fn main() {
|
||||
let mut i = 3;
|
||||
let _val = catch_unwind(AssertUnwindSafe(|| {i -= 2;} ));
|
||||
let _val = catch_unwind(AssertUnwindSafe(|| {
|
||||
i -= 2;
|
||||
}));
|
||||
println!("{}", i);
|
||||
}
|
||||
|
@ -17,9 +17,10 @@ fn main() {
|
||||
// this closure never by val uses its captures
|
||||
// so it's basically a fn(&self)
|
||||
// the shim used to not drop the `x`
|
||||
let x = move || { let _val = x; };
|
||||
let x = move || {
|
||||
let _val = x;
|
||||
};
|
||||
f(x);
|
||||
}
|
||||
assert!(ran_drop);
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,9 @@ fn main() {
|
||||
let mut y = 0;
|
||||
{
|
||||
let mut box_maybe_closure = Box::new(None);
|
||||
*box_maybe_closure = Some(|| { y += 1; });
|
||||
*box_maybe_closure = Some(|| {
|
||||
y += 1;
|
||||
});
|
||||
(box_maybe_closure.unwrap())();
|
||||
}
|
||||
assert_eq!(y, 1);
|
||||
|
@ -22,7 +22,9 @@ fn crazy_closure() -> (i32, i32, i32) {
|
||||
}
|
||||
|
||||
fn closure_arg_adjustment_problem() -> i64 {
|
||||
fn once<F: FnOnce(i64)>(f: F) { f(2); }
|
||||
fn once<F: FnOnce(i64)>(f: F) {
|
||||
f(2);
|
||||
}
|
||||
let mut y = 1;
|
||||
{
|
||||
let f = |x| y += x;
|
||||
@ -32,7 +34,9 @@ fn closure_arg_adjustment_problem() -> i64 {
|
||||
}
|
||||
|
||||
fn fn_once_closure_with_multiple_args() -> i64 {
|
||||
fn once<F: FnOnce(i64, i64) -> i64>(f: F) -> i64 { f(2, 3) }
|
||||
fn once<F: FnOnce(i64, i64) -> i64>(f: F) -> i64 {
|
||||
f(2, 3)
|
||||
}
|
||||
let y = 1;
|
||||
{
|
||||
let f = |x, z| x + y + z;
|
||||
@ -50,7 +54,8 @@ fn box_dyn() {
|
||||
let mut i = 5;
|
||||
{
|
||||
let mut x: Box<dyn FnMut()> = Box::new(|| i *= 2);
|
||||
x(); x();
|
||||
x();
|
||||
x();
|
||||
}
|
||||
assert_eq!(i, 20);
|
||||
}
|
||||
@ -88,7 +93,9 @@ fn fn_item_with_multiple_args_as_closure_trait_object() {
|
||||
|
||||
fn fn_ptr_as_closure_trait_object() {
|
||||
fn foo() {}
|
||||
fn bar(u: u32) { assert_eq!(u, 42); }
|
||||
fn bar(u: u32) {
|
||||
assert_eq!(u, 42);
|
||||
}
|
||||
fn baa(u: u32, f: f32) {
|
||||
assert_eq!(u, 42);
|
||||
assert_eq!(f, 3.141);
|
||||
@ -101,13 +108,18 @@ fn fn_ptr_as_closure_trait_object() {
|
||||
f(42, 3.141);
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
assert_eq!(simple(), 12);
|
||||
assert_eq!(crazy_closure(), (84, 10, 10));
|
||||
assert_eq!(closure_arg_adjustment_problem(), 3);
|
||||
assert_eq!(fn_once_closure_with_multiple_args(), 6);
|
||||
assert_eq!(boxed_fn_once(Box::new({let x = 13; move || x})), 13);
|
||||
assert_eq!(
|
||||
boxed_fn_once(Box::new({
|
||||
let x = 13;
|
||||
move || x
|
||||
})),
|
||||
13
|
||||
);
|
||||
|
||||
box_dyn();
|
||||
fn_item_as_closure_trait_object();
|
||||
|
@ -1,11 +1,19 @@
|
||||
static FOO: fn() = || { assert_ne!(42, 43) };
|
||||
static BAR: fn(i32, i32) = |a, b| { assert_ne!(a, b) };
|
||||
static FOO: fn() = || assert_ne!(42, 43);
|
||||
static BAR: fn(i32, i32) = |a, b| assert_ne!(a, b);
|
||||
|
||||
// use to first make the closure FnOnce() before making it fn()
|
||||
fn force_once0<R, F: FnOnce() -> R>(f: F) -> F { f }
|
||||
fn force_once1<T, R, F: FnOnce(T) -> R>(f: F) -> F { f }
|
||||
fn force_mut0<R, F: FnMut() -> R>(f: F) -> F { f }
|
||||
fn force_mut1<T, R, F: FnMut(T) -> R>(f: F) -> F { f }
|
||||
fn force_once0<R, F: FnOnce() -> R>(f: F) -> F {
|
||||
f
|
||||
}
|
||||
fn force_once1<T, R, F: FnOnce(T) -> R>(f: F) -> F {
|
||||
f
|
||||
}
|
||||
fn force_mut0<R, F: FnMut() -> R>(f: F) -> F {
|
||||
f
|
||||
}
|
||||
fn force_mut1<T, R, F: FnMut(T) -> R>(f: F) -> F {
|
||||
f
|
||||
}
|
||||
|
||||
fn main() {
|
||||
FOO();
|
||||
@ -15,11 +23,11 @@ fn main() {
|
||||
let boo: &dyn Fn(i32, i32) = &BAR;
|
||||
boo(48, 49);
|
||||
|
||||
let f: fn() = ||{};
|
||||
let f: fn() = || {};
|
||||
f();
|
||||
let f = force_once0(||{}) as fn();
|
||||
let f = force_once0(|| {}) as fn();
|
||||
f();
|
||||
let f = force_mut0(||{}) as fn();
|
||||
let f = force_mut0(|| {}) as fn();
|
||||
f();
|
||||
|
||||
let g: fn(i32) = |i| assert_eq!(i, 2);
|
||||
|
@ -1,30 +1,32 @@
|
||||
#![feature(coerce_unsized, unsize)]
|
||||
|
||||
use std::ops::CoerceUnsized;
|
||||
use std::marker::Unsize;
|
||||
use std::ops::CoerceUnsized;
|
||||
|
||||
fn identity_coercion(x: &(dyn Fn(u32)->u32 + Send)) -> &dyn Fn(u32)->u32 {
|
||||
fn identity_coercion(x: &(dyn Fn(u32) -> u32 + Send)) -> &dyn Fn(u32) -> u32 {
|
||||
x
|
||||
}
|
||||
fn fn_coercions(f: &fn(u32) -> u32) ->
|
||||
(unsafe fn(u32) -> u32,
|
||||
&(dyn Fn(u32) -> u32 + Send))
|
||||
{
|
||||
fn fn_coercions(f: &fn(u32) -> u32) -> (unsafe fn(u32) -> u32, &(dyn Fn(u32) -> u32 + Send)) {
|
||||
(*f, f)
|
||||
}
|
||||
|
||||
fn simple_array_coercion(x: &[u8; 3]) -> &[u8] { x }
|
||||
fn simple_array_coercion(x: &[u8; 3]) -> &[u8] {
|
||||
x
|
||||
}
|
||||
|
||||
fn square(a: u32) -> u32 { a * a }
|
||||
fn square(a: u32) -> u32 {
|
||||
a * a
|
||||
}
|
||||
|
||||
#[derive(PartialEq,Eq)]
|
||||
struct PtrWrapper<'a, T: 'a+?Sized>(u32, u32, (), &'a T);
|
||||
impl<'a, T: ?Sized+Unsize<U>, U: ?Sized>
|
||||
CoerceUnsized<PtrWrapper<'a, U>> for PtrWrapper<'a, T> {}
|
||||
#[derive(PartialEq, Eq)]
|
||||
struct PtrWrapper<'a, T: 'a + ?Sized>(u32, u32, (), &'a T);
|
||||
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<PtrWrapper<'a, U>> for PtrWrapper<'a, T> {}
|
||||
|
||||
struct TrivPtrWrapper<'a, T: 'a+?Sized>(&'a T);
|
||||
impl<'a, T: ?Sized+Unsize<U>, U: ?Sized>
|
||||
CoerceUnsized<TrivPtrWrapper<'a, U>> for TrivPtrWrapper<'a, T> {}
|
||||
struct TrivPtrWrapper<'a, T: 'a + ?Sized>(&'a T);
|
||||
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<TrivPtrWrapper<'a, U>>
|
||||
for TrivPtrWrapper<'a, T>
|
||||
{
|
||||
}
|
||||
|
||||
fn coerce_ptr_wrapper(p: PtrWrapper<[u8; 3]>) -> PtrWrapper<[u8]> {
|
||||
p
|
||||
@ -34,40 +36,41 @@ fn coerce_triv_ptr_wrapper(p: TrivPtrWrapper<[u8; 3]>) -> TrivPtrWrapper<[u8]> {
|
||||
p
|
||||
}
|
||||
|
||||
fn coerce_fat_ptr_wrapper(p: PtrWrapper<dyn Fn(u32) -> u32 + Send>)
|
||||
-> PtrWrapper<dyn Fn(u32) -> u32> {
|
||||
fn coerce_fat_ptr_wrapper(
|
||||
p: PtrWrapper<dyn Fn(u32) -> u32 + Send>,
|
||||
) -> PtrWrapper<dyn Fn(u32) -> u32> {
|
||||
p
|
||||
}
|
||||
|
||||
fn coerce_ptr_wrapper_poly<'a, T, Trait: ?Sized>(p: PtrWrapper<'a, T>)
|
||||
-> PtrWrapper<'a, Trait>
|
||||
where PtrWrapper<'a, T>: CoerceUnsized<PtrWrapper<'a, Trait>>
|
||||
fn coerce_ptr_wrapper_poly<'a, T, Trait: ?Sized>(p: PtrWrapper<'a, T>) -> PtrWrapper<'a, Trait>
|
||||
where
|
||||
PtrWrapper<'a, T>: CoerceUnsized<PtrWrapper<'a, Trait>>,
|
||||
{
|
||||
p
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let a = [0,1,2];
|
||||
let square_local : fn(u32) -> u32 = square;
|
||||
let (f,g) = fn_coercions(&square_local);
|
||||
let a = [0, 1, 2];
|
||||
let square_local: fn(u32) -> u32 = square;
|
||||
let (f, g) = fn_coercions(&square_local);
|
||||
// cannot use `square as *const ()` because we can't know whether the compiler duplicates
|
||||
// functions, so two function pointers are only equal if they result from the same function
|
||||
// to function pointer cast
|
||||
assert_eq!(f as *const (), square_local as *const());
|
||||
assert_eq!(f as *const (), square_local as *const ());
|
||||
assert_eq!(g(4), 16);
|
||||
assert_eq!(identity_coercion(g)(5), 25);
|
||||
|
||||
assert_eq!(simple_array_coercion(&a), &a);
|
||||
let w = coerce_ptr_wrapper(PtrWrapper(2,3,(),&a));
|
||||
assert!(w == PtrWrapper(2,3,(),&a) as PtrWrapper<[u8]>);
|
||||
let w = coerce_ptr_wrapper(PtrWrapper(2, 3, (), &a));
|
||||
assert!(w == PtrWrapper(2, 3, (), &a) as PtrWrapper<[u8]>);
|
||||
|
||||
let w = coerce_triv_ptr_wrapper(TrivPtrWrapper(&a));
|
||||
assert_eq!(&w.0, &a);
|
||||
|
||||
let z = coerce_fat_ptr_wrapper(PtrWrapper(2,3,(),&square_local));
|
||||
let z = coerce_fat_ptr_wrapper(PtrWrapper(2, 3, (), &square_local));
|
||||
assert_eq!((z.3)(6), 36);
|
||||
|
||||
let z: PtrWrapper<dyn Fn(u32) -> u32> =
|
||||
coerce_ptr_wrapper_poly(PtrWrapper(2,3,(),&square_local));
|
||||
coerce_ptr_wrapper_poly(PtrWrapper(2, 3, (), &square_local));
|
||||
assert_eq!((z.3)(6), 36);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
// ignore-windows: Concurrency on Windows is not supported yet.
|
||||
|
||||
use std::thread::spawn;
|
||||
use std::panic::Location;
|
||||
use std::thread::spawn;
|
||||
|
||||
fn initialize() {
|
||||
let _ignore = initialize_inner();
|
||||
|
@ -1,8 +1,7 @@
|
||||
// ignore-windows: Concurrency on Windows is not supported yet.
|
||||
// compile-flags: -Zmiri-disable-weak-memory-emulation
|
||||
|
||||
|
||||
use std::sync::atomic::{AtomicUsize, fence, Ordering};
|
||||
use std::sync::atomic::{fence, AtomicUsize, Ordering};
|
||||
use std::thread::spawn;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
@ -18,9 +17,10 @@ fn test_fence_sync() {
|
||||
let ptr = &mut var as *mut u32;
|
||||
let evil_ptr = EvilSend(ptr);
|
||||
|
||||
|
||||
let j1 = spawn(move || {
|
||||
unsafe { *evil_ptr.0 = 1; }
|
||||
unsafe {
|
||||
*evil_ptr.0 = 1;
|
||||
}
|
||||
fence(Ordering::Release);
|
||||
SYNC.store(1, Ordering::Relaxed)
|
||||
});
|
||||
@ -38,16 +38,15 @@ fn test_fence_sync() {
|
||||
j2.join().unwrap();
|
||||
}
|
||||
|
||||
|
||||
fn test_multiple_reads() {
|
||||
let mut var = 42u32;
|
||||
let ptr = &mut var as *mut u32;
|
||||
let evil_ptr = EvilSend(ptr);
|
||||
|
||||
let j1 = spawn(move || unsafe {*evil_ptr.0});
|
||||
let j2 = spawn(move || unsafe {*evil_ptr.0});
|
||||
let j3 = spawn(move || unsafe {*evil_ptr.0});
|
||||
let j4 = spawn(move || unsafe {*evil_ptr.0});
|
||||
let j1 = spawn(move || unsafe { *evil_ptr.0 });
|
||||
let j2 = spawn(move || unsafe { *evil_ptr.0 });
|
||||
let j3 = spawn(move || unsafe { *evil_ptr.0 });
|
||||
let j4 = spawn(move || unsafe { *evil_ptr.0 });
|
||||
|
||||
assert_eq!(j1.join().unwrap(), 42);
|
||||
assert_eq!(j2.join().unwrap(), 42);
|
||||
@ -75,13 +74,7 @@ pub fn test_rmw_no_block() {
|
||||
}
|
||||
});
|
||||
|
||||
let j3 = spawn(move || {
|
||||
if SYNC.load(Ordering::Acquire) == 2 {
|
||||
*c.0
|
||||
} else {
|
||||
0
|
||||
}
|
||||
});
|
||||
let j3 = spawn(move || if SYNC.load(Ordering::Acquire) == 2 { *c.0 } else { 0 });
|
||||
|
||||
j1.join().unwrap();
|
||||
j2.join().unwrap();
|
||||
@ -101,16 +94,10 @@ pub fn test_simple_release() {
|
||||
SYNC.store(1, Ordering::Release);
|
||||
});
|
||||
|
||||
let j2 = spawn(move || {
|
||||
if SYNC.load(Ordering::Acquire) == 1 {
|
||||
*c.0
|
||||
} else {
|
||||
0
|
||||
}
|
||||
});
|
||||
let j2 = spawn(move || if SYNC.load(Ordering::Acquire) == 1 { *c.0 } else { 0 });
|
||||
|
||||
j1.join().unwrap();
|
||||
assert_eq!(j2.join().unwrap(),1);
|
||||
assert_eq!(j2.join().unwrap(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,31 +42,25 @@ fn create_move_in() {
|
||||
}
|
||||
|
||||
fn create_move_out() {
|
||||
let result = thread::spawn(|| {
|
||||
String::from("Hello!")
|
||||
})
|
||||
.join()
|
||||
.unwrap();
|
||||
let result = thread::spawn(|| String::from("Hello!")).join().unwrap();
|
||||
assert_eq!(result.len(), 6);
|
||||
}
|
||||
|
||||
fn panic() {
|
||||
let result = thread::spawn(|| {
|
||||
panic!("Hello!")
|
||||
})
|
||||
.join()
|
||||
.unwrap_err();
|
||||
let result = thread::spawn(|| panic!("Hello!")).join().unwrap_err();
|
||||
let msg = result.downcast_ref::<&'static str>().unwrap();
|
||||
assert_eq!(*msg, "Hello!");
|
||||
}
|
||||
|
||||
fn panic_named() {
|
||||
thread::Builder::new().name("childthread".to_string()).spawn(move || {
|
||||
panic!("Hello, world!");
|
||||
})
|
||||
.unwrap()
|
||||
.join()
|
||||
.unwrap_err();
|
||||
thread::Builder::new()
|
||||
.name("childthread".to_string())
|
||||
.spawn(move || {
|
||||
panic!("Hello, world!");
|
||||
})
|
||||
.unwrap()
|
||||
.join()
|
||||
.unwrap_err();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -1,6 +1,6 @@
|
||||
// ignore-windows: Concurrency on Windows is not supported yet.
|
||||
use std::thread;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::thread;
|
||||
|
||||
static FLAG: AtomicUsize = AtomicUsize::new(0);
|
||||
|
||||
|
@ -2,10 +2,10 @@
|
||||
// This specifically tests behavior *without* preemption.
|
||||
// compile-flags: -Zmiri-preemption-rate=0
|
||||
|
||||
use std::thread;
|
||||
use std::cell::Cell;
|
||||
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
|
||||
use std::sync::mpsc;
|
||||
use std::cell::Cell;
|
||||
use std::thread;
|
||||
|
||||
/// When a thread yields, Miri's scheduler used to pick the thread with the lowest ID
|
||||
/// that can run. IDs are assigned in thread creation order.
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::sync::{Mutex, TryLockError};
|
||||
use std::sync::atomic;
|
||||
use std::hint;
|
||||
use std::sync::atomic;
|
||||
use std::sync::{Mutex, TryLockError};
|
||||
|
||||
fn main() {
|
||||
test_mutex_stdlib();
|
||||
|
@ -9,7 +9,9 @@ struct TestCell {
|
||||
|
||||
impl Drop for TestCell {
|
||||
fn drop(&mut self) {
|
||||
for _ in 0..10 { thread::yield_now(); }
|
||||
for _ in 0..10 {
|
||||
thread::yield_now();
|
||||
}
|
||||
println!("Dropping: {} (should be before 'Continue main 1').", *self.value.borrow())
|
||||
}
|
||||
}
|
||||
@ -43,7 +45,9 @@ struct JoinCell {
|
||||
|
||||
impl Drop for JoinCell {
|
||||
fn drop(&mut self) {
|
||||
for _ in 0..10 { thread::yield_now(); }
|
||||
for _ in 0..10 {
|
||||
thread::yield_now();
|
||||
}
|
||||
let join_handle = self.value.borrow_mut().take().unwrap();
|
||||
println!("Joining: {} (should be before 'Continue main 2').", join_handle.join().unwrap());
|
||||
}
|
||||
@ -118,9 +122,10 @@ fn join_orders_after_tls_destructors() {
|
||||
match sync_state {
|
||||
THREAD2_LAUNCHED | THREAD1_WAITING => thread::yield_now(),
|
||||
MAIN_THREAD_RENDEZVOUS => break,
|
||||
THREAD2_JOINED => panic!(
|
||||
"Thread 1 still running after thread 2 joined on thread 1"
|
||||
),
|
||||
THREAD2_JOINED =>
|
||||
panic!(
|
||||
"Thread 1 still running after thread 2 joined on thread 1"
|
||||
),
|
||||
v => unreachable!("sync state: {}", v),
|
||||
}
|
||||
sync_state = SYNC_STATE.load(Ordering::SeqCst);
|
||||
|
@ -7,13 +7,13 @@ use std::mem;
|
||||
|
||||
pub type Key = libc::pthread_key_t;
|
||||
|
||||
static mut RECORD : usize = 0;
|
||||
static mut KEYS : [Key; 2] = [0; 2];
|
||||
static mut GLOBALS : [u64; 2] = [1, 0];
|
||||
static mut RECORD: usize = 0;
|
||||
static mut KEYS: [Key; 2] = [0; 2];
|
||||
static mut GLOBALS: [u64; 2] = [1, 0];
|
||||
|
||||
static mut CANNARY : *mut u64 = 0 as *mut _; // this serves as a cannary: if TLS dtors are not run properly, this will not get deallocated, making the test fail.
|
||||
static mut CANNARY: *mut u64 = 0 as *mut _; // this serves as a cannary: if TLS dtors are not run properly, this will not get deallocated, making the test fail.
|
||||
|
||||
pub unsafe fn create(dtor: Option<unsafe extern fn(*mut u8)>) -> Key {
|
||||
pub unsafe fn create(dtor: Option<unsafe extern "C" fn(*mut u8)>) -> Key {
|
||||
let mut key = 0;
|
||||
assert_eq!(libc::pthread_key_create(&mut key, mem::transmute(dtor)), 0);
|
||||
key
|
||||
@ -26,18 +26,19 @@ pub unsafe fn set(key: Key, value: *mut u8) {
|
||||
|
||||
pub fn record(r: usize) {
|
||||
assert!(r < 10);
|
||||
unsafe { RECORD = RECORD*10 + r };
|
||||
unsafe { RECORD = RECORD * 10 + r };
|
||||
}
|
||||
|
||||
unsafe extern fn dtor(ptr: *mut u64) {
|
||||
unsafe extern "C" fn dtor(ptr: *mut u64) {
|
||||
assert!(CANNARY != 0 as *mut _); // make sure we do not get run too often
|
||||
let val = *ptr;
|
||||
|
||||
let which_key = GLOBALS.iter().position(|global| global as *const _ == ptr).expect("Should find my global");
|
||||
let which_key =
|
||||
GLOBALS.iter().position(|global| global as *const _ == ptr).expect("Should find my global");
|
||||
record(which_key);
|
||||
|
||||
if val > 0 {
|
||||
*ptr = val-1;
|
||||
*ptr = val - 1;
|
||||
set(KEYS[which_key], ptr as *mut _);
|
||||
}
|
||||
|
||||
@ -57,7 +58,7 @@ fn main() {
|
||||
|
||||
// Initialize the keys we use to check destructor ordering
|
||||
for (key, global) in KEYS.iter_mut().zip(GLOBALS.iter_mut()) {
|
||||
*key = create(Some(mem::transmute(dtor as unsafe extern fn(*mut u64))));
|
||||
*key = create(Some(mem::transmute(dtor as unsafe extern "C" fn(*mut u64))));
|
||||
set(*key, global as *mut _ as *mut u8);
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
* should be read as a null or otherwise wrong pointer and crash.
|
||||
*/
|
||||
|
||||
fn f() { }
|
||||
fn f() {}
|
||||
static mut CLOSURES: &'static mut [fn()] = &mut [f as fn(), f as fn()];
|
||||
|
||||
pub fn main() {
|
||||
|
@ -2,6 +2,6 @@
|
||||
|
||||
fn main() {
|
||||
// With the nested Vec, this is calling Offset(Unique::empty(), 0) on drop.
|
||||
let args : Vec<Vec<i32>> = Vec::new();
|
||||
let args: Vec<Vec<i32>> = Vec::new();
|
||||
let _val = box args;
|
||||
}
|
||||
|
@ -5,7 +5,9 @@ static mut DROP_COUNT: usize = 0;
|
||||
impl Drop for Bar {
|
||||
fn drop(&mut self) {
|
||||
assert_eq!(self.0 as usize, unsafe { DROP_COUNT }); // tests whether we are called at a valid address
|
||||
unsafe { DROP_COUNT += 1; }
|
||||
unsafe {
|
||||
DROP_COUNT += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,7 +18,7 @@ fn main() {
|
||||
assert_eq!(unsafe { DROP_COUNT }, 4);
|
||||
|
||||
// check empty case
|
||||
let b : [Bar; 0] = [];
|
||||
let b: [Bar; 0] = [];
|
||||
drop(b);
|
||||
assert_eq!(unsafe { DROP_COUNT }, 4);
|
||||
}
|
||||
|
@ -8,7 +8,9 @@ static mut DROP_COUNT: usize = 0;
|
||||
|
||||
impl Drop for Bar {
|
||||
fn drop(&mut self) {
|
||||
unsafe { DROP_COUNT += 1; }
|
||||
unsafe {
|
||||
DROP_COUNT += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,9 @@ static mut DROP_COUNT: usize = 0;
|
||||
|
||||
impl Drop for Bar {
|
||||
fn drop(&mut self) {
|
||||
unsafe { DROP_COUNT += 1; }
|
||||
unsafe {
|
||||
DROP_COUNT += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,7 +17,7 @@ fn main() {
|
||||
assert_eq!(unsafe { DROP_COUNT }, 4);
|
||||
|
||||
// check empty case
|
||||
let b : [Bar; 0] = [];
|
||||
let b: [Bar; 0] = [];
|
||||
drop(b);
|
||||
assert_eq!(unsafe { DROP_COUNT }, 4);
|
||||
}
|
||||
|
@ -4,7 +4,9 @@ static mut DROP_COUNT: usize = 0;
|
||||
|
||||
impl Drop for Bar {
|
||||
fn drop(&mut self) {
|
||||
unsafe { DROP_COUNT += 1; }
|
||||
unsafe {
|
||||
DROP_COUNT += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,9 @@ static mut DROP_CALLED: bool = false;
|
||||
|
||||
impl Drop for Bar {
|
||||
fn drop(&mut self) {
|
||||
unsafe { DROP_CALLED = true; }
|
||||
unsafe {
|
||||
DROP_CALLED = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,9 @@ static mut DROP_CALLED: bool = false;
|
||||
|
||||
impl Drop for Bar {
|
||||
fn drop(&mut self) {
|
||||
unsafe { DROP_CALLED = true; }
|
||||
unsafe {
|
||||
DROP_CALLED = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#[allow(dead_code)]
|
||||
struct Foo<T: ?Sized> {
|
||||
a: u16,
|
||||
b: T
|
||||
b: T,
|
||||
}
|
||||
|
||||
trait Bar {
|
||||
@ -9,59 +9,58 @@ trait Bar {
|
||||
}
|
||||
|
||||
impl Bar for usize {
|
||||
fn get(&self) -> usize { *self }
|
||||
fn get(&self) -> usize {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
struct Baz<T: ?Sized> {
|
||||
a: T
|
||||
a: T,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
struct HasDrop<T: ?Sized> {
|
||||
ptr: Box<usize>,
|
||||
data: T
|
||||
data: T,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// Test that zero-offset works properly
|
||||
let b : Baz<usize> = Baz { a: 7 };
|
||||
let b: Baz<usize> = Baz { a: 7 };
|
||||
assert_eq!(b.a.get(), 7);
|
||||
let b : &Baz<dyn Bar> = &b;
|
||||
let b: &Baz<dyn Bar> = &b;
|
||||
assert_eq!(b.a.get(), 7);
|
||||
|
||||
// Test that the field is aligned properly
|
||||
let f : Foo<usize> = Foo { a: 0, b: 11 };
|
||||
let f: Foo<usize> = Foo { a: 0, b: 11 };
|
||||
assert_eq!(f.b.get(), 11);
|
||||
let ptr1 : *const u8 = &f.b as *const _ as *const u8;
|
||||
let ptr1: *const u8 = &f.b as *const _ as *const u8;
|
||||
|
||||
let f : &Foo<dyn Bar> = &f;
|
||||
let ptr2 : *const u8 = &f.b as *const _ as *const u8;
|
||||
let f: &Foo<dyn Bar> = &f;
|
||||
let ptr2: *const u8 = &f.b as *const _ as *const u8;
|
||||
assert_eq!(f.b.get(), 11);
|
||||
|
||||
// The pointers should be the same
|
||||
assert_eq!(ptr1, ptr2);
|
||||
|
||||
// Test that nested DSTs work properly
|
||||
let f : Foo<Foo<usize>> = Foo { a: 0, b: Foo { a: 1, b: 17 }};
|
||||
let f: Foo<Foo<usize>> = Foo { a: 0, b: Foo { a: 1, b: 17 } };
|
||||
assert_eq!(f.b.b.get(), 17);
|
||||
let f : &Foo<Foo<dyn Bar>> = &f;
|
||||
let f: &Foo<Foo<dyn Bar>> = &f;
|
||||
assert_eq!(f.b.b.get(), 17);
|
||||
|
||||
// Test that get the pointer via destructuring works
|
||||
|
||||
let f : Foo<usize> = Foo { a: 0, b: 11 };
|
||||
let f : &Foo<dyn Bar> = &f;
|
||||
let f: Foo<usize> = Foo { a: 0, b: 11 };
|
||||
let f: &Foo<dyn Bar> = &f;
|
||||
let &Foo { a: _, b: ref bar } = f;
|
||||
assert_eq!(bar.get(), 11);
|
||||
|
||||
// Make sure that drop flags don't screw things up
|
||||
|
||||
let d : HasDrop<Baz<[i32; 4]>> = HasDrop {
|
||||
ptr: Box::new(0),
|
||||
data: Baz { a: [1,2,3,4] }
|
||||
};
|
||||
assert_eq!([1,2,3,4], d.data.a);
|
||||
let d: HasDrop<Baz<[i32; 4]>> = HasDrop { ptr: Box::new(0), data: Baz { a: [1, 2, 3, 4] } };
|
||||
assert_eq!([1, 2, 3, 4], d.data.a);
|
||||
|
||||
let d : &HasDrop<Baz<[i32]>> = &d;
|
||||
assert_eq!(&[1,2,3,4], &d.data.a);
|
||||
let d: &HasDrop<Baz<[i32]>> = &d;
|
||||
assert_eq!(&[1, 2, 3, 4], &d.data.a);
|
||||
}
|
||||
|
@ -1,14 +1,14 @@
|
||||
struct Test<T: ?Sized>(T);
|
||||
|
||||
fn main() {
|
||||
let x = Test([1,2,3]);
|
||||
let x : &Test<[i32]> = &x;
|
||||
let x = Test([1, 2, 3]);
|
||||
let x: &Test<[i32]> = &x;
|
||||
|
||||
let & ref _y = x;
|
||||
let &ref _y = x;
|
||||
|
||||
// Make sure binding to a fat pointer behind a reference
|
||||
// still works
|
||||
let slice = &[1,2,3];
|
||||
let slice = &[1, 2, 3];
|
||||
let x = Test(&slice);
|
||||
let Test(&_slice) = x;
|
||||
}
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Test DST raw pointers
|
||||
|
||||
|
||||
trait Trait {
|
||||
fn foo(&self) -> isize;
|
||||
}
|
||||
|
||||
struct A {
|
||||
f: isize
|
||||
f: isize,
|
||||
}
|
||||
impl Trait for A {
|
||||
fn foo(&self) -> isize {
|
||||
@ -15,24 +14,20 @@ impl Trait for A {
|
||||
}
|
||||
|
||||
struct Foo<T: ?Sized> {
|
||||
f: T
|
||||
f: T,
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
// raw trait object
|
||||
let x = A { f: 42 };
|
||||
let z: *const dyn Trait = &x;
|
||||
let r = unsafe {
|
||||
(&*z).foo()
|
||||
};
|
||||
let r = unsafe { (&*z).foo() };
|
||||
assert_eq!(r, 42);
|
||||
|
||||
// raw DST struct
|
||||
let p = Foo {f: A { f: 42 }};
|
||||
let p = Foo { f: A { f: 42 } };
|
||||
let o: *const Foo<dyn Trait> = &p;
|
||||
let r = unsafe {
|
||||
(&*o).f.foo()
|
||||
};
|
||||
let r = unsafe { (&*o).f.foo() };
|
||||
assert_eq!(r, 42);
|
||||
|
||||
// raw slice
|
||||
@ -54,7 +49,7 @@ pub fn main() {
|
||||
}
|
||||
|
||||
// raw DST struct with slice
|
||||
let c: *const Foo<[_]> = &Foo {f: [1, 2, 3]};
|
||||
let c: *const Foo<[_]> = &Foo { f: [1, 2, 3] };
|
||||
unsafe {
|
||||
let b = (&*c).f[0];
|
||||
assert_eq!(b, 1);
|
||||
@ -65,16 +60,12 @@ pub fn main() {
|
||||
// all of the above with *mut
|
||||
let mut x = A { f: 42 };
|
||||
let z: *mut dyn Trait = &mut x;
|
||||
let r = unsafe {
|
||||
(&*z).foo()
|
||||
};
|
||||
let r = unsafe { (&*z).foo() };
|
||||
assert_eq!(r, 42);
|
||||
|
||||
let mut p = Foo {f: A { f: 42 }};
|
||||
let mut p = Foo { f: A { f: 42 } };
|
||||
let o: *mut Foo<dyn Trait> = &mut p;
|
||||
let r = unsafe {
|
||||
(&*o).f.foo()
|
||||
};
|
||||
let r = unsafe { (&*o).f.foo() };
|
||||
assert_eq!(r, 42);
|
||||
|
||||
let a: *mut [_] = &mut [1, 2, 3];
|
||||
@ -93,7 +84,7 @@ pub fn main() {
|
||||
assert_eq!(len, 3);
|
||||
}
|
||||
|
||||
let c: *mut Foo<[_]> = &mut Foo {f: [1, 2, 3]};
|
||||
let c: *mut Foo<[_]> = &mut Foo { f: [1, 2, 3] };
|
||||
unsafe {
|
||||
let b = (&*c).f[0];
|
||||
assert_eq!(b, 1);
|
||||
|
@ -1,8 +1,7 @@
|
||||
// As dst-struct.rs, but the unsized field is the only field in the struct.
|
||||
|
||||
|
||||
struct Fat<T: ?Sized> {
|
||||
ptr: T
|
||||
ptr: T,
|
||||
}
|
||||
|
||||
// x is a fat pointer
|
||||
@ -13,7 +12,7 @@ fn foo(x: &Fat<[isize]>) {
|
||||
assert_eq!(x.ptr[1], 2);
|
||||
}
|
||||
|
||||
fn foo2<T:ToBar>(x: &Fat<[T]>) {
|
||||
fn foo2<T: ToBar>(x: &Fat<[T]>) {
|
||||
let y = &x.ptr;
|
||||
let bar = Bar;
|
||||
assert_eq!(x.ptr.len(), 3);
|
||||
|
@ -3,7 +3,7 @@
|
||||
struct Fat<T: ?Sized> {
|
||||
f1: isize,
|
||||
f2: &'static str,
|
||||
ptr: T
|
||||
ptr: T,
|
||||
}
|
||||
|
||||
// x is a fat pointer
|
||||
@ -16,7 +16,7 @@ fn foo(x: &Fat<[isize]>) {
|
||||
assert_eq!(x.f2, "some str");
|
||||
}
|
||||
|
||||
fn foo2<T:ToBar>(x: &Fat<[T]>) {
|
||||
fn foo2<T: ToBar>(x: &Fat<[T]>) {
|
||||
let y = &x.ptr;
|
||||
let bar = Bar;
|
||||
assert_eq!(x.ptr.len(), 3);
|
||||
@ -37,7 +37,6 @@ fn foo3(x: &Fat<Fat<[isize]>>) {
|
||||
assert_eq!(x.ptr.ptr[1], 2);
|
||||
}
|
||||
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
struct Bar;
|
||||
|
||||
@ -53,9 +52,9 @@ impl ToBar for Bar {
|
||||
|
||||
pub fn main() {
|
||||
// With a vec of ints.
|
||||
let f1 : Fat<[isize; 3]> = Fat { f1: 5, f2: "some str", ptr: [1, 2, 3] };
|
||||
let f1: Fat<[isize; 3]> = Fat { f1: 5, f2: "some str", ptr: [1, 2, 3] };
|
||||
foo(&f1);
|
||||
let f2 : &Fat<[isize; 3]> = &f1;
|
||||
let f2: &Fat<[isize; 3]> = &f1;
|
||||
foo(f2);
|
||||
let f3: &Fat<[isize]> = f2;
|
||||
foo(f3);
|
||||
@ -91,7 +90,7 @@ pub fn main() {
|
||||
assert!(f5.ptr.is_empty());
|
||||
|
||||
// Deeply nested.
|
||||
let f1 = Fat { f1: 5, f2: "some str", ptr: Fat { f1: 8, f2: "deep str", ptr: [1, 2, 3]} };
|
||||
let f1 = Fat { f1: 5, f2: "some str", ptr: Fat { f1: 8, f2: "deep str", ptr: [1, 2, 3] } };
|
||||
foo3(&f1);
|
||||
let f2 = &f1;
|
||||
foo3(f2);
|
||||
@ -100,7 +99,7 @@ pub fn main() {
|
||||
let f4: &Fat<Fat<[isize]>> = &f1;
|
||||
foo3(f4);
|
||||
let f5: &Fat<Fat<[isize]>> =
|
||||
&Fat { f1: 5, f2: "some str", ptr: Fat { f1: 8, f2: "deep str", ptr: [1, 2, 3]} };
|
||||
&Fat { f1: 5, f2: "some str", ptr: Fat { f1: 8, f2: "deep str", ptr: [1, 2, 3] } };
|
||||
foo3(f5);
|
||||
|
||||
// Box.
|
||||
@ -110,14 +109,14 @@ pub fn main() {
|
||||
assert_eq!((*f2)[1], 2);
|
||||
|
||||
// Nested Box.
|
||||
let f1 : Box<Fat<[isize; 3]>> = box Fat { f1: 5, f2: "some str", ptr: [1, 2, 3] };
|
||||
let f1: Box<Fat<[isize; 3]>> = box Fat { f1: 5, f2: "some str", ptr: [1, 2, 3] };
|
||||
foo(&*f1);
|
||||
let f2 : Box<Fat<[isize]>> = f1;
|
||||
let f2: Box<Fat<[isize]>> = f1;
|
||||
foo(&*f2);
|
||||
|
||||
let f3 : Box<Fat<[isize]>> =
|
||||
let f3: Box<Fat<[isize]>> =
|
||||
Box::<Fat<[_; 3]>>::new(Fat { f1: 5, f2: "some str", ptr: [1, 2, 3] });
|
||||
foo(&*f3);
|
||||
let f4 : Box<Fat<[isize]>> = box Fat { f1: 5, f2: "some str", ptr: [1, 2, 3] };
|
||||
let f4: Box<Fat<[isize]>> = box Fat { f1: 5, f2: "some str", ptr: [1, 2, 3] };
|
||||
foo(&*f4);
|
||||
}
|
||||
|
@ -19,11 +19,7 @@ fn pin_box_dyn() {
|
||||
}
|
||||
|
||||
fn stdlib_pointers() {
|
||||
use std::{
|
||||
rc::Rc,
|
||||
sync::Arc,
|
||||
pin::Pin,
|
||||
};
|
||||
use std::{pin::Pin, rc::Rc, sync::Arc};
|
||||
|
||||
trait Trait {
|
||||
fn by_rc(self: Rc<Self>) -> i64;
|
||||
@ -63,8 +59,8 @@ fn stdlib_pointers() {
|
||||
|
||||
fn pointers_and_wrappers() {
|
||||
use std::{
|
||||
ops::{Deref, CoerceUnsized, DispatchFromDyn},
|
||||
marker::Unsize,
|
||||
ops::{CoerceUnsized, Deref, DispatchFromDyn},
|
||||
};
|
||||
|
||||
struct Ptr<T: ?Sized>(Box<T>);
|
||||
@ -93,7 +89,6 @@ fn pointers_and_wrappers() {
|
||||
impl<T: CoerceUnsized<U>, U> CoerceUnsized<Wrapper<U>> for Wrapper<T> {}
|
||||
impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<Wrapper<U>> for Wrapper<T> {}
|
||||
|
||||
|
||||
trait Trait {
|
||||
// This method isn't object-safe yet. Unsized by-value `self` is object-safe (but not callable
|
||||
// without unsized_locals), but wrappers arond `Self` currently are not.
|
||||
@ -126,7 +121,6 @@ fn pointers_and_wrappers() {
|
||||
assert_eq!(wpw.wrapper_ptr_wrapper(), 7);
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
pin_box_dyn();
|
||||
stdlib_pointers();
|
||||
|
@ -39,7 +39,6 @@ fn ref_box_dyn() {
|
||||
y.box_method();
|
||||
}
|
||||
|
||||
|
||||
fn box_box_trait() {
|
||||
struct DroppableStruct;
|
||||
|
||||
@ -47,17 +46,23 @@ fn box_box_trait() {
|
||||
|
||||
impl Drop for DroppableStruct {
|
||||
fn drop(&mut self) {
|
||||
unsafe { DROPPED = true; }
|
||||
unsafe {
|
||||
DROPPED = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trait MyTrait { fn dummy(&self) { } }
|
||||
trait MyTrait {
|
||||
fn dummy(&self) {}
|
||||
}
|
||||
impl MyTrait for Box<DroppableStruct> {}
|
||||
|
||||
struct Whatever { w: Box<dyn MyTrait+'static> }
|
||||
struct Whatever {
|
||||
w: Box<dyn MyTrait + 'static>,
|
||||
}
|
||||
|
||||
impl Whatever {
|
||||
fn new(w: Box<dyn MyTrait+'static>) -> Whatever {
|
||||
impl Whatever {
|
||||
fn new(w: Box<dyn MyTrait + 'static>) -> Whatever {
|
||||
Whatever { w: w }
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
use std::result::Result;
|
||||
use std::result::Result::Ok;
|
||||
|
||||
|
@ -2,24 +2,21 @@ enum MyEnum {
|
||||
MyEmptyVariant,
|
||||
MyNewtypeVariant(i32),
|
||||
MyTupleVariant(i32, i32),
|
||||
MyStructVariant {
|
||||
my_first_field: i32,
|
||||
my_second_field: i32,
|
||||
}
|
||||
MyStructVariant { my_first_field: i32, my_second_field: i32 },
|
||||
}
|
||||
|
||||
fn test(me: MyEnum) {
|
||||
match me {
|
||||
MyEnum::MyEmptyVariant => {},
|
||||
MyEnum::MyEmptyVariant => {}
|
||||
MyEnum::MyNewtypeVariant(ref val) => assert_eq!(val, &42),
|
||||
MyEnum::MyTupleVariant(ref a, ref b) => {
|
||||
assert_eq!(a, &43);
|
||||
assert_eq!(b, &44);
|
||||
},
|
||||
}
|
||||
MyEnum::MyStructVariant { ref my_first_field, ref my_second_field } => {
|
||||
assert_eq!(my_first_field, &45);
|
||||
assert_eq!(my_second_field, &46);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,7 +38,7 @@ fn discriminant_overflow() {
|
||||
|
||||
let x = Foo::B;
|
||||
match x {
|
||||
Foo::B => {},
|
||||
Foo::B => {}
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
@ -126,10 +123,7 @@ fn main() {
|
||||
test(MyEnum::MyEmptyVariant);
|
||||
test(MyEnum::MyNewtypeVariant(42));
|
||||
test(MyEnum::MyTupleVariant(43, 44));
|
||||
test(MyEnum::MyStructVariant{
|
||||
my_first_field: 45,
|
||||
my_second_field: 46,
|
||||
});
|
||||
test(MyEnum::MyStructVariant { my_first_field: 45, my_second_field: 46 });
|
||||
|
||||
discriminant_overflow();
|
||||
more_discriminant_overflow();
|
||||
|
@ -1,6 +1,6 @@
|
||||
#![feature(extern_types)]
|
||||
|
||||
extern {
|
||||
extern "C" {
|
||||
type Foo;
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
struct Wrapper<T: ?Sized>(u32, T);
|
||||
|
||||
struct FatPtrContainer<'a> {
|
||||
ptr: &'a [u8]
|
||||
ptr: &'a [u8],
|
||||
}
|
||||
|
||||
fn fat_ptr_project(a: &Wrapper<[u8]>) -> &[u8] {
|
||||
@ -36,14 +36,14 @@ fn fat_ptr_constant() -> &'static str {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let a = Wrapper(4, [7,6,5]);
|
||||
let a = Wrapper(4, [7, 6, 5]);
|
||||
|
||||
let p = fat_ptr_project(&a);
|
||||
let p = fat_ptr_simple(p);
|
||||
let p = fat_ptr_via_local(p);
|
||||
let p = fat_ptr_from_struct(fat_ptr_to_struct(p));
|
||||
|
||||
let mut target : &[u8] = &[42];
|
||||
let mut target: &[u8] = &[42];
|
||||
fat_ptr_store_to(p, &mut target);
|
||||
assert_eq!(target, &a.1);
|
||||
|
||||
|
@ -26,60 +26,110 @@ trait FloatToInt<Int>: Copy {
|
||||
}
|
||||
|
||||
impl FloatToInt<i8> for f32 {
|
||||
fn cast(self) -> i8 { self as _ }
|
||||
unsafe fn cast_unchecked(self) -> i8 { self.to_int_unchecked() }
|
||||
fn cast(self) -> i8 {
|
||||
self as _
|
||||
}
|
||||
unsafe fn cast_unchecked(self) -> i8 {
|
||||
self.to_int_unchecked()
|
||||
}
|
||||
}
|
||||
impl FloatToInt<i32> for f32 {
|
||||
fn cast(self) -> i32 { self as _ }
|
||||
unsafe fn cast_unchecked(self) -> i32 { self.to_int_unchecked() }
|
||||
fn cast(self) -> i32 {
|
||||
self as _
|
||||
}
|
||||
unsafe fn cast_unchecked(self) -> i32 {
|
||||
self.to_int_unchecked()
|
||||
}
|
||||
}
|
||||
impl FloatToInt<u32> for f32 {
|
||||
fn cast(self) -> u32 { self as _ }
|
||||
unsafe fn cast_unchecked(self) -> u32 { self.to_int_unchecked() }
|
||||
fn cast(self) -> u32 {
|
||||
self as _
|
||||
}
|
||||
unsafe fn cast_unchecked(self) -> u32 {
|
||||
self.to_int_unchecked()
|
||||
}
|
||||
}
|
||||
impl FloatToInt<i64> for f32 {
|
||||
fn cast(self) -> i64 { self as _ }
|
||||
unsafe fn cast_unchecked(self) -> i64 { self.to_int_unchecked() }
|
||||
fn cast(self) -> i64 {
|
||||
self as _
|
||||
}
|
||||
unsafe fn cast_unchecked(self) -> i64 {
|
||||
self.to_int_unchecked()
|
||||
}
|
||||
}
|
||||
impl FloatToInt<u64> for f32 {
|
||||
fn cast(self) -> u64 { self as _ }
|
||||
unsafe fn cast_unchecked(self) -> u64 { self.to_int_unchecked() }
|
||||
fn cast(self) -> u64 {
|
||||
self as _
|
||||
}
|
||||
unsafe fn cast_unchecked(self) -> u64 {
|
||||
self.to_int_unchecked()
|
||||
}
|
||||
}
|
||||
|
||||
impl FloatToInt<i8> for f64 {
|
||||
fn cast(self) -> i8 { self as _ }
|
||||
unsafe fn cast_unchecked(self) -> i8 { self.to_int_unchecked() }
|
||||
fn cast(self) -> i8 {
|
||||
self as _
|
||||
}
|
||||
unsafe fn cast_unchecked(self) -> i8 {
|
||||
self.to_int_unchecked()
|
||||
}
|
||||
}
|
||||
impl FloatToInt<i32> for f64 {
|
||||
fn cast(self) -> i32 { self as _ }
|
||||
unsafe fn cast_unchecked(self) -> i32 { self.to_int_unchecked() }
|
||||
fn cast(self) -> i32 {
|
||||
self as _
|
||||
}
|
||||
unsafe fn cast_unchecked(self) -> i32 {
|
||||
self.to_int_unchecked()
|
||||
}
|
||||
}
|
||||
impl FloatToInt<u32> for f64 {
|
||||
fn cast(self) -> u32 { self as _ }
|
||||
unsafe fn cast_unchecked(self) -> u32 { self.to_int_unchecked() }
|
||||
fn cast(self) -> u32 {
|
||||
self as _
|
||||
}
|
||||
unsafe fn cast_unchecked(self) -> u32 {
|
||||
self.to_int_unchecked()
|
||||
}
|
||||
}
|
||||
impl FloatToInt<i64> for f64 {
|
||||
fn cast(self) -> i64 { self as _ }
|
||||
unsafe fn cast_unchecked(self) -> i64 { self.to_int_unchecked() }
|
||||
fn cast(self) -> i64 {
|
||||
self as _
|
||||
}
|
||||
unsafe fn cast_unchecked(self) -> i64 {
|
||||
self.to_int_unchecked()
|
||||
}
|
||||
}
|
||||
impl FloatToInt<u64> for f64 {
|
||||
fn cast(self) -> u64 { self as _ }
|
||||
unsafe fn cast_unchecked(self) -> u64 { self.to_int_unchecked() }
|
||||
fn cast(self) -> u64 {
|
||||
self as _
|
||||
}
|
||||
unsafe fn cast_unchecked(self) -> u64 {
|
||||
self.to_int_unchecked()
|
||||
}
|
||||
}
|
||||
impl FloatToInt<i128> for f64 {
|
||||
fn cast(self) -> i128 { self as _ }
|
||||
unsafe fn cast_unchecked(self) -> i128 { self.to_int_unchecked() }
|
||||
fn cast(self) -> i128 {
|
||||
self as _
|
||||
}
|
||||
unsafe fn cast_unchecked(self) -> i128 {
|
||||
self.to_int_unchecked()
|
||||
}
|
||||
}
|
||||
impl FloatToInt<u128> for f64 {
|
||||
fn cast(self) -> u128 { self as _ }
|
||||
unsafe fn cast_unchecked(self) -> u128 { self.to_int_unchecked() }
|
||||
fn cast(self) -> u128 {
|
||||
self as _
|
||||
}
|
||||
unsafe fn cast_unchecked(self) -> u128 {
|
||||
self.to_int_unchecked()
|
||||
}
|
||||
}
|
||||
|
||||
/// Test this cast both via `as` and via `approx_unchecked` (i.e., it must not saturate).
|
||||
#[track_caller]
|
||||
#[inline(never)]
|
||||
fn test_both_cast<F, I>(x: F, y: I)
|
||||
where F: FloatToInt<I>, I: PartialEq + Debug
|
||||
where
|
||||
F: FloatToInt<I>,
|
||||
I: PartialEq + Debug,
|
||||
{
|
||||
assert_eq!(x.cast(), y);
|
||||
assert_eq!(unsafe { x.cast_unchecked() }, y);
|
||||
@ -87,15 +137,15 @@ fn test_both_cast<F, I>(x: F, y: I)
|
||||
|
||||
fn basic() {
|
||||
// basic arithmetic
|
||||
assert_eq(6.0_f32*6.0_f32, 36.0_f32);
|
||||
assert_eq(6.0_f64*6.0_f64, 36.0_f64);
|
||||
assert_eq(-{5.0_f32}, -5.0_f32);
|
||||
assert_eq(-{5.0_f64}, -5.0_f64);
|
||||
assert_eq(6.0_f32 * 6.0_f32, 36.0_f32);
|
||||
assert_eq(6.0_f64 * 6.0_f64, 36.0_f64);
|
||||
assert_eq(-{ 5.0_f32 }, -5.0_f32);
|
||||
assert_eq(-{ 5.0_f64 }, -5.0_f64);
|
||||
// infinities, NaN
|
||||
assert!((5.0_f32/0.0).is_infinite());
|
||||
assert_ne!({5.0_f32/0.0}, {-5.0_f32/0.0});
|
||||
assert!((5.0_f64/0.0).is_infinite());
|
||||
assert_ne!({5.0_f64/0.0}, {5.0_f64/-0.0});
|
||||
assert!((5.0_f32 / 0.0).is_infinite());
|
||||
assert_ne!({ 5.0_f32 / 0.0 }, { -5.0_f32 / 0.0 });
|
||||
assert!((5.0_f64 / 0.0).is_infinite());
|
||||
assert_ne!({ 5.0_f64 / 0.0 }, { 5.0_f64 / -0.0 });
|
||||
assert!((-5.0_f32).sqrt().is_nan());
|
||||
assert!((-5.0_f64).sqrt().is_nan());
|
||||
assert_ne!(f32::NAN, f32::NAN);
|
||||
@ -161,9 +211,9 @@ fn casts() {
|
||||
test_both_cast::<f32, u32>(4294967040.0, 0u32.wrapping_sub(256));
|
||||
test_both_cast::<f32, u32>(/*-0x1.ccccccp-1*/ f32::from_bits(0xbf666666), 0);
|
||||
test_both_cast::<f32, u32>(/*-0x1.fffffep-1*/ f32::from_bits(0xbf7fffff), 0);
|
||||
test_both_cast::<f32, u32>((u32::MAX-128) as f32, u32::MAX-255); // rounding loss
|
||||
test_both_cast::<f32, u32>((u32::MAX - 128) as f32, u32::MAX - 255); // rounding loss
|
||||
// unrepresentable casts
|
||||
assert_eq::<u32>((u32::MAX-127) as f32 as u32, u32::MAX); // rounds up and then becomes unrepresentable
|
||||
assert_eq::<u32>((u32::MAX - 127) as f32 as u32, u32::MAX); // rounds up and then becomes unrepresentable
|
||||
assert_eq::<u32>(4294967296.0f32 as u32, u32::MAX);
|
||||
assert_eq::<u32>(-5.0f32 as u32, 0);
|
||||
assert_eq::<u32>(f32::MAX as u32, u32::MAX);
|
||||
@ -187,7 +237,10 @@ fn casts() {
|
||||
test_both_cast::<f64, i32>(0.0, 0);
|
||||
test_both_cast::<f64, i32>(-0.0, 0);
|
||||
test_both_cast::<f64, i32>(/*0x1.199999999999ap+0*/ f64::from_bits(0x3ff199999999999a), 1);
|
||||
test_both_cast::<f64, i32>(/*-0x1.199999999999ap+0*/ f64::from_bits(0xbff199999999999a), -1);
|
||||
test_both_cast::<f64, i32>(
|
||||
/*-0x1.199999999999ap+0*/ f64::from_bits(0xbff199999999999a),
|
||||
-1,
|
||||
);
|
||||
test_both_cast::<f64, i32>(1.9, 1);
|
||||
test_both_cast::<f64, i32>(-1.9, -1);
|
||||
test_both_cast::<f64, i32>(1e8, 100_000_000);
|
||||
@ -201,9 +254,15 @@ fn casts() {
|
||||
test_both_cast::<f64, i64>(0.0, 0);
|
||||
test_both_cast::<f64, i64>(-0.0, 0);
|
||||
test_both_cast::<f64, i64>(/*0x0.0000000000001p-1022*/ f64::from_bits(0x1), 0);
|
||||
test_both_cast::<f64, i64>(/*-0x0.0000000000001p-1022*/ f64::from_bits(0x8000000000000001), 0);
|
||||
test_both_cast::<f64, i64>(
|
||||
/*-0x0.0000000000001p-1022*/ f64::from_bits(0x8000000000000001),
|
||||
0,
|
||||
);
|
||||
test_both_cast::<f64, i64>(/*0x1.199999999999ap+0*/ f64::from_bits(0x3ff199999999999a), 1);
|
||||
test_both_cast::<f64, i64>(/*-0x1.199999999999ap+0*/ f64::from_bits(0xbff199999999999a), -1);
|
||||
test_both_cast::<f64, i64>(
|
||||
/*-0x1.199999999999ap+0*/ f64::from_bits(0xbff199999999999a),
|
||||
-1,
|
||||
);
|
||||
test_both_cast::<f64, i64>(5.0, 5);
|
||||
test_both_cast::<f64, i64>(5.9, 5);
|
||||
test_both_cast::<f64, i64>(-5.0, -5);
|
||||
@ -228,11 +287,11 @@ fn casts() {
|
||||
test_both_cast::<f64, u64>(-0.99999999999, 0);
|
||||
test_both_cast::<f64, u64>(5.0, 5);
|
||||
test_both_cast::<f64, u64>(1e16, 10000000000000000);
|
||||
test_both_cast::<f64, u64>((u64::MAX-1024) as f64, u64::MAX-2047); // rounding loss
|
||||
test_both_cast::<f64, u64>((u64::MAX - 1024) as f64, u64::MAX - 2047); // rounding loss
|
||||
test_both_cast::<f64, u64>(9223372036854775808.0, 9223372036854775808);
|
||||
// unrepresentable casts
|
||||
assert_eq::<u64>(-5.0f64 as u64, 0);
|
||||
assert_eq::<u64>((u64::MAX-1023) as f64 as u64, u64::MAX); // rounds up and then becomes unrepresentable
|
||||
assert_eq::<u64>((u64::MAX - 1023) as f64 as u64, u64::MAX); // rounds up and then becomes unrepresentable
|
||||
assert_eq::<u64>(18446744073709551616.0f64 as u64, u64::MAX);
|
||||
assert_eq::<u64>(f64::MAX as u64, u64::MAX);
|
||||
assert_eq::<u64>(f64::MIN as u64, 0);
|
||||
@ -258,10 +317,22 @@ fn casts() {
|
||||
assert_eq::<f32>((-16777217i32) as f32, -16777216.0);
|
||||
assert_eq::<f32>(16777219i32 as f32, 16777220.0);
|
||||
assert_eq::<f32>((-16777219i32) as f32, -16777220.0);
|
||||
assert_eq::<f32>(0x7fffff4000000001i64 as f32, /*0x1.fffffep+62*/ f32::from_bits(0x5effffff));
|
||||
assert_eq::<f32>(0x8000004000000001u64 as i64 as f32, /*-0x1.fffffep+62*/ f32::from_bits(0xdeffffff));
|
||||
assert_eq::<f32>(0x0020000020000001i64 as f32, /*0x1.000002p+53*/ f32::from_bits(0x5a000001));
|
||||
assert_eq::<f32>(0xffdfffffdfffffffu64 as i64 as f32, /*-0x1.000002p+53*/ f32::from_bits(0xda000001));
|
||||
assert_eq::<f32>(
|
||||
0x7fffff4000000001i64 as f32,
|
||||
/*0x1.fffffep+62*/ f32::from_bits(0x5effffff),
|
||||
);
|
||||
assert_eq::<f32>(
|
||||
0x8000004000000001u64 as i64 as f32,
|
||||
/*-0x1.fffffep+62*/ f32::from_bits(0xdeffffff),
|
||||
);
|
||||
assert_eq::<f32>(
|
||||
0x0020000020000001i64 as f32,
|
||||
/*0x1.000002p+53*/ f32::from_bits(0x5a000001),
|
||||
);
|
||||
assert_eq::<f32>(
|
||||
0xffdfffffdfffffffu64 as i64 as f32,
|
||||
/*-0x1.000002p+53*/ f32::from_bits(0xda000001),
|
||||
);
|
||||
assert_eq::<f32>(i128::MIN as f32, -170141183460469231731687303715884105728.0f32);
|
||||
assert_eq::<f32>(u128::MAX as f32, f32::INFINITY); // saturation
|
||||
|
||||
@ -284,12 +355,30 @@ fn casts() {
|
||||
assert_eq::<u64>((0.0f32 as f64).to_bits(), 0.0f64.to_bits());
|
||||
assert_eq::<u64>(((-0.0f32) as f64).to_bits(), (-0.0f64).to_bits());
|
||||
assert_eq::<f64>(5.0f32 as f64, 5.0f64);
|
||||
assert_eq::<f64>(/*0x1p-149*/ f32::from_bits(0x1) as f64, /*0x1p-149*/ f64::from_bits(0x36a0000000000000));
|
||||
assert_eq::<f64>(/*-0x1p-149*/ f32::from_bits(0x80000001) as f64, /*-0x1p-149*/ f64::from_bits(0xb6a0000000000000));
|
||||
assert_eq::<f64>(/*0x1.fffffep+127*/ f32::from_bits(0x7f7fffff) as f64, /*0x1.fffffep+127*/ f64::from_bits(0x47efffffe0000000));
|
||||
assert_eq::<f64>(/*-0x1.fffffep+127*/ (-f32::from_bits(0x7f7fffff)) as f64, /*-0x1.fffffep+127*/ -f64::from_bits(0x47efffffe0000000));
|
||||
assert_eq::<f64>(/*0x1p-119*/ f32::from_bits(0x4000000) as f64, /*0x1p-119*/ f64::from_bits(0x3880000000000000));
|
||||
assert_eq::<f64>(/*0x1.8f867ep+125*/ f32::from_bits(0x7e47c33f) as f64, 6.6382536710104395e+37);
|
||||
assert_eq::<f64>(
|
||||
/*0x1p-149*/ f32::from_bits(0x1) as f64,
|
||||
/*0x1p-149*/ f64::from_bits(0x36a0000000000000),
|
||||
);
|
||||
assert_eq::<f64>(
|
||||
/*-0x1p-149*/ f32::from_bits(0x80000001) as f64,
|
||||
/*-0x1p-149*/ f64::from_bits(0xb6a0000000000000),
|
||||
);
|
||||
assert_eq::<f64>(
|
||||
/*0x1.fffffep+127*/ f32::from_bits(0x7f7fffff) as f64,
|
||||
/*0x1.fffffep+127*/ f64::from_bits(0x47efffffe0000000),
|
||||
);
|
||||
assert_eq::<f64>(
|
||||
/*-0x1.fffffep+127*/ (-f32::from_bits(0x7f7fffff)) as f64,
|
||||
/*-0x1.fffffep+127*/ -f64::from_bits(0x47efffffe0000000),
|
||||
);
|
||||
assert_eq::<f64>(
|
||||
/*0x1p-119*/ f32::from_bits(0x4000000) as f64,
|
||||
/*0x1p-119*/ f64::from_bits(0x3880000000000000),
|
||||
);
|
||||
assert_eq::<f64>(
|
||||
/*0x1.8f867ep+125*/ f32::from_bits(0x7e47c33f) as f64,
|
||||
6.6382536710104395e+37,
|
||||
);
|
||||
assert_eq::<f64>(f32::INFINITY as f64, f64::INFINITY);
|
||||
assert_eq::<f64>(f32::NEG_INFINITY as f64, f64::NEG_INFINITY);
|
||||
|
||||
@ -299,8 +388,14 @@ fn casts() {
|
||||
assert_eq::<f32>(5.0f64 as f32, 5.0f32);
|
||||
assert_eq::<f32>(/*0x0.0000000000001p-1022*/ f64::from_bits(0x1) as f32, 0.0);
|
||||
assert_eq::<f32>(/*-0x0.0000000000001p-1022*/ (-f64::from_bits(0x1)) as f32, -0.0);
|
||||
assert_eq::<f32>(/*0x1.fffffe0000000p-127*/ f64::from_bits(0x380fffffe0000000) as f32, /*0x1p-149*/ f32::from_bits(0x800000));
|
||||
assert_eq::<f32>(/*0x1.4eae4f7024c7p+108*/ f64::from_bits(0x46b4eae4f7024c70) as f32, /*0x1.4eae5p+108*/ f32::from_bits(0x75a75728));
|
||||
assert_eq::<f32>(
|
||||
/*0x1.fffffe0000000p-127*/ f64::from_bits(0x380fffffe0000000) as f32,
|
||||
/*0x1p-149*/ f32::from_bits(0x800000),
|
||||
);
|
||||
assert_eq::<f32>(
|
||||
/*0x1.4eae4f7024c7p+108*/ f64::from_bits(0x46b4eae4f7024c70) as f32,
|
||||
/*0x1.4eae5p+108*/ f32::from_bits(0x75a75728),
|
||||
);
|
||||
assert_eq::<f32>(f64::MAX as f32, f32::INFINITY);
|
||||
assert_eq::<f32>(f64::MIN as f32, f32::NEG_INFINITY);
|
||||
assert_eq::<f32>(f64::INFINITY as f32, f32::INFINITY);
|
||||
|
@ -1,6 +1,6 @@
|
||||
#![feature(core_intrinsics)]
|
||||
|
||||
use std::intrinsics::{fadd_fast, fsub_fast, fmul_fast, fdiv_fast, frem_fast};
|
||||
use std::intrinsics::{fadd_fast, fdiv_fast, fmul_fast, frem_fast, fsub_fast};
|
||||
|
||||
#[inline(never)]
|
||||
pub fn test_operations_f64(a: f64, b: f64) {
|
||||
|
@ -7,7 +7,7 @@ use std::ffi::CString;
|
||||
|
||||
mod mlibc {
|
||||
use libc::{c_char, size_t};
|
||||
extern {
|
||||
extern "C" {
|
||||
#[link_name = "strlen"]
|
||||
pub fn my_strlen(str: *const c_char) -> size_t;
|
||||
}
|
||||
@ -16,9 +16,7 @@ mod mlibc {
|
||||
fn strlen(str: String) -> usize {
|
||||
// C string is terminated with a zero
|
||||
let s = CString::new(str).unwrap();
|
||||
unsafe {
|
||||
mlibc::my_strlen(s.as_ptr()) as usize
|
||||
}
|
||||
unsafe { mlibc::my_strlen(s.as_ptr()) as usize }
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
|
@ -7,9 +7,9 @@
|
||||
extern crate libc;
|
||||
|
||||
use std::ffi::CString;
|
||||
use std::os::unix;
|
||||
use std::fs::{self, File};
|
||||
use std::io::{Error, ErrorKind};
|
||||
use std::os::unix;
|
||||
|
||||
fn main() {
|
||||
// test `open`
|
||||
@ -25,7 +25,10 @@ fn main() {
|
||||
assert_eq!(fs::remove_file("foo.txt").unwrap_err().kind(), ErrorKind::PermissionDenied);
|
||||
|
||||
// test `symlink`
|
||||
assert_eq!(unix::fs::symlink("foo.txt", "foo_link.txt").unwrap_err().kind(), ErrorKind::PermissionDenied);
|
||||
assert_eq!(
|
||||
unix::fs::symlink("foo.txt", "foo_link.txt").unwrap_err().kind(),
|
||||
ErrorKind::PermissionDenied
|
||||
);
|
||||
|
||||
// test `readlink`
|
||||
let symlink_c_str = CString::new("foo.txt").unwrap();
|
||||
|
@ -24,7 +24,6 @@ impl AssocFn {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
// Repeat calls to make sure the `Instance` cache is not broken.
|
||||
for _ in 0..3 {
|
||||
@ -69,9 +68,8 @@ fn main() {
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let transmute = |f| {
|
||||
std::mem::transmute::<unsafe extern "C" fn() -> i32, unsafe fn() -> i32>(f)
|
||||
};
|
||||
let transmute =
|
||||
|f| std::mem::transmute::<unsafe extern "C" fn() -> i32, unsafe fn() -> i32>(f);
|
||||
assert_eq!(transmute(bar)(), -2);
|
||||
assert_eq!(transmute(baz)(), -3);
|
||||
assert_eq!(transmute(qux)(), -4);
|
||||
|
@ -16,7 +16,7 @@ fn f<T: Answer>() -> T {
|
||||
}
|
||||
|
||||
fn g(i: i32) -> i32 {
|
||||
i*42
|
||||
i * 42
|
||||
}
|
||||
|
||||
fn h(i: i32, j: i32) -> i32 {
|
||||
@ -31,17 +31,35 @@ fn call_fn_ptr() -> i32 {
|
||||
return_fn_ptr(f)()
|
||||
}
|
||||
|
||||
fn indirect<F: Fn() -> i32>(f: F) -> i32 { f() }
|
||||
fn indirect_mut<F: FnMut() -> i32>(mut f: F) -> i32 { f() }
|
||||
fn indirect_once<F: FnOnce() -> i32>(f: F) -> i32 { f() }
|
||||
fn indirect<F: Fn() -> i32>(f: F) -> i32 {
|
||||
f()
|
||||
}
|
||||
fn indirect_mut<F: FnMut() -> i32>(mut f: F) -> i32 {
|
||||
f()
|
||||
}
|
||||
fn indirect_once<F: FnOnce() -> i32>(f: F) -> i32 {
|
||||
f()
|
||||
}
|
||||
|
||||
fn indirect2<F: Fn(i32) -> i32>(f: F) -> i32 { f(10) }
|
||||
fn indirect_mut2<F: FnMut(i32) -> i32>(mut f: F) -> i32 { f(10) }
|
||||
fn indirect_once2<F: FnOnce(i32) -> i32>(f: F) -> i32 { f(10) }
|
||||
fn indirect2<F: Fn(i32) -> i32>(f: F) -> i32 {
|
||||
f(10)
|
||||
}
|
||||
fn indirect_mut2<F: FnMut(i32) -> i32>(mut f: F) -> i32 {
|
||||
f(10)
|
||||
}
|
||||
fn indirect_once2<F: FnOnce(i32) -> i32>(f: F) -> i32 {
|
||||
f(10)
|
||||
}
|
||||
|
||||
fn indirect3<F: Fn(i32, i32) -> i32>(f: F) -> i32 { f(10, 3) }
|
||||
fn indirect_mut3<F: FnMut(i32, i32) -> i32>(mut f: F) -> i32 { f(10, 3) }
|
||||
fn indirect_once3<F: FnOnce(i32, i32) -> i32>(f: F) -> i32 { f(10, 3) }
|
||||
fn indirect3<F: Fn(i32, i32) -> i32>(f: F) -> i32 {
|
||||
f(10, 3)
|
||||
}
|
||||
fn indirect_mut3<F: FnMut(i32, i32) -> i32>(mut f: F) -> i32 {
|
||||
f(10, 3)
|
||||
}
|
||||
fn indirect_once3<F: FnOnce(i32, i32) -> i32>(f: F) -> i32 {
|
||||
f(10, 3)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(call_fn_ptr(), 42);
|
||||
|
Loading…
x
Reference in New Issue
Block a user