Don't lint range syntax with var name `start` and `end`

This commit is contained in:
Hidehito Yabuuchi 2018-03-05 14:31:37 +09:00
parent e5f2d62c46
commit 7b59557dcd
3 changed files with 54 additions and 6 deletions

View File

@ -1,6 +1,8 @@
use syntax::ast::Name;
use rustc::lint::*;
use rustc::hir::*;
use utils::{span_lint_and_sugg, match_var};
use utils::{match_qpath, match_var, span_lint_and_sugg};
use utils::paths;
/// **What it does:** Checks for fields in struct literals where shorthands
/// could be used.
@ -36,10 +38,14 @@ 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;
if is_range_struct_field(path, &name) {
continue;
}
if match_var(&field.expr, name) && !field.is_shorthand {
span_lint_and_sugg (
cx,
@ -54,3 +60,27 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RedundantFieldNames {
}
}
}
/// ```rust
/// let start = 0;
/// let _ = start..;
///
/// let end = 0;
/// let _ = ..end;
///
/// let _ = start..end;
/// ```
fn is_range_struct_field(path: &QPath, name: &Name) -> bool {
match name.as_str().as_ref() {
"start" => {
match_qpath(path, &paths::RANGE_STD) || match_qpath(path, &paths::RANGE_FROM_STD)
|| match_qpath(path, &paths::RANGE_INCLUSIVE_STD)
},
"end" => {
match_qpath(path, &paths::RANGE_STD) || match_qpath(path, &paths::RANGE_TO_STD)
|| match_qpath(path, &paths::RANGE_INCLUSIVE_STD)
|| match_qpath(path, &paths::RANGE_TO_INCLUSIVE_STD)
},
_ => false,
}
}

View File

@ -1,5 +1,6 @@
#![warn(redundant_field_names)]
#![allow(unused_variables)]
#![feature(inclusive_range,inclusive_range_syntax)]
mod foo {
pub const BAR: u8 = 0;
@ -27,4 +28,21 @@ fn main() {
buzz: fizz, //should be ok
foo: foo::BAR, //should be ok
};
// Range syntax
let (start, end) = (0, 0);
let _ = start..;
let _ = ..end;
let _ = start..end;
let _ = ..=end;
let _ = start..=end;
// TODO: the followings shoule be linted
let _ = ::std::ops::RangeFrom { start: start };
let _ = ::std::ops::RangeTo { end: end };
let _ = ::std::ops::Range { start: start, end: end };
let _ = ::std::ops::RangeInclusive { start: start, end: end };
let _ = ::std::ops::RangeToInclusive { end: end };
}

View File

@ -1,15 +1,15 @@
error: redundant field names in struct initialization
--> $DIR/redundant_field_names.rs:23:9
--> $DIR/redundant_field_names.rs:24:9
|
23 | gender: gender,
24 | 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:25:9
|
24 | age: age,
25 | age: age,
| ^^^^^^^^ help: replace it with: `age`
error: aborting due to 2 previous errors