Skip to content

Commit b1332d8

Browse files
committed
Auto merge of #1039 - RalfJung:dyn-tests, r=RalfJung
More tests for dyn trait (in particular, unsized receivers) So far we only tested them indirectly through `dyn FnOnce`; this also adds some self-contained tests from the rustc test suite.
2 parents 0740a20 + b7a8ce1 commit b1332d8

10 files changed

+150
-63
lines changed

tests/run-pass/box_box_trait.rs

Lines changed: 0 additions & 31 deletions
This file was deleted.

tests/run-pass/closures.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,21 @@ fn fn_once_closure_with_multiple_args() -> i64 {
4040
}
4141
}
4242

43-
fn boxed(f: Box<dyn FnOnce() -> i32>) -> i32 {
43+
fn boxed_fn_once(f: Box<dyn FnOnce() -> i32>) -> i32 {
4444
f()
4545
}
4646

47+
fn box_dyn() {
48+
let x: Box<dyn Fn(i32) -> i32> = Box::new(|x| x * 2);
49+
assert_eq!(x(21), 42);
50+
let mut i = 5;
51+
{
52+
let mut x: Box<dyn FnMut()> = Box::new(|| i *= 2);
53+
x(); x();
54+
}
55+
assert_eq!(i, 20);
56+
}
57+
4758
fn fn_item_as_closure_trait_object() {
4859
fn foo() {}
4960
let f: &dyn Fn() = &foo;
@@ -96,8 +107,9 @@ fn main() {
96107
assert_eq!(crazy_closure(), (84, 10, 10));
97108
assert_eq!(closure_arg_adjustment_problem(), 3);
98109
assert_eq!(fn_once_closure_with_multiple_args(), 6);
99-
assert_eq!(boxed(Box::new({let x = 13; move || x})), 13);
110+
assert_eq!(boxed_fn_once(Box::new({let x = 13; move || x})), 13);
100111

112+
box_dyn();
101113
fn_item_as_closure_trait_object();
102114
fn_item_with_args_as_closure_trait_object();
103115
fn_item_with_multiple_args_as_closure_trait_object();

tests/run-pass/dyn-traits.rs

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
#![feature(unsized_locals)]
2+
3+
fn ref_box_dyn() {
4+
struct Struct(i32);
5+
6+
trait Trait {
7+
fn method(&self);
8+
}
9+
10+
impl Trait for Struct {
11+
fn method(&self) {
12+
assert_eq!(self.0, 42);
13+
}
14+
}
15+
16+
struct Foo<T: ?Sized>(T);
17+
18+
let y: &dyn Trait = &Struct(42);
19+
y.method();
20+
21+
let x: Foo<Struct> = Foo(Struct(42));
22+
let y: &Foo<dyn Trait> = &x;
23+
y.0.method();
24+
25+
let y: Box<dyn Trait> = Box::new(Struct(42));
26+
y.method();
27+
28+
let y = &y;
29+
y.method();
30+
}
31+
32+
33+
fn box_box_trait() {
34+
struct DroppableStruct;
35+
36+
static mut DROPPED: bool = false;
37+
38+
impl Drop for DroppableStruct {
39+
fn drop(&mut self) {
40+
unsafe { DROPPED = true; }
41+
}
42+
}
43+
44+
trait MyTrait { fn dummy(&self) { } }
45+
impl MyTrait for Box<DroppableStruct> {}
46+
47+
struct Whatever { w: Box<dyn MyTrait+'static> }
48+
49+
impl Whatever {
50+
fn new(w: Box<dyn MyTrait+'static>) -> Whatever {
51+
Whatever { w: w }
52+
}
53+
}
54+
55+
{
56+
let f = Box::new(DroppableStruct);
57+
let a = Whatever::new(Box::new(f) as Box<dyn MyTrait>);
58+
a.w.dummy();
59+
}
60+
assert!(unsafe { DROPPED });
61+
}
62+
63+
fn unsized_dyn() {
64+
pub trait Foo {
65+
fn foo(self) -> String;
66+
}
67+
68+
struct A;
69+
70+
impl Foo for A {
71+
fn foo(self) -> String {
72+
format!("hello")
73+
}
74+
}
75+
76+
let x = *(Box::new(A) as Box<dyn Foo>);
77+
assert_eq!(x.foo(), format!("hello"));
78+
79+
// I'm not sure whether we want this to work
80+
let x = Box::new(A) as Box<dyn Foo>;
81+
assert_eq!(x.foo(), format!("hello"));
82+
}
83+
84+
fn unsized_dyn_autoderef() {
85+
pub trait Foo {
86+
fn foo(self) -> String;
87+
}
88+
89+
impl Foo for [char] {
90+
fn foo(self) -> String {
91+
self.iter().collect()
92+
}
93+
}
94+
95+
impl Foo for str {
96+
fn foo(self) -> String {
97+
self.to_owned()
98+
}
99+
}
100+
101+
impl Foo for dyn FnMut() -> String {
102+
fn foo(mut self) -> String {
103+
self()
104+
}
105+
}
106+
107+
let x = *(Box::new(['h', 'e', 'l', 'l', 'o']) as Box<[char]>);
108+
assert_eq!(&x.foo() as &str, "hello");
109+
110+
let x = Box::new(['h', 'e', 'l', 'l', 'o']) as Box<[char]>;
111+
assert_eq!(&x.foo() as &str, "hello");
112+
113+
let x = "hello".to_owned().into_boxed_str();
114+
assert_eq!(&x.foo() as &str, "hello");
115+
116+
let x = *("hello".to_owned().into_boxed_str());
117+
assert_eq!(&x.foo() as &str, "hello");
118+
119+
let x = "hello".to_owned().into_boxed_str();
120+
assert_eq!(&x.foo() as &str, "hello");
121+
122+
let x = *(Box::new(|| "hello".to_owned()) as Box<dyn FnMut() -> String>);
123+
assert_eq!(&x.foo() as &str, "hello");
124+
125+
let x = Box::new(|| "hello".to_owned()) as Box<dyn FnMut() -> String>;
126+
assert_eq!(&x.foo() as &str, "hello");
127+
}
128+
129+
fn main() {
130+
ref_box_dyn();
131+
box_box_trait();
132+
133+
// "exotic" receivers
134+
unsized_dyn();
135+
unsized_dyn_autoderef();
136+
}

tests/run-pass/traits.rs

Lines changed: 0 additions & 30 deletions
This file was deleted.

0 commit comments

Comments
 (0)