Disallow reference to static mut
for expressions
Add `E0796` error code. Add `static_mut_ref` lint. This is the idea for the 2024 edition.
This commit is contained in:
parent
595bc6f003
commit
2c088f9520
9 changed files with 261 additions and 0 deletions
78
compiler/rustc_hir_analysis/src/check/errs.rs
Normal file
78
compiler/rustc_hir_analysis/src/check/errs.rs
Normal file
|
@ -0,0 +1,78 @@
|
|||
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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
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 },
|
||||
);
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue