Skip to content

Commit aa5af2a

Browse files
committed
Allow unsafe through inline const for THIR unsafety checker
The closure handling code is changed slightly to avoid allocation when THIR building failed.
1 parent 9342d1e commit aa5af2a

File tree

1 file changed

+25
-12
lines changed

1 file changed

+25
-12
lines changed

compiler/rustc_mir_build/src/check_unsafety.rs

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -408,16 +408,29 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
408408
} else {
409409
ty::WithOptConstParam::unknown(closure_id)
410410
};
411-
let (closure_thir, expr) = self.tcx.thir_body(closure_def).unwrap_or_else(|_| {
412-
(self.tcx.alloc_steal_thir(Thir::new()), ExprId::from_u32(0))
413-
});
414-
let closure_thir = &closure_thir.borrow();
415-
let hir_context = self.tcx.hir().local_def_id_to_hir_id(closure_id);
416-
let mut closure_visitor =
417-
UnsafetyVisitor { thir: closure_thir, hir_context, ..*self };
418-
closure_visitor.visit_expr(&closure_thir[expr]);
419-
// Unsafe blocks can be used in closures, make sure to take it into account
420-
self.safety_context = closure_visitor.safety_context;
411+
if let Ok((closure_thir, expr)) = self.tcx.thir_body(closure_def) {
412+
let closure_thir = &closure_thir.borrow();
413+
let hir_context = self.tcx.hir().local_def_id_to_hir_id(closure_id);
414+
let mut closure_visitor =
415+
UnsafetyVisitor { thir: closure_thir, hir_context, ..*self };
416+
closure_visitor.visit_expr(&closure_thir[expr]);
417+
// Unsafe blocks can be used in closures, make sure to take it into account
418+
self.safety_context = closure_visitor.safety_context;
419+
}
420+
}
421+
ExprKind::ConstBlock { did, substs: _ } => {
422+
let def_id = did.expect_local();
423+
if let Ok((inner_thir, expr)) =
424+
self.tcx.thir_body(ty::WithOptConstParam::unknown(def_id))
425+
{
426+
let inner_thir = &inner_thir.borrow();
427+
let hir_context = self.tcx.hir().local_def_id_to_hir_id(def_id);
428+
let mut inner_visitor =
429+
UnsafetyVisitor { thir: inner_thir, hir_context, ..*self };
430+
inner_visitor.visit_expr(&inner_thir[expr]);
431+
// Unsafe blocks can be used in inline consts, make sure to take it into account
432+
self.safety_context = inner_visitor.safety_context;
433+
}
421434
}
422435
ExprKind::Field { lhs, .. } => {
423436
let lhs = &self.thir[lhs];
@@ -612,8 +625,8 @@ pub fn check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam<LocalD
612625
return;
613626
}
614627

615-
// Closures are handled by their owner, if it has a body
616-
if tcx.is_closure(def.did.to_def_id()) {
628+
// Closures and inline consts are handled by their owner, if it has a body
629+
if tcx.is_typeck_child(def.did.to_def_id()) {
617630
let hir = tcx.hir();
618631
let owner = hir.enclosing_body_owner(hir.local_def_id_to_hir_id(def.did));
619632
tcx.ensure().thir_check_unsafety(owner);

0 commit comments

Comments
 (0)