about summary refs log tree commit diff
path: root/compiler/rustc_hir_analysis/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-01-09 14:50:14 +0000
committerbors <bors@rust-lang.org>2024-01-09 14:50:14 +0000
commit5876c8cdfd3df742c334d6447d44d760c77103b6 (patch)
treeb2437656721ba0a5f4068566975525a9bab87974 /compiler/rustc_hir_analysis/src
parentbe00c5a9b89161b7f45ba80340f709e8e41122f9 (diff)
parentf41d7739880e72743a74722ae6fcc1be9f7b4e5c (diff)
downloadrust-5876c8cdfd3df742c334d6447d44d760c77103b6.tar.gz
rust-5876c8cdfd3df742c334d6447d44d760c77103b6.zip
Auto merge of #119767 - GuillaumeGomez:rollup-fbp26yb, r=GuillaumeGomez
Rollup of 9 pull requests

Successful merges:

 - #117556 (Disallow reference to `static mut` and adding `static_mut_ref` lint)
 - #118748 (std: getrandom simplification for freebsd.)
 - #119282 (Rework and improve the unstable documentation of check-cfg)
 - #119527 (don't reexport atomic::ordering via rustc_data_structures, use std import)
 - #119668 (Simplify implementation of MIR promotion)
 - #119699 (Merge dead bb pruning and unreachable bb deduplication.)
 - #119723 (Remove `-Zdont-buffer-diagnostics`.)
 - #119756 (rustdoc-search: reuse individual types in function signatures)
 - #119758 (GNU/Hurd: unconditionally use inline stack probes)

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_hir_analysis/src')
-rw-r--r--compiler/rustc_hir_analysis/src/check/errs.rs97
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/check/region.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs91
4 files changed, 195 insertions, 0 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/errs.rs b/compiler/rustc_hir_analysis/src/check/errs.rs
new file mode 100644
index 00000000000..27bb2c57a5c
--- /dev/null
+++ b/compiler/rustc_hir_analysis/src/check/errs.rs
@@ -0,0 +1,97 @@
+use rustc_hir as hir;
+use rustc_hir_pretty::qpath_to_string;
+use rustc_lint_defs::builtin::STATIC_MUT_REF;
+use rustc_middle::ty::TyCtxt;
+use rustc_span::Span;
+use rustc_type_ir::Mutability;
+
+use crate::errors;
+
+/// Check for shared or mutable references of `static mut` inside expression
+pub fn maybe_expr_static_mut(tcx: TyCtxt<'_>, expr: hir::Expr<'_>) {
+    let span = expr.span;
+    let hir_id = expr.hir_id;
+    if let hir::ExprKind::AddrOf(borrow_kind, m, expr) = expr.kind
+        && matches!(borrow_kind, hir::BorrowKind::Ref)
+        && let Some(var) = is_path_static_mut(*expr)
+    {
+        handle_static_mut_ref(
+            tcx,
+            span,
+            var,
+            span.edition().at_least_rust_2024(),
+            matches!(m, Mutability::Mut),
+            hir_id,
+        );
+    }
+}
+
+/// Check for shared or mutable references of `static mut` inside statement
+pub fn maybe_stmt_static_mut(tcx: TyCtxt<'_>, stmt: hir::Stmt<'_>) {
+    if let hir::StmtKind::Local(loc) = stmt.kind
+        && let hir::PatKind::Binding(ba, _, _, _) = loc.pat.kind
+        && matches!(ba.0, rustc_ast::ByRef::Yes)
+        && let Some(init) = loc.init
+        && let Some(var) = is_path_static_mut(*init)
+    {
+        handle_static_mut_ref(
+            tcx,
+            init.span,
+            var,
+            loc.span.edition().at_least_rust_2024(),
+            matches!(ba.1, Mutability::Mut),
+            stmt.hir_id,
+        );
+    }
+}
+
+fn is_path_static_mut(expr: hir::Expr<'_>) -> Option<String> {
+    if let hir::ExprKind::Path(qpath) = expr.kind
+        && let hir::QPath::Resolved(_, path) = qpath
+        && let hir::def::Res::Def(def_kind, _) = path.res
+        && let hir::def::DefKind::Static(mt) = def_kind
+        && matches!(mt, Mutability::Mut)
+    {
+        return Some(qpath_to_string(&qpath));
+    }
+    None
+}
+
+fn handle_static_mut_ref(
+    tcx: TyCtxt<'_>,
+    span: Span,
+    var: String,
+    e2024: bool,
+    mutable: bool,
+    hir_id: hir::HirId,
+) {
+    if e2024 {
+        let sugg = if mutable {
+            errors::StaticMutRefSugg::Mut { span, var }
+        } else {
+            errors::StaticMutRefSugg::Shared { span, var }
+        };
+        tcx.sess.parse_sess.dcx.emit_err(errors::StaticMutRef { span, sugg });
+        return;
+    }
+
+    let (label, sugg, shared) = if mutable {
+        (
+            errors::RefOfMutStaticLabel::Mut { span },
+            errors::RefOfMutStaticSugg::Mut { span, var },
+            "mutable ",
+        )
+    } else {
+        (
+            errors::RefOfMutStaticLabel::Shared { span },
+            errors::RefOfMutStaticSugg::Shared { span, var },
+            "shared ",
+        )
+    };
+    tcx.emit_spanned_lint(
+        STATIC_MUT_REF,
+        hir_id,
+        span,
+        errors::RefOfMutStatic { shared, why_note: (), label, sugg },
+    );
+}
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index f60d6950670..ac0c715c6b3 100644
--- a/compiler/rustc_hir_analysis/src/check/mod.rs
+++ b/compiler/rustc_hir_analysis/src/check/mod.rs
@@ -66,6 +66,7 @@ mod check;
 mod compare_impl_item;
 pub mod dropck;
 mod entry;
