Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-diagnostics/src/handlers/unused_variables.rs')
-rw-r--r--crates/ide-diagnostics/src/handlers/unused_variables.rs121
1 files changed, 110 insertions, 11 deletions
diff --git a/crates/ide-diagnostics/src/handlers/unused_variables.rs b/crates/ide-diagnostics/src/handlers/unused_variables.rs
index 28ccf474b4..a9e1d07d7c 100644
--- a/crates/ide-diagnostics/src/handlers/unused_variables.rs
+++ b/crates/ide-diagnostics/src/handlers/unused_variables.rs
@@ -1,3 +1,11 @@
+use ide_db::{
+ assists::{Assist, AssistId, AssistKind},
+ base_db::FileRange,
+ label::Label,
+ source_change::SourceChange,
+};
+use text_edit::TextEdit;
+
use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext};
// Diagnostic: unused-variables
@@ -8,18 +16,38 @@ pub(crate) fn unused_variables(
d: &hir::UnusedVariable,
) -> Diagnostic {
let ast = d.local.primary_source(ctx.sema.db).syntax_ptr();
+ let diagnostic_range = ctx.sema.diagnostics_display_range(ast);
+ let var_name = d.local.primary_source(ctx.sema.db).syntax().to_string();
Diagnostic::new_with_syntax_node_ptr(
ctx,
DiagnosticCode::RustcLint("unused_variables"),
"unused variable",
ast,
)
+ .with_fixes(fixes(&var_name, diagnostic_range, ast.file_id.is_macro()))
.experimental()
}
+fn fixes(var_name: &String, diagnostic_range: FileRange, is_in_marco: bool) -> Option<Vec<Assist>> {
+ if is_in_marco {
+ return None;
+ }
+ Some(vec![Assist {
+ id: AssistId("unscore_unused_variable_name", AssistKind::QuickFix),
+ label: Label::new(format!("Rename unused {} to _{}", var_name, var_name)),
+ group: None,
+ target: diagnostic_range.range,
+ source_change: Some(SourceChange::from_text_edit(
+ diagnostic_range.file_id,
+ TextEdit::replace(diagnostic_range.range, format!("_{}", var_name)),
+ )),
+ trigger_signature_help: false,
+ }])
+}
+
#[cfg(test)]
mod tests {
- use crate::tests::check_diagnostics;
+ use crate::tests::{check_diagnostics, check_fix, check_no_fix};
#[test]
fn unused_variables_simple() {
@@ -29,23 +57,23 @@ mod tests {
struct Foo { f1: i32, f2: i64 }
fn f(kkk: i32) {}
- //^^^ warn: unused variable
+ //^^^ 💡 warn: unused variable
fn main() {
let a = 2;
- //^ warn: unused variable
+ //^ 💡 warn: unused variable
let b = 5;
// note: `unused variable` implies `unused mut`, so we should not emit both at the same time.
let mut c = f(b);
- //^^^^^ warn: unused variable
+ //^^^^^ 💡 warn: unused variable
let (d, e) = (3, 5);
- //^ warn: unused variable
+ //^ 💡 warn: unused variable
let _ = e;
let f1 = 2;
let f2 = 5;
let f = Foo { f1, f2 };
match f {
Foo { f1, f2 } => {
- //^^ warn: unused variable
+ //^^ 💡 warn: unused variable
_ = f2;
}
}
@@ -53,7 +81,7 @@ fn main() {
if g {}
let h: fn() -> i32 = || 2;
let i = h();
- //^ warn: unused variable
+ //^ 💡 warn: unused variable
}
"#,
);
@@ -67,11 +95,11 @@ struct S {
}
impl S {
fn owned_self(self, u: i32) {}
- //^ warn: unused variable
+ //^ 💡 warn: unused variable
fn ref_self(&self, u: i32) {}
- //^ warn: unused variable
+ //^ 💡 warn: unused variable
fn ref_mut_self(&mut self, u: i32) {}
- //^ warn: unused variable
+ //^ 💡 warn: unused variable
fn owned_mut_self(mut self) {}
//^^^^^^^^ 💡 warn: variable does not need to be mutable
@@ -103,7 +131,78 @@ fn main() {
#[deny(unused)]
fn main2() {
let x = 2;
- //^ error: unused variable
+ //^ 💡 error: unused variable
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn fix_unused_variable() {
+ check_fix(
+ r#"
+fn main() {
+ let x$0 = 2;
+}
+"#,
+ r#"
+fn main() {
+ let _x = 2;
+}
+"#,
+ );
+
+ check_fix(
+ r#"
+fn main() {
+ let ($0d, _e) = (3, 5);
+}
+"#,
+ r#"
+fn main() {
+ let (_d, _e) = (3, 5);
+}
+"#,
+ );
+
+ check_fix(
+ r#"
+struct Foo { f1: i32, f2: i64 }
+fn main() {
+ let f = Foo { f1: 0, f2: 0 };
+ match f {
+ Foo { f1$0, f2 } => {
+ _ = f2;
+ }
+ }
+}
+"#,
+ r#"
+struct Foo { f1: i32, f2: i64 }
+fn main() {
+ let f = Foo { f1: 0, f2: 0 };
+ match f {
+ Foo { _f1, f2 } => {
+ _ = f2;
+ }
+ }
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn no_fix_for_marco() {
+ check_no_fix(
+ r#"
+macro_rules! my_macro {
+ () => {
+ let x = 3;
+ };
+}
+
+fn main() {
+ $0my_macro!();
}
"#,
);