Skip to content

Commit 3b15ead

Browse files
Mark unsafe binder casts as unsafe
1 parent 5c25145 commit 3b15ead

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
@@ -627,6 +627,9 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
627627
}
628628
}
629629
}
630+
ExprKind::PlaceUnsafeBinderCast { .. } | ExprKind::ValueUnsafeBinderCast { .. } => {
631+
self.requires_unsafe(expr.span, UnsafeBinderCast);
632+
}
630633
_ => {}
631634
}
632635
visit::walk_expr(self, expr);
@@ -673,6 +676,7 @@ enum UnsafeOpKind {
673676
/// (e.g., with `-C target-feature`).
674677
build_enabled: Vec<Symbol>,
675678
},
679+
UnsafeBinderCast,
676680
}
677681

678682
use UnsafeOpKind::*;
@@ -815,6 +819,15 @@ impl UnsafeOpKind {
815819
unsafe_not_inherited_note,
816820
},
817821
),
822+
UnsafeBinderCast => tcx.emit_node_span_lint(
823+
UNSAFE_OP_IN_UNSAFE_FN,
824+
hir_id,
825+
span,
826+
UnsafeOpInUnsafeFnUnsafeBinderCastRequiresUnsafe {
827+
span,
828+
unsafe_not_inherited_note,
829+
},
830+
),
818831
}
819832
}
820833

@@ -1000,6 +1013,15 @@ impl UnsafeOpKind {
10001013
function: tcx.def_path_str(*function),
10011014
});
10021015
}
1016+
UnsafeBinderCast if unsafe_op_in_unsafe_fn_allowed => {
1017+
dcx.emit_err(UnsafeBinderCastRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
1018+
span,
1019+
unsafe_not_inherited_note,
1020+
});
1021+
}
1022+
UnsafeBinderCast => {
1023+
dcx.emit_err(UnsafeBinderCastRequiresUnsafe { span, unsafe_not_inherited_note });
1024+
}
10031025
}
10041026
}
10051027
}

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)