Skip to content

Commit a7379f7

Browse files
Mark unsafe binder casts as unsafe
1 parent 69b356c commit a7379f7

File tree

4 files changed

+75
-1
lines changed

4 files changed

+75
-1
lines changed

Diff for: compiler/rustc_mir_build/messages.ftl

+13
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ mir_build_bindings_with_variant_name =
88
pattern binding `{$name}` is named the same as one of the variants of the type `{$ty_path}`
99
.suggestion = to match on the variant, qualify the path
1010
11+
1112
mir_build_borrow = value is borrowed by `{$name}` here
1213
1314
mir_build_borrow_of_layout_constrained_field_requires_unsafe =
@@ -370,6 +371,18 @@ mir_build_unreachable_pattern = unreachable pattern
370371
.unreachable_pattern_let_binding = there is a binding of the same name; if you meant to pattern match against the value of that binding, that is a feature of constants that is not available for `let` bindings
371372
.suggestion = remove the match arm
372373
374+
mir_build_unsafe_binder_cast_requires_unsafe =
375+
unsafe binder cast is unsafe and requires unsafe block
376+
.label = unsafe binder cast
377+
.note = casting to or from an `unsafe<...>` binder type is unsafe since it erases lifetime
378+
information that may be required to uphold safety guarantees of a type
379+
380+
mir_build_unsafe_binder_cast_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
381+
unsafe binder cast is unsafe and requires unsafe block or unsafe fn
382+
.label = unsafe binder cast
383+
.note = casting to or from an `unsafe<...>` binder type is unsafe since it erases lifetime
384+
information that may be required to uphold safety guarantees of a type
385+
373386
mir_build_unsafe_field_requires_unsafe =
374387
use of unsafe field is unsafe and requires unsafe block
375388
.note = unsafe fields may carry library invariants

Diff for: compiler/rustc_mir_build/src/check_unsafety.rs

+22
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,9 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
680680
}
681681
}
682682
}
683+
ExprKind::PlaceUnsafeBinderCast { .. } | ExprKind::ValueUnsafeBinderCast { .. } => {
684+
self.requires_unsafe(expr.span, UnsafeBinderCast);
685+
}
683686
_ => {}
684687
}
685688
visit::walk_expr(self, expr);
@@ -728,6 +731,7 @@ enum UnsafeOpKind {
728731
/// (e.g., with `-C target-feature`).
729732
build_enabled: Vec<Symbol>,
730733
},
734+
UnsafeBinderCast,
731735
}
732736

733737
use UnsafeOpKind::*;
@@ -888,6 +892,15 @@ impl UnsafeOpKind {
888892
unsafe_not_inherited_note,
889893
},
890894
),
895+
UnsafeBinderCast => tcx.emit_node_span_lint(
896+
UNSAFE_OP_IN_UNSAFE_FN,
897+
hir_id,
898+
span,
899+
UnsafeOpInUnsafeFnUnsafeBinderCastRequiresUnsafe {
900+
span,
901+
unsafe_not_inherited_note,
902+
},
903+
),
891904
}
892905
}
893906

@@ -1096,6 +1109,15 @@ impl UnsafeOpKind {
10961109
function: tcx.def_path_str(*function),
10971110
});
10981111
}
1112+
UnsafeBinderCast if unsafe_op_in_unsafe_fn_allowed => {
1113+
dcx.emit_err(UnsafeBinderCastRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
1114+
span,
1115+
unsafe_not_inherited_note,
1116+
});
1117+
}
1118+
UnsafeBinderCast => {
1119+
dcx.emit_err(UnsafeBinderCastRequiresUnsafe { span, unsafe_not_inherited_note });
1120+
}
10991121
}
11001122
}
11011123
}

Diff for: compiler/rustc_mir_build/src/errors.rs

+38
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,18 @@ pub(crate) struct UnsafeOpInUnsafeFnBorrowOfLayoutConstrainedFieldRequiresUnsafe
171171
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedLintNote>,
172172
}
173173

174+
#[derive(LintDiagnostic)]
175+
#[diag(
176+
mir_build_unsafe_binder_cast_requires_unsafe,
177+
code = E0133,
178+
)]
179+
pub(crate) struct UnsafeOpInUnsafeFnUnsafeBinderCastRequiresUnsafe {
180+
#[label]
181+
pub(crate) span: Span,
182+
#[subdiagnostic]
183+
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedLintNote>,
184+
}
185+
174186
#[derive(LintDiagnostic)]
175187
#[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_fn_with_requires_unsafe, code = E0133)]
176188
#[help]
@@ -505,6 +517,32 @@ pub(crate) struct CallToFunctionWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
505517
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
506518
}
507519

520+
#[derive(Diagnostic)]
521+
#[diag(
522+
mir_build_unsafe_binder_cast_requires_unsafe,
523+
code = E0133,
524+
)]
525+
pub(crate) struct UnsafeBinderCastRequiresUnsafe {
526+
#[primary_span]
527+
#[label]
528+
pub(crate) span: Span,
529+
#[subdiagnostic]
530+
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
531+
}
532+
533+
#[derive(Diagnostic)]
534+
#[diag(
535+
mir_build_unsafe_binder_cast_requires_unsafe_unsafe_op_in_unsafe_fn_allowed,
536+
code = E0133,
537+
)]
538+
pub(crate) struct UnsafeBinderCastRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
539+
#[primary_span]
540+
#[label]
541+
pub(crate) span: Span,
542+
#[subdiagnostic]
543+
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
544+
}
545+
508546
#[derive(Subdiagnostic)]
509547
#[label(mir_build_unsafe_not_inherited)]
510548
pub(crate) struct UnsafeNotInheritedNote {

Diff for: compiler/rustc_type_ir/src/fast_reject.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ pub enum SimplifiedType<DefId> {
4141
Coroutine(DefId),
4242
CoroutineWitness(DefId),
4343
Function(usize),
44+
UnsafeBinder,
4445
Placeholder,
4546
Error,
4647
}
@@ -138,7 +139,7 @@ pub fn simplify_type<I: Interner>(
138139
ty::FnPtr(sig_tys, _hdr) => {
139140
Some(SimplifiedType::Function(sig_tys.skip_binder().inputs().len()))
140141
}
141-
ty::UnsafeBinder(binder) => simplify_type(cx, binder.skip_binder(), treat_params),
142+
ty::UnsafeBinder(_) => Some(SimplifiedType::UnsafeBinder),
142143
ty::Placeholder(..) => Some(SimplifiedType::Placeholder),
143144
ty::Param(_) => match treat_params {
144145
TreatParams::AsRigid => Some(SimplifiedType::Placeholder),

0 commit comments

Comments
 (0)