|
1 | 1 | use rustc_data_structures::fx::FxHashSet; |
2 | 2 | use rustc_errors::struct_span_err; |
3 | 3 | use rustc_hir as hir; |
| 4 | +use rustc_hir::def::DefKind; |
4 | 5 | use rustc_hir::def_id::{DefId, LocalDefId}; |
5 | 6 | use rustc_hir::hir_id::HirId; |
6 | 7 | use rustc_hir::intravisit; |
@@ -134,6 +135,28 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> { |
134 | 135 | self.super_rvalue(rvalue, location); |
135 | 136 | } |
136 | 137 |
|
| 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 | + |
137 | 160 | fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: Location) { |
138 | 161 | // On types with `scalar_valid_range`, prevent |
139 | 162 | // * `&mut x.field` |
@@ -410,6 +433,12 @@ impl<'tcx> intravisit::Visitor<'tcx> for UnusedUnsafeVisitor<'_, 'tcx> { |
410 | 433 | intravisit::walk_block(self, block); |
411 | 434 | } |
412 | 435 |
|
| 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 | + |
413 | 442 | fn visit_fn( |
414 | 443 | &mut self, |
415 | 444 | fk: intravisit::FnKind<'tcx>, |
@@ -484,7 +513,7 @@ fn unsafety_check_result<'tcx>( |
484 | 513 | let mut checker = UnsafetyChecker::new(body, def.did, tcx, param_env); |
485 | 514 | checker.visit_body(&body); |
486 | 515 |
|
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())) |
488 | 517 | .then(|| check_unused_unsafe(tcx, def.did, &checker.used_unsafe_blocks)); |
489 | 518 |
|
490 | 519 | tcx.arena.alloc(UnsafetyCheckResult { |
@@ -516,8 +545,8 @@ fn report_unused_unsafe(tcx: TyCtxt<'_>, kind: UnusedUnsafe, id: HirId) { |
516 | 545 | pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) { |
517 | 546 | debug!("check_unsafety({:?})", def_id); |
518 | 547 |
|
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()) { |
521 | 550 | return; |
522 | 551 | } |
523 | 552 |
|
|
0 commit comments