6
6
//!
7
7
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/borrow_check.html
8
8
9
- use rustc_ast:: walk_list;
9
+ use rustc_ast:: { walk_list, BorrowKind } ;
10
10
use rustc_data_structures:: fx:: FxHashSet ;
11
11
use rustc_hir as hir;
12
12
use rustc_hir:: def_id:: DefId ;
@@ -17,9 +17,12 @@ use rustc_middle::middle::region::*;
17
17
use rustc_middle:: ty:: TyCtxt ;
18
18
use rustc_span:: source_map;
19
19
use rustc_span:: Span ;
20
+ use rustc_type_ir:: Mutability ;
20
21
21
22
use std:: mem;
22
23
24
+ use crate :: errors;
25
+
23
26
#[ derive( Debug , Copy , Clone ) ]
24
27
pub struct Context {
25
28
/// The scope that contains any new variables declared, plus its depth in
@@ -90,6 +93,13 @@ fn resolve_block<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, blk: &'tcx h
90
93
91
94
let prev_cx = visitor. cx ;
92
95
96
+ if let hir:: BlockCheckMode :: UnsafeBlock ( src) = blk. rules
97
+ && matches ! ( src, hir:: UnsafeSource :: UserProvided )
98
+ && blk. span . edition ( ) . at_least_rust_2024 ( )
99
+ {
100
+ static_mut_ref ( visitor. tcx , blk. stmts ) ;
101
+ }
102
+
93
103
// We treat the tail expression in the block (if any) somewhat
94
104
// differently from the statements. The issue has to do with
95
105
// temporary lifetimes. Consider the following:
@@ -887,3 +897,22 @@ pub fn region_scope_tree(tcx: TyCtxt<'_>, def_id: DefId) -> &ScopeTree {
887
897
888
898
tcx. arena . alloc ( scope_tree)
889
899
}
900
+
901
+ /// Check for use of mutable static
902
+ pub fn static_mut_ref ( tcx : TyCtxt < ' _ > , stmts : & [ Stmt < ' _ > ] ) {
903
+ for stmt in stmts {
904
+ if let hir:: StmtKind :: Local ( loc) = stmt. kind
905
+ && let Some ( init) = loc. init
906
+ && let hir:: ExprKind :: AddrOf ( borrow_kind, _, expr) = init. kind
907
+ && matches ! ( borrow_kind, BorrowKind :: Ref )
908
+ && let hir:: ExprKind :: Path ( qpath) = expr. kind
909
+ && let hir:: QPath :: Resolved ( _, path) = qpath
910
+ && let hir:: def:: Res :: Def ( def_kind, _) = path. res
911
+ && let hir:: def:: DefKind :: Static ( mt) = def_kind
912
+ && matches ! ( mt, Mutability :: Mut )
913
+ {
914
+ let span = init. span ;
915
+ tcx. sess . emit_err ( errors:: StaticMutRef { span } ) ;
916
+ }
917
+ }
918
+ }
0 commit comments