Add more tests · rust-lang/rust@c4bce0b (original) (raw)

File tree

5 files changed

lines changed

5 files changed

lines changed

Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@ fn main() {
9 9 struct_();
10 10 replace_vptr();
11 11 vtable_nop_cast();
12 +drop_principal();
12 13 }
13 14
14 15 fn vtable_nop_cast() {
@@ -430,3 +431,53 @@ fn replace_vptr() {
430 431 let s = S(42);
431 432 invoke_outer(&s);
432 433 }
434 +
435 +fn drop_principal() {
436 +use std::{alloc::Layout, any::Any};
437 +
438 +const fn yeet_principal(x: Box<dyn Any + Send>) -> Box<dyn Send> {
439 + x
440 +}
441 +
442 +trait Bar: Send + Sync {}
443 +
444 +impl<T: Send + Sync> Bar for T {}
445 +
446 +const fn yeet_principal_2(x: Box<dyn Bar>) -> Box<dyn Send> {
447 + x
448 +}
449 +
450 +struct CallMe<F: FnOnce()>(Option<F>);
451 +
452 +impl<F: FnOnce()> CallMe<F> {
453 +fn new(f: F) -> Self {
454 +CallMe(Some(f))
455 +}
456 +}
457 +
458 +impl<F: FnOnce()> Drop for CallMe<F> {
459 +fn drop(&mut self) {
460 +(self.0.take().unwrap())();
461 +}
462 +}
463 +
464 +fn goodbye() {
465 +println!("goodbye");
466 +}
467 +
468 +let x = Box::new(CallMe::new(goodbye)) as Box<dyn Any + Send>;
469 +let x_layout = Layout::for_value(&*x);
470 +let y = yeet_principal(x);
471 +let y_layout = Layout::for_value(&*y);
472 +assert_eq!(x_layout, y_layout);
473 +println!("before");
474 +drop(y);
475 +
476 +let x = Box::new(CallMe::new(goodbye)) as Box<dyn Bar>;
477 +let x_layout = Layout::for_value(&*x);
478 +let y = yeet_principal_2(x);
479 +let y_layout = Layout::for_value(&*y);
480 +assert_eq!(x_layout, y_layout);
481 +println!("before");
482 +drop(y);
483 +}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
1 +before
2 +goodbye
3 +before
4 +goodbye
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
1 1 //@ run-pass
2 2 //@ check-run-results
3 3
4 -use std::any::Any;
4 +use std::{alloc::Layout, any::Any};
5 5
6 6 const fn yeet_principal(x: Box<dyn Any + Send>) -> Box<dyn Send> {
7 7 x
@@ -35,12 +35,18 @@ fn goodbye() {
35 35
36 36 fn main() {
37 37 let x = Box::new(CallMe::new(goodbye)) as Box<dyn Any + Send>;
38 +let x_layout = Layout::for_value(&*x);
38 39 let y = yeet_principal(x);
40 +let y_layout = Layout::for_value(&*y);
41 +assert_eq!(x_layout, y_layout);
39 42 println!("before");
40 43 drop(y);
41 44
42 45 let x = Box::new(CallMe::new(goodbye)) as Box<dyn Bar>;
46 +let x_layout = Layout::for_value(&*x);
43 47 let y = yeet_principal_2(x);
48 +let y_layout = Layout::for_value(&*y);
49 +assert_eq!(x_layout, y_layout);
44 50 println!("before");
45 51 drop(y);
46 52 }
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
1 +#![feature(dyn_star)]
2 +#![allow(incomplete_features)]
3 +
4 +trait Trait {}
5 +impl Trait for usize {}
6 +
7 +fn main() {
8 +// We allow &dyn Trait + Send -> &dyn Send (i.e. dropping principal),
9 +// but we don't (currently?) allow the same for dyn*
10 +let x: dyn* Trait + Send = 1usize;
11 + x as dyn* Send; //~ error: `dyn* Trait + Send` needs to have the same ABI as a pointer
12 +}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
1 +error[E0277]: `dyn* Trait + Send` needs to have the same ABI as a pointer
2 + --> $DIR/dyn-star-drop-principal.rs:11:5
3 + |
4 +LL | x as dyn* Send;
5 + | ^ `dyn* Trait + Send` needs to be a pointer-like type
6 + |
7 + = help: the trait `PointerLike` is not implemented for `dyn* Trait + Send`
8 +
9 +error: aborting due to 1 previous error
10 +
11 +For more information about this error, try `rustc --explain E0277`.