Skip to content

Commit

Permalink
Rollup merge of rust-lang#54787 - varkor:unused-mut-in-desugaring, r=…
Browse files Browse the repository at this point in the history
…nikomatsakis

Only warn about unused `mut` in user-written code

Fixes rust-lang#54586.

r? @pnkfelix
cc @blitzerr
  • Loading branch information
pietroalbini committed Oct 5, 2018
2 parents 9e8f522 + ea3d8f5 commit 3810657
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 17 deletions.
25 changes: 16 additions & 9 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4132,16 +4132,16 @@ impl<'a> LoweringContext<'a> {
// expand <head>
let head = self.lower_expr(head);
let head_sp = head.span;
let desugared_span = self.allow_internal_unstable(
CompilerDesugaringKind::ForLoop,
head_sp,
);

let iter = self.str_to_ident("iter");

let next_ident = self.str_to_ident("__next");
let next_sp = self.allow_internal_unstable(
CompilerDesugaringKind::ForLoop,
head_sp,
);
let next_pat = self.pat_ident_binding_mode(
next_sp,
desugared_span,
next_ident,
hir::BindingAnnotation::Mutable,
);
Expand Down Expand Up @@ -4170,8 +4170,11 @@ impl<'a> LoweringContext<'a> {
};

// `mut iter`
let iter_pat =
self.pat_ident_binding_mode(head_sp, iter, hir::BindingAnnotation::Mutable);
let iter_pat = self.pat_ident_binding_mode(
desugared_span,
iter,
hir::BindingAnnotation::Mutable
);

// `match ::std::iter::Iterator::next(&mut iter) { ... }`
let match_expr = {
Expand Down Expand Up @@ -4200,8 +4203,12 @@ impl<'a> LoweringContext<'a> {
let next_expr = P(self.expr_ident(head_sp, next_ident, next_pat.id));

// `let mut __next`
let next_let =
self.stmt_let_pat(head_sp, None, next_pat, hir::LocalSource::ForLoopDesugar);
let next_let = self.stmt_let_pat(
desugared_span,
None,
next_pat,
hir::LocalSource::ForLoopDesugar,
);

// `let <pat> = __next`
let pat = self.lower_pat(pat);
Expand Down
22 changes: 17 additions & 5 deletions src/librustc/traits/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ use ty::subst::Subst;
use ty::SubtypePredicate;
use util::nodemap::{FxHashMap, FxHashSet};

use syntax_pos::{DUMMY_SP, Span};
use syntax_pos::{DUMMY_SP, Span, ExpnInfo, ExpnFormat};

impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
pub fn report_fulfillment_errors(&self,
Expand All @@ -68,18 +68,30 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
}).collect();

for (index, error) in errors.iter().enumerate() {
error_map.entry(error.obligation.cause.span).or_default().push(
// We want to ignore desugarings here: spans are equivalent even
// if one is the result of a desugaring and the other is not.
let mut span = error.obligation.cause.span;
if let Some(ExpnInfo {
format: ExpnFormat::CompilerDesugaring(_),
def_site: Some(def_span),
..
}) = span.ctxt().outer().expn_info() {
span = def_span;
}

error_map.entry(span).or_default().push(
ErrorDescriptor {
predicate: error.obligation.predicate.clone(),
index: Some(index)
});
}
);

self.reported_trait_errors.borrow_mut()
.entry(error.obligation.cause.span).or_default()
.entry(span).or_default()
.push(error.obligation.predicate.clone());
}

// We do this in 2 passes because we want to display errors in order, tho
// We do this in 2 passes because we want to display errors in order, though
// maybe it *is* better to sort errors by span or something.
let mut is_suppressed = vec![false; errors.len()];
for (_, error_set) in error_map.iter() {
Expand Down
6 changes: 5 additions & 1 deletion src/librustc_borrowck/borrowck/unused.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,14 @@ impl<'a, 'tcx> UnusedMutCx<'a, 'tcx> {
}

let (hir_id, span) = ids[0];
let mut_span = tcx.sess.source_map().span_until_non_whitespace(span);
if span.compiler_desugaring_kind().is_some() {
// If the `mut` arises as part of a desugaring, we should ignore it.
continue;
}

// Ok, every name wasn't used mutably, so issue a warning that this
// didn't need to be mutable.
let mut_span = tcx.sess.source_map().span_until_non_whitespace(span);
tcx.struct_span_lint_hir(UNUSED_MUT,
hir_id,
span,
Expand Down
6 changes: 5 additions & 1 deletion src/librustc_mir/borrow_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,14 +316,18 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
}

let span = local_decl.source_info.span;
let mut_span = tcx.sess.source_map().span_until_non_whitespace(span);
if span.compiler_desugaring_kind().is_some() {
// If the `mut` arises as part of a desugaring, we should ignore it.
continue;
}

let mut err = tcx.struct_span_lint_node(
UNUSED_MUT,
vsi[local_decl.source_info.scope].lint_root,
span,
"variable does not need to be mutable",
);
let mut_span = tcx.sess.source_map().span_until_non_whitespace(span);
err.span_suggestion_short_with_applicability(
mut_span,
"remove this `mut`",
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_mir/shim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@ enum CallKind {
fn temp_decl(mutability: Mutability, ty: Ty, span: Span) -> LocalDecl {
let source_info = SourceInfo { scope: OUTERMOST_SOURCE_SCOPE, span };
LocalDecl {
mutability, ty,
mutability,
ty,
user_ty: None,
name: None,
source_info,
Expand Down
8 changes: 8 additions & 0 deletions src/test/ui/mut/no-mut-lint-for-desugared-mut.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// run-pass

#![deny(unused_mut)]
#![allow(unreachable_code)]

fn main() {
for _ in { return (); 0..3 } {} // ok
}

0 comments on commit 3810657

Please sign in to comment.