Rollup merge of #54787 - varkor:unused-mut-in-desugaring, r=nikomatsakis
Only warn about unused `mut` in user-written code Fixes https://github.com/rust-lang/rust/issues/54586. r? @pnkfelix cc @blitzerr
This commit is contained in:
commit
3810657ae3
@ -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,
|
||||
);
|
||||
@ -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 = {
|
||||
@ -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);
|
||||
|
@ -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,
|
||||
@ -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() {
|
||||
|
@ -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,
|
||||
|
@ -316,7 +316,10 @@ 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,
|
||||
@ -324,6 +327,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
|
||||
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`",
|
||||
|
@ -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,
|
||||
|
8
src/test/ui/mut/no-mut-lint-for-desugared-mut.rs
Normal file
8
src/test/ui/mut/no-mut-lint-for-desugared-mut.rs
Normal file
@ -0,0 +1,8 @@
|
||||
// run-pass
|
||||
|
||||
#![deny(unused_mut)]
|
||||
#![allow(unreachable_code)]
|
||||
|
||||
fn main() {
|
||||
for _ in { return (); 0..3 } {} // ok
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user