diff options
| author | Michael Goulet <michael@errs.io> | 2025-01-31 02:04:10 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2025-01-31 17:40:28 +0000 |
| commit | b63341e892447f73888f858052bca57495ee8d67 (patch) | |
| tree | 33f254d4c70018d8fd6d232f904c2c682e10a78a | |
| parent | fc1a9186dcdad111fd99ddd38bd961a8a205c380 (diff) | |
| download | rust-b63341e892447f73888f858052bca57495ee8d67.tar.gz rust-b63341e892447f73888f858052bca57495ee8d67.zip | |
Enforce unsafe binders must be Copy (for now)
| -rw-r--r-- | compiler/rustc_codegen_cranelift/src/base.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/wf.rs | 21 | ||||
| -rw-r--r-- | src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs | 1 | ||||
| -rw-r--r-- | tests/ui/unsafe-binders/moves.rs | 15 | ||||
| -rw-r--r-- | tests/ui/unsafe-binders/moves.stderr | 98 |
5 files changed, 98 insertions, 41 deletions
diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index ea37e19099a..97d8baa6157 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -915,6 +915,10 @@ fn codegen_stmt<'tcx>( } crate::discriminant::codegen_set_discriminant(fx, lval, variant_index); } + Rvalue::WrapUnsafeBinder(ref operand, _to_ty) => { + let operand = codegen_operand(fx, operand); + lval.write_cvalue_transmute(fx, operand); + } } } StatementKind::StorageLive(_) diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 20b675bcb76..0afe483f721 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -828,8 +828,25 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> { // Let the visitor iterate into the argument/return // types appearing in the fn signature. } - ty::UnsafeBinder(_) => { - // FIXME(unsafe_binders): We should also recurse into the binder here. + ty::UnsafeBinder(ty) => { + // FIXME(unsafe_binders): For now, we have no way to express + // that a type must be `ManuallyDrop` OR `Copy` (or a pointer). + if !ty.has_escaping_bound_vars() { + self.out.push(traits::Obligation::new( + self.tcx(), + self.cause(ObligationCauseCode::Misc), + self.param_env, + ty.map_bound(|ty| { + ty::TraitRef::new( + self.tcx(), + self.tcx().require_lang_item(LangItem::Copy, Some(self.span)), + [ty], + ) + }), + )); + } + + // We recurse into the binder below. } ty::Dynamic(data, r, _) => { diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index 916017b09dd..0aaef91e48a 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -116,6 +116,7 @@ fn check_rvalue<'tcx>( Rvalue::CopyForDeref(place) => check_place(tcx, *place, span, body, msrv), Rvalue::Repeat(operand, _) | Rvalue::Use(operand) + | Rvalue::WrapUnsafeBinder(operand, _) | Rvalue::Cast( CastKind::PointerWithExposedProvenance | CastKind::IntToInt diff --git a/tests/ui/unsafe-binders/moves.rs b/tests/ui/unsafe-binders/moves.rs index 1f61d2bf144..5bfcee62402 100644 --- a/tests/ui/unsafe-binders/moves.rs +++ b/tests/ui/unsafe-binders/moves.rs @@ -1,17 +1,20 @@ +//@ known-bug: unknown + #![feature(unsafe_binders)] -//~^ WARN the feature `unsafe_binders` is incomplete +// FIXME(unsafe_binders) ~^ WARN the feature `unsafe_binders` is incomplete use std::unsafe_binder::{wrap_binder, unwrap_binder}; -use std::mem::drop; +use std::mem::{drop, ManuallyDrop}; -struct NotCopy; +struct NotCopyInner; +type NotCopy = ManuallyDrop<NotCopyInner>; fn use_after_wrap() { unsafe { let base = NotCopy; let binder: unsafe<> NotCopy = wrap_binder!(base); drop(base); - //~^ ERROR use of moved value: `base` + // FIXME(unsafe_binders) ~^ ERROR use of moved value: `base` } } @@ -20,7 +23,7 @@ fn move_out_of_wrap() { let binder: unsafe<> NotCopy = wrap_binder!(NotCopy); drop(unwrap_binder!(binder)); drop(unwrap_binder!(binder)); - //~^ ERROR use of moved value: `binder` + // FIXME(unsafe_binders) ~^ ERROR use of moved value: `binder` } } @@ -31,7 +34,7 @@ fn not_conflicting() { drop(unwrap_binder!(binder).1); // ^ NOT a problem. drop(unwrap_binder!(binder).0); - //~^ ERROR use of moved value: `binder.0` + // FIXME(unsafe_binders) ~^ ERROR use of moved value: `binder.0` } } diff --git a/tests/ui/unsafe-binders/moves.stderr b/tests/ui/unsafe-binders/moves.stderr index d90823bf7e2..ca507964008 100644 --- a/tests/ui/unsafe-binders/moves.stderr +++ b/tests/ui/unsafe-binders/moves.stderr @@ -1,5 +1,37 @@ +error[E0423]: expected value, found type alias `NotCopy` + --> $DIR/moves.rs:14:20 + | +LL | let base = NotCopy; + | ^^^^^^^ + | + = note: can't use a type alias as a constructor + +error[E0423]: expected value, found type alias `NotCopy` + --> $DIR/moves.rs:23:53 + | +LL | let binder: unsafe<> NotCopy = wrap_binder!(NotCopy); + | ^^^^^^^ + | + = note: can't use a type alias as a constructor + +error[E0423]: expected value, found type alias `NotCopy` + --> $DIR/moves.rs:32:65 + | +LL | let binder: unsafe<> (NotCopy, NotCopy) = wrap_binder!((NotCopy, NotCopy)); + | ^^^^^^^ + | + = note: can't use a type alias as a constructor + +error[E0423]: expected value, found type alias `NotCopy` + --> $DIR/moves.rs:32:74 + | +LL | let binder: unsafe<> (NotCopy, NotCopy) = wrap_binder!((NotCopy, NotCopy)); + | ^^^^^^^ + | + = note: can't use a type alias as a constructor + warning: the feature `unsafe_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/moves.rs:1:12 + --> $DIR/moves.rs:3:12 | LL | #![feature(unsafe_binders)] | ^^^^^^^^^^^^^^ @@ -7,47 +39,47 @@ 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 +error[E0277]: the trait bound `NotCopyInner: Copy` is not satisfied + --> $DIR/moves.rs:15:21 | -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 + | ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `NotCopyInner` | -note: if `NotCopy` implemented `Clone`, you could clone the value - --> $DIR/moves.rs:7:1 + = note: required for `ManuallyDrop<NotCopyInner>` to implement `Copy` +help: consider annotating `NotCopyInner` with `#[derive(Copy)]` + | +LL + #[derive(Copy)] +LL | struct NotCopyInner; | -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 +error[E0277]: the trait bound `NotCopyInner: Copy` is not satisfied + --> $DIR/moves.rs:23:21 + | +LL | let binder: unsafe<> NotCopy = wrap_binder!(NotCopy); + | ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `NotCopyInner` + | + = note: required for `ManuallyDrop<NotCopyInner>` to implement `Copy` +help: consider annotating `NotCopyInner` with `#[derive(Copy)]` | -LL | drop(unwrap_binder!(binder)); - | ---------------------- value moved here -LL | drop(unwrap_binder!(binder)); - | ^^^^^^^^^^^^^^^^^^^^^^ value used here after move +LL + #[derive(Copy)] +LL | struct NotCopyInner; | - = 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 +error[E0277]: the trait bound `NotCopyInner: Copy` is not satisfied + --> $DIR/moves.rs:32:21 + | +LL | let binder: unsafe<> (NotCopy, NotCopy) = wrap_binder!((NotCopy, NotCopy)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `NotCopyInner` + | + = note: required for `ManuallyDrop<NotCopyInner>` to implement `Copy` + = note: required because it appears within the type `(ManuallyDrop<NotCopyInner>, ManuallyDrop<NotCopyInner>)` +help: consider annotating `NotCopyInner` with `#[derive(Copy)]` | -LL | drop(unwrap_binder!(binder).0); - | ------------------------ value moved here -... -LL | drop(unwrap_binder!(binder).0); - | ^^^^^^^^^^^^^^^^^^^^^^^^ value used here after move +LL + #[derive(Copy)] +LL | struct NotCopyInner; | - = 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 +error: aborting due to 7 previous errors; 1 warning emitted -For more information about this error, try `rustc --explain E0382`. +Some errors have detailed explanations: E0277, E0423. +For more information about an error, try `rustc --explain E0277`. |
