diff --git a/compiler/rustc_borrowck/src/consumers.rs b/compiler/rustc_borrowck/src/consumers.rs index efc17a173f4d3..d8cf9a1227e20 100644 --- a/compiler/rustc_borrowck/src/consumers.rs +++ b/compiler/rustc_borrowck/src/consumers.rs @@ -34,6 +34,6 @@ pub fn get_body_with_borrowck_facts<'tcx>( tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(def.did)).enter(|infcx| { let input_body: &Body<'_> = &input_body.borrow(); let promoted: &IndexVec<_, _> = &promoted.borrow(); - *super::do_mir_borrowck(&infcx, input_body, promoted, true).1.unwrap() + *super::do_mir_borrowck(&infcx, input_body, promoted, &None, true).1.unwrap() }) } diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 86da87d060313..0237831ba8f75 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -17,7 +17,7 @@ extern crate rustc_middle; #[macro_use] extern crate tracing; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; use rustc_data_structures::graph::dominators::Dominators; use rustc_errors::{Diagnostic, DiagnosticBuilder, ErrorGuaranteed}; use rustc_hir as hir; @@ -129,16 +129,22 @@ fn mir_borrowck<'tcx>( def: ty::WithOptConstParam, ) -> &'tcx BorrowCheckResult<'tcx> { let (input_body, promoted) = tcx.mir_promoted(def); - debug!("run query mir_borrowck: {}", tcx.def_path_str(def.did.to_def_id())); + + let def_id = def.did.to_def_id(); + debug!("run query mir_borrowck: {}", tcx.def_path_str(def_id)); + let hir_owner = tcx.hir().local_def_id_to_hir_id(def.did).owner; + let is_fn = matches!(tcx.hir().body_owner_kind(def.did), hir::BodyOwnerKind::Fn); + let unused_variables_spans = if is_fn { tcx.check_liveness(def_id) } else { &None }; + let opt_closure_req = tcx .infer_ctxt() .with_opaque_type_inference(DefiningAnchor::Bind(hir_owner)) .enter(|infcx| { let input_body: &Body<'_> = &input_body.borrow(); let promoted: &IndexVec<_, _> = &promoted.borrow(); - do_mir_borrowck(&infcx, input_body, promoted, false).0 + do_mir_borrowck(&infcx, input_body, promoted, unused_variables_spans, false).0 }); debug!("mir_borrowck done"); @@ -155,6 +161,7 @@ fn do_mir_borrowck<'a, 'tcx>( infcx: &InferCtxt<'a, 'tcx>, input_body: &Body<'tcx>, input_promoted: &IndexVec>, + unused_variables_spans: &Option>, return_body_with_facts: bool, ) -> (BorrowCheckResult<'tcx>, Option>>) { let def = input_body.source.with_opt_param().as_local().unwrap(); @@ -428,6 +435,14 @@ fn do_mir_borrowck<'a, 'tcx>( } let mut_span = tcx.sess.source_map().span_until_non_whitespace(span); + let ident_span = span.with_lo(mut_span.hi()); + + // Suppress lints if we already reported unused variables + if let Some(unused_variables_spans) = unused_variables_spans { + if unused_variables_spans.contains(&ident_span) { + continue; + } + } tcx.emit_spanned_lint(UNUSED_MUT, lint_root, span, VarNeedNotMut { span: mut_span }) } diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index e5dfda24dc701..56c6fe1b69c71 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -1558,6 +1558,7 @@ declare_lint! { /// /// ```rust /// let mut x = 5; + /// drop(x); /// ``` /// /// {{produces}} diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 53c254119f436..4e9eb0e3b534e 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -830,7 +830,8 @@ rustc_queries! { desc { |tcx| "checking privacy in {}", describe_as_module(key, tcx) } } - query check_liveness(key: DefId) { + query check_liveness(key: DefId) -> Option> { + arena_cache desc { |tcx| "checking liveness of variables in {}", tcx.def_path_str(key) } } diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 6a4cd79cde712..a888cfb30ac0a 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -85,7 +85,7 @@ use self::LiveNodeKind::*; use self::VarKind::*; use rustc_ast::InlineAsmOptions; -use rustc_data_structures::fx::FxIndexMap; +use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::def::*; @@ -99,6 +99,7 @@ use rustc_session::lint; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::{BytePos, Span}; +use std::cell::RefCell; use std::collections::VecDeque; use std::io; use std::io::prelude::*; @@ -138,9 +139,9 @@ fn live_node_kind_to_string(lnk: LiveNodeKind, tcx: TyCtxt<'_>) -> String { } } -fn check_liveness(tcx: TyCtxt<'_>, def_id: DefId) { +fn check_liveness(tcx: TyCtxt<'_>, def_id: DefId) -> Option> { let local_def_id = match def_id.as_local() { - None => return, + None => return None, Some(def_id) => def_id, }; @@ -149,12 +150,12 @@ fn check_liveness(tcx: TyCtxt<'_>, def_id: DefId) { if let DefKind::Impl = tcx.def_kind(parent) && tcx.has_attr(parent.to_def_id(), sym::automatically_derived) { - return; + return None; } // Don't run unused pass for #[naked] if tcx.has_attr(def_id, sym::naked) { - return; + return None; } let mut maps = IrMaps::new(tcx); @@ -182,6 +183,8 @@ fn check_liveness(tcx: TyCtxt<'_>, def_id: DefId) { lsets.visit_body(body); lsets.warn_about_unused_upvars(entry_ln); lsets.warn_about_unused_args(body, entry_ln); + + Some(lsets.unused_variables_spans.into_inner()) } pub fn provide(providers: &mut Providers) { @@ -517,6 +520,8 @@ struct Liveness<'a, 'tcx> { // it probably doesn't now) break_ln: HirIdMap, cont_ln: HirIdMap, + + unused_variables_spans: RefCell>, } impl<'a, 'tcx> Liveness<'a, 'tcx> { @@ -541,6 +546,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { exit_ln, break_ln: Default::default(), cont_ln: Default::default(), + unused_variables_spans: Default::default(), } } @@ -1504,6 +1510,7 @@ impl<'tcx> Liveness<'_, 'tcx> { } } else { if let Some(name) = self.should_warn(var) { + self.unused_variables_spans.borrow_mut().insert(span); self.ir.tcx.struct_span_lint_hir( lint::builtin::UNUSED_VARIABLES, var_hir_id, @@ -1594,13 +1601,15 @@ impl<'tcx> Liveness<'_, 'tcx> { if ln == self.exit_ln { false } else { self.assigned_on_exit(ln, var) }; if is_assigned { + let spans = hir_ids_and_spans + .into_iter() + .map(|(_, _, ident_span)| ident_span) + .collect::>(); + self.unused_variables_spans.borrow_mut().extend(&spans); self.ir.tcx.struct_span_lint_hir( lint::builtin::UNUSED_VARIABLES, first_hir_id, - hir_ids_and_spans - .into_iter() - .map(|(_, _, ident_span)| ident_span) - .collect::>(), + spans, |lint| { lint.build(&format!("variable `{}` is assigned to, but never used", name)) .note(&format!("consider using `_{}` instead", name)) @@ -1608,10 +1617,13 @@ impl<'tcx> Liveness<'_, 'tcx> { }, ) } else if can_remove { + let spans = + hir_ids_and_spans.iter().map(|(_, pat_span, _)| *pat_span).collect::>(); + self.unused_variables_spans.borrow_mut().extend(&spans); self.ir.tcx.struct_span_lint_hir( lint::builtin::UNUSED_VARIABLES, first_hir_id, - hir_ids_and_spans.iter().map(|(_, pat_span, _)| *pat_span).collect::>(), + spans, |lint| { let mut err = lint.build(&format!("unused variable: `{}`", name)); err.multipart_suggestion( @@ -1654,13 +1666,15 @@ impl<'tcx> Liveness<'_, 'tcx> { ) .collect::>(); + let spans = hir_ids_and_spans + .iter() + .map(|(_, pat_span, _)| *pat_span) + .collect::>(); + self.unused_variables_spans.borrow_mut().extend(&spans); self.ir.tcx.struct_span_lint_hir( lint::builtin::UNUSED_VARIABLES, first_hir_id, - hir_ids_and_spans - .iter() - .map(|(_, pat_span, _)| *pat_span) - .collect::>(), + spans, |lint| { let mut err = lint.build(&format!("unused variable: `{}`", name)); err.multipart_suggestion( @@ -1677,13 +1691,15 @@ impl<'tcx> Liveness<'_, 'tcx> { .map(|(_, _, ident_span)| (ident_span, format!("_{}", name))) .collect::>(); + let spans = hir_ids_and_spans + .iter() + .map(|(_, _, ident_span)| *ident_span) + .collect::>(); + self.unused_variables_spans.borrow_mut().extend(&spans); self.ir.tcx.struct_span_lint_hir( lint::builtin::UNUSED_VARIABLES, first_hir_id, - hir_ids_and_spans - .iter() - .map(|(_, _, ident_span)| *ident_span) - .collect::>(), + spans, |lint| { let mut err = lint.build(&format!("unused variable: `{}`", name)); if self.has_added_lit_match_name_span(&name, opt_body, &mut err) { diff --git a/src/test/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.rs b/src/test/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.rs index 8f94bd6ec6cb8..085e9aed26bc6 100644 --- a/src/test/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.rs +++ b/src/test/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.rs @@ -21,22 +21,22 @@ mod foo { } #[expect( - unused_mut, + unused_variables, //~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations] - //~| NOTE this `expect` is overridden by a `warn` attribute before the `unused_mut` lint is triggered - reason = "this `expect` is overridden by a `warn` attribute before the `unused_mut` lint is triggered" + //~| NOTE this `expect` is overridden by a `warn` attribute before the `unused_variables` lint is triggered + reason = "this `expect` is overridden by a `warn` attribute before the `unused_variables` lint is triggered" )] mod oof { #[warn( - unused_mut, + unused_variables, //~^ NOTE the lint level is defined here - reason = "this overrides the previous `expect` lint level and warns about the `unused_mut` lint here" + reason = "this overrides the previous `expect` lint level and warns about the `unused_variables` lint here" )] fn bar() { let mut v = 0; - //~^ WARNING variable does not need to be mutable [unused_mut] - //~| NOTE this overrides the previous `expect` lint level and warns about the `unused_mut` lint here - //~| HELP remove this `mut` + //~^ WARNING unused variable: `v` [unused_variables] + //~| NOTE this overrides the previous `expect` lint level and warns about the `unused_variables` lint here + //~| HELP if this is intentional, prefix it with an underscore } } diff --git a/src/test/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.stderr b/src/test/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.stderr index 370e51bf70a7a..a93b4314503bd 100644 --- a/src/test/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.stderr +++ b/src/test/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.stderr @@ -1,3 +1,16 @@ +warning: unused variable: `v` + --> $DIR/expect_nested_lint_levels.rs:36:17 + | +LL | let mut v = 0; + | ^ help: if this is intentional, prefix it with an underscore: `_v` + | + = note: this overrides the previous `expect` lint level and warns about the `unused_variables` lint here +note: the lint level is defined here + --> $DIR/expect_nested_lint_levels.rs:31:9 + | +LL | unused_variables, + | ^^^^^^^^^^^^^^^^ + error: unused variable: `this_is_my_function` --> $DIR/expect_nested_lint_levels.rs:48:9 | @@ -10,21 +23,6 @@ note: the lint level is defined here LL | #[forbid(unused_variables)] | ^^^^^^^^^^^^^^^^ -warning: variable does not need to be mutable - --> $DIR/expect_nested_lint_levels.rs:36:13 - | -LL | let mut v = 0; - | ----^ - | | - | help: remove this `mut` - | - = note: this overrides the previous `expect` lint level and warns about the `unused_mut` lint here -note: the lint level is defined here - --> $DIR/expect_nested_lint_levels.rs:31:9 - | -LL | unused_mut, - | ^^^^^^^^^^ - warning: this lint expectation is unfulfilled --> $DIR/expect_nested_lint_levels.rs:7:5 | @@ -37,10 +35,10 @@ LL | unused_mut, warning: this lint expectation is unfulfilled --> $DIR/expect_nested_lint_levels.rs:24:5 | -LL | unused_mut, - | ^^^^^^^^^^ +LL | unused_variables, + | ^^^^^^^^^^^^^^^^ | - = note: this `expect` is overridden by a `warn` attribute before the `unused_mut` lint is triggered + = note: this `expect` is overridden by a `warn` attribute before the `unused_variables` lint is triggered warning: this lint expectation is unfulfilled --> $DIR/expect_nested_lint_levels.rs:43:10 diff --git a/src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.rs b/src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.rs index 4822a9b2c7ff8..f1248285dc363 100644 --- a/src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.rs +++ b/src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.rs @@ -32,12 +32,10 @@ fn main() { let mut mut_unused_var = 1; //~^ WARNING unused variable: `mut_unused_var` - //~| WARNING variable does not need to be mutable let (mut var, unused_var) = (1, 2); //~^ WARNING unused variable: `var` //~| WARNING unused variable: `unused_var` - //~| WARNING variable does not need to be mutable // NOTE: `var` comes after `unused_var` lexicographically yet the warning // for `var` will be emitted before the one for `unused_var`. We use an // `IndexMap` to ensure this is the case instead of a `BTreeMap`. diff --git a/src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.stderr b/src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.stderr index 26fa6eb9b9bc6..9f5fe71957056 100644 --- a/src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.stderr +++ b/src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.stderr @@ -18,25 +18,25 @@ LL | let mut mut_unused_var = 1; | ^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_mut_unused_var` warning: unused variable: `var` - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:37:14 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:36:14 | LL | let (mut var, unused_var) = (1, 2); | ^^^ help: if this is intentional, prefix it with an underscore: `_var` warning: unused variable: `unused_var` - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:37:19 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:36:19 | LL | let (mut var, unused_var) = (1, 2); | ^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused_var` warning: unused variable: `corridors_of_light` - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:45:26 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:43:26 | LL | if let SoulHistory { corridors_of_light, | ^^^^^^^^^^^^^^^^^^ help: try ignoring the field: `corridors_of_light: _` warning: variable `hours_are_suns` is assigned to, but never used - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:46:30 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:44:30 | LL | mut hours_are_suns, | ^^^^^^^^^^^^^^ @@ -44,7 +44,7 @@ LL | mut hours_are_suns, = note: consider using `_hours_are_suns` instead warning: value assigned to `hours_are_suns` is never read - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:48:9 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:46:9 | LL | hours_are_suns = false; | ^^^^^^^^^^^^^^ @@ -53,64 +53,46 @@ LL | hours_are_suns = false; = help: maybe it is overwritten before being read? warning: unused variable: `fire` - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:52:32 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:50:32 | LL | let LovelyAmbition { lips, fire } = the_spirit; | ^^^^ help: try ignoring the field: `fire: _` warning: unused variable: `case` - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:61:23 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:59:23 | LL | Large::Suit { case } => {} | ^^^^ help: try ignoring the field: `case: _` warning: unused variable: `case` - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:66:24 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:64:24 | LL | &Large::Suit { case } => {} | ^^^^ help: try ignoring the field: `case: _` warning: unused variable: `case` - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:71:27 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:69:27 | LL | box Large::Suit { case } => {} | ^^^^ help: try ignoring the field: `case: _` warning: unused variable: `case` - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:76:24 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:74:24 | LL | (Large::Suit { case },) => {} | ^^^^ help: try ignoring the field: `case: _` warning: unused variable: `case` - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:81:24 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:79:24 | LL | [Large::Suit { case }] => {} | ^^^^ help: try ignoring the field: `case: _` warning: unused variable: `case` - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:86:29 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:84:29 | LL | Tuple(Large::Suit { case }, ()) => {} | ^^^^ help: try ignoring the field: `case: _` -warning: variable does not need to be mutable - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:33:9 - | -LL | let mut mut_unused_var = 1; - | ----^^^^^^^^^^^^^^ - | | - | help: remove this `mut` - | - = note: `#[warn(unused_mut)]` implied by `#[warn(unused)]` - -warning: variable does not need to be mutable - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:37:10 - | -LL | let (mut var, unused_var) = (1, 2); - | ----^^^ - | | - | help: remove this `mut` - -warning: 16 warnings emitted +warning: 14 warnings emitted diff --git a/src/test/ui/lint/unused/issue-97074-unused-variable-suppress-unused-mut.rs b/src/test/ui/lint/unused/issue-97074-unused-variable-suppress-unused-mut.rs new file mode 100644 index 0000000000000..7779f42692143 --- /dev/null +++ b/src/test/ui/lint/unused/issue-97074-unused-variable-suppress-unused-mut.rs @@ -0,0 +1,6 @@ +#![deny(unused_variables)] + +fn main() { + let mut s = String::from("a"); + //~^ ERROR unused variable: `s` [unused_variables] +} diff --git a/src/test/ui/lint/unused/issue-97074-unused-variable-suppress-unused-mut.stderr b/src/test/ui/lint/unused/issue-97074-unused-variable-suppress-unused-mut.stderr new file mode 100644 index 0000000000000..004d3075a1e4d --- /dev/null +++ b/src/test/ui/lint/unused/issue-97074-unused-variable-suppress-unused-mut.stderr @@ -0,0 +1,14 @@ +error: unused variable: `s` + --> $DIR/issue-97074-unused-variable-suppress-unused-mut.rs:4:13 + | +LL | let mut s = String::from("a"); + | ^ help: if this is intentional, prefix it with an underscore: `_s` + | +note: the lint level is defined here + --> $DIR/issue-97074-unused-variable-suppress-unused-mut.rs:1:9 + | +LL | #![deny(unused_variables)] + | ^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/lint/unused/lint-unused-mut-variables.rs b/src/test/ui/lint/unused/lint-unused-mut-variables.rs index 67ec7facf1780..3e19104b7ff45 100644 --- a/src/test/ui/lint/unused/lint-unused-mut-variables.rs +++ b/src/test/ui/lint/unused/lint-unused-mut-variables.rs @@ -9,13 +9,18 @@ async fn baz_async( mut a: i32, //~^ WARN: variable does not need to be mutable #[allow(unused_mut)] mut b: i32, -) {} +) { + drop((a, b)); +} + fn baz( mut a: i32, //~^ WARN: variable does not need to be mutable #[allow(unused_mut)] mut b: i32, #[allow(unused_mut)] (mut c, d): (i32, i32) -) {} +) { + drop((a, b, c, d)); +} struct RefStruct {} impl RefStruct { @@ -23,14 +28,19 @@ impl RefStruct { mut a: i32, //~^ WARN: variable does not need to be mutable #[allow(unused_mut)] mut b: i32, - ) {} + ) { + drop((a, b)); + } + fn baz( &self, mut a: i32, //~^ WARN: variable does not need to be mutable #[allow(unused_mut)] mut b: i32, #[allow(unused_mut)] (mut c, d): (i32, i32) - ) {} + ) { + drop((a, b, c, d)); + } } trait RefTrait { @@ -40,8 +50,11 @@ trait RefTrait { //~^ WARN: variable does not need to be mutable #[allow(unused_mut)] mut b: i32, #[allow(unused_mut)] (mut c, d): (i32, i32) - ) {} + ) { + drop((a, b, c, d)); + } } + impl RefTrait for () { fn baz( &self, @@ -49,7 +62,9 @@ impl RefTrait for () { //~^ WARN: variable does not need to be mutable #[allow(unused_mut)] mut b: i32, #[allow(unused_mut)] (mut c, d): (i32, i32) - ) {} + ) { + drop((a, b, c, d)); + } } fn main() { @@ -57,57 +72,55 @@ fn main() { mut a: i32, //~^ WARN: variable does not need to be mutable #[allow(unused_mut)] mut b: i32, - | {}; + | { drop((a, b)); }; let _ = | mut a: i32, //~^ WARN: variable does not need to be mutable #[allow(unused_mut)] mut b: i32, #[allow(unused_mut)] (mut c, d): (i32, i32) - | {}; + | { drop((a, b, c, d)); }; // negative cases let mut a = 3; //~ WARN: variable does not need to be mutable - + drop(a); let mut a = 2; //~ WARN: variable does not need to be mutable - + drop(a); let mut b = 3; //~ WARN: variable does not need to be mutable - + drop(b); let mut a = vec![3]; //~ WARN: variable does not need to be mutable - + drop(a); let (mut a, b) = (1, 2); //~ WARN: variable does not need to be mutable - + drop((a, b)); let mut a; //~ WARN: variable does not need to be mutable - a = 3; - + drop(a); let mut b; //~ WARN: variable does not need to be mutable - if true { b = 3; } else { b = 4; } - + drop(b); match 30 { - mut x => {} //~ WARN: variable does not need to be mutable - + mut x => { drop(x); } //~ WARN: variable does not need to be mutable } match (30, 2) { // FIXME: Here's a false positive, // shouldn't be removed `mut` not to be bound with a different way. (mut x, 1) | //~ WARN: variable does not need to be mutable - (mut x, 2) | (mut x, 3) => { + drop(x); } _ => {} } let x = |mut y: isize| 10; //~ WARN: variable does not need to be mutable - fn what(mut foo: isize) {} //~ WARN: variable does not need to be mutable - + fn what(mut foo: isize) { //~ WARN: variable does not need to be mutable + drop(foo); + } let mut a = &mut 5; //~ WARN: variable does not need to be mutable @@ -203,5 +216,5 @@ fn bar() { #[allow(unused_mut)] let mut a = 3; let mut b = vec![2]; //~ ERROR: variable does not need to be mutable - + drop((a, b)); } diff --git a/src/test/ui/lint/unused/lint-unused-mut-variables.stderr b/src/test/ui/lint/unused/lint-unused-mut-variables.stderr index 805ed2b40bb7b..2a8b5a64c9f08 100644 --- a/src/test/ui/lint/unused/lint-unused-mut-variables.stderr +++ b/src/test/ui/lint/unused/lint-unused-mut-variables.stderr @@ -13,7 +13,7 @@ LL | #![warn(unused_mut)] | ^^^^^^^^^^ warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:23:9 + --> $DIR/lint-unused-mut-variables.rs:28:9 | LL | mut a: i32, | ----^ @@ -21,7 +21,7 @@ LL | mut a: i32, | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:14:5 + --> $DIR/lint-unused-mut-variables.rs:17:5 | LL | mut a: i32, | ----^ @@ -29,7 +29,7 @@ LL | mut a: i32, | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:29:9 + --> $DIR/lint-unused-mut-variables.rs:37:9 | LL | mut a: i32, | ----^ @@ -37,7 +37,7 @@ LL | mut a: i32, | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:39:9 + --> $DIR/lint-unused-mut-variables.rs:49:9 | LL | mut a: i32, | ----^ @@ -45,7 +45,7 @@ LL | mut a: i32, | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:48:9 + --> $DIR/lint-unused-mut-variables.rs:61:9 | LL | mut a: i32, | ----^ @@ -53,7 +53,7 @@ LL | mut a: i32, | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:57:9 + --> $DIR/lint-unused-mut-variables.rs:72:9 | LL | mut a: i32, | ----^ @@ -61,7 +61,7 @@ LL | mut a: i32, | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:62:9 + --> $DIR/lint-unused-mut-variables.rs:77:9 | LL | mut a: i32, | ----^ @@ -69,7 +69,7 @@ LL | mut a: i32, | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:107:14 + --> $DIR/lint-unused-mut-variables.rs:119:14 | LL | let x = |mut y: isize| 10; | ----^ @@ -77,7 +77,7 @@ LL | let x = |mut y: isize| 10; | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:69:9 + --> $DIR/lint-unused-mut-variables.rs:84:9 | LL | let mut a = 3; | ----^ @@ -85,7 +85,7 @@ LL | let mut a = 3; | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:71:9 + --> $DIR/lint-unused-mut-variables.rs:86:9 | LL | let mut a = 2; | ----^ @@ -93,7 +93,7 @@ LL | let mut a = 2; | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:73:9 + --> $DIR/lint-unused-mut-variables.rs:88:9 | LL | let mut b = 3; | ----^ @@ -101,7 +101,7 @@ LL | let mut b = 3; | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:75:9 + --> $DIR/lint-unused-mut-variables.rs:90:9 | LL | let mut a = vec![3]; | ----^ @@ -109,7 +109,7 @@ LL | let mut a = vec![3]; | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:77:10 + --> $DIR/lint-unused-mut-variables.rs:92:10 | LL | let (mut a, b) = (1, 2); | ----^ @@ -117,7 +117,7 @@ LL | let (mut a, b) = (1, 2); | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:79:9 + --> $DIR/lint-unused-mut-variables.rs:94:9 | LL | let mut a; | ----^ @@ -125,7 +125,7 @@ LL | let mut a; | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:83:9 + --> $DIR/lint-unused-mut-variables.rs:97:9 | LL | let mut b; | ----^ @@ -133,15 +133,15 @@ LL | let mut b; | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:92:9 + --> $DIR/lint-unused-mut-variables.rs:105:9 | -LL | mut x => {} +LL | mut x => { drop(x); } | ----^ | | | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:99:10 + --> $DIR/lint-unused-mut-variables.rs:111:10 | LL | (mut x, 1) | | ----^ @@ -149,7 +149,7 @@ LL | (mut x, 1) | | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:112:9 + --> $DIR/lint-unused-mut-variables.rs:125:9 | LL | let mut a = &mut 5; | ----^ @@ -157,7 +157,7 @@ LL | let mut a = &mut 5; | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:117:9 + --> $DIR/lint-unused-mut-variables.rs:130:9 | LL | let mut b = (&mut a,); | ----^ @@ -165,7 +165,7 @@ LL | let mut b = (&mut a,); | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:120:9 + --> $DIR/lint-unused-mut-variables.rs:133:9 | LL | let mut x = &mut 1; | ----^ @@ -173,7 +173,7 @@ LL | let mut x = &mut 1; | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:132:9 + --> $DIR/lint-unused-mut-variables.rs:145:9 | LL | let mut v : &mut Vec<()> = &mut vec![]; | ----^ @@ -181,7 +181,7 @@ LL | let mut v : &mut Vec<()> = &mut vec![]; | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:187:9 + --> $DIR/lint-unused-mut-variables.rs:200:9 | LL | let mut raw_address_of_const = 1; | ----^^^^^^^^^^^^^^^^^^^^ @@ -189,15 +189,15 @@ LL | let mut raw_address_of_const = 1; | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:109:13 + --> $DIR/lint-unused-mut-variables.rs:121:13 | -LL | fn what(mut foo: isize) {} +LL | fn what(mut foo: isize) { | ----^^^ | | | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:127:20 + --> $DIR/lint-unused-mut-variables.rs:140:20 | LL | fn mut_ref_arg(mut arg : &mut [u8]) -> &mut [u8] { | ----^^^ @@ -205,7 +205,7 @@ LL | fn mut_ref_arg(mut arg : &mut [u8]) -> &mut [u8] { | help: remove this `mut` error: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:205:9 + --> $DIR/lint-unused-mut-variables.rs:218:9 | LL | let mut b = vec![2]; | ----^ @@ -213,7 +213,7 @@ LL | let mut b = vec![2]; | help: remove this `mut` | note: the lint level is defined here - --> $DIR/lint-unused-mut-variables.rs:201:8 + --> $DIR/lint-unused-mut-variables.rs:214:8 | LL | #[deny(unused_mut)] | ^^^^^^^^^^