about summary refs log tree commit diff
path: root/tests/ui/unsafe-binders
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2025-01-31 01:24:37 +0000
committerMichael Goulet <michael@errs.io>2025-01-31 17:19:53 +0000
commitfc1a9186dcdad111fd99ddd38bd961a8a205c380 (patch)
treec60452a9af751853a3ccef6e8eefd0dc145685a5 /tests/ui/unsafe-binders
parent7f36543a48e52912ac6664a70c0a5b9d86509eaf (diff)
downloadrust-fc1a9186dcdad111fd99ddd38bd961a8a205c380.tar.gz
rust-fc1a9186dcdad111fd99ddd38bd961a8a205c380.zip
Implement MIR, CTFE, and codegen for unsafe binders
Diffstat (limited to 'tests/ui/unsafe-binders')
-rw-r--r--tests/ui/unsafe-binders/expr.rs4
-rw-r--r--tests/ui/unsafe-binders/expr.stderr16
-rw-r--r--tests/ui/unsafe-binders/mismatch.rs17
-rw-r--r--tests/ui/unsafe-binders/mismatch.stderr47
-rw-r--r--tests/ui/unsafe-binders/moves.rs38
-rw-r--r--tests/ui/unsafe-binders/moves.stderr53
6 files changed, 119 insertions, 56 deletions
diff --git a/tests/ui/unsafe-binders/expr.rs b/tests/ui/unsafe-binders/expr.rs
index 0fe68751f0a..d437d8f8ac0 100644
--- a/tests/ui/unsafe-binders/expr.rs
+++ b/tests/ui/unsafe-binders/expr.rs
@@ -1,3 +1,5 @@
+//@ check-pass
+
 #![feature(unsafe_binders)]
 //~^ WARN the feature `unsafe_binders` is incomplete
 
@@ -7,8 +9,6 @@ fn main() {
     unsafe {
     let x = 1;
         let binder: unsafe<'a> &'a i32 = wrap_binder!(&x);
-        //~^ ERROR unsafe binder casts are not fully implemented
         let rx = *unwrap_binder!(binder);
-        //~^ ERROR unsafe binder casts are not fully implemented
     }
 }
diff --git a/tests/ui/unsafe-binders/expr.stderr b/tests/ui/unsafe-binders/expr.stderr
index 78a288e10a3..07026e18e12 100644
--- a/tests/ui/unsafe-binders/expr.stderr
+++ b/tests/ui/unsafe-binders/expr.stderr
@@ -1,5 +1,5 @@
 warning: the feature `unsafe_binders` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/expr.rs:1:12
+  --> $DIR/expr.rs:3:12
    |
 LL | #![feature(unsafe_binders)]
    |            ^^^^^^^^^^^^^^
@@ -7,17 +7,5 @@ LL | #![feature(unsafe_binders)]
    = note: see issue #130516 <https://github.com/rust-lang/rust/issues/130516> for more information
    = note: `#[warn(incomplete_features)]` on by default
 
-error: unsafe binder casts are not fully implemented
-  --> $DIR/expr.rs:9:55
-   |
-LL |         let binder: unsafe<'a> &'a i32 = wrap_binder!(&x);
-   |                                                       ^^
-
-error: unsafe binder casts are not fully implemented
-  --> $DIR/expr.rs:11:34
-   |
-LL |         let rx = *unwrap_binder!(binder);
-   |                                  ^^^^^^
-
-error: aborting due to 2 previous errors; 1 warning emitted
+warning: 1 warning emitted
 
