diff --git a/tests/run-pass/box_box_trait.rs b/tests/run-pass/box_box_trait.rs deleted file mode 100644 index e7620cd42f70..000000000000 --- a/tests/run-pass/box_box_trait.rs +++ /dev/null @@ -1,31 +0,0 @@ -#![feature(box_syntax)] - -struct DroppableStruct; - -static mut DROPPED: bool = false; - -impl Drop for DroppableStruct { - fn drop(&mut self) { - unsafe { DROPPED = true; } - } -} - -trait MyTrait { fn dummy(&self) { } } -impl MyTrait for Box {} - -#[allow(dead_code)] -struct Whatever { w: Box } - -impl Whatever { - fn new(w: Box) -> Whatever { - Whatever { w: w } - } -} - -fn main() { - { - let f: Box<_> = box DroppableStruct; - let _a = Whatever::new(box f as Box); - } - assert!(unsafe { DROPPED }); -} diff --git a/tests/run-pass/closures.rs b/tests/run-pass/closures.rs index eb8d8f0d5b98..5e2e0f87bdaf 100644 --- a/tests/run-pass/closures.rs +++ b/tests/run-pass/closures.rs @@ -40,10 +40,21 @@ fn once i64>(f: F) -> i64 { f(2, 3) } } } -fn boxed(f: Box i32>) -> i32 { +fn boxed_fn_once(f: Box i32>) -> i32 { f() } +fn box_dyn() { + let x: Box i32> = Box::new(|x| x * 2); + assert_eq!(x(21), 42); + let mut i = 5; + { + let mut x: Box = Box::new(|| i *= 2); + x(); x(); + } + assert_eq!(i, 20); +} + fn fn_item_as_closure_trait_object() { fn foo() {} let f: &dyn Fn() = &foo; @@ -96,8 +107,9 @@ fn main() { 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(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(); fn_item_with_args_as_closure_trait_object(); fn_item_with_multiple_args_as_closure_trait_object(); diff --git a/tests/run-pass/call_drop_on_array_elements.rs b/tests/run-pass/drop_on_array_elements.rs similarity index 100% rename from tests/run-pass/call_drop_on_array_elements.rs rename to tests/run-pass/drop_on_array_elements.rs diff --git a/tests/run-pass/call_drop_on_fat_ptr_array_elements.rs b/tests/run-pass/drop_on_fat_ptr_array_elements.rs similarity index 100% rename from tests/run-pass/call_drop_on_fat_ptr_array_elements.rs rename to tests/run-pass/drop_on_fat_ptr_array_elements.rs diff --git a/tests/run-pass/call_drop_on_zst_array_elements.rs b/tests/run-pass/drop_on_zst_array_elements.rs similarity index 100% rename from tests/run-pass/call_drop_on_zst_array_elements.rs rename to tests/run-pass/drop_on_zst_array_elements.rs diff --git a/tests/run-pass/call_drop_through_owned_slice.rs b/tests/run-pass/drop_through_owned_slice.rs similarity index 100% rename from tests/run-pass/call_drop_through_owned_slice.rs rename to tests/run-pass/drop_through_owned_slice.rs diff --git a/tests/run-pass/call_drop_through_trait_object.rs b/tests/run-pass/drop_through_trait_object.rs similarity index 100% rename from tests/run-pass/call_drop_through_trait_object.rs rename to tests/run-pass/drop_through_trait_object.rs diff --git a/tests/run-pass/call_drop_through_trait_object_rc.rs b/tests/run-pass/drop_through_trait_object_rc.rs similarity index 100% rename from tests/run-pass/call_drop_through_trait_object_rc.rs rename to tests/run-pass/drop_through_trait_object_rc.rs diff --git a/tests/run-pass/dyn-traits.rs b/tests/run-pass/dyn-traits.rs new file mode 100644 index 000000000000..33d1f4fc1cf0 --- /dev/null +++ b/tests/run-pass/dyn-traits.rs @@ -0,0 +1,145 @@ +#![feature(unsized_locals)] + +fn ref_box_dyn() { + struct Struct(i32); + + trait Trait { + fn method(&self); + + fn box_method(self: Box); + } + + impl Trait for Struct { + fn method(&self) { + assert_eq!(self.0, 42); + } + + fn box_method(self: Box) { + assert_eq!(self.0, 7); + } + } + + struct Foo(T); + + let y: &dyn Trait = &Struct(42); + y.method(); + + let x: Foo = Foo(Struct(42)); + let y: &Foo = &x; + y.0.method(); + + let y: Box = Box::new(Struct(42)); + y.method(); + + let y = &y; + y.method(); + + let y: Box = Box::new(Struct(7)); + y.box_method(); +} + + +fn box_box_trait() { + struct DroppableStruct; + + static mut DROPPED: bool = false; + + impl Drop for DroppableStruct { + fn drop(&mut self) { + unsafe { DROPPED = true; } + } + } + + trait MyTrait { fn dummy(&self) { } } + impl MyTrait for Box {} + + struct Whatever { w: Box } + + impl Whatever { + fn new(w: Box) -> Whatever { + Whatever { w: w } + } + } + + { + let f = Box::new(DroppableStruct); + let a = Whatever::new(Box::new(f) as Box); + a.w.dummy(); + } + assert!(unsafe { DROPPED }); +} + +fn unsized_dyn() { + pub trait Foo { + fn foo(self) -> String; + } + + struct A; + + impl Foo for A { + fn foo(self) -> String { + format!("hello") + } + } + + let x = *(Box::new(A) as Box); + assert_eq!(x.foo(), format!("hello")); + + // I'm not sure whether we want this to work + let x = Box::new(A) as Box; + assert_eq!(x.foo(), format!("hello")); +} + +fn unsized_dyn_autoderef() { + pub trait Foo { + fn foo(self) -> String; + } + + impl Foo for [char] { + fn foo(self) -> String { + self.iter().collect() + } + } + + impl Foo for str { + fn foo(self) -> String { + self.to_owned() + } + } + + impl Foo for dyn FnMut() -> String { + fn foo(mut self) -> String { + self() + } + } + + let x = *(Box::new(['h', 'e', 'l', 'l', 'o']) as Box<[char]>); + assert_eq!(&x.foo() as &str, "hello"); + + let x = Box::new(['h', 'e', 'l', 'l', 'o']) as Box<[char]>; + assert_eq!(&x.foo() as &str, "hello"); + + let x = "hello".to_owned().into_boxed_str(); + assert_eq!(&x.foo() as &str, "hello"); + + let x = *("hello".to_owned().into_boxed_str()); + assert_eq!(&x.foo() as &str, "hello"); + + let x = "hello".to_owned().into_boxed_str(); + assert_eq!(&x.foo() as &str, "hello"); + + let x = *(Box::new(|| "hello".to_owned()) as Box String>); + assert_eq!(&x.foo() as &str, "hello"); + + let x = Box::new(|| "hello".to_owned()) as Box String>; + assert_eq!(&x.foo() as &str, "hello"); +} + +fn main() { + ref_box_dyn(); + box_box_trait(); + + // "exotic" receivers + unsized_dyn(); + unsized_dyn_autoderef(); +} diff --git a/tests/run-pass/traits.rs b/tests/run-pass/traits.rs deleted file mode 100644 index 03d2db400f01..000000000000 --- a/tests/run-pass/traits.rs +++ /dev/null @@ -1,30 +0,0 @@ -struct Struct(i32); - -trait Trait { - fn method(&self); -} - -impl Trait for Struct { - fn method(&self) { - assert_eq!(self.0, 42); - } -} - -struct Foo(T); - -fn main() { - let y: &dyn Trait = &Struct(42); - y.method(); - let x: Foo = Foo(Struct(42)); - let y: &Foo = &x; - y.0.method(); - - let x: Box i32> = Box::new(|x| x * 2); - assert_eq!(x(21), 42); - let mut i = 5; - { - let mut x: Box = Box::new(|| i *= 2); - x(); x(); - } - assert_eq!(i, 20); -}