mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-04 19:29:07 +00:00
Rustup to *rustc 1.15.0-nightly (7b3eeea22
2016-11-21)*
This commit is contained in:
parent
530083c3b9
commit
c35f82b823
@ -2,6 +2,7 @@ use rustc::lint::*;
|
|||||||
use rustc::hir::*;
|
use rustc::hir::*;
|
||||||
use std::f64::consts as f64;
|
use std::f64::consts as f64;
|
||||||
use syntax::ast::{Lit, LitKind, FloatTy};
|
use syntax::ast::{Lit, LitKind, FloatTy};
|
||||||
|
use syntax::symbol;
|
||||||
use utils::span_lint;
|
use utils::span_lint;
|
||||||
|
|
||||||
/// **What it does:** Checks for floating point literals that approximate
|
/// **What it does:** Checks for floating point literals that approximate
|
||||||
@ -75,7 +76,8 @@ fn check_lit(cx: &LateContext, lit: &Lit, e: &Expr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_known_consts(cx: &LateContext, e: &Expr, s: &str, module: &str) {
|
fn check_known_consts(cx: &LateContext, e: &Expr, s: &symbol::Symbol, module: &str) {
|
||||||
|
let s = &*s.as_str();
|
||||||
if s.parse::<f64>().is_ok() {
|
if s.parse::<f64>().is_ok() {
|
||||||
for &(constant, name, min_digits) in KNOWN_CONSTS {
|
for &(constant, name, min_digits) in KNOWN_CONSTS {
|
||||||
if is_approx_const(constant, s, min_digits) {
|
if is_approx_const(constant, s, min_digits) {
|
||||||
|
@ -83,15 +83,15 @@ impl LintPass for AttrPass {
|
|||||||
|
|
||||||
impl LateLintPass for AttrPass {
|
impl LateLintPass for AttrPass {
|
||||||
fn check_attribute(&mut self, cx: &LateContext, attr: &Attribute) {
|
fn check_attribute(&mut self, cx: &LateContext, attr: &Attribute) {
|
||||||
if let MetaItemKind::List(ref name, ref items) = attr.node.value.node {
|
if let MetaItemKind::List(ref items) = attr.value.node {
|
||||||
if items.is_empty() || name != &"deprecated" {
|
if items.is_empty() || attr.name() != "deprecated" {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for item in items {
|
for item in items {
|
||||||
if_let_chain! {[
|
if_let_chain! {[
|
||||||
let NestedMetaItemKind::MetaItem(ref mi) = item.node,
|
let NestedMetaItemKind::MetaItem(ref mi) = item.node,
|
||||||
let MetaItemKind::NameValue(ref name, ref lit) = mi.node,
|
let MetaItemKind::NameValue(ref lit) = mi.node,
|
||||||
name == &"since",
|
mi.name() == "since",
|
||||||
], {
|
], {
|
||||||
check_semver(cx, item.span, lit);
|
check_semver(cx, item.span, lit);
|
||||||
}}
|
}}
|
||||||
@ -107,8 +107,8 @@ impl LateLintPass for AttrPass {
|
|||||||
ItemExternCrate(_) |
|
ItemExternCrate(_) |
|
||||||
ItemUse(_) => {
|
ItemUse(_) => {
|
||||||
for attr in &item.attrs {
|
for attr in &item.attrs {
|
||||||
if let MetaItemKind::List(ref name, ref lint_list) = attr.node.value.node {
|
if let MetaItemKind::List(ref lint_list) = attr.value.node {
|
||||||
match &**name {
|
match &*attr.name().as_str() {
|
||||||
"allow" | "warn" | "deny" | "forbid" => {
|
"allow" | "warn" | "deny" | "forbid" => {
|
||||||
// whitelist `unused_imports`
|
// whitelist `unused_imports`
|
||||||
for lint in lint_list {
|
for lint in lint_list {
|
||||||
@ -210,8 +210,8 @@ fn check_attrs(cx: &LateContext, span: Span, name: &Name, attrs: &[Attribute]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for attr in attrs {
|
for attr in attrs {
|
||||||
if let MetaItemKind::List(ref inline, ref values) = attr.node.value.node {
|
if let MetaItemKind::List(ref values) = attr.value.node {
|
||||||
if values.len() != 1 || inline != &"inline" {
|
if values.len() != 1 || attr.name() != "inline" {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if is_word(&values[0], "always") {
|
if is_word(&values[0], "always") {
|
||||||
@ -227,7 +227,7 @@ fn check_attrs(cx: &LateContext, span: Span, name: &Name, attrs: &[Attribute]) {
|
|||||||
|
|
||||||
fn check_semver(cx: &LateContext, span: Span, lit: &Lit) {
|
fn check_semver(cx: &LateContext, span: Span, lit: &Lit) {
|
||||||
if let LitKind::Str(ref is, _) = lit.node {
|
if let LitKind::Str(ref is, _) = lit.node {
|
||||||
if Version::parse(&*is).is_ok() {
|
if Version::parse(&*is.as_str()).is_ok() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -239,10 +239,8 @@ fn check_semver(cx: &LateContext, span: Span, lit: &Lit) {
|
|||||||
|
|
||||||
fn is_word(nmi: &NestedMetaItem, expected: &str) -> bool {
|
fn is_word(nmi: &NestedMetaItem, expected: &str) -> bool {
|
||||||
if let NestedMetaItemKind::MetaItem(ref mi) = nmi.node {
|
if let NestedMetaItemKind::MetaItem(ref mi) = nmi.node {
|
||||||
if let MetaItemKind::Word(ref word) = mi.node {
|
mi.is_word() && mi.name() == expected
|
||||||
return word == expected;
|
} else {
|
||||||
}
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
false
|
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ use rustc::ty;
|
|||||||
use rustc::hir::*;
|
use rustc::hir::*;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::collections::hash_map::Entry;
|
use std::collections::hash_map::Entry;
|
||||||
use syntax::parse::token::InternedString;
|
use syntax::symbol::InternedString;
|
||||||
use syntax::util::small_vector::SmallVector;
|
use syntax::util::small_vector::SmallVector;
|
||||||
use utils::{SpanlessEq, SpanlessHash};
|
use utils::{SpanlessEq, SpanlessHash};
|
||||||
use utils::{get_parent_expr, in_macro, span_lint_and_then, span_note_and_lint, snippet};
|
use utils::{get_parent_expr, in_macro, span_lint_and_then, span_note_and_lint, snippet};
|
||||||
|
@ -59,13 +59,13 @@ impl EarlyLintPass for Doc {
|
|||||||
/// `syntax::parse::lexer::comments::strip_doc_comment_decoration` because we need to keep track of
|
/// `syntax::parse::lexer::comments::strip_doc_comment_decoration` because we need to keep track of
|
||||||
/// the span but this function is inspired from the later.
|
/// the span but this function is inspired from the later.
|
||||||
#[allow(cast_possible_truncation)]
|
#[allow(cast_possible_truncation)]
|
||||||
pub fn strip_doc_comment_decoration((comment, span): (&str, Span)) -> Vec<(&str, Span)> {
|
pub fn strip_doc_comment_decoration((comment, span): (String, Span)) -> Vec<(String, Span)> {
|
||||||
// one-line comments lose their prefix
|
// one-line comments lose their prefix
|
||||||
const ONELINERS: &'static [&'static str] = &["///!", "///", "//!", "//"];
|
const ONELINERS: &'static [&'static str] = &["///!", "///", "//!", "//"];
|
||||||
for prefix in ONELINERS {
|
for prefix in ONELINERS {
|
||||||
if comment.starts_with(*prefix) {
|
if comment.starts_with(*prefix) {
|
||||||
return vec![(
|
return vec![(
|
||||||
&comment[prefix.len()..],
|
comment[prefix.len()..].to_owned(),
|
||||||
Span { lo: span.lo + BytePos(prefix.len() as u32), ..span }
|
Span { lo: span.lo + BytePos(prefix.len() as u32), ..span }
|
||||||
)];
|
)];
|
||||||
}
|
}
|
||||||
@ -77,7 +77,7 @@ pub fn strip_doc_comment_decoration((comment, span): (&str, Span)) -> Vec<(&str,
|
|||||||
debug_assert_eq!(offset as u32 as usize, offset);
|
debug_assert_eq!(offset as u32 as usize, offset);
|
||||||
|
|
||||||
(
|
(
|
||||||
line,
|
line.to_owned(),
|
||||||
Span {
|
Span {
|
||||||
lo: span.lo + BytePos(offset as u32),
|
lo: span.lo + BytePos(offset as u32),
|
||||||
..span
|
..span
|
||||||
@ -93,9 +93,10 @@ pub fn check_attrs<'a>(cx: &EarlyContext, valid_idents: &[String], attrs: &'a [a
|
|||||||
let mut docs = vec![];
|
let mut docs = vec![];
|
||||||
|
|
||||||
for attr in attrs {
|
for attr in attrs {
|
||||||
if attr.node.is_sugared_doc {
|
if attr.is_sugared_doc {
|
||||||
if let ast::MetaItemKind::NameValue(_, ref doc) = attr.node.value.node {
|
if let ast::MetaItemKind::NameValue(ref doc) = attr.value.node {
|
||||||
if let ast::LitKind::Str(ref doc, _) = doc.node {
|
if let ast::LitKind::Str(ref doc, _) = doc.node {
|
||||||
|
let doc = (*doc.as_str()).to_owned();
|
||||||
docs.extend_from_slice(&strip_doc_comment_decoration((doc, attr.span)));
|
docs.extend_from_slice(&strip_doc_comment_decoration((doc, attr.span)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -108,7 +109,7 @@ pub fn check_attrs<'a>(cx: &EarlyContext, valid_idents: &[String], attrs: &'a [a
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(while_let_loop)] // #362
|
#[allow(while_let_loop)] // #362
|
||||||
fn check_doc(cx: &EarlyContext, valid_idents: &[String], docs: &[(&str, Span)]) -> Result<(), ()> {
|
fn check_doc(cx: &EarlyContext, valid_idents: &[String], docs: &[(String, Span)]) -> Result<(), ()> {
|
||||||
// In markdown, `_` can be used to emphasize something, or, is a raw `_` depending on context.
|
// In markdown, `_` can be used to emphasize something, or, is a raw `_` depending on context.
|
||||||
// There really is no markdown specification that would disambiguate this properly. This is
|
// There really is no markdown specification that would disambiguate this properly. This is
|
||||||
// what GitHub and Rustdoc do:
|
// what GitHub and Rustdoc do:
|
||||||
@ -136,7 +137,7 @@ fn check_doc(cx: &EarlyContext, valid_idents: &[String], docs: &[(&str, Span)])
|
|||||||
/// First byte of the current potential match
|
/// First byte of the current potential match
|
||||||
current_word_begin: usize,
|
current_word_begin: usize,
|
||||||
/// List of lines and their associated span
|
/// List of lines and their associated span
|
||||||
docs: &'a [(&'a str, Span)],
|
docs: &'a [(String, Span)],
|
||||||
/// Index of the current line we are parsing
|
/// Index of the current line we are parsing
|
||||||
line: usize,
|
line: usize,
|
||||||
/// Whether we are in a link
|
/// Whether we are in a link
|
||||||
@ -155,7 +156,8 @@ fn check_doc(cx: &EarlyContext, valid_idents: &[String], docs: &[(&str, Span)])
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn line(&self) -> (&'a str, Span) {
|
fn line(&self) -> (&'a str, Span) {
|
||||||
self.docs[self.line]
|
let (ref doc, span) = self.docs[self.line];
|
||||||
|
(doc, span)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn peek(&self) -> Option<char> {
|
fn peek(&self) -> Option<char> {
|
||||||
|
@ -82,7 +82,7 @@ fn check_cond<'a, 'tcx, 'b>(cx: &'a LateContext<'a, 'tcx>, check: &'b Expr) -> O
|
|||||||
if_let_chain! {[
|
if_let_chain! {[
|
||||||
let ExprMethodCall(ref name, _, ref params) = check.node,
|
let ExprMethodCall(ref name, _, ref params) = check.node,
|
||||||
params.len() >= 2,
|
params.len() >= 2,
|
||||||
name.node.as_str() == "contains_key",
|
&*name.node.as_str() == "contains_key",
|
||||||
let ExprAddrOf(_, ref key) = params[1].node
|
let ExprAddrOf(_, ref key) = params[1].node
|
||||||
], {
|
], {
|
||||||
let map = ¶ms[0];
|
let map = ¶ms[0];
|
||||||
@ -116,7 +116,7 @@ impl<'a, 'tcx, 'v, 'b> Visitor<'v> for InsertVisitor<'a, 'tcx, 'b> {
|
|||||||
if_let_chain! {[
|
if_let_chain! {[
|
||||||
let ExprMethodCall(ref name, _, ref params) = expr.node,
|
let ExprMethodCall(ref name, _, ref params) = expr.node,
|
||||||
params.len() == 3,
|
params.len() == 3,
|
||||||
name.node.as_str() == "insert",
|
&*name.node.as_str() == "insert",
|
||||||
get_item_name(self.cx, self.map) == get_item_name(self.cx, &*params[0]),
|
get_item_name(self.cx, self.map) == get_item_name(self.cx, &*params[0]),
|
||||||
SpanlessEq::new(self.cx).eq_expr(self.key, ¶ms[1])
|
SpanlessEq::new(self.cx).eq_expr(self.key, ¶ms[1])
|
||||||
], {
|
], {
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use rustc::lint::*;
|
use rustc::lint::*;
|
||||||
use syntax::ast::*;
|
use syntax::ast::*;
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use syntax::parse::token::InternedString;
|
use syntax::symbol::InternedString;
|
||||||
use utils::{span_help_and_lint, span_lint};
|
use utils::{span_help_and_lint, span_lint};
|
||||||
use utils::{camel_case_from, camel_case_until, in_macro};
|
use utils::{camel_case_from, camel_case_until, in_macro};
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ use rustc::hir::map::Node::NodeItem;
|
|||||||
use rustc::lint::*;
|
use rustc::lint::*;
|
||||||
use rustc::ty::TypeVariants;
|
use rustc::ty::TypeVariants;
|
||||||
use syntax::ast::LitKind;
|
use syntax::ast::LitKind;
|
||||||
|
use syntax::symbol::InternedString;
|
||||||
use utils::paths;
|
use utils::paths;
|
||||||
use utils::{is_expn_of, match_def_path, match_type, resolve_node, span_lint, walk_ptrs_ty};
|
use utils::{is_expn_of, match_def_path, match_type, resolve_node, span_lint, walk_ptrs_ty};
|
||||||
|
|
||||||
@ -73,14 +74,14 @@ impl LateLintPass for Pass {
|
|||||||
/// Returns the slice of format string parts in an `Arguments::new_v1` call.
|
/// Returns the slice of format string parts in an `Arguments::new_v1` call.
|
||||||
/// Public because it's shared with a lint in print.rs.
|
/// Public because it's shared with a lint in print.rs.
|
||||||
pub fn get_argument_fmtstr_parts<'a, 'b>(cx: &LateContext<'a, 'b>, expr: &'a Expr)
|
pub fn get_argument_fmtstr_parts<'a, 'b>(cx: &LateContext<'a, 'b>, expr: &'a Expr)
|
||||||
-> Option<Vec<&'a str>> {
|
-> Option<Vec<InternedString>> {
|
||||||
if_let_chain! {[
|
if_let_chain! {[
|
||||||
let ExprBlock(ref block) = expr.node,
|
let ExprBlock(ref block) = expr.node,
|
||||||
block.stmts.len() == 1,
|
block.stmts.len() == 1,
|
||||||
let StmtDecl(ref decl, _) = block.stmts[0].node,
|
let StmtDecl(ref decl, _) = block.stmts[0].node,
|
||||||
let DeclItem(ref decl) = decl.node,
|
let DeclItem(ref decl) = decl.node,
|
||||||
let Some(NodeItem(decl)) = cx.tcx.map.find(decl.id),
|
let Some(NodeItem(decl)) = cx.tcx.map.find(decl.id),
|
||||||
decl.name.as_str() == "__STATIC_FMTSTR",
|
&*decl.name.as_str() == "__STATIC_FMTSTR",
|
||||||
let ItemStatic(_, _, ref expr) = decl.node,
|
let ItemStatic(_, _, ref expr) = decl.node,
|
||||||
let ExprAddrOf(_, ref expr) = expr.node, // &["…", "…", …]
|
let ExprAddrOf(_, ref expr) = expr.node, // &["…", "…", …]
|
||||||
let ExprArray(ref exprs) = expr.node,
|
let ExprArray(ref exprs) = expr.node,
|
||||||
@ -89,7 +90,7 @@ pub fn get_argument_fmtstr_parts<'a, 'b>(cx: &LateContext<'a, 'b>, expr: &'a Exp
|
|||||||
for expr in exprs {
|
for expr in exprs {
|
||||||
if let ExprLit(ref lit) = expr.node {
|
if let ExprLit(ref lit) = expr.node {
|
||||||
if let LitKind::Str(ref lit, _) = lit.node {
|
if let LitKind::Str(ref lit, _) = lit.node {
|
||||||
result.push(&**lit);
|
result.push(lit.as_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ impl LateLintPass for LenZero {
|
|||||||
|
|
||||||
fn check_trait_items(cx: &LateContext, item: &Item, trait_items: &[TraitItem]) {
|
fn check_trait_items(cx: &LateContext, item: &Item, trait_items: &[TraitItem]) {
|
||||||
fn is_named_self(item: &TraitItem, name: &str) -> bool {
|
fn is_named_self(item: &TraitItem, name: &str) -> bool {
|
||||||
item.name.as_str() == name &&
|
&*item.name.as_str() == name &&
|
||||||
if let MethodTraitItem(ref sig, _) = item.node {
|
if let MethodTraitItem(ref sig, _) = item.node {
|
||||||
if sig.decl.has_self() {
|
if sig.decl.has_self() {
|
||||||
sig.decl.inputs.len() == 1
|
sig.decl.inputs.len() == 1
|
||||||
@ -117,7 +117,7 @@ fn check_trait_items(cx: &LateContext, item: &Item, trait_items: &[TraitItem]) {
|
|||||||
|
|
||||||
fn check_impl_items(cx: &LateContext, item: &Item, impl_items: &[ImplItemRef]) {
|
fn check_impl_items(cx: &LateContext, item: &Item, impl_items: &[ImplItemRef]) {
|
||||||
fn is_named_self(cx: &LateContext, item: &ImplItemRef, name: &str) -> bool {
|
fn is_named_self(cx: &LateContext, item: &ImplItemRef, name: &str) -> bool {
|
||||||
item.name.as_str() == name &&
|
&*item.name.as_str() == name &&
|
||||||
if let AssociatedItemKind::Method { has_self } = item.kind {
|
if let AssociatedItemKind::Method { has_self } = item.kind {
|
||||||
has_self && {
|
has_self && {
|
||||||
let did = cx.tcx.map.local_def_id(item.id.node_id);
|
let did = cx.tcx.map.local_def_id(item.id.node_id);
|
||||||
@ -157,7 +157,7 @@ fn check_impl_items(cx: &LateContext, item: &Item, impl_items: &[ImplItemRef]) {
|
|||||||
fn check_cmp(cx: &LateContext, span: Span, left: &Expr, right: &Expr, op: &str) {
|
fn check_cmp(cx: &LateContext, span: Span, left: &Expr, right: &Expr, op: &str) {
|
||||||
// check if we are in an is_empty() method
|
// check if we are in an is_empty() method
|
||||||
if let Some(name) = get_item_name(cx, left) {
|
if let Some(name) = get_item_name(cx, left) {
|
||||||
if name.as_str() == "is_empty" {
|
if &*name.as_str() == "is_empty" {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -172,7 +172,7 @@ fn check_cmp(cx: &LateContext, span: Span, left: &Expr, right: &Expr, op: &str)
|
|||||||
|
|
||||||
fn check_len_zero(cx: &LateContext, span: Span, name: &Name, args: &[P<Expr>], lit: &Lit, op: &str) {
|
fn check_len_zero(cx: &LateContext, span: Span, name: &Name, args: &[P<Expr>], lit: &Lit, op: &str) {
|
||||||
if let Spanned { node: LitKind::Int(0, _), .. } = *lit {
|
if let Spanned { node: LitKind::Int(0, _), .. } = *lit {
|
||||||
if name.as_str() == "len" && args.len() == 1 && has_is_empty(cx, &args[0]) {
|
if &*name.as_str() == "len" && args.len() == 1 && has_is_empty(cx, &args[0]) {
|
||||||
span_lint_and_then(cx, LEN_ZERO, span, "length comparison to zero", |db| {
|
span_lint_and_then(cx, LEN_ZERO, span, "length comparison to zero", |db| {
|
||||||
db.span_suggestion(span,
|
db.span_suggestion(span,
|
||||||
"consider using `is_empty`",
|
"consider using `is_empty`",
|
||||||
@ -187,7 +187,7 @@ fn has_is_empty(cx: &LateContext, expr: &Expr) -> bool {
|
|||||||
/// Get an `AssociatedItem` and return true if it matches `is_empty(self)`.
|
/// Get an `AssociatedItem` and return true if it matches `is_empty(self)`.
|
||||||
fn is_is_empty(cx: &LateContext, item: &ty::AssociatedItem) -> bool {
|
fn is_is_empty(cx: &LateContext, item: &ty::AssociatedItem) -> bool {
|
||||||
if let ty::AssociatedKind::Method = item.kind {
|
if let ty::AssociatedKind::Method = item.kind {
|
||||||
if item.name.as_str() == "is_empty" {
|
if &*item.name.as_str() == "is_empty" {
|
||||||
let ty = cx.tcx.item_type(item.def_id).fn_sig().skip_binder();
|
let ty = cx.tcx.item_type(item.def_id).fn_sig().skip_binder();
|
||||||
ty.inputs.len() == 1
|
ty.inputs.len() == 1
|
||||||
} else {
|
} else {
|
||||||
|
@ -196,7 +196,7 @@ fn allowed_lts_from(named_lts: &[LifetimeDef]) -> HashSet<RefLt> {
|
|||||||
|
|
||||||
fn lts_from_bounds<'a, T: Iterator<Item = &'a Lifetime>>(mut vec: Vec<RefLt>, bounds_lts: T) -> Vec<RefLt> {
|
fn lts_from_bounds<'a, T: Iterator<Item = &'a Lifetime>>(mut vec: Vec<RefLt>, bounds_lts: T) -> Vec<RefLt> {
|
||||||
for lt in bounds_lts {
|
for lt in bounds_lts {
|
||||||
if lt.name.as_str() != "'static" {
|
if &*lt.name.as_str() != "'static" {
|
||||||
vec.push(RefLt::Named(lt.name));
|
vec.push(RefLt::Named(lt.name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -225,7 +225,7 @@ impl<'v, 't> RefVisitor<'v, 't> {
|
|||||||
|
|
||||||
fn record(&mut self, lifetime: &Option<Lifetime>) {
|
fn record(&mut self, lifetime: &Option<Lifetime>) {
|
||||||
if let Some(ref lt) = *lifetime {
|
if let Some(ref lt) = *lifetime {
|
||||||
if lt.name.as_str() == "'static" {
|
if &*lt.name.as_str() == "'static" {
|
||||||
self.lts.push(RefLt::Static);
|
self.lts.push(RefLt::Static);
|
||||||
} else {
|
} else {
|
||||||
self.lts.push(RefLt::Named(lt.name));
|
self.lts.push(RefLt::Named(lt.name));
|
||||||
|
@ -370,9 +370,9 @@ impl LateLintPass for Pass {
|
|||||||
&ExprMethodCall(method_name, _, ref method_args)) = (pat, &match_expr.node) {
|
&ExprMethodCall(method_name, _, ref method_args)) = (pat, &match_expr.node) {
|
||||||
let iter_expr = &method_args[0];
|
let iter_expr = &method_args[0];
|
||||||
if let Some(lhs_constructor) = path.segments.last() {
|
if let Some(lhs_constructor) = path.segments.last() {
|
||||||
if method_name.node.as_str() == "next" &&
|
if &*method_name.node.as_str() == "next" &&
|
||||||
match_trait_method(cx, match_expr, &paths::ITERATOR) &&
|
match_trait_method(cx, match_expr, &paths::ITERATOR) &&
|
||||||
lhs_constructor.name.as_str() == "Some" &&
|
&*lhs_constructor.name.as_str() == "Some" &&
|
||||||
!is_refutable(cx, &pat_args[0]) &&
|
!is_refutable(cx, &pat_args[0]) &&
|
||||||
!is_iterator_used_after_while_let(cx, iter_expr) {
|
!is_iterator_used_after_while_let(cx, iter_expr) {
|
||||||
let iterator = snippet(cx, method_args[0].span, "_");
|
let iterator = snippet(cx, method_args[0].span, "_");
|
||||||
@ -395,7 +395,7 @@ impl LateLintPass for Pass {
|
|||||||
fn check_stmt(&mut self, cx: &LateContext, stmt: &Stmt) {
|
fn check_stmt(&mut self, cx: &LateContext, stmt: &Stmt) {
|
||||||
if let StmtSemi(ref expr, _) = stmt.node {
|
if let StmtSemi(ref expr, _) = stmt.node {
|
||||||
if let ExprMethodCall(ref method, _, ref args) = expr.node {
|
if let ExprMethodCall(ref method, _, ref args) = expr.node {
|
||||||
if args.len() == 1 && method.node.as_str() == "collect" &&
|
if args.len() == 1 && &*method.node.as_str() == "collect" &&
|
||||||
match_trait_method(cx, expr, &paths::ITERATOR) {
|
match_trait_method(cx, expr, &paths::ITERATOR) {
|
||||||
span_lint(cx,
|
span_lint(cx,
|
||||||
UNUSED_COLLECT,
|
UNUSED_COLLECT,
|
||||||
@ -509,7 +509,7 @@ fn is_len_call(expr: &Expr, var: &Name) -> bool {
|
|||||||
if_let_chain! {[
|
if_let_chain! {[
|
||||||
let ExprMethodCall(method, _, ref len_args) = expr.node,
|
let ExprMethodCall(method, _, ref len_args) = expr.node,
|
||||||
len_args.len() == 1,
|
len_args.len() == 1,
|
||||||
method.node.as_str() == "len",
|
&*method.node.as_str() == "len",
|
||||||
let ExprPath(_, ref path) = len_args[0].node,
|
let ExprPath(_, ref path) = len_args[0].node,
|
||||||
path.segments.len() == 1,
|
path.segments.len() == 1,
|
||||||
&path.segments[0].name == var
|
&path.segments[0].name == var
|
||||||
@ -580,14 +580,14 @@ fn check_for_loop_arg(cx: &LateContext, pat: &Pat, arg: &Expr, expr: &Expr) {
|
|||||||
if args.len() == 1 {
|
if args.len() == 1 {
|
||||||
let method_name = method.node;
|
let method_name = method.node;
|
||||||
// check for looping over x.iter() or x.iter_mut(), could use &x or &mut x
|
// check for looping over x.iter() or x.iter_mut(), could use &x or &mut x
|
||||||
if method_name.as_str() == "iter" || method_name.as_str() == "iter_mut" {
|
if &*method_name.as_str() == "iter" || &*method_name.as_str() == "iter_mut" {
|
||||||
if is_ref_iterable_type(cx, &args[0]) {
|
if is_ref_iterable_type(cx, &args[0]) {
|
||||||
let object = snippet(cx, args[0].span, "_");
|
let object = snippet(cx, args[0].span, "_");
|
||||||
span_lint(cx,
|
span_lint(cx,
|
||||||
EXPLICIT_ITER_LOOP,
|
EXPLICIT_ITER_LOOP,
|
||||||
expr.span,
|
expr.span,
|
||||||
&format!("it is more idiomatic to loop over `&{}{}` instead of `{}.{}()`",
|
&format!("it is more idiomatic to loop over `&{}{}` instead of `{}.{}()`",
|
||||||
if method_name.as_str() == "iter_mut" {
|
if &*method_name.as_str() == "iter_mut" {
|
||||||
"mut "
|
"mut "
|
||||||
} else {
|
} else {
|
||||||
""
|
""
|
||||||
@ -596,7 +596,7 @@ fn check_for_loop_arg(cx: &LateContext, pat: &Pat, arg: &Expr, expr: &Expr) {
|
|||||||
object,
|
object,
|
||||||
method_name));
|
method_name));
|
||||||
}
|
}
|
||||||
} else if method_name.as_str() == "into_iter" && match_trait_method(cx, arg, &paths::INTO_ITERATOR) {
|
} else if &*method_name.as_str() == "into_iter" && match_trait_method(cx, arg, &paths::INTO_ITERATOR) {
|
||||||
let object = snippet(cx, args[0].span, "_");
|
let object = snippet(cx, args[0].span, "_");
|
||||||
span_lint(cx,
|
span_lint(cx,
|
||||||
EXPLICIT_INTO_ITER_LOOP,
|
EXPLICIT_INTO_ITER_LOOP,
|
||||||
@ -606,7 +606,7 @@ fn check_for_loop_arg(cx: &LateContext, pat: &Pat, arg: &Expr, expr: &Expr) {
|
|||||||
object,
|
object,
|
||||||
method_name));
|
method_name));
|
||||||
|
|
||||||
} else if method_name.as_str() == "next" && match_trait_method(cx, arg, &paths::ITERATOR) {
|
} else if &*method_name.as_str() == "next" && match_trait_method(cx, arg, &paths::ITERATOR) {
|
||||||
span_lint(cx,
|
span_lint(cx,
|
||||||
ITER_NEXT_LOOP,
|
ITER_NEXT_LOOP,
|
||||||
expr.span,
|
expr.span,
|
||||||
|
@ -28,7 +28,7 @@ impl LateLintPass for Pass {
|
|||||||
fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
|
fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
|
||||||
// call to .map()
|
// call to .map()
|
||||||
if let ExprMethodCall(name, _, ref args) = expr.node {
|
if let ExprMethodCall(name, _, ref args) = expr.node {
|
||||||
if name.node.as_str() == "map" && args.len() == 2 {
|
if &*name.node.as_str() == "map" && args.len() == 2 {
|
||||||
match args[1].node {
|
match args[1].node {
|
||||||
ExprClosure(_, ref decl, ref closure_expr, _) => {
|
ExprClosure(_, ref decl, ref closure_expr, _) => {
|
||||||
let closure_expr = remove_blocks(closure_expr);
|
let closure_expr = remove_blocks(closure_expr);
|
||||||
@ -51,7 +51,7 @@ impl LateLintPass for Pass {
|
|||||||
}
|
}
|
||||||
// explicit clone() calls ( .map(|x| x.clone()) )
|
// explicit clone() calls ( .map(|x| x.clone()) )
|
||||||
else if let ExprMethodCall(clone_call, _, ref clone_args) = closure_expr.node {
|
else if let ExprMethodCall(clone_call, _, ref clone_args) = closure_expr.node {
|
||||||
if clone_call.node.as_str() == "clone" &&
|
if &*clone_call.node.as_str() == "clone" &&
|
||||||
clone_args.len() == 1 &&
|
clone_args.len() == 1 &&
|
||||||
match_trait_method(cx, closure_expr, &paths::CLONE_TRAIT) &&
|
match_trait_method(cx, closure_expr, &paths::CLONE_TRAIT) &&
|
||||||
expr_eq_name(&clone_args[0], arg_ident)
|
expr_eq_name(&clone_args[0], arg_ident)
|
||||||
|
@ -605,14 +605,14 @@ impl LateLintPass for Pass {
|
|||||||
lint_or_fun_call(cx, expr, &name.node.as_str(), args);
|
lint_or_fun_call(cx, expr, &name.node.as_str(), args);
|
||||||
|
|
||||||
let self_ty = cx.tcx.tables().expr_ty_adjusted(&args[0]);
|
let self_ty = cx.tcx.tables().expr_ty_adjusted(&args[0]);
|
||||||
if args.len() == 1 && name.node.as_str() == "clone" {
|
if args.len() == 1 && &*name.node.as_str() == "clone" {
|
||||||
lint_clone_on_copy(cx, expr, &args[0], self_ty);
|
lint_clone_on_copy(cx, expr, &args[0], self_ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
match self_ty.sty {
|
match self_ty.sty {
|
||||||
ty::TyRef(_, ty) if ty.ty.sty == ty::TyStr => {
|
ty::TyRef(_, ty) if ty.ty.sty == ty::TyStr => {
|
||||||
for &(method, pos) in &PATTERN_METHODS {
|
for &(method, pos) in &PATTERN_METHODS {
|
||||||
if name.node.as_str() == method && args.len() > pos {
|
if &*name.node.as_str() == method && args.len() > pos {
|
||||||
lint_single_char_pattern(cx, expr, &args[pos]);
|
lint_single_char_pattern(cx, expr, &args[pos]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -643,7 +643,7 @@ impl LateLintPass for Pass {
|
|||||||
], {
|
], {
|
||||||
// check missing trait implementations
|
// check missing trait implementations
|
||||||
for &(method_name, n_args, self_kind, out_type, trait_name) in &TRAIT_METHODS {
|
for &(method_name, n_args, self_kind, out_type, trait_name) in &TRAIT_METHODS {
|
||||||
if name.as_str() == method_name &&
|
if &*name.as_str() == method_name &&
|
||||||
sig.decl.inputs.len() == n_args &&
|
sig.decl.inputs.len() == n_args &&
|
||||||
out_type.matches(&sig.decl.output) &&
|
out_type.matches(&sig.decl.output) &&
|
||||||
self_kind.matches(&explicit_self, false) {
|
self_kind.matches(&explicit_self, false) {
|
||||||
@ -681,7 +681,7 @@ impl LateLintPass for Pass {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let ret_ty = return_ty(cx, implitem.id);
|
let ret_ty = return_ty(cx, implitem.id);
|
||||||
if &name.as_str() == &"new" &&
|
if &*name.as_str() == "new" &&
|
||||||
!ret_ty.walk().any(|t| same_tys(cx, t, ty, implitem.id)) {
|
!ret_ty.walk().any(|t| same_tys(cx, t, ty, implitem.id)) {
|
||||||
span_lint(cx,
|
span_lint(cx,
|
||||||
NEW_RET_NO_SELF,
|
NEW_RET_NO_SELF,
|
||||||
@ -979,7 +979,7 @@ fn derefs_to_slice(cx: &LateContext, expr: &hir::Expr, ty: ty::Ty) -> Option<sug
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let hir::ExprMethodCall(name, _, ref args) = expr.node {
|
if let hir::ExprMethodCall(name, _, ref args) = expr.node {
|
||||||
if &name.node.as_str() == &"iter" && may_slice(cx, cx.tcx.tables().expr_ty(&args[0])) {
|
if &*name.node.as_str() == "iter" && may_slice(cx, cx.tcx.tables().expr_ty(&args[0])) {
|
||||||
sugg::Sugg::hir_opt(cx, &*args[0]).map(|sugg| {
|
sugg::Sugg::hir_opt(cx, &*args[0]).map(|sugg| {
|
||||||
sugg.addr()
|
sugg.addr()
|
||||||
})
|
})
|
||||||
@ -1209,7 +1209,7 @@ fn lint_chars_next(cx: &LateContext, expr: &hir::Expr, chain: &hir::Expr, other:
|
|||||||
let hir::ExprCall(ref fun, ref arg_char) = other.node,
|
let hir::ExprCall(ref fun, ref arg_char) = other.node,
|
||||||
arg_char.len() == 1,
|
arg_char.len() == 1,
|
||||||
let hir::ExprPath(None, ref path) = fun.node,
|
let hir::ExprPath(None, ref path) = fun.node,
|
||||||
path.segments.len() == 1 && path.segments[0].name.as_str() == "Some"
|
path.segments.len() == 1 && &*path.segments[0].name.as_str() == "Some"
|
||||||
], {
|
], {
|
||||||
let self_ty = walk_ptrs_ty(cx.tcx.tables().expr_ty_adjusted(&args[0][0]));
|
let self_ty = walk_ptrs_ty(cx.tcx.tables().expr_ty_adjusted(&args[0][0]));
|
||||||
|
|
||||||
|
@ -235,7 +235,7 @@ impl LateLintPass for Pass {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if let Some(name) = get_item_name(cx, expr) {
|
if let Some(name) = get_item_name(cx, expr) {
|
||||||
let name = name.as_str();
|
let name = &*name.as_str();
|
||||||
if name == "eq" || name == "ne" || name == "is_nan" || name.starts_with("eq_") ||
|
if name == "eq" || name == "ne" || name == "is_nan" || name.starts_with("eq_") ||
|
||||||
name.ends_with("_eq") {
|
name.ends_with("_eq") {
|
||||||
return;
|
return;
|
||||||
@ -271,7 +271,7 @@ impl LateLintPass for Pass {
|
|||||||
.as_str();
|
.as_str();
|
||||||
if binding.starts_with('_') &&
|
if binding.starts_with('_') &&
|
||||||
!binding.starts_with("__") &&
|
!binding.starts_with("__") &&
|
||||||
binding != "_result" && // FIXME: #944
|
&*binding != "_result" && // FIXME: #944
|
||||||
is_used(cx, expr) &&
|
is_used(cx, expr) &&
|
||||||
// don't lint if the declaration is in a macro
|
// don't lint if the declaration is in a macro
|
||||||
non_macro_local(cx, &cx.tcx.expect_def(expr.id)) {
|
non_macro_local(cx, &cx.tcx.expect_def(expr.id)) {
|
||||||
@ -315,7 +315,7 @@ impl LateLintPass for Pass {
|
|||||||
|
|
||||||
fn check_nan(cx: &LateContext, path: &Path, span: Span) {
|
fn check_nan(cx: &LateContext, path: &Path, span: Span) {
|
||||||
path.segments.last().map(|seg| {
|
path.segments.last().map(|seg| {
|
||||||
if seg.name.as_str() == "NAN" {
|
if &*seg.name.as_str() == "NAN" {
|
||||||
span_lint(cx,
|
span_lint(cx,
|
||||||
CMP_NAN,
|
CMP_NAN,
|
||||||
span,
|
span,
|
||||||
@ -359,7 +359,8 @@ fn is_float(cx: &LateContext, expr: &Expr) -> bool {
|
|||||||
fn check_to_owned(cx: &LateContext, expr: &Expr, other: &Expr, left: bool, op: Span) {
|
fn check_to_owned(cx: &LateContext, expr: &Expr, other: &Expr, left: bool, op: Span) {
|
||||||
let (arg_ty, snip) = match expr.node {
|
let (arg_ty, snip) = match expr.node {
|
||||||
ExprMethodCall(Spanned { node: ref name, .. }, _, ref args) if args.len() == 1 => {
|
ExprMethodCall(Spanned { node: ref name, .. }, _, ref args) if args.len() == 1 => {
|
||||||
if name.as_str() == "to_string" || name.as_str() == "to_owned" && is_str_arg(cx, args) {
|
let name = &*name.as_str();
|
||||||
|
if name == "to_string" || name == "to_owned" && is_str_arg(cx, args) {
|
||||||
(cx.tcx.tables().expr_ty(&args[0]), snippet(cx, args[0].span, ".."))
|
(cx.tcx.tables().expr_ty(&args[0]), snippet(cx, args[0].span, ".."))
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
|
@ -100,7 +100,7 @@ impl LateLintPass for NewWithoutDefault {
|
|||||||
// can't be implemented by default
|
// can't be implemented by default
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if decl.inputs.is_empty() && name.as_str() == "new" && cx.access_levels.is_reachable(id) {
|
if decl.inputs.is_empty() && &*name.as_str() == "new" && cx.access_levels.is_reachable(id) {
|
||||||
let self_ty = cx.tcx
|
let self_ty = cx.tcx
|
||||||
.item_type(cx.tcx.map.local_def_id(cx.tcx.map.get_parent(id)));
|
.item_type(cx.tcx.map.local_def_id(cx.tcx.map.get_parent(id)));
|
||||||
if_let_chain!{[
|
if_let_chain!{[
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use rustc::lint::*;
|
use rustc::lint::*;
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use syntax::parse::token::InternedString;
|
use syntax::symbol::InternedString;
|
||||||
use syntax::ast::*;
|
use syntax::ast::*;
|
||||||
use syntax::attr;
|
use syntax::attr;
|
||||||
use syntax::visit::{Visitor, walk_block, walk_pat, walk_expr};
|
use syntax::visit::{Visitor, walk_block, walk_pat, walk_expr};
|
||||||
|
@ -36,7 +36,7 @@ impl LateLintPass for NonSensical {
|
|||||||
fn check_expr(&mut self, cx: &LateContext, e: &Expr) {
|
fn check_expr(&mut self, cx: &LateContext, e: &Expr) {
|
||||||
if let ExprMethodCall(ref name, _, ref arguments) = e.node {
|
if let ExprMethodCall(ref name, _, ref arguments) = e.node {
|
||||||
let (obj_ty, _) = walk_ptrs_ty_depth(cx.tcx.tables().expr_ty(&arguments[0]));
|
let (obj_ty, _) = walk_ptrs_ty_depth(cx.tcx.tables().expr_ty(&arguments[0]));
|
||||||
if name.node.as_str() == "open" && match_type(cx, obj_ty, &paths::OPEN_OPTIONS) {
|
if &*name.node.as_str() == "open" && match_type(cx, obj_ty, &paths::OPEN_OPTIONS) {
|
||||||
let mut options = Vec::new();
|
let mut options = Vec::new();
|
||||||
get_open_options(cx, &arguments[0], &mut options);
|
get_open_options(cx, &arguments[0], &mut options);
|
||||||
check_open_options(cx, &options, e.span);
|
check_open_options(cx, &options, e.span);
|
||||||
|
@ -45,8 +45,8 @@ impl LateLintPass for Pass {
|
|||||||
let ExprLit(ref lit) = params[0].node,
|
let ExprLit(ref lit) = params[0].node,
|
||||||
is_direct_expn_of(cx, params[0].span, "panic").is_some(),
|
is_direct_expn_of(cx, params[0].span, "panic").is_some(),
|
||||||
let LitKind::Str(ref string, _) = lit.node,
|
let LitKind::Str(ref string, _) = lit.node,
|
||||||
let Some(par) = string.find('{'),
|
let Some(par) = string.as_str().find('{'),
|
||||||
string[par..].contains('}')
|
string.as_str()[par..].contains('}')
|
||||||
], {
|
], {
|
||||||
span_lint(cx, PANIC_PARAMS, params[0].span,
|
span_lint(cx, PANIC_PARAMS, params[0].span,
|
||||||
"you probably are missing some parameter in your format string");
|
"you probably are missing some parameter in your format string");
|
||||||
|
@ -49,27 +49,29 @@ impl LintPass for StepByZero {
|
|||||||
impl LateLintPass for StepByZero {
|
impl LateLintPass for StepByZero {
|
||||||
fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
|
fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
|
||||||
if let ExprMethodCall(Spanned { node: ref name, .. }, _, ref args) = expr.node {
|
if let ExprMethodCall(Spanned { node: ref name, .. }, _, ref args) = expr.node {
|
||||||
|
let name = &*name.as_str();
|
||||||
|
|
||||||
// Range with step_by(0).
|
// Range with step_by(0).
|
||||||
if name.as_str() == "step_by" && args.len() == 2 && has_step_by(cx, &args[0]) &&
|
if name == "step_by" && args.len() == 2 && has_step_by(cx, &args[0]) &&
|
||||||
is_integer_literal(&args[1], 0) {
|
is_integer_literal(&args[1], 0) {
|
||||||
span_lint(cx,
|
span_lint(cx,
|
||||||
RANGE_STEP_BY_ZERO,
|
RANGE_STEP_BY_ZERO,
|
||||||
expr.span,
|
expr.span,
|
||||||
"Range::step_by(0) produces an infinite iterator. Consider using `std::iter::repeat()` \
|
"Range::step_by(0) produces an infinite iterator. Consider using `std::iter::repeat()` \
|
||||||
instead");
|
instead");
|
||||||
} else if name.as_str() == "zip" && args.len() == 2 {
|
} else if name == "zip" && args.len() == 2 {
|
||||||
let iter = &args[0].node;
|
let iter = &args[0].node;
|
||||||
let zip_arg = &args[1];
|
let zip_arg = &args[1];
|
||||||
if_let_chain! {[
|
if_let_chain! {[
|
||||||
// .iter() call
|
// .iter() call
|
||||||
let ExprMethodCall( Spanned { node: ref iter_name, .. }, _, ref iter_args ) = *iter,
|
let ExprMethodCall( Spanned { node: ref iter_name, .. }, _, ref iter_args ) = *iter,
|
||||||
iter_name.as_str() == "iter",
|
&*iter_name.as_str() == "iter",
|
||||||
// range expression in .zip() call: 0..x.len()
|
// range expression in .zip() call: 0..x.len()
|
||||||
let Some(higher::Range { start: Some(ref start), end: Some(ref end), .. }) = higher::range(zip_arg),
|
let Some(higher::Range { start: Some(ref start), end: Some(ref end), .. }) = higher::range(zip_arg),
|
||||||
is_integer_literal(start, 0),
|
is_integer_literal(start, 0),
|
||||||
// .len() call
|
// .len() call
|
||||||
let ExprMethodCall(Spanned { node: ref len_name, .. }, _, ref len_args) = end.node,
|
let ExprMethodCall(Spanned { node: ref len_name, .. }, _, ref len_args) = end.node,
|
||||||
len_name.as_str() == "len" && len_args.len() == 1,
|
&*len_name.as_str() == "len" && len_args.len() == 1,
|
||||||
// .iter() and .len() called on same Path
|
// .iter() and .len() called on same Path
|
||||||
let ExprPath(_, Path { segments: ref iter_path, .. }) = iter_args[0].node,
|
let ExprPath(_, Path { segments: ref iter_path, .. }) = iter_args[0].node,
|
||||||
let ExprPath(_, Path { segments: ref len_path, .. }) = len_args[0].node,
|
let ExprPath(_, Path { segments: ref len_path, .. }) = len_args[0].node,
|
||||||
|
@ -8,7 +8,7 @@ use std::collections::HashSet;
|
|||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use syntax::ast::{LitKind, NodeId};
|
use syntax::ast::{LitKind, NodeId};
|
||||||
use syntax::codemap::{Span, BytePos};
|
use syntax::codemap::{Span, BytePos};
|
||||||
use syntax::parse::token::InternedString;
|
use syntax::symbol::InternedString;
|
||||||
use utils::{is_expn_of, match_def_path, match_type, paths, span_lint, span_help_and_lint};
|
use utils::{is_expn_of, match_def_path, match_type, paths, span_lint, span_help_and_lint};
|
||||||
|
|
||||||
/// **What it does:** Checks [regex] creation (with `Regex::new`,
|
/// **What it does:** Checks [regex] creation (with `Regex::new`,
|
||||||
@ -203,6 +203,7 @@ fn check_regex(cx: &LateContext, expr: &Expr, utf8: bool) {
|
|||||||
|
|
||||||
if let ExprLit(ref lit) = expr.node {
|
if let ExprLit(ref lit) = expr.node {
|
||||||
if let LitKind::Str(ref r, _) = lit.node {
|
if let LitKind::Str(ref r, _) = lit.node {
|
||||||
|
let r = &*r.as_str();
|
||||||
match builder.parse(r) {
|
match builder.parse(r) {
|
||||||
Ok(r) => {
|
Ok(r) => {
|
||||||
if let Some(repl) = is_trivial_regex(&r) {
|
if let Some(repl) = is_trivial_regex(&r) {
|
||||||
|
@ -146,8 +146,8 @@ impl EarlyLintPass for ReturnPass {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn attr_is_cfg(attr: &ast::Attribute) -> bool {
|
fn attr_is_cfg(attr: &ast::Attribute) -> bool {
|
||||||
if let ast::MetaItemKind::List(ref key, _) = attr.node.value.node {
|
if let ast::MetaItemKind::List(_) = attr.value.node {
|
||||||
*key == "cfg"
|
attr.name() == "cfg"
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
@ -143,10 +143,10 @@ impl LateLintPass for StringLitAsBytes {
|
|||||||
use utils::{snippet, in_macro};
|
use utils::{snippet, in_macro};
|
||||||
|
|
||||||
if let ExprMethodCall(ref name, _, ref args) = e.node {
|
if let ExprMethodCall(ref name, _, ref args) = e.node {
|
||||||
if name.node.as_str() == "as_bytes" {
|
if &*name.node.as_str() == "as_bytes" {
|
||||||
if let ExprLit(ref lit) = args[0].node {
|
if let ExprLit(ref lit) = args[0].node {
|
||||||
if let LitKind::Str(ref lit_content, _) = lit.node {
|
if let LitKind::Str(ref lit_content, _) = lit.node {
|
||||||
if lit_content.chars().all(|c| c.is_ascii()) && !in_macro(cx, args[0].span) {
|
if lit_content.as_str().chars().all(|c| c.is_ascii()) && !in_macro(cx, args[0].span) {
|
||||||
span_lint_and_then(cx,
|
span_lint_and_then(cx,
|
||||||
STRING_LIT_AS_BYTES,
|
STRING_LIT_AS_BYTES,
|
||||||
e.span,
|
e.span,
|
||||||
|
@ -2,7 +2,7 @@ use rustc::hir::*;
|
|||||||
use rustc::lint::*;
|
use rustc::lint::*;
|
||||||
use syntax::ast::Name;
|
use syntax::ast::Name;
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use syntax::parse::token::InternedString;
|
use syntax::symbol::InternedString;
|
||||||
use utils::span_lint;
|
use utils::span_lint;
|
||||||
|
|
||||||
/// **What it does:** Checks for imports that remove "unsafe" from an item's
|
/// **What it does:** Checks for imports that remove "unsafe" from an item's
|
||||||
|
@ -4,7 +4,7 @@ use rustc::hir::intravisit::{FnKind, Visitor, walk_expr, walk_fn};
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use syntax::parse::token::InternedString;
|
use syntax::symbol::InternedString;
|
||||||
use utils::{in_macro, span_lint};
|
use utils::{in_macro, span_lint};
|
||||||
|
|
||||||
/// **What it does:** Checks for unused labels.
|
/// **What it does:** Checks for unused labels.
|
||||||
|
@ -10,22 +10,20 @@ use toml;
|
|||||||
/// Get the configuration file from arguments.
|
/// Get the configuration file from arguments.
|
||||||
pub fn file_from_args(args: &[codemap::Spanned<ast::NestedMetaItemKind>]) -> Result<Option<path::PathBuf>, (&'static str, codemap::Span)> {
|
pub fn file_from_args(args: &[codemap::Spanned<ast::NestedMetaItemKind>]) -> Result<Option<path::PathBuf>, (&'static str, codemap::Span)> {
|
||||||
for arg in args.iter().filter_map(|a| a.meta_item()) {
|
for arg in args.iter().filter_map(|a| a.meta_item()) {
|
||||||
match arg.node {
|
if arg.name() == "conf_file" {
|
||||||
ast::MetaItemKind::Word(ref name) |
|
return match arg.node {
|
||||||
ast::MetaItemKind::List(ref name, _) => {
|
ast::MetaItemKind::Word |
|
||||||
if name == &"conf_file" {
|
ast::MetaItemKind::List(_) => {
|
||||||
return Err(("`conf_file` must be a named value", arg.span));
|
Err(("`conf_file` must be a named value", arg.span))
|
||||||
}
|
}
|
||||||
}
|
ast::MetaItemKind::NameValue(ref value) => {
|
||||||
ast::MetaItemKind::NameValue(ref name, ref value) => {
|
if let ast::LitKind::Str(ref file, _) = value.node {
|
||||||
if name == &"conf_file" {
|
|
||||||
return if let ast::LitKind::Str(ref file, _) = value.node {
|
|
||||||
Ok(Some(file.to_string().into()))
|
Ok(Some(file.to_string().into()))
|
||||||
} else {
|
} else {
|
||||||
Err(("`conf_file` value must be a string", value.span))
|
Err(("`conf_file` value must be a string", value.span))
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ pub fn range(expr: &hir::Expr) -> Option<Range> {
|
|||||||
/// Find the field named `name` in the field. Always return `Some` for convenience.
|
/// Find the field named `name` in the field. Always return `Some` for convenience.
|
||||||
fn get_field<'a>(name: &str, fields: &'a [hir::Field]) -> Option<&'a hir::Expr> {
|
fn get_field<'a>(name: &str, fields: &'a [hir::Field]) -> Option<&'a hir::Expr> {
|
||||||
let expr = &fields.iter()
|
let expr = &fields.iter()
|
||||||
.find(|field| field.name.node.as_str() == name)
|
.find(|field| field.name.node == name)
|
||||||
.unwrap_or_else(|| panic!("missing {} field for range", name))
|
.unwrap_or_else(|| panic!("missing {} field for range", name))
|
||||||
.expr;
|
.expr;
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ use rustc::lint::*;
|
|||||||
use rustc::hir::*;
|
use rustc::hir::*;
|
||||||
use rustc::hir::intravisit::{Visitor, walk_expr};
|
use rustc::hir::intravisit::{Visitor, walk_expr};
|
||||||
use utils::{paths, match_path, span_lint};
|
use utils::{paths, match_path, span_lint};
|
||||||
use syntax::parse::token::InternedString;
|
use syntax::symbol::InternedString;
|
||||||
use syntax::ast::{Name, NodeId, ItemKind, Crate as AstCrate};
|
use syntax::ast::{Name, NodeId, ItemKind, Crate as AstCrate};
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use std::collections::{HashSet, HashMap};
|
use std::collections::{HashSet, HashMap};
|
||||||
@ -63,9 +63,9 @@ impl LintPass for Clippy {
|
|||||||
|
|
||||||
impl EarlyLintPass for Clippy {
|
impl EarlyLintPass for Clippy {
|
||||||
fn check_crate(&mut self, cx: &EarlyContext, krate: &AstCrate) {
|
fn check_crate(&mut self, cx: &EarlyContext, krate: &AstCrate) {
|
||||||
if let Some(utils) = krate.module.items.iter().find(|item| item.ident.name.as_str() == "utils") {
|
if let Some(utils) = krate.module.items.iter().find(|item| item.ident.name == "utils") {
|
||||||
if let ItemKind::Mod(ref utils_mod) = utils.node {
|
if let ItemKind::Mod(ref utils_mod) = utils.node {
|
||||||
if let Some(paths) = utils_mod.items.iter().find(|item| item.ident.name.as_str() == "paths") {
|
if let Some(paths) = utils_mod.items.iter().find(|item| item.ident.name == "paths") {
|
||||||
if let ItemKind::Mod(ref paths_mod) = paths.node {
|
if let ItemKind::Mod(ref paths_mod) = paths.node {
|
||||||
let mut last_name: Option<InternedString> = None;
|
let mut last_name: Option<InternedString> = None;
|
||||||
for item in &paths_mod.items {
|
for item in &paths_mod.items {
|
||||||
@ -109,7 +109,7 @@ impl LateLintPass for LintWithoutLintPass {
|
|||||||
if let ItemStatic(ref ty, MutImmutable, ref expr) = item.node {
|
if let ItemStatic(ref ty, MutImmutable, ref expr) = item.node {
|
||||||
if is_lint_ref_type(ty) {
|
if is_lint_ref_type(ty) {
|
||||||
self.declared_lints.insert(item.name, item.span);
|
self.declared_lints.insert(item.name, item.span);
|
||||||
} else if is_lint_array_type(ty) && item.vis == Visibility::Inherited && item.name.as_str() == "ARRAY" {
|
} else if is_lint_array_type(ty) && item.vis == Visibility::Inherited && item.name == "ARRAY" {
|
||||||
let mut collector = LintCollector { output: &mut self.registered_lints };
|
let mut collector = LintCollector { output: &mut self.registered_lints };
|
||||||
collector.visit_expr(expr);
|
collector.visit_expr(expr);
|
||||||
}
|
}
|
||||||
|
@ -129,10 +129,10 @@ pub fn in_external_macro<T: LintContext>(cx: &T, span: Span) -> bool {
|
|||||||
///
|
///
|
||||||
/// See also the `paths` module.
|
/// See also the `paths` module.
|
||||||
pub fn match_def_path(cx: &LateContext, def_id: DefId, path: &[&str]) -> bool {
|
pub fn match_def_path(cx: &LateContext, def_id: DefId, path: &[&str]) -> bool {
|
||||||
use syntax::parse::token;
|
use syntax::symbol;
|
||||||
|
|
||||||
struct AbsolutePathBuffer {
|
struct AbsolutePathBuffer {
|
||||||
names: Vec<token::InternedString>,
|
names: Vec<symbol::InternedString>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ty::item_path::ItemPathBuffer for AbsolutePathBuffer {
|
impl ty::item_path::ItemPathBuffer for AbsolutePathBuffer {
|
||||||
@ -142,7 +142,7 @@ pub fn match_def_path(cx: &LateContext, def_id: DefId, path: &[&str]) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn push(&mut self, text: &str) {
|
fn push(&mut self, text: &str) {
|
||||||
self.names.push(token::intern(text).as_str());
|
self.names.push(symbol::Symbol::intern(text).as_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,7 +150,8 @@ pub fn match_def_path(cx: &LateContext, def_id: DefId, path: &[&str]) -> bool {
|
|||||||
|
|
||||||
cx.tcx.push_item_path(&mut apb, def_id);
|
cx.tcx.push_item_path(&mut apb, def_id);
|
||||||
|
|
||||||
apb.names == path
|
apb.names.len() == path.len() &&
|
||||||
|
apb.names.iter().zip(path.iter()).all(|(a, &b)| &**a == b)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if type is struct, enum or union type with given def path.
|
/// Check if type is struct, enum or union type with given def path.
|
||||||
@ -202,7 +203,7 @@ pub fn match_trait_method(cx: &LateContext, expr: &Expr, path: &[&str]) -> bool
|
|||||||
/// match_path(path, &["std", "rt", "begin_unwind"])
|
/// match_path(path, &["std", "rt", "begin_unwind"])
|
||||||
/// ```
|
/// ```
|
||||||
pub fn match_path(path: &Path, segments: &[&str]) -> bool {
|
pub fn match_path(path: &Path, segments: &[&str]) -> bool {
|
||||||
path.segments.iter().rev().zip(segments.iter().rev()).all(|(a, b)| a.name.as_str() == *b)
|
path.segments.iter().rev().zip(segments.iter().rev()).all(|(a, b)| a.name == *b)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Match a `Path` against a slice of segment string literals, e.g.
|
/// Match a `Path` against a slice of segment string literals, e.g.
|
||||||
@ -212,7 +213,7 @@ pub fn match_path(path: &Path, segments: &[&str]) -> bool {
|
|||||||
/// match_path(path, &["std", "rt", "begin_unwind"])
|
/// match_path(path, &["std", "rt", "begin_unwind"])
|
||||||
/// ```
|
/// ```
|
||||||
pub fn match_path_ast(path: &ast::Path, segments: &[&str]) -> bool {
|
pub fn match_path_ast(path: &ast::Path, segments: &[&str]) -> bool {
|
||||||
path.segments.iter().rev().zip(segments.iter().rev()).all(|(a, b)| a.identifier.name.as_str() == *b)
|
path.segments.iter().rev().zip(segments.iter().rev()).all(|(a, b)| a.identifier.name == *b)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the definition associated to a path.
|
/// Get the definition associated to a path.
|
||||||
@ -234,7 +235,7 @@ pub fn path_to_def(cx: &LateContext, path: &[&str]) -> Option<def::Def> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
for item in &mem::replace(&mut items, vec![]) {
|
for item in &mem::replace(&mut items, vec![]) {
|
||||||
if item.name.as_str() == *segment {
|
if item.name == *segment {
|
||||||
if path_it.peek().is_none() {
|
if path_it.peek().is_none() {
|
||||||
return Some(item.def);
|
return Some(item.def);
|
||||||
}
|
}
|
||||||
@ -297,7 +298,7 @@ pub fn method_chain_args<'a>(expr: &'a Expr, methods: &[&str]) -> Option<Vec<&'a
|
|||||||
for method_name in methods.iter().rev() {
|
for method_name in methods.iter().rev() {
|
||||||
// method chains are stored last -> first
|
// method chains are stored last -> first
|
||||||
if let ExprMethodCall(ref name, _, ref args) = current.node {
|
if let ExprMethodCall(ref name, _, ref args) = current.node {
|
||||||
if name.node.as_str() == *method_name {
|
if name.node == *method_name {
|
||||||
matched.push(args); // build up `matched` backwards
|
matched.push(args); // build up `matched` backwards
|
||||||
current = &args[0] // go to parent expression
|
current = &args[0] // go to parent expression
|
||||||
} else {
|
} else {
|
||||||
@ -580,13 +581,13 @@ impl LimitStack {
|
|||||||
|
|
||||||
fn parse_attrs<F: FnMut(u64)>(sess: &Session, attrs: &[ast::Attribute], name: &'static str, mut f: F) {
|
fn parse_attrs<F: FnMut(u64)>(sess: &Session, attrs: &[ast::Attribute], name: &'static str, mut f: F) {
|
||||||
for attr in attrs {
|
for attr in attrs {
|
||||||
if attr.node.is_sugared_doc {
|
if attr.is_sugared_doc {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if let ast::MetaItemKind::NameValue(ref key, ref value) = attr.node.value.node {
|
if let ast::MetaItemKind::NameValue(ref value) = attr.value.node {
|
||||||
if *key == name {
|
if attr.name() == name {
|
||||||
if let LitKind::Str(ref s, _) = value.node {
|
if let LitKind::Str(ref s, _) = value.node {
|
||||||
if let Ok(value) = FromStr::from_str(s) {
|
if let Ok(value) = FromStr::from_str(&*s.as_str()) {
|
||||||
attr::mark_used(attr);
|
attr::mark_used(attr);
|
||||||
f(value)
|
f(value)
|
||||||
} else {
|
} else {
|
||||||
@ -610,7 +611,7 @@ pub fn is_expn_of(cx: &LateContext, mut span: Span, name: &str) -> Option<Span>
|
|||||||
.with_expn_info(span.expn_id, |expn| expn.map(|ei| (ei.callee.name(), ei.call_site)));
|
.with_expn_info(span.expn_id, |expn| expn.map(|ei| (ei.callee.name(), ei.call_site)));
|
||||||
|
|
||||||
match span_name_span {
|
match span_name_span {
|
||||||
Some((mac_name, new_span)) if mac_name.as_str() == name => return Some(new_span),
|
Some((mac_name, new_span)) if mac_name == name => return Some(new_span),
|
||||||
None => return None,
|
None => return None,
|
||||||
Some((_, new_span)) => span = new_span,
|
Some((_, new_span)) => span = new_span,
|
||||||
}
|
}
|
||||||
@ -631,7 +632,7 @@ pub fn is_direct_expn_of(cx: &LateContext, span: Span, name: &str) -> Option<Spa
|
|||||||
.with_expn_info(span.expn_id, |expn| expn.map(|ei| (ei.callee.name(), ei.call_site)));
|
.with_expn_info(span.expn_id, |expn| expn.map(|ei| (ei.callee.name(), ei.call_site)));
|
||||||
|
|
||||||
match span_name_span {
|
match span_name_span {
|
||||||
Some((mac_name, new_span)) if mac_name.as_str() == name => Some(new_span),
|
Some((mac_name, new_span)) if mac_name == name => Some(new_span),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ use rustc_const_math::ConstInt;
|
|||||||
use rustc::hir::*;
|
use rustc::hir::*;
|
||||||
use syntax::ast::{LitIntType, LitKind, NodeId, StrStyle};
|
use syntax::ast::{LitIntType, LitKind, NodeId, StrStyle};
|
||||||
use syntax::codemap::{Spanned, COMMAND_LINE_SP};
|
use syntax::codemap::{Spanned, COMMAND_LINE_SP};
|
||||||
use syntax::parse::token::InternedString;
|
use syntax::symbol::Symbol;
|
||||||
use syntax::ptr::P;
|
use syntax::ptr::P;
|
||||||
use syntax::util::ThinVec;
|
use syntax::util::ThinVec;
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ fn test_lit() {
|
|||||||
check(FALSE, &lit(LitKind::Bool(false)));
|
check(FALSE, &lit(LitKind::Bool(false)));
|
||||||
check(ZERO, &lit(LitKind::Int(0, LitIntType::Unsuffixed)));
|
check(ZERO, &lit(LitKind::Int(0, LitIntType::Unsuffixed)));
|
||||||
check(Constant::Str("cool!".into(), StrStyle::Cooked),
|
check(Constant::Str("cool!".into(), StrStyle::Cooked),
|
||||||
&lit(LitKind::Str(InternedString::new("cool!"), StrStyle::Cooked)));
|
&lit(LitKind::Str(Symbol::intern("cool!"), StrStyle::Cooked)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
Loading…
Reference in New Issue
Block a user