+mod errs;
 pub mod intrinsic;
 pub mod intrinsicck;
 mod region;
diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs
index 542e69a6c34..5d5a4789734 100644
--- a/compiler/rustc_hir_analysis/src/check/region.rs
+++ b/compiler/rustc_hir_analysis/src/check/region.rs
@@ -18,6 +18,8 @@ use rustc_middle::ty::TyCtxt;
 use rustc_span::source_map;
 use rustc_span::Span;
 
+use super::errs::{maybe_expr_static_mut, maybe_stmt_static_mut};
+
 use std::mem;
 
 #[derive(Debug, Copy, Clone)]
@@ -224,6 +226,8 @@ fn resolve_stmt<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, stmt: &'tcx h
     let stmt_id = stmt.hir_id.local_id;
     debug!("resolve_stmt(stmt.id={:?})", stmt_id);
 
+    maybe_stmt_static_mut(visitor.tcx, *stmt);
+
     // Every statement will clean up the temporaries created during
     // execution of that statement. Therefore each statement has an
     // associated destruction scope that represents the scope of the
@@ -242,6 +246,8 @@ fn resolve_stmt<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, stmt: &'tcx h
 fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
     debug!("resolve_expr - pre-increment {} expr = {:?}", visitor.expr_and_pat_count, expr);
 
+    maybe_expr_static_mut(visitor.tcx, *expr);
+
     let prev_cx = visitor.cx;
     visitor.enter_node_scope_with_dtor(expr.hir_id.local_id);
 
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index 9124d502110..4f22da4ba3b 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -1410,3 +1410,94 @@ pub struct OnlyCurrentTraitsPointerSugg<'a> {
     pub mut_key: &'a str,
     pub ptr_ty: Ty<'a>,
 }
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_static_mut_ref, code = "E0796")]
+#[note]
+pub struct StaticMutRef {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+    #[subdiagnostic]
+    pub sugg: StaticMutRefSugg,
+}
+
+#[derive(Subdiagnostic)]
+pub enum StaticMutRefSugg {
+    #[suggestion(
+        hir_analysis_suggestion,
+        style = "verbose",
+        code = "addr_of!({var})",
+        applicability = "maybe-incorrect"
+    )]
+    Shared {
+        #[primary_span]
+        span: Span,
+        var: String,
+    },
+    #[suggestion(
+        hir_analysis_suggestion_mut,
+        style = "verbose",
+        code = "addr_of_mut!({var})",
+        applicability = "maybe-incorrect"
+    )]
+    Mut {
+        #[primary_span]
+        span: Span,
+        var: String,
+    },
+}
+
+// STATIC_MUT_REF lint
+#[derive(LintDiagnostic)]
+#[diag(hir_analysis_static_mut_ref_lint)]
+#[note]
+pub struct RefOfMutStatic<'a> {
+    pub shared: &'a str,
+    #[note(hir_analysis_why_note)]
+    pub why_note: (),
+    #[subdiagnostic]
+    pub label: RefOfMutStaticLabel,
+    #[subdiagnostic]
+    pub sugg: RefOfMutStaticSugg,
+}
+
+#[derive(Subdiagnostic)]
+pub enum RefOfMutStaticLabel {
+    #[label(hir_analysis_label)]
+    Shared {
+        #[primary_span]
+        span: Span,
+    },
+    #[label(hir_analysis_label_mut)]
+    Mut {
+        #[primary_span]
+        span: Span,
+    },
+}
+
+#[derive(Subdiagnostic)]
+pub enum RefOfMutStaticSugg {
+    #[suggestion(
+        hir_analysis_suggestion,
+        style = "verbose",
+        code = "addr_of!({var})",
+        applicability = "maybe-incorrect"
+    )]
+    Shared {
+        #[primary_span]
+        span: Span,
+        var: String,
+    },
+    #[suggestion(
+        hir_analysis_suggestion_mut,
+        style = "verbose",
+        code = "addr_of_mut!({var})",
+        applicability = "maybe-incorrect"
+    )]
+    Mut {
+        #[primary_span]
+        span: Span,
+        var: String,
+    },
+}