@@ -34,6 +34,7 @@ struct UnsafetyVisitor<'a, 'tcx> {
34
34
/// When inside the LHS of an assignment to a field, this is the type
35
35
/// of the LHS and the span of the assignment expression.
36
36
assignment_info : Option < Ty < ' tcx > > ,
37
+ in_addr_of : bool ,
37
38
in_union_destructure : bool ,
38
39
param_env : ParamEnv < ' tcx > ,
39
40
inside_adt : bool ,
@@ -170,6 +171,7 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
170
171
safety_context,
171
172
body_target_features : self . body_target_features ,
172
173
assignment_info : self . assignment_info ,
174
+ in_addr_of : false ,
173
175
in_union_destructure : false ,
174
176
param_env : self . param_env ,
175
177
inside_adt : false ,
@@ -449,12 +451,21 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
449
451
}
450
452
}
451
453
}
454
+ ExprKind :: AddressOf { .. } => {
455
+ self . in_addr_of = true ;
456
+ }
452
457
ExprKind :: Deref { arg } => {
458
+ let allow_implicit_static_deref = self . in_addr_of ;
459
+ self . in_addr_of = false ;
460
+
453
461
if let ExprKind :: StaticRef { def_id, .. } | ExprKind :: ThreadLocalRef ( def_id) =
454
462
self . thir [ arg] . kind
455
463
{
456
- if self . tcx . is_mutable_static ( def_id) {
464
+ // We want to forgive only one deref, so addr_of!(STATIC_MUT) works
465
+ // as one deref is a synthetic `*ptr` for a place expression
466
+ if !allow_implicit_static_deref && self . tcx . is_mutable_static ( def_id) {
457
467
self . requires_unsafe ( expr. span , UseOfMutableStatic ) ;
468
+ // In some cases we synthesize references to extern statics, however
458
469
} else if self . tcx . is_foreign_item ( def_id) {
459
470
self . requires_unsafe ( expr. span , UseOfExternStatic ) ;
460
471
}
@@ -956,8 +967,9 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) {
956
967
hir_context : hir_id,
957
968
body_target_features,
958
969
assignment_info : None ,
959
- in_union_destructure : false ,
960
970
param_env : tcx. param_env ( def) ,
971
+ in_addr_of : false ,
972
+ in_union_destructure : false ,
961
973
inside_adt : false ,
962
974
warnings : & mut warnings,
963
975
suggest_unsafe_block : true ,
0 commit comments