diff --git a/tests/ui/unsafe-binders/mismatch.rs b/tests/ui/unsafe-binders/mismatch.rs
index 731fe2d1ce9..840d938cbe9 100644
--- a/tests/ui/unsafe-binders/mismatch.rs
+++ b/tests/ui/unsafe-binders/mismatch.rs
@@ -5,38 +5,31 @@ use std::unsafe_binder::{wrap_binder, unwrap_binder};
 
 fn a() {
     let _: unsafe<'a> &'a i32 = wrap_binder!(&());
-    //~^ ERROR unsafe binder casts are not fully implemented
-    //~| ERROR mismatched types
+    //~^ ERROR mismatched types
 }
 
 fn b() {
     let _: i32 = wrap_binder!(&());
-    //~^ ERROR unsafe binder casts are not fully implemented
-    //~| ERROR `wrap_binder!()` can only wrap into unsafe binder
+    //~^ ERROR `wrap_binder!()` can only wrap into unsafe binder
 }
 
 fn c() {
     let y = 1;
     unwrap_binder!(y);
-    //~^ ERROR unsafe binder casts are not fully implemented
-    //~| ERROR expected unsafe binder, found integer as input
+    //~^ ERROR expected unsafe binder, found integer as input
 }
 
 fn d() {
     let unknown = Default::default();
+    //~^ ERROR type annotations needed
     unwrap_binder!(unknown);
-    //~^ ERROR unsafe binder casts are not fully implemented
-    // FIXME(unsafe_binders): This should report ambiguity once we've removed
-    // the error above which taints the infcx.
 }
 
 fn e() {
     let x = wrap_binder!(&42);
-    //~^ ERROR unsafe binder casts are not fully implemented
+    //~^ ERROR type annotations needed
     // Currently, type inference doesn't flow backwards for unsafe binders.
     // It could, perhaps, but that may cause even more surprising corners.
-    // FIXME(unsafe_binders): This should report ambiguity once we've removed
-    // the error above which taints the infcx.
     let _: unsafe<'a> &'a i32 = x;
 }
 
diff --git a/tests/ui/unsafe-binders/mismatch.stderr b/tests/ui/unsafe-binders/mismatch.stderr
index a720e5dbdc1..f64db92eb65 100644
--- a/tests/ui/unsafe-binders/mismatch.stderr
+++ b/tests/ui/unsafe-binders/mismatch.stderr
@@ -7,12 +7,6 @@ LL | #![feature(unsafe_binders)]
    = note: see issue #130516 <https://github.com/rust-lang/rust/issues/130516> for more information
    = note: `#[warn(incomplete_features)]` on by default
 
-error: unsafe binder casts are not fully implemented
-  --> $DIR/mismatch.rs:7:46
-   |
-LL |     let _: unsafe<'a> &'a i32 = wrap_binder!(&());
-   |                                              ^^^
-
 error[E0308]: mismatched types
   --> $DIR/mismatch.rs:7:46
    |
@@ -22,14 +16,8 @@ LL |     let _: unsafe<'a> &'a i32 = wrap_binder!(&());
    = note: expected reference `&i32`
               found reference `&()`
 
-error: unsafe binder casts are not fully implemented
-  --> $DIR/mismatch.rs:13:31
-   |
-LL |     let _: i32 = wrap_binder!(&());
-   |                               ^^^
-
 error: `wrap_binder!()` can only wrap into unsafe binder, not `i32`
-  --> $DIR/mismatch.rs:13:18
+  --> $DIR/mismatch.rs:12:18
    |
 LL |     let _: i32 = wrap_binder!(&());
    |                  ^^^^^^^^^^^^^^^^^
@@ -37,32 +25,35 @@ LL |     let _: i32 = wrap_binder!(&());
    = note: unsafe binders are the only valid output of wrap
    = note: this error originates in the macro `wrap_binder` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: unsafe binder casts are not fully implemented
-  --> $DIR/mismatch.rs:20:20
-   |
-LL |     unwrap_binder!(y);
-   |                    ^
-
 error: expected unsafe binder, found integer as input of `unwrap_binder!()`
-  --> $DIR/mismatch.rs:20:20
+  --> $DIR/mismatch.rs:18:20
    |
 LL |     unwrap_binder!(y);
    |                    ^
    |
    = note: only an unsafe binder type can be unwrapped
 
-error: unsafe binder casts are not fully implemented
-  --> $DIR/mismatch.rs:27:20
+error[E0282]: type annotations needed
+  --> $DIR/mismatch.rs:23:9
    |
+LL |     let unknown = Default::default();
+   |         ^^^^^^^
+LL |
 LL |     unwrap_binder!(unknown);
-   |                    ^^^^^^^
+   |                    ------- type must be known at this point
+   |
+help: consider giving `unknown` an explicit type
+   |
+LL |     let unknown: /* Type */ = Default::default();
+   |                ++++++++++++
 
