Merge pull request #2507 from ordovicia/redundant_field_names_range

Don't lint range syntax with var name `start` and/or `end`
This commit is contained in:
Oliver Schneider 2018-03-05 09:41:00 +01:00 committed by GitHub
commit 05f92b84c9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 86 additions and 7 deletions

View file

@ -1,6 +1,6 @@
use rustc::lint::*;
use rustc::hir::*;
use utils::{span_lint_and_sugg, match_var};
use utils::{is_range_expression, match_var, span_lint_and_sugg};
/// **What it does:** Checks for fields in struct literals where shorthands
/// could be used.
@ -36,10 +36,17 @@ impl LintPass for RedundantFieldNames {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RedundantFieldNames {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
if let ExprStruct(_, ref fields, _) = expr.node {
if let ExprStruct(ref path, ref fields, _) = expr.node {
for field in fields {
let name = field.name.node;
// Do not care about range expressions.
// They could have redundant field name when desugared to structs.
// e.g. `start..end` is desugared to `Range { start: start, end: end }`
if is_range_expression(expr.span) {
continue;
}
if match_var(&field.expr, name) && !field.is_shorthand {
span_lint_and_sugg (
cx,

View file

@ -64,6 +64,16 @@ pub fn in_macro(span: Span) -> bool {
})
}
/// Returns true if `expn_info` was expanded by range expressions.
pub fn is_range_expression(span: Span) -> bool {
span.ctxt().outer().expn_info().map_or(false, |info| {
match info.callee.format {
ExpnFormat::CompilerDesugaring(CompilerDesugaringKind::DotFill) => true,
_ => false,
}
})
}
/// Returns true if the macro that expanded the crate was outside of the
/// current crate or was a
/// compiler plugin.

View file

@ -1,5 +1,8 @@
#![warn(redundant_field_names)]
#![allow(unused_variables)]
#![feature(inclusive_range, inclusive_range_syntax)]
use std::ops::{Range, RangeFrom, RangeTo, RangeInclusive, RangeToInclusive};
mod foo {
pub const BAR: u8 = 0;
@ -27,4 +30,21 @@ fn main() {
buzz: fizz, //should be ok
foo: foo::BAR, //should be ok
};
// Range expressions
let (start, end) = (0, 0);
let _ = start..;
let _ = ..end;
let _ = start..end;
let _ = ..=end;
let _ = start..=end;
// hand-written Range family structs are linted
let _ = RangeFrom { start: start };
let _ = RangeTo { end: end };
let _ = Range { start: start, end: end };
let _ = RangeInclusive { start: start, end: end };
let _ = RangeToInclusive { end: end };
}

View file

@ -1,16 +1,58 @@
error: redundant field names in struct initialization
--> $DIR/redundant_field_names.rs:23:9
--> $DIR/redundant_field_names.rs:26:9
|
23 | gender: gender,
26 | gender: gender,
| ^^^^^^^^^^^^^^ help: replace it with: `gender`
|
= note: `-D redundant-field-names` implied by `-D warnings`
error: redundant field names in struct initialization
--> $DIR/redundant_field_names.rs:24:9
--> $DIR/redundant_field_names.rs:27:9
|
24 | age: age,
27 | age: age,
| ^^^^^^^^ help: replace it with: `age`
error: aborting due to 2 previous errors
error: redundant field names in struct initialization
--> $DIR/redundant_field_names.rs:45:25
|
45 | let _ = RangeFrom { start: start };
| ^^^^^^^^^^^^ help: replace it with: `start`
error: redundant field names in struct initialization
--> $DIR/redundant_field_names.rs:46:23
|
46 | let _ = RangeTo { end: end };
| ^^^^^^^^ help: replace it with: `end`
error: redundant field names in struct initialization
--> $DIR/redundant_field_names.rs:47:21
|
47 | let _ = Range { start: start, end: end };
| ^^^^^^^^^^^^ help: replace it with: `start`
error: redundant field names in struct initialization
--> $DIR/redundant_field_names.rs:47:35
|
47 | let _ = Range { start: start, end: end };
| ^^^^^^^^ help: replace it with: `end`
error: redundant field names in struct initialization
--> $DIR/redundant_field_names.rs:48:30
|
48 | let _ = RangeInclusive { start: start, end: end };
| ^^^^^^^^^^^^ help: replace it with: `start`
error: redundant field names in struct initialization
--> $DIR/redundant_field_names.rs:48:44
|
48 | let _ = RangeInclusive { start: start, end: end };
| ^^^^^^^^ help: replace it with: `end`
error: redundant field names in struct initialization
--> $DIR/redundant_field_names.rs:49:32
|
49 | let _ = RangeToInclusive { end: end };
| ^^^^^^^^ help: replace it with: `end`
error: aborting due to 9 previous errors