@@ -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,11 +451,22 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
449
451
}
450
452
}
451
453
}
454
+ ExprKind :: AddressOf { .. } => {
455
+ // we want to forgive one deref, so addr_of!(STATIC_MUT) works
456
+ self . in_addr_of = true ;
457
+ }
452
458
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
+
453
464
if let ExprKind :: StaticRef { def_id, .. } | ExprKind :: ThreadLocalRef ( def_id) =
454
465
self . thir [ arg] . kind
455
466
{
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) {
457
470
self . requires_unsafe ( expr. span , UseOfMutableStatic ) ;
458
471
} else if self . tcx . is_foreign_item ( def_id) {
459
472
self . requires_unsafe ( expr. span , UseOfExternStatic ) ;
@@ -956,8 +969,9 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) {
956
969
hir_context : hir_id,
957
970
body_target_features,
958
971
assignment_info : None ,
959
- in_union_destructure : false ,
960
972
param_env : tcx. param_env ( def) ,
973
+ in_addr_of : false ,
974
+ in_union_destructure : false ,
961
975
inside_adt : false ,
962
976
warnings : & mut warnings,
963
977
suggest_unsafe_block : true ,
0 commit comments