about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJules Bertholet <julesbertholet@quoi.xyz>2024-07-10 13:00:36 -0400
committerMaybe Lapkin <waffle.lapkin@gmail.com>2024-10-18 00:33:50 +0200
commitc4bce0b8b13f2ae39bfd01e55bf98a556b2d703f (patch)
treef1787fe661599b482653e8baf086b2a69478d2cd
parente3800a1a04f338ce69bd403f230a019cebc54ece (diff)
downloadrust-c4bce0b8b13f2ae39bfd01e55bf98a556b2d703f.tar.gz
rust-c4bce0b8b13f2ae39bfd01e55bf98a556b2d703f.zip
Add more tests
-rw-r--r--src/tools/miri/tests/pass/dyn-upcast.rs51
-rw-r--r--src/tools/miri/tests/pass/dyn-upcast.stdout4
-rw-r--r--tests/ui/traits/dyn-drop-principal.rs8
-rw-r--r--tests/ui/traits/dyn-star-drop-principal.rs12
-rw-r--r--tests/ui/traits/dyn-star-drop-principal.stderr11
5 files changed, 85 insertions, 1 deletions
diff --git a/src/tools/miri/tests/pass/dyn-upcast.rs b/src/tools/miri/tests/pass/dyn-upcast.rs
index ff995f38196..306e9ab9c67 100644
--- a/src/tools/miri/tests/pass/dyn-upcast.rs
+++ b/src/tools/miri/tests/pass/dyn-upcast.rs
@@ -9,6 +9,7 @@ fn main() {
     struct_();
     replace_vptr();
     vtable_nop_cast();
+    drop_principal();
 }
 
 fn vtable_nop_cast() {
@@ -430,3 +431,53 @@ fn replace_vptr() {
     let s = S(42);
     invoke_outer(&s);
 }
+
+fn drop_principal() {
+    use std::{alloc::Layout, any::Any};
+
+    const fn yeet_principal(x: Box<dyn Any + Send>) -> Box<dyn Send> {
+        x
+    }
+
+    trait Bar: Send + Sync {}
+
+    impl<T: Send + Sync> Bar for T {}
+
+    const fn yeet_principal_2(x: Box<dyn Bar>) -> Box<dyn Send> {
+        x
+    }
+
+    struct CallMe<F: FnOnce()>(Option<F>);
+
+    impl<F: FnOnce()> CallMe<F> {
+        fn new(f: F) -> Self {
+            CallMe(Some(f))
+        }
+    }
+
+    impl<F: FnOnce()> Drop for CallMe<F> {
+        fn drop(&mut self) {
+            (self.0.take().unwrap())();
+        }
+    }
+
+    fn goodbye() {
+        println!("goodbye");
+    }
+
+    let x = Box::new(CallMe::new(goodbye)) as Box<dyn Any + Send>;
+    let x_layout = Layout::for_value(&*x);
+    let y = yeet_principal(x);
+    let y_layout = Layout::for_value(&*y);
+    assert_eq!(x_layout, y_layout);
+    println!("before");
+    drop(y);
+
+    let x = Box::new(CallMe::new(goodbye)) as Box<dyn Bar>;
+    let x_layout = Layout::for_value(&*x);
+    let y = yeet_principal_2(x);
+    let y_layout = Layout::for_value(&*y);
+    assert_eq!(x_layout, y_layout);
+    println!("before");
+    drop(y);
+}
diff --git a/src/tools/miri/tests/pass/dyn-upcast.stdout b/src/tools/miri/tests/pass/dyn-upcast.stdout
new file mode 100644
index 00000000000..edd99a114a1
--- /dev/null
+++ b/src/tools/miri/tests/pass/dyn-upcast.stdout
@@ -0,0 +1,4 @@
+before
+goodbye
+before
+goodbye
diff --git a/tests/ui/traits/dyn-drop-principal.rs b/tests/ui/traits/dyn-drop-principal.rs
index eeff0550fcb..c233127e43d 100644
--- a/tests/ui/traits/dyn-drop-principal.rs
+++ b/tests/ui/traits/dyn-drop-principal.rs
@@ -1,7 +1,7 @@
 //@ run-pass
 //@ check-run-results
 
-use std::any::Any;
+use std::{alloc::Layout, any::Any};
 
 const fn yeet_principal(x: Box<dyn Any + Send>) -> Box<dyn Send> {
     x
@@ -35,12 +35,18 @@ fn goodbye() {
 
 fn main() {
     let x = Box::new(CallMe::new(goodbye)) as Box<dyn Any + Send>;
+    let x_layout = Layout::for_value(&*x);
     let y = yeet_principal(x);
+    let y_layout = Layout::for_value(&*y);
+    assert_eq!(x_layout, y_layout);
     println!("before");
     drop(y);
 
     let x = Box::new(CallMe::new(goodbye)) as Box<dyn Bar>;
+    let x_layout = Layout::for_value(&*x);
     let y = yeet_principal_2(x);
+    let y_layout = Layout::for_value(&*y);
+    assert_eq!(x_layout, y_layout);
     println!("before");
     drop(y);
 }
diff --git a/tests/ui/traits/dyn-star-drop-principal.rs b/tests/ui/traits/dyn-star-drop-principal.rs
new file mode 100644
index 00000000000..1ad99070339
--- /dev/null
+++ b/tests/ui/traits/dyn-star-drop-principal.rs
@@ -0,0 +1,12 @@
+#![feature(dyn_star)]
+#![allow(incomplete_features)]
+
+trait Trait {}
+impl Trait for usize {}
+
+fn main() {
+    // We allow &dyn Trait + Send -> &dyn Send (i.e. dropping principal),
+    // but we don't (currently?) allow the same for dyn*
+    let x: dyn* Trait + Send = 1usize;
+    x as dyn* Send; //~ error: `dyn* Trait + Send` needs to have the same ABI as a pointer
+}
diff --git a/tests/ui/traits/dyn-star-drop-principal.stderr b/tests/ui/traits/dyn-star-drop-principal.stderr
new file mode 100644
index 00000000000..721ae7e191e
--- /dev/null
+++ b/tests/ui/traits/dyn-star-drop-principal.stderr
@@ -0,0 +1,11 @@
+error[E0277]: `dyn* Trait + Send` needs to have the same ABI as a pointer
+  --> $DIR/dyn-star-drop-principal.rs:11:5
+   |
+LL |     x as dyn* Send;
+   |     ^ `dyn* Trait + Send` needs to be a pointer-like type
+   |
+   = help: the trait `PointerLike` is not implemented for `dyn* Trait + Send`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.