-error: unsafe binder casts are not fully implemented
-  --> $DIR/mismatch.rs:34:26
+error[E0282]: type annotations needed
+  --> $DIR/mismatch.rs:29:26
    |
 LL |     let x = wrap_binder!(&42);
-   |                          ^^^
+   |                          ^^^ cannot infer type
 
-error: aborting due to 8 previous errors; 1 warning emitted
+error: aborting due to 5 previous errors; 1 warning emitted
 
-For more information about this error, try `rustc --explain E0308`.
+Some errors have detailed explanations: E0282, E0308.
+For more information about an error, try `rustc --explain E0282`.
diff --git a/tests/ui/unsafe-binders/moves.rs b/tests/ui/unsafe-binders/moves.rs
new file mode 100644
index 00000000000..1f61d2bf144
--- /dev/null
+++ b/tests/ui/unsafe-binders/moves.rs
@@ -0,0 +1,38 @@
+#![feature(unsafe_binders)]
+//~^ WARN the feature `unsafe_binders` is incomplete
+
+use std::unsafe_binder::{wrap_binder, unwrap_binder};
+use std::mem::drop;
+
+struct NotCopy;
+
+fn use_after_wrap() {
+    unsafe {
+        let base = NotCopy;
+        let binder: unsafe<> NotCopy = wrap_binder!(base);
+        drop(base);
+        //~^ ERROR use of moved value: `base`
+    }
+}
+
+fn move_out_of_wrap() {
+    unsafe {
+        let binder: unsafe<> NotCopy = wrap_binder!(NotCopy);
+        drop(unwrap_binder!(binder));
+        drop(unwrap_binder!(binder));
+        //~^ ERROR use of moved value: `binder`
+    }
+}
+
+fn not_conflicting() {
+    unsafe {
+        let binder: unsafe<> (NotCopy, NotCopy) = wrap_binder!((NotCopy, NotCopy));
+        drop(unwrap_binder!(binder).0);
+        drop(unwrap_binder!(binder).1);
+        // ^ NOT a problem.
+        drop(unwrap_binder!(binder).0);
+        //~^ ERROR use of moved value: `binder.0`
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/unsafe-binders/moves.stderr b/tests/ui/unsafe-binders/moves.stderr
new file mode 100644
index 00000000000..d90823bf7e2
--- /dev/null
+++ b/tests/ui/unsafe-binders/moves.stderr
@@ -0,0 +1,53 @@
+warning: the feature `unsafe_binders` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/moves.rs:1:12
+   |
+LL | #![feature(unsafe_binders)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: see issue #130516 <https://github.com/rust-lang/rust/issues/130516> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0382]: use of moved value: `base`
+  --> $DIR/moves.rs:13:14
+   |
+LL |         let base = NotCopy;
+   |             ---- move occurs because `base` has type `NotCopy`, which does not implement the `Copy` trait
+LL |         let binder: unsafe<> NotCopy = wrap_binder!(base);
+   |                                                     ---- value moved here
+LL |         drop(base);
+   |              ^^^^ value used here after move
+   |
+note: if `NotCopy` implemented `Clone`, you could clone the value
+  --> $DIR/moves.rs:7:1
+   |
+LL | struct NotCopy;
+   | ^^^^^^^^^^^^^^ consider implementing `Clone` for this type
+...
+LL |         let binder: unsafe<> NotCopy = wrap_binder!(base);
+   |                                                     ---- you could clone this value
+
+error[E0382]: use of moved value: `binder`
+  --> $DIR/moves.rs:22:14
+   |
+LL |         drop(unwrap_binder!(binder));
+   |              ---------------------- value moved here
+LL |         drop(unwrap_binder!(binder));
+   |              ^^^^^^^^^^^^^^^^^^^^^^ value used here after move
+   |
+   = note: move occurs because `binder` has type `NotCopy`, which does not implement the `Copy` trait
+   = note: this error originates in the macro `unwrap_binder` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0382]: use of moved value: `binder.0`
+  --> $DIR/moves.rs:33:14
+   |
+LL |         drop(unwrap_binder!(binder).0);
+   |              ------------------------ value moved here
+...
+LL |         drop(unwrap_binder!(binder).0);
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^ value used here after move
+   |
+   = note: move occurs because `binder.0` has type `NotCopy`, which does not implement the `Copy` trait
+
+error: aborting due to 3 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0382`.