Enforce unsafe binders must be Copy (for now)
This commit is contained in:
parent
fc1a9186dc
commit
b63341e892
5 changed files with 98 additions and 41 deletions
|
@ -915,6 +915,10 @@ fn codegen_stmt<'tcx>(
|
||||||
}
|
}
|
||||||
crate::discriminant::codegen_set_discriminant(fx, lval, variant_index);
|
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(_)
|
StatementKind::StorageLive(_)
|
||||||
|
|
|
@ -828,8 +828,25 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
|
||||||
// Let the visitor iterate into the argument/return
|
// Let the visitor iterate into the argument/return
|
||||||
// types appearing in the fn signature.
|
// types appearing in the fn signature.
|
||||||
}
|
}
|
||||||
ty::UnsafeBinder(_) => {
|
ty::UnsafeBinder(ty) => {
|
||||||
// FIXME(unsafe_binders): We should also recurse into the binder here.
|
// 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, _) => {
|
ty::Dynamic(data, r, _) => {
|
||||||
|
|
|
@ -116,6 +116,7 @@ fn check_rvalue<'tcx>(
|
||||||
Rvalue::CopyForDeref(place) => check_place(tcx, *place, span, body, msrv),
|
Rvalue::CopyForDeref(place) => check_place(tcx, *place, span, body, msrv),
|
||||||
Rvalue::Repeat(operand, _)
|
Rvalue::Repeat(operand, _)
|
||||||
| Rvalue::Use(operand)
|
| Rvalue::Use(operand)
|
||||||
|
| Rvalue::WrapUnsafeBinder(operand, _)
|
||||||
| Rvalue::Cast(
|
| Rvalue::Cast(
|
||||||
CastKind::PointerWithExposedProvenance
|
CastKind::PointerWithExposedProvenance
|
||||||
| CastKind::IntToInt
|
| CastKind::IntToInt
|
||||||
|
|
|
@ -1,17 +1,20 @@
|
||||||
|
//@ known-bug: unknown
|
||||||
|
|
||||||
#![feature(unsafe_binders)]
|
#![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::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() {
|
fn use_after_wrap() {
|
||||||
unsafe {
|
unsafe {
|
||||||
let base = NotCopy;
|
let base = NotCopy;
|
||||||
let binder: unsafe<> NotCopy = wrap_binder!(base);
|
let binder: unsafe<> NotCopy = wrap_binder!(base);
|
||||||
drop(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);
|
let binder: unsafe<> NotCopy = wrap_binder!(NotCopy);
|
||||||
drop(unwrap_binder!(binder));
|
drop(unwrap_binder!(binder));
|
||||||
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);
|
drop(unwrap_binder!(binder).1);
|
||||||
// ^ NOT a problem.
|
// ^ NOT a problem.
|
||||||
drop(unwrap_binder!(binder).0);
|
drop(unwrap_binder!(binder).0);
|
||||||
//~^ ERROR use of moved value: `binder.0`
|
// FIXME(unsafe_binders) ~^ ERROR use of moved value: `binder.0`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
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)]
|
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: see issue #130516 <https://github.com/rust-lang/rust/issues/130516> for more information
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
error[E0382]: use of moved value: `base`
|
error[E0277]: the trait bound `NotCopyInner: Copy` is not satisfied
|
||||||
--> $DIR/moves.rs:13:14
|
--> $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);
|
LL | let binder: unsafe<> NotCopy = wrap_binder!(base);
|
||||||
| ---- value moved here
|
| ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `NotCopyInner`
|
||||||
LL | drop(base);
|
|
||||||
| ^^^^ value used here after move
|
|
||||||
|
|
|
|
||||||
note: if `NotCopy` implemented `Clone`, you could clone the value
|
= note: required for `ManuallyDrop<NotCopyInner>` to implement `Copy`
|
||||||
--> $DIR/moves.rs:7:1
|
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`
|
error[E0277]: the trait bound `NotCopyInner: Copy` is not satisfied
|
||||||
--> $DIR/moves.rs:22:14
|
--> $DIR/moves.rs:23:21
|
||||||
|
|
|
|
||||||
LL | drop(unwrap_binder!(binder));
|
LL | let binder: unsafe<> NotCopy = wrap_binder!(NotCopy);
|
||||||
| ---------------------- value moved here
|
| ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `NotCopyInner`
|
||||||
LL | drop(unwrap_binder!(binder));
|
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^ value used here after move
|
= note: required for `ManuallyDrop<NotCopyInner>` to implement `Copy`
|
||||||
|
help: consider annotating `NotCopyInner` with `#[derive(Copy)]`
|
||||||
|
|
|
||||||
|
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`
|
error[E0277]: the trait bound `NotCopyInner: Copy` is not satisfied
|
||||||
--> $DIR/moves.rs:33:14
|
--> $DIR/moves.rs:32:21
|
||||||
|
|
|
|
||||||
LL | drop(unwrap_binder!(binder).0);
|
LL | let binder: unsafe<> (NotCopy, NotCopy) = wrap_binder!((NotCopy, NotCopy));
|
||||||
| ------------------------ value moved here
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `NotCopyInner`
|
||||||
...
|
|
|
||||||
LL | drop(unwrap_binder!(binder).0);
|
= note: required for `ManuallyDrop<NotCopyInner>` to implement `Copy`
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ value used here after move
|
= note: required because it appears within the type `(ManuallyDrop<NotCopyInner>, ManuallyDrop<NotCopyInner>)`
|
||||||
|
help: consider annotating `NotCopyInner` with `#[derive(Copy)]`
|
||||||
|
|
|
||||||
|
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`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue