mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-29 05:15:04 +00:00
Add need-mut
and unused-mut
diagnostics
This commit is contained in:
parent
c0a0664d12
commit
a25710b0c0
10 changed files with 1089 additions and 277 deletions
|
@ -10,7 +10,7 @@ use hir_def::path::ModPath;
|
|||
use hir_expand::{name::Name, HirFileId, InFile};
|
||||
use syntax::{ast, AstPtr, SyntaxNodePtr, TextRange};
|
||||
|
||||
use crate::{AssocItem, Field, MacroKind, Type};
|
||||
use crate::{AssocItem, Field, Local, MacroKind, Type};
|
||||
|
||||
macro_rules! diagnostics {
|
||||
($($diag:ident,)*) => {
|
||||
|
@ -41,6 +41,7 @@ diagnostics![
|
|||
MissingFields,
|
||||
MissingMatchArms,
|
||||
MissingUnsafe,
|
||||
NeedMut,
|
||||
NoSuchField,
|
||||
PrivateAssocItem,
|
||||
PrivateField,
|
||||
|
@ -54,6 +55,7 @@ diagnostics![
|
|||
UnresolvedMethodCall,
|
||||
UnresolvedModule,
|
||||
UnresolvedProcMacro,
|
||||
UnusedMut,
|
||||
];
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -209,4 +211,15 @@ pub struct TypeMismatch {
|
|||
pub actual: Type,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct NeedMut {
|
||||
pub local: Local,
|
||||
pub span: InFile<SyntaxNodePtr>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct UnusedMut {
|
||||
pub local: Local,
|
||||
}
|
||||
|
||||
pub use hir_ty::diagnostics::IncorrectCase;
|
||||
|
|
|
@ -63,7 +63,7 @@ use hir_ty::{
|
|||
display::HexifiedConst,
|
||||
layout::layout_of_ty,
|
||||
method_resolution::{self, TyFingerprint},
|
||||
mir::interpret_mir,
|
||||
mir::{self, interpret_mir},
|
||||
primitive::UintTy,
|
||||
traits::FnTrait,
|
||||
AliasTy, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast, ClosureId,
|
||||
|
@ -85,12 +85,12 @@ use crate::db::{DefDatabase, HirDatabase};
|
|||
pub use crate::{
|
||||
attrs::{HasAttrs, Namespace},
|
||||
diagnostics::{
|
||||
AnyDiagnostic, BreakOutsideOfLoop, ExpectedFunction, InactiveCode, IncorrectCase,
|
||||
InvalidDeriveTarget, MacroError, MalformedDerive, MismatchedArgCount, MissingFields,
|
||||
MissingMatchArms, MissingUnsafe, NoSuchField, PrivateAssocItem, PrivateField,
|
||||
AnyDiagnostic, BreakOutsideOfLoop, InactiveCode, IncorrectCase, InvalidDeriveTarget,
|
||||
MacroError, MalformedDerive, MismatchedArgCount, MissingFields, MissingMatchArms,
|
||||
MissingUnsafe, NeedMut, NoSuchField, PrivateAssocItem, PrivateField,
|
||||
ReplaceFilterMapNextWithFindMap, TypeMismatch, UnimplementedBuiltinMacro,
|
||||
UnresolvedExternCrate, UnresolvedField, UnresolvedImport, UnresolvedMacroCall,
|
||||
UnresolvedMethodCall, UnresolvedModule, UnresolvedProcMacro,
|
||||
UnresolvedExternCrate, UnresolvedImport, UnresolvedMacroCall, UnresolvedModule,
|
||||
UnresolvedProcMacro, UnusedMut,
|
||||
},
|
||||
has_source::HasSource,
|
||||
semantics::{PathResolution, Semantics, SemanticsScope, TypeInfo, VisibleTraits},
|
||||
|
@ -1500,6 +1500,38 @@ impl DefWithBody {
|
|||
}
|
||||
}
|
||||
|
||||
let hir_body = db.body(self.into());
|
||||
|
||||
if let Ok(mir_body) = db.mir_body(self.into()) {
|
||||
let mol = mir::borrowck::mutability_of_locals(&mir_body);
|
||||
for (binding_id, _) in hir_body.bindings.iter() {
|
||||
let need_mut = &mol[mir_body.binding_locals[binding_id]];
|
||||
let local = Local { parent: self.into(), binding_id };
|
||||
match (need_mut, local.is_mut(db)) {
|
||||
(mir::borrowck::Mutability::Mut { .. }, true)
|
||||
| (mir::borrowck::Mutability::Not, false) => (),
|
||||
(mir::borrowck::Mutability::Mut { span }, false) => {
|
||||
let span: InFile<SyntaxNodePtr> = match span {
|
||||
mir::MirSpan::ExprId(e) => match source_map.expr_syntax(*e) {
|
||||
Ok(s) => s.map(|x| x.into()),
|
||||
Err(_) => continue,
|
||||
},
|
||||
mir::MirSpan::PatId(p) => match source_map.pat_syntax(*p) {
|
||||
Ok(s) => s.map(|x| match x {
|
||||
Either::Left(e) => e.into(),
|
||||
Either::Right(e) => e.into(),
|
||||
}),
|
||||
Err(_) => continue,
|
||||
},
|
||||
mir::MirSpan::Unknown => continue,
|
||||
};
|
||||
acc.push(NeedMut { local, span }.into());
|
||||
}
|
||||
(mir::borrowck::Mutability::Not, true) => acc.push(UnusedMut { local }.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for diagnostic in BodyValidationDiagnostic::collect(db, self.into()) {
|
||||
match diagnostic {
|
||||
BodyValidationDiagnostic::RecordMissingFields {
|
||||
|
@ -2490,6 +2522,10 @@ impl LocalSource {
|
|||
pub fn syntax(&self) -> &SyntaxNode {
|
||||
self.source.value.syntax()
|
||||
}
|
||||
|
||||
pub fn syntax_ptr(self) -> InFile<SyntaxNodePtr> {
|
||||
self.source.map(|x| SyntaxNodePtr::new(x.syntax()))
|
||||
}
|
||||
}
|
||||
|
||||
impl Local {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue