@@ -34,6 +34,7 @@ struct UnsafetyVisitor<'a, 'tcx> {
3434 /// When inside the LHS of an assignment to a field, this is the type
3535 /// of the LHS and the span of the assignment expression.
3636 assignment_info : Option < Ty < ' tcx > > ,
37+ in_addr_of : bool ,
3738 in_union_destructure : bool ,
3839 param_env : ParamEnv < ' tcx > ,
3940 inside_adt : bool ,
@@ -170,6 +171,7 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
170171 safety_context,
171172 body_target_features : self . body_target_features ,
172173 assignment_info : self . assignment_info ,
174+ in_addr_of : false ,
173175 in_union_destructure : false ,
174176 param_env : self . param_env ,
175177 inside_adt : false ,
@@ -449,11 +451,22 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
449451 }
450452 }
451453 }
454+ ExprKind :: AddressOf { .. } => {
455+ // we want to forgive one deref, so addr_of!(STATIC_MUT) works
456+ self . in_addr_of = true ;
457+ }
452458 ExprKind :: Deref { arg } => {
459+ // during HIR -> THIR, we synthesize a pointer to the static and then deref it
460+ let allow_implicit_static_deref = self . in_addr_of ;
461+ // we don't want to accidentally allow addr_of!(*STATIC_MUT)
462+ self . in_addr_of = false ;
463+
453464 if let ExprKind :: StaticRef { def_id, .. } | ExprKind :: ThreadLocalRef ( def_id) =
454465 self . thir [ arg] . kind
455466 {
456- if self . tcx . is_mutable_static ( def_id) {
467+ if self . tcx . is_mutable_static ( def_id) && allow_implicit_static_deref {
468+ // we're only taking the address of the implicit place expr, it's fine
469+ } else if self . tcx . is_mutable_static ( def_id) {
457470 self . requires_unsafe ( expr. span , UseOfMutableStatic ) ;
458471 } else if self . tcx . is_foreign_item ( def_id) {
459472 self . requires_unsafe ( expr. span , UseOfExternStatic ) ;
@@ -956,8 +969,9 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) {
956969 hir_context : hir_id,
957970 body_target_features,
958971 assignment_info : None ,
959- in_union_destructure : false ,
960972 param_env : tcx. param_env ( def) ,
973+ in_addr_of : false ,
974+ in_union_destructure : false ,
961975 inside_adt : false ,
962976 warnings : & mut warnings,
963977 suggest_unsafe_block : true ,
0 commit comments