Rollup merge of #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:
- https://github.com/rust-lang/rfcs/pull/3458#discussion_r1971676100
- 502113897
Tracking Issue: #132922
This commit is contained in:
commit
1c3733aa69
6 changed files with 5 additions and 80 deletions
|
@ -275,13 +275,6 @@ hir_analysis_invalid_union_field =
|
|||
hir_analysis_invalid_union_field_sugg =
|
||||
wrap the field type in `ManuallyDrop<...>`
|
||||
|
||||
hir_analysis_invalid_unsafe_field =
|
||||
field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be unsafe
|
||||
.note = unsafe fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>`
|
||||
|
||||
hir_analysis_invalid_unsafe_field_sugg =
|
||||
wrap the field type in `ManuallyDrop<...>`
|
||||
|
||||
hir_analysis_late_bound_const_in_apit = `impl Trait` can only mention const parameters from an fn or impl
|
||||
.label = const parameter declared here
|
||||
|
||||
|
|
|
@ -70,7 +70,6 @@ fn check_struct(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
|||
|
||||
check_transparent(tcx, def);
|
||||
check_packed(tcx, span, def);
|
||||
check_unsafe_fields(tcx, def_id);
|
||||
}
|
||||
|
||||
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
|
|||
true
|
||||
}
|
||||
|
||||
/// Check that the unsafe fields do not need dropping.
|
||||
fn check_unsafe_fields(tcx: TyCtxt<'_>, item_def_id: LocalDefId) {
|
||||
let span = tcx.def_span(item_def_id);
|
||||
let def = tcx.adt_def(item_def_id);
|
||||
|
||||
let typing_env = ty::TypingEnv::non_body_analysis(tcx, item_def_id);
|
||||
let args = ty::GenericArgs::identity_for_item(tcx, item_def_id);
|
||||
|
||||
for field in def.all_fields() {
|
||||
if !field.safety.is_unsafe() {
|
||||
continue;
|
||||
}
|
||||
|
||||
if !allowed_union_or_unsafe_field(tcx, field.ty(tcx, args), typing_env, span) {
|
||||
let hir::Node::Field(field) = tcx.hir_node_by_def_id(field.did.expect_local()) else {
|
||||
unreachable!("field has to correspond to hir field")
|
||||
};
|
||||
let ty_span = field.ty.span;
|
||||
tcx.dcx().emit_err(errors::InvalidUnsafeField {
|
||||
field_span: field.span,
|
||||
sugg: errors::InvalidUnsafeFieldSuggestion {
|
||||
lo: ty_span.shrink_to_lo(),
|
||||
hi: ty_span.shrink_to_hi(),
|
||||
},
|
||||
note: (),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Check that a `static` is inhabited.
|
||||
fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
||||
// Make sure statics are inhabited.
|
||||
|
@ -1512,7 +1481,6 @@ fn check_enum(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
|||
|
||||
detect_discriminant_duplicate(tcx, def);
|
||||
check_transparent(tcx, def);
|
||||
check_unsafe_fields(tcx, def_id);
|
||||
}
|
||||
|
||||
/// Part of enum check. Given the discriminants of an enum, errors if two or more discriminants are equal
|
||||
|
|
|
@ -710,17 +710,6 @@ pub(crate) struct InvalidUnionField {
|
|||
pub note: (),
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_invalid_unsafe_field, code = E0740)]
|
||||
pub(crate) struct InvalidUnsafeField {
|
||||
#[primary_span]
|
||||
pub field_span: Span,
|
||||
#[subdiagnostic]
|
||||
pub sugg: InvalidUnsafeFieldSuggestion,
|
||||
#[note]
|
||||
pub note: (),
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_return_type_notation_on_non_rpitit)]
|
||||
pub(crate) struct ReturnTypeNotationOnNonRpitit<'tcx> {
|
||||
|
@ -742,18 +731,6 @@ pub(crate) struct InvalidUnionFieldSuggestion {
|
|||
pub hi: Span,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[multipart_suggestion(
|
||||
hir_analysis_invalid_unsafe_field_sugg,
|
||||
applicability = "machine-applicable"
|
||||
)]
|
||||
pub(crate) struct InvalidUnsafeFieldSuggestion {
|
||||
#[suggestion_part(code = "std::mem::ManuallyDrop<")]
|
||||
pub lo: Span,
|
||||
#[suggestion_part(code = ">")]
|
||||
pub hi: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_return_type_notation_equality_bound)]
|
||||
pub(crate) struct ReturnTypeNotationEqualityBound {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue