Skip to content

Commit 9342d1e

Browse files
committed
Allow unsafe through inline const
This is handled similar to closures
1 parent 37d7de3 commit 9342d1e

File tree

1 file changed

+32
-3
lines changed

1 file changed

+32
-3
lines changed

compiler/rustc_mir_transform/src/check_unsafety.rs

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use rustc_data_structures::fx::FxHashSet;
22
use rustc_errors::struct_span_err;
33
use rustc_hir as hir;
4+
use rustc_hir::def::DefKind;
45
use rustc_hir::def_id::{DefId, LocalDefId};
56
use rustc_hir::hir_id::HirId;
67
use rustc_hir::intravisit;
@@ -134,6 +135,28 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> {
134135
self.super_rvalue(rvalue, location);
135136
}
136137

138+
fn visit_operand(&mut self, op: &Operand<'tcx>, location: Location) {
139+
if let Operand::Constant(constant) = op {
140+
let maybe_uneval = match constant.literal {
141+
ConstantKind::Val(..) | ConstantKind::Ty(_) => None,
142+
ConstantKind::Unevaluated(uv, _) => Some(uv),
143+
};
144+
145+
if let Some(uv) = maybe_uneval {
146+
if uv.promoted.is_none() {
147+
let def_id = uv.def.def_id_for_type_of();
148+
if self.tcx.def_kind(def_id) == DefKind::InlineConst {
149+
let local_def_id = def_id.expect_local();
150+
let UnsafetyCheckResult { violations, used_unsafe_blocks, .. } =
151+
self.tcx.unsafety_check_result(local_def_id);
152+
self.register_violations(violations, used_unsafe_blocks.iter().copied());
153+
}
154+
}
155+
}
156+
}
157+
self.super_operand(op, location);
158+
}
159+
137160
fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: Location) {
138161
// On types with `scalar_valid_range`, prevent
139162
// * `&mut x.field`
@@ -410,6 +433,12 @@ impl<'tcx> intravisit::Visitor<'tcx> for UnusedUnsafeVisitor<'_, 'tcx> {
410433
intravisit::walk_block(self, block);
411434
}
412435

436+
fn visit_anon_const(&mut self, c: &'tcx hir::AnonConst) {
437+
if matches!(self.tcx.def_kind(c.def_id), DefKind::InlineConst) {
438+
self.visit_body(self.tcx.hir().body(c.body))
439+
}
440+
}
441+
413442
fn visit_fn(
414443
&mut self,
415444
fk: intravisit::FnKind<'tcx>,
@@ -484,7 +513,7 @@ fn unsafety_check_result<'tcx>(
484513
let mut checker = UnsafetyChecker::new(body, def.did, tcx, param_env);
485514
checker.visit_body(&body);
486515

487-
let unused_unsafes = (!tcx.is_closure(def.did.to_def_id()))
516+
let unused_unsafes = (!tcx.is_typeck_child(def.did.to_def_id()))
488517
.then(|| check_unused_unsafe(tcx, def.did, &checker.used_unsafe_blocks));
489518

490519
tcx.arena.alloc(UnsafetyCheckResult {
@@ -516,8 +545,8 @@ fn report_unused_unsafe(tcx: TyCtxt<'_>, kind: UnusedUnsafe, id: HirId) {
516545
pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) {
517546
debug!("check_unsafety({:?})", def_id);
518547

519-
// closures are handled by their parent fn.
520-
if tcx.is_closure(def_id.to_def_id()) {
548+
// closures and inline consts are handled by their parent fn.
549+
if tcx.is_typeck_child(def_id.to_def_id()) {
521550
return;
522551
}
523552

0 commit comments

Comments
 (0)