|
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;
|
13 | 13 | use rustc_hir::intravisit::{self, Visitor};
|
14 | 14 | use rustc_hir::{Arm, Block, Expr, Local, Pat, PatKind, Stmt};
|
| 15 | +use rustc_hir_pretty::qpath_to_string; |
15 | 16 | use rustc_index::Idx;
|
16 | 17 | use rustc_middle::middle::region::*;
|
17 | 18 | use rustc_middle::ty::TyCtxt;
|
18 | 19 | use rustc_span::source_map;
|
19 | 20 | use rustc_span::Span;
|
| 21 | +use rustc_type_ir::Mutability; |
20 | 22 |
|
21 | 23 | use std::mem;
|
22 | 24 |
|
| 25 | +use crate::errors; |
| 26 | + |
23 | 27 | #[derive(Debug, Copy, Clone)]
|
24 | 28 | pub struct Context {
|
25 | 29 | /// The scope that contains any new variables declared, plus its depth in
|
@@ -90,6 +94,12 @@ fn resolve_block<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, blk: &'tcx h
|
90 | 94 |
|
91 | 95 | let prev_cx = visitor.cx;
|
92 | 96 |
|
| 97 | + if let hir::BlockCheckMode::UnsafeBlock(src) = blk.rules |
| 98 | + && matches!(src, hir::UnsafeSource::UserProvided) |
| 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,24 @@ 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 | + && loc.span.edition().at_least_rust_2024() |
| 914 | + { |
| 915 | + let span = init.span; |
| 916 | + let var = qpath_to_string(&qpath); |
| 917 | + tcx.sess.emit_err(errors::StaticMutRef { span, var }); |
| 918 | + } |
| 919 | + } |
| 920 | +} |
0 commit comments