Skip to content

Commit 3700fe8

Browse files
Enforce unsafe binders must be Copy (for now)
1 parent 8c3a723 commit 3700fe8

File tree

5 files changed

+98
-41
lines changed

5 files changed

+98
-41
lines changed

compiler/rustc_codegen_cranelift/src/base.rs

+4
Original file line numberDiff line numberDiff line change
@@ -915,6 +915,10 @@ fn codegen_stmt<'tcx>(
915915
}
916916
crate::discriminant::codegen_set_discriminant(fx, lval, variant_index);
917917
}
918+
Rvalue::WrapUnsafeBinder(ref operand, _to_ty) => {
919+
let operand = codegen_operand(fx, operand);
920+
lval.write_cvalue_transmute(fx, operand);
921+
}
918922
}
919923
}
920924
StatementKind::StorageLive(_)

compiler/rustc_trait_selection/src/traits/wf.rs

+19-2
Original file line numberDiff line numberDiff line change
@@ -828,8 +828,25 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
828828
// Let the visitor iterate into the argument/return
829829
// types appearing in the fn signature.
830830
}
831-
ty::UnsafeBinder(_) => {
832-
// FIXME(unsafe_binders): We should also recurse into the binder here.
831+
ty::UnsafeBinder(ty) => {
832+
// FIXME(unsafe_binders): For now, we have no way to express
833+
// that a type must be `ManuallyDrop` OR `Copy` (or a pointer).
834+
if !ty.has_escaping_bound_vars() {
835+
self.out.push(traits::Obligation::new(
836+
self.tcx(),
837+
self.cause(ObligationCauseCode::Misc),
838+
self.param_env,
839+
ty.map_bound(|ty| {
840+
ty::TraitRef::new(
841+
self.tcx(),
842+
self.tcx().require_lang_item(LangItem::Copy, Some(self.span)),
843+
[ty],
844+
)
845+
}),
846+
));
847+
}
848+
849+
// We recurse into the binder below.
833850
}
834851

835852
ty::Dynamic(data, r, _) => {

src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs

+1
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ fn check_rvalue<'tcx>(
116116
Rvalue::CopyForDeref(place) => check_place(tcx, *place, span, body, msrv),
117117
Rvalue::Repeat(operand, _)
118118
| Rvalue::Use(operand)
119+
| Rvalue::WrapUnsafeBinder(operand, _)
119120
| Rvalue::Cast(
120121
CastKind::PointerWithExposedProvenance
121122
| CastKind::IntToInt

tests/ui/unsafe-binders/moves.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
1+
//@ known-bug: unknown
2+
13
#![feature(unsafe_binders)]
2-
//~^ WARN the feature `unsafe_binders` is incomplete
4+
// FIXME(unsafe_binders) ~^ WARN the feature `unsafe_binders` is incomplete
35

46
use std::unsafe_binder::{wrap_binder, unwrap_binder};
5-
use std::mem::drop;
7+
use std::mem::{drop, ManuallyDrop};
68

7-
struct NotCopy;
9+
struct NotCopyInner;
10+
type NotCopy = ManuallyDrop<NotCopyInner>;
811

912
fn use_after_wrap() {
1013
unsafe {
1114
let base = NotCopy;
1215
let binder: unsafe<> NotCopy = wrap_binder!(base);
1316
drop(base);
14-
//~^ ERROR use of moved value: `base`
17+
// FIXME(unsafe_binders) ~^ ERROR use of moved value: `base`
1518
}
1619
}
1720

@@ -20,7 +23,7 @@ fn move_out_of_wrap() {
2023
let binder: unsafe<> NotCopy = wrap_binder!(NotCopy);
2124
drop(unwrap_binder!(binder));
2225
drop(unwrap_binder!(binder));
23-
//~^ ERROR use of moved value: `binder`
26+
// FIXME(unsafe_binders) ~^ ERROR use of moved value: `binder`
2427
}
2528
}
2629

@@ -31,7 +34,7 @@ fn not_conflicting() {
3134
drop(unwrap_binder!(binder).1);
3235
// ^ NOT a problem.
3336
drop(unwrap_binder!(binder).0);
34-
//~^ ERROR use of moved value: `binder.0`
37+
// FIXME(unsafe_binders) ~^ ERROR use of moved value: `binder.0`
3538
}
3639
}
3740

tests/ui/unsafe-binders/moves.stderr

+65-33
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,85 @@
1+
error[E0423]: expected value, found type alias `NotCopy`
2+
--> $DIR/moves.rs:14:20
3+
|
4+
LL | let base = NotCopy;
5+
| ^^^^^^^
6+
|
7+
= note: can't use a type alias as a constructor
8+
9+
error[E0423]: expected value, found type alias `NotCopy`
10+
--> $DIR/moves.rs:23:53
11+
|
12+
LL | let binder: unsafe<> NotCopy = wrap_binder!(NotCopy);
13+
| ^^^^^^^
14+
|
15+
= note: can't use a type alias as a constructor
16+
17+
error[E0423]: expected value, found type alias `NotCopy`
18+
--> $DIR/moves.rs:32:65
19+
|
20+
LL | let binder: unsafe<> (NotCopy, NotCopy) = wrap_binder!((NotCopy, NotCopy));
21+
| ^^^^^^^
22+
|
23+
= note: can't use a type alias as a constructor
24+
25+
error[E0423]: expected value, found type alias `NotCopy`
26+
--> $DIR/moves.rs:32:74
27+
|
28+
LL | let binder: unsafe<> (NotCopy, NotCopy) = wrap_binder!((NotCopy, NotCopy));
29+
| ^^^^^^^
30+
|
31+
= note: can't use a type alias as a constructor
32+
133
warning: the feature `unsafe_binders` is incomplete and may not be safe to use and/or cause compiler crashes
2-
--> $DIR/moves.rs:1:12
34+
--> $DIR/moves.rs:3:12
335
|
436
LL | #![feature(unsafe_binders)]
537
| ^^^^^^^^^^^^^^
638
|
739
= note: see issue #130516 <https://github.com/rust-lang/rust/issues/130516> for more information
840
= note: `#[warn(incomplete_features)]` on by default
941

10-
error[E0382]: use of moved value: `base`
11-
--> $DIR/moves.rs:13:14
42+
error[E0277]: the trait bound `NotCopyInner: Copy` is not satisfied
43+
--> $DIR/moves.rs:15:21
1244
|
13-
LL | let base = NotCopy;
14-
| ---- move occurs because `base` has type `NotCopy`, which does not implement the `Copy` trait
1545
LL | let binder: unsafe<> NotCopy = wrap_binder!(base);
16-
| ---- value moved here
17-
LL | drop(base);
18-
| ^^^^ value used here after move
46+
| ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `NotCopyInner`
1947
|
20-
note: if `NotCopy` implemented `Clone`, you could clone the value
21-
--> $DIR/moves.rs:7:1
48+
= note: required for `ManuallyDrop<NotCopyInner>` to implement `Copy`
49+
help: consider annotating `NotCopyInner` with `#[derive(Copy)]`
50+
|
51+
LL + #[derive(Copy)]
52+
LL | struct NotCopyInner;
2253
|
23-
LL | struct NotCopy;
24-
| ^^^^^^^^^^^^^^ consider implementing `Clone` for this type
25-
...
26-
LL | let binder: unsafe<> NotCopy = wrap_binder!(base);
27-
| ---- you could clone this value
2854

29-
error[E0382]: use of moved value: `binder`
30-
--> $DIR/moves.rs:22:14
55+
error[E0277]: the trait bound `NotCopyInner: Copy` is not satisfied
56+
--> $DIR/moves.rs:23:21
57+
|
58+
LL | let binder: unsafe<> NotCopy = wrap_binder!(NotCopy);
59+
| ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `NotCopyInner`
60+
|
61+
= note: required for `ManuallyDrop<NotCopyInner>` to implement `Copy`
62+
help: consider annotating `NotCopyInner` with `#[derive(Copy)]`
3163
|
32-
LL | drop(unwrap_binder!(binder));
33-
| ---------------------- value moved here
34-
LL | drop(unwrap_binder!(binder));
35-
| ^^^^^^^^^^^^^^^^^^^^^^ value used here after move
64+
LL + #[derive(Copy)]
65+
LL | struct NotCopyInner;
3666
|
37-
= note: move occurs because `binder` has type `NotCopy`, which does not implement the `Copy` trait
38-
= note: this error originates in the macro `unwrap_binder` (in Nightly builds, run with -Z macro-backtrace for more info)
3967

40-
error[E0382]: use of moved value: `binder.0`
41-
--> $DIR/moves.rs:33:14
68+
error[E0277]: the trait bound `NotCopyInner: Copy` is not satisfied
69+
--> $DIR/moves.rs:32:21
70+
|
71+
LL | let binder: unsafe<> (NotCopy, NotCopy) = wrap_binder!((NotCopy, NotCopy));
72+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `NotCopyInner`
73+
|
74+
= note: required for `ManuallyDrop<NotCopyInner>` to implement `Copy`
75+
= note: required because it appears within the type `(ManuallyDrop<NotCopyInner>, ManuallyDrop<NotCopyInner>)`
76+
help: consider annotating `NotCopyInner` with `#[derive(Copy)]`
4277
|
43-
LL | drop(unwrap_binder!(binder).0);
44-
| ------------------------ value moved here
45-
...
46-
LL | drop(unwrap_binder!(binder).0);
47-
| ^^^^^^^^^^^^^^^^^^^^^^^^ value used here after move
78+
LL + #[derive(Copy)]
79+
LL | struct NotCopyInner;
4880
|
49-
= note: move occurs because `binder.0` has type `NotCopy`, which does not implement the `Copy` trait
5081

51-
error: aborting due to 3 previous errors; 1 warning emitted
82+
error: aborting due to 7 previous errors; 1 warning emitted
5283

53-
For more information about this error, try `rustc --explain E0382`.
84+
Some errors have detailed explanations: E0277, E0423.
85+
For more information about an error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)