Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 1c4da09

Browse files
authoredMar 5, 2025
Rollup merge of rust-lang#137808 - jswrenn:droppy-unsafe-fields, r=nnethercote
Do not require that unsafe fields lack drop glue Instead, we adopt the position that introducing an `unsafe` field itself carries a safety invariant: that if you assign an invariant to that field weaker than what the field's destructor requires, you must ensure that field is in a droppable state in your destructor. See: - rust-lang/rfcs#3458 (comment) - https://rust-lang.zulipchat.com/#narrow/channel/213817-t-lang/topic/unsafe.20fields.20RFC/near/502113897 Tracking Issue: rust-lang#132922
2 parents a7d1fa7 + 91034ad commit 1c4da09

File tree

6 files changed

+5
-80
lines changed

6 files changed

+5
-80
lines changed
 

‎compiler/rustc_hir_analysis/messages.ftl

-7
Original file line numberDiff line numberDiff line change
@@ -278,13 +278,6 @@ hir_analysis_invalid_union_field =
278278
hir_analysis_invalid_union_field_sugg =
279279
wrap the field type in `ManuallyDrop<...>`
280280
281-
hir_analysis_invalid_unsafe_field =
282-
field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be unsafe
283-
.note = unsafe fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>`
284-
285-
hir_analysis_invalid_unsafe_field_sugg =
286-
wrap the field type in `ManuallyDrop<...>`
287-
288281
hir_analysis_late_bound_const_in_apit = `impl Trait` can only mention const parameters from an fn or impl
289282
.label = const parameter declared here
290283

‎compiler/rustc_hir_analysis/src/check/check.rs

-32
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ fn check_struct(tcx: TyCtxt<'_>, def_id: LocalDefId) {
7070

7171
check_transparent(tcx, def);
7272
check_packed(tcx, span, def);
73-
check_unsafe_fields(tcx, def_id);
7473
}
7574

7675
fn check_union(tcx: TyCtxt<'_>, def_id: LocalDefId) {
@@ -144,36 +143,6 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b
144143
true
145144
}
146145

147-
/// Check that the unsafe fields do not need dropping.
148-
fn check_unsafe_fields(tcx: TyCtxt<'_>, item_def_id: LocalDefId) {
149-
let span = tcx.def_span(item_def_id);
150-
let def = tcx.adt_def(item_def_id);
151-
152-
let typing_env = ty::TypingEnv::non_body_analysis(tcx, item_def_id);
153-
let args = ty::GenericArgs::identity_for_item(tcx, item_def_id);
154-
155-
for field in def.all_fields() {
156-
if !field.safety.is_unsafe() {
157-
continue;
158-
}
159-
160-
if !allowed_union_or_unsafe_field(tcx, field.ty(tcx, args), typing_env, span) {
161-
let hir::Node::Field(field) = tcx.hir_node_by_def_id(field.did.expect_local()) else {
162-
unreachable!("field has to correspond to hir field")
163-
};
164-
let ty_span = field.ty.span;
165-
tcx.dcx().emit_err(errors::InvalidUnsafeField {
166-
field_span: field.span,
167-
sugg: errors::InvalidUnsafeFieldSuggestion {
168-
lo: ty_span.shrink_to_lo(),
169-
hi: ty_span.shrink_to_hi(),
170-
},
171-
note: (),
172-
});
173-
}
174-
}
175-
}
176-
177146
/// Check that a `static` is inhabited.
178147
fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
179148
// Make sure statics are inhabited.
@@ -1512,7 +1481,6 @@ fn check_enum(tcx: TyCtxt<'_>, def_id: LocalDefId) {
15121481

15131482
detect_discriminant_duplicate(tcx, def);
15141483
check_transparent(tcx, def);
1515-
check_unsafe_fields(tcx, def_id);
15161484
}
15171485

15181486
/// Part of enum check. Given the discriminants of an enum, errors if two or more discriminants are equal

‎compiler/rustc_hir_analysis/src/errors.rs

-23
Original file line numberDiff line numberDiff line change
@@ -712,17 +712,6 @@ pub(crate) struct InvalidUnionField {
712712
pub note: (),
713713
}
714714

715-
#[derive(Diagnostic)]
716-
#[diag(hir_analysis_invalid_unsafe_field, code = E0740)]
717-
pub(crate) struct InvalidUnsafeField {
718-
#[primary_span]
719-
pub field_span: Span,
720-
#[subdiagnostic]
721-
pub sugg: InvalidUnsafeFieldSuggestion,
722-
#[note]
723-
pub note: (),
724-
}
725-
726715
#[derive(Diagnostic)]
727716
#[diag(hir_analysis_return_type_notation_on_non_rpitit)]
728717
pub(crate) struct ReturnTypeNotationOnNonRpitit<'tcx> {
@@ -744,18 +733,6 @@ pub(crate) struct InvalidUnionFieldSuggestion {
744733
pub hi: Span,
745734
}
746735

747-
#[derive(Subdiagnostic)]
748-
#[multipart_suggestion(
749-
hir_analysis_invalid_unsafe_field_sugg,
750-
applicability = "machine-applicable"
751-
)]
752-
pub(crate) struct InvalidUnsafeFieldSuggestion {
753-
#[suggestion_part(code = "std::mem::ManuallyDrop<")]
754-
pub lo: Span,
755-
#[suggestion_part(code = ">")]
756-
pub hi: Span,
757-
}
758-
759736
#[derive(Diagnostic)]
760737
#[diag(hir_analysis_return_type_notation_equality_bound)]
761738
pub(crate) struct ReturnTypeNotationEqualityBound {

‎library/core/src/marker.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -453,8 +453,8 @@ impl Copy for ! {}
453453
#[stable(feature = "rust1", since = "1.0.0")]
454454
impl<T: ?Sized> Copy for &T {}
455455

456-
/// Marker trait for the types that are allowed in union fields, unsafe fields,
457-
/// and unsafe binder types.
456+
/// Marker trait for the types that are allowed in union fields and unsafe
457+
/// binder types.
458458
///
459459
/// Implemented for:
460460
/// * `&T`, `&mut T` for all `T`,

‎tests/ui/unsafe-fields/unsafe-fields.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ fn f(a: A) {
1717
}
1818

1919
struct WithInvalidUnsafeField {
20-
unsafe unsafe_noncopy_field: Vec<u32>, //~ ERROR
20+
unsafe unsafe_noncopy_field: Vec<u32>,
2121
}
2222

2323
struct WithManuallyDropUnsafeField {

‎tests/ui/unsafe-fields/unsafe-fields.stderr

+2-15
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,3 @@
1-
error[E0740]: field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be unsafe
2-
--> $DIR/unsafe-fields.rs:20:5
3-
|
4-
LL | unsafe unsafe_noncopy_field: Vec<u32>,
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6-
|
7-
= note: unsafe fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>`
8-
help: wrap the field type in `ManuallyDrop<...>`
9-
|
10-
LL | unsafe unsafe_noncopy_field: std::mem::ManuallyDrop<Vec<u32>>,
11-
| +++++++++++++++++++++++ +
12-
131
error[E0133]: use of unsafe field is unsafe and requires unsafe block
142
--> $DIR/unsafe-fields.rs:15:30
153
|
@@ -69,7 +57,6 @@ LL | &raw const self.unsafe_field
6957
|
7058
= note: unsafe fields may carry library invariants
7159

72-
error: aborting due to 8 previous errors
60+
error: aborting due to 7 previous errors
7361

74-
Some errors have detailed explanations: E0133, E0740.
75-
For more information about an error, try `rustc --explain E0133`.
62+
For more information about this error, try `rustc --explain E0133`.

0 commit comments

Comments
 (0)
Failed to load comments.