Skip to content

Commit 285ab06

Browse files
Mark unsafe binder casts as unsafe
1 parent 17eefd9 commit 285ab06

File tree

4 files changed

+75
-1
lines changed

4 files changed

+75
-1
lines changed

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 =
@@ -340,6 +341,18 @@ mir_build_unreachable_pattern = unreachable pattern
340341
.unreachable_covered_by_many = multiple earlier patterns match some of the same values
341342
.suggestion = remove the match arm
342343
344+
mir_build_unsafe_binder_cast_requires_unsafe =
345+
unsafe binder cast is unsafe and requires unsafe block
346+
.label = unsafe binder cast
347+
.note = casting to or from an `unsafe<...>` binder type is unsafe since it erases lifetime
348+
information that may be required to uphold safety guarantees of a type
349+
350+
mir_build_unsafe_binder_cast_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
351+
unsafe binder cast is unsafe and requires unsafe block or unsafe fn
352+
.label = unsafe binder cast
353+
.note = casting to or from an `unsafe<...>` binder type is unsafe since it erases lifetime
354+
information that may be required to uphold safety guarantees of a type
355+
343356
mir_build_unsafe_fn_safe_body = an unsafe function restricts its caller, but its body is safe by default
344357
mir_build_unsafe_not_inherited = items do not inherit unsafety from separate enclosing items
345358

compiler/rustc_mir_build/src/check_unsafety.rs

+22
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,9 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
618618
}
619619
}
620620
}
621+
ExprKind::PlaceUnsafeBinderCast { .. } | ExprKind::ValueUnsafeBinderCast { .. } => {
622+
self.requires_unsafe(expr.span, UnsafeBinderCast);
623+
}
621624
_ => {}
622625
}
623626
visit::walk_expr(self, expr);
@@ -664,6 +667,7 @@ enum UnsafeOpKind {
664667
/// (e.g., with `-C target-feature`).
665668
build_enabled: Vec<Symbol>,
666669
},
670+
UnsafeBinderCast,
667671
}
668672

669673
use UnsafeOpKind::*;
@@ -806,6 +810,15 @@ impl UnsafeOpKind {
806810
unsafe_not_inherited_note,
807811
},
808812
),
813+
UnsafeBinderCast => tcx.emit_node_span_lint(
814+
UNSAFE_OP_IN_UNSAFE_FN,
815+
hir_id,
816+
span,
817+
UnsafeOpInUnsafeFnUnsafeBinderCastRequiresUnsafe {
818+
span,
819+
unsafe_not_inherited_note,
820+
},
821+
),
809822
}
810823
}
811824

@@ -991,6 +1004,15 @@ impl UnsafeOpKind {
9911004
function: tcx.def_path_str(*function),
9921005
});
9931006
}
1007+
UnsafeBinderCast if unsafe_op_in_unsafe_fn_allowed => {
1008+
dcx.emit_err(UnsafeBinderCastRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
1009+
span,
1010+
unsafe_not_inherited_note,
1011+
});
1012+
}
1013+
UnsafeBinderCast => {
1014+
dcx.emit_err(UnsafeBinderCastRequiresUnsafe { span, unsafe_not_inherited_note });
1015+
}
9941016
}
9951017
}
9961018
}

compiler/rustc_mir_build/src/errors.rs

+38
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,18 @@ pub(crate) struct UnsafeOpInUnsafeFnBorrowOfLayoutConstrainedFieldRequiresUnsafe
151151
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedLintNote>,
152152
}
153153

154+
#[derive(LintDiagnostic)]
155+
#[diag(
156+
mir_build_unsafe_binder_cast_requires_unsafe,
157+
code = E0133,
158+
)]
159+
pub(crate) struct UnsafeOpInUnsafeFnUnsafeBinderCastRequiresUnsafe {
160+
#[label]
161+
pub(crate) span: Span,
162+
#[subdiagnostic]
163+
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedLintNote>,
164+
}
165+
154166
#[derive(LintDiagnostic)]
155167
#[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_fn_with_requires_unsafe, code = E0133)]
156168
#[help]
@@ -438,6 +450,32 @@ pub(crate) struct CallToFunctionWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
438450
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
439451
}
440452

453+
#[derive(Diagnostic)]
454+
#[diag(
455+
mir_build_unsafe_binder_cast_requires_unsafe,
456+
code = E0133,
457+
)]
458+
pub(crate) struct UnsafeBinderCastRequiresUnsafe {
459+
#[primary_span]
460+
#[label]
461+
pub(crate) span: Span,
462+
#[subdiagnostic]
463+
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
464+
}
465+
466+
#[derive(Diagnostic)]
467+
#[diag(
468+
mir_build_unsafe_binder_cast_requires_unsafe_unsafe_op_in_unsafe_fn_allowed,
469+
code = E0133,
470+
)]
471+
pub(crate) struct UnsafeBinderCastRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
472+
#[primary_span]
473+
#[label]
474+
pub(crate) span: Span,
475+
#[subdiagnostic]
476+
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
477+
}
478+
441479
#[derive(Subdiagnostic)]
442480
#[label(mir_build_unsafe_not_inherited)]
443481
pub(crate) struct UnsafeNotInheritedNote {

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)