rust/compiler/rustc_hir_analysis/src/check/errs.rs

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

79 lines
2.1 KiB
Rust
Raw Normal View History

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 },
);
}