Skip to content

Commit 5d96558

Browse files
authored
Merge pull request #1287 from Manishearth/rustup
Rustup to *rustc 1.14.0-nightly (f094206 2016-10-20)* and bump to 0.0.96
2 parents 4cf87a9 + ceb5087 commit 5d96558

File tree

10 files changed

+108
-89
lines changed

10 files changed

+108
-89
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
# Change Log
22
All notable changes to this project will be documented in this file.
33

4+
## 0.0.96 — 2016-10-22
5+
* Rustup to *rustc 1.14.0-nightly (f09420685 2016-10-20)*
6+
* New lint: [`iter_skip_next`]
7+
48
## 0.0.95 — 2016-10-06
59
* Rustup to *rustc 1.14.0-nightly (3210fd5c2 2016-10-05)*
610

Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "clippy"
3-
version = "0.0.95"
3+
version = "0.0.96"
44
authors = [
55
"Manish Goregaokar <[email protected]>",
66
"Andre Bogus <[email protected]>",
@@ -25,7 +25,7 @@ test = false
2525

2626
[dependencies]
2727
# begin automatic update
28-
clippy_lints = { version = "0.0.95", path = "clippy_lints" }
28+
clippy_lints = { version = "0.0.96", path = "clippy_lints" }
2929
# end automatic update
3030

3131
[dev-dependencies]

clippy_lints/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "clippy_lints"
33
# begin automatic update
4-
version = "0.0.95"
4+
version = "0.0.96"
55
# end automatic update
66
authors = [
77
"Manish Goregaokar <[email protected]>",

clippy_lints/src/attrs.rs

+19-19
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ use rustc::hir::*;
66
use semver::Version;
77
use syntax::ast::{Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem, NestedMetaItemKind};
88
use syntax::codemap::Span;
9-
use utils::{in_macro, match_path, span_lint, span_lint_and_then, snippet_opt};
10-
use utils::paths;
9+
use utils::{in_macro, match_def_path, resolve_node, paths, span_lint, span_lint_and_then, snippet_opt};
1110

1211
/// **What it does:** Checks for items annotated with `#[inline(always)]`,
1312
/// unless the annotated function is empty or simply panics.
@@ -101,7 +100,7 @@ impl LateLintPass for AttrPass {
101100
}
102101

103102
fn check_item(&mut self, cx: &LateContext, item: &Item) {
104-
if is_relevant_item(item) {
103+
if is_relevant_item(cx, item) {
105104
check_attrs(cx, item.span, &item.name, &item.attrs)
106105
}
107106
match item.node {
@@ -140,62 +139,63 @@ impl LateLintPass for AttrPass {
140139
}
141140

142141
fn check_impl_item(&mut self, cx: &LateContext, item: &ImplItem) {
143-
if is_relevant_impl(item) {
142+
if is_relevant_impl(cx, item) {
144143
check_attrs(cx, item.span, &item.name, &item.attrs)
145144
}
146145
}
147146

148147
fn check_trait_item(&mut self, cx: &LateContext, item: &TraitItem) {
149-
if is_relevant_trait(item) {
148+
if is_relevant_trait(cx, item) {
150149
check_attrs(cx, item.span, &item.name, &item.attrs)
151150
}
152151
}
153152
}
154153

155-
fn is_relevant_item(item: &Item) -> bool {
154+
fn is_relevant_item(cx: &LateContext, item: &Item) -> bool {
156155
if let ItemFn(_, _, _, _, _, ref block) = item.node {
157-
is_relevant_block(block)
156+
is_relevant_block(cx, block)
158157
} else {
159158
false
160159
}
161160
}
162161

163-
fn is_relevant_impl(item: &ImplItem) -> bool {
162+
fn is_relevant_impl(cx: &LateContext, item: &ImplItem) -> bool {
164163
match item.node {
165-
ImplItemKind::Method(_, ref block) => is_relevant_block(block),
164+
ImplItemKind::Method(_, ref block) => is_relevant_block(cx, block),
166165
_ => false,
167166
}
168167
}
169168

170-
fn is_relevant_trait(item: &TraitItem) -> bool {
169+
fn is_relevant_trait(cx: &LateContext, item: &TraitItem) -> bool {
171170
match item.node {
172171
MethodTraitItem(_, None) => true,
173-
MethodTraitItem(_, Some(ref block)) => is_relevant_block(block),
172+
MethodTraitItem(_, Some(ref block)) => is_relevant_block(cx, block),
174173
_ => false,
175174
}
176175
}
177176

178-
fn is_relevant_block(block: &Block) -> bool {
177+
fn is_relevant_block(cx: &LateContext, block: &Block) -> bool {
179178
for stmt in &block.stmts {
180179
match stmt.node {
181180
StmtDecl(_, _) => return true,
182181
StmtExpr(ref expr, _) |
183182
StmtSemi(ref expr, _) => {
184-
return is_relevant_expr(expr);
183+
return is_relevant_expr(cx, expr);
185184
}
186185
}
187186
}
188-
block.expr.as_ref().map_or(false, |e| is_relevant_expr(e))
187+
block.expr.as_ref().map_or(false, |e| is_relevant_expr(cx, e))
189188
}
190189

191-
fn is_relevant_expr(expr: &Expr) -> bool {
190+
fn is_relevant_expr(cx: &LateContext, expr: &Expr) -> bool {
192191
match expr.node {
193-
ExprBlock(ref block) => is_relevant_block(block),
194-
ExprRet(Some(ref e)) => is_relevant_expr(e),
192+
ExprBlock(ref block) => is_relevant_block(cx, block),
193+
ExprRet(Some(ref e)) => is_relevant_expr(cx, e),
195194
ExprRet(None) | ExprBreak(_) => false,
196195
ExprCall(ref path_expr, _) => {
197-
if let ExprPath(_, ref path) = path_expr.node {
198-
!match_path(path, &paths::BEGIN_PANIC)
196+
if let ExprPath(..) = path_expr.node {
197+
let fun_id = resolve_node(cx, path_expr.id).expect("function should be resolved").def_id();
198+
!match_def_path(cx, fun_id, &paths::BEGIN_PANIC)
199199
} else {
200200
true
201201
}

clippy_lints/src/format.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use rustc::lint::*;
44
use rustc::ty::TypeVariants;
55
use syntax::ast::LitKind;
66
use utils::paths;
7-
use utils::{is_expn_of, match_path, match_type, span_lint, walk_ptrs_ty};
7+
use utils::{is_expn_of, match_def_path, match_path, match_type, resolve_node, span_lint, walk_ptrs_ty};
88

99
/// **What it does:** Checks for the use of `format!("string literal with no
1010
/// argument")` and `format!("{}", foo)` where `foo` is a string.
@@ -44,9 +44,10 @@ impl LateLintPass for Pass {
4444
// `format!("{}", foo)` expansion
4545
ExprCall(ref fun, ref args) => {
4646
if_let_chain!{[
47-
let ExprPath(_, ref path) = fun.node,
47+
let ExprPath(..) = fun.node,
4848
args.len() == 2,
49-
match_path(path, &paths::FMT_ARGUMENTS_NEWV1),
49+
let Some(fun) = resolve_node(cx, fun.id),
50+
match_def_path(cx, fun.def_id(), &paths::FMT_ARGUMENTS_NEWV1),
5051
// ensure the format string is `"{..}"` with only one argument and no text
5152
check_static_str(cx, &args[0]),
5253
// ensure the format argument is `{}` ie. Display with no fancy option
@@ -127,8 +128,9 @@ fn check_arg_is_display(cx: &LateContext, expr: &Expr) -> bool {
127128
exprs.len() == 1,
128129
let ExprCall(_, ref args) = exprs[0].node,
129130
args.len() == 2,
130-
let ExprPath(None, ref path) = args[1].node,
131-
match_path(path, &paths::DISPLAY_FMT_METHOD)
131+
let ExprPath(None, _) = args[1].node,
132+
let Some(fun) = resolve_node(cx, args[1].id),
133+
match_def_path(cx, fun.def_id(), &paths::DISPLAY_FMT_METHOD),
132134
], {
133135
let ty = walk_ptrs_ty(cx.tcx.pat_ty(&pat[0]));
134136

clippy_lints/src/panic.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use rustc::hir::*;
22
use rustc::lint::*;
33
use syntax::ast::LitKind;
4-
use utils::{is_direct_expn_of, match_path, paths, span_lint};
4+
use utils::{is_direct_expn_of, match_def_path, resolve_node, paths, span_lint};
55

66
/// **What it does:** Checks for missing parameters in `panic!`.
77
///
@@ -39,8 +39,9 @@ impl LateLintPass for Pass {
3939
let Some(ref ex) = block.expr,
4040
let ExprCall(ref fun, ref params) = ex.node,
4141
params.len() == 2,
42-
let ExprPath(None, ref path) = fun.node,
43-
match_path(path, &paths::BEGIN_PANIC),
42+
let ExprPath(None, _) = fun.node,
43+
let Some(fun) = resolve_node(cx, fun.id),
44+
match_def_path(cx, fun.def_id(), &paths::BEGIN_PANIC),
4445
let ExprLit(ref lit) = params[0].node,
4546
is_direct_expn_of(cx, params[0].span, "panic").is_some(),
4647
let LitKind::Str(ref string, _) = lit.node,

clippy_lints/src/print.rs

+55-49
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use rustc::hir::*;
22
use rustc::hir::map::Node::{NodeItem, NodeImplItem};
33
use rustc::lint::*;
44
use utils::paths;
5-
use utils::{is_expn_of, match_path, span_lint};
5+
use utils::{is_expn_of, match_path, match_def_path, resolve_node, span_lint};
66
use format::get_argument_fmtstr_parts;
77

88
/// **What it does:** This lint warns when you using `print!()` with a format string that
@@ -67,63 +67,69 @@ impl LintPass for Pass {
6767

6868
impl LateLintPass for Pass {
6969
fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
70-
if let ExprCall(ref fun, ref args) = expr.node {
71-
if let ExprPath(_, ref path) = fun.node {
72-
// Search for `std::io::_print(..)` which is unique in a
73-
// `print!` expansion.
74-
if match_path(path, &paths::IO_PRINT) {
75-
if let Some(span) = is_expn_of(cx, expr.span, "print") {
76-
// `println!` uses `print!`.
77-
let (span, name) = match is_expn_of(cx, span, "println") {
78-
Some(span) => (span, "println"),
79-
None => (span, "print"),
80-
};
70+
if_let_chain! {[
71+
let ExprCall(ref fun, ref args) = expr.node,
72+
let ExprPath(..) = fun.node,
73+
let Some(fun) = resolve_node(cx, fun.id),
74+
], {
75+
let fun_id = fun.def_id();
8176

82-
span_lint(cx, PRINT_STDOUT, span, &format!("use of `{}!`", name));
77+
// Search for `std::io::_print(..)` which is unique in a
78+
// `print!` expansion.
79+
if match_def_path(cx, fun_id, &paths::IO_PRINT) {
80+
if let Some(span) = is_expn_of(cx, expr.span, "print") {
81+
// `println!` uses `print!`.
82+
let (span, name) = match is_expn_of(cx, span, "println") {
83+
Some(span) => (span, "println"),
84+
None => (span, "print"),
85+
};
8386

84-
// Check print! with format string ending in "\n".
85-
if_let_chain!{[
86-
name == "print",
87+
span_lint(cx, PRINT_STDOUT, span, &format!("use of `{}!`", name));
8788

88-
// ensure we're calling Arguments::new_v1
89-
args.len() == 1,
90-
let ExprCall(ref args_fun, ref args_args) = args[0].node,
91-
let ExprPath(_, ref args_path) = args_fun.node,
92-
match_path(args_path, &paths::FMT_ARGUMENTS_NEWV1),
93-
args_args.len() == 2,
94-
let ExprAddrOf(_, ref match_expr) = args_args[1].node,
95-
let ExprMatch(ref args, _, _) = match_expr.node,
96-
let ExprTup(ref args) = args.node,
89+
// Check print! with format string ending in "\n".
90+
if_let_chain!{[
91+
name == "print",
9792

98-
// collect the format string parts and check the last one
99-
let Some(fmtstrs) = get_argument_fmtstr_parts(cx, &args_args[0]),
100-
let Some(last_str) = fmtstrs.last(),
101-
let Some('\n') = last_str.chars().last(),
93+
// ensure we're calling Arguments::new_v1
94+
args.len() == 1,
95+
let ExprCall(ref args_fun, ref args_args) = args[0].node,
96+
let ExprPath(..) = args_fun.node,
97+
let Some(def) = resolve_node(cx, args_fun.id),
98+
match_def_path(cx, def.def_id(), &paths::FMT_ARGUMENTS_NEWV1),
99+
args_args.len() == 2,
100+
let ExprAddrOf(_, ref match_expr) = args_args[1].node,
101+
let ExprMatch(ref args, _, _) = match_expr.node,
102+
let ExprTup(ref args) = args.node,
102103

103-
// "foo{}bar" is made into two strings + one argument,
104-
// if the format string starts with `{}` (eg. "{}foo"),
105-
// the string array is prepended an empty string "".
106-
// We only want to check the last string after any `{}`:
107-
args.len() < fmtstrs.len(),
108-
], {
109-
span_lint(cx, PRINT_WITH_NEWLINE, span,
110-
"using `print!()` with a format string that ends in a \
111-
newline, consider using `println!()` instead");
112-
}}
113-
}
104+
// collect the format string parts and check the last one
105+
let Some(fmtstrs) = get_argument_fmtstr_parts(cx, &args_args[0]),
106+
let Some(last_str) = fmtstrs.last(),
107+
let Some('\n') = last_str.chars().last(),
108+
109+
// "foo{}bar" is made into two strings + one argument,
110+
// if the format string starts with `{}` (eg. "{}foo"),
111+
// the string array is prepended an empty string "".
112+
// We only want to check the last string after any `{}`:
113+
args.len() < fmtstrs.len(),
114+
], {
115+
span_lint(cx, PRINT_WITH_NEWLINE, span,
116+
"using `print!()` with a format string that ends in a \
117+
newline, consider using `println!()` instead");
118+
}}
114119
}
115-
// Search for something like
116-
// `::std::fmt::ArgumentV1::new(__arg0, ::std::fmt::Debug::fmt)`
117-
else if args.len() == 2 && match_path(path, &paths::FMT_ARGUMENTV1_NEW) {
118-
if let ExprPath(None, ref path) = args[1].node {
119-
if match_path(path, &paths::DEBUG_FMT_METHOD) && !is_in_debug_impl(cx, expr) &&
120-
is_expn_of(cx, expr.span, "panic").is_none() {
121-
span_lint(cx, USE_DEBUG, args[0].span, "use of `Debug`-based formatting");
122-
}
120+
}
121+
// Search for something like
122+
// `::std::fmt::ArgumentV1::new(__arg0, ::std::fmt::Debug::fmt)`
123+
else if args.len() == 2 && match_def_path(cx, fun_id, &paths::FMT_ARGUMENTV1_NEW) {
124+
if let ExprPath(None, _) = args[1].node {
125+
let def_id = resolve_node(cx, args[1].id).unwrap().def_id();
126+
if match_def_path(cx, def_id, &paths::DEBUG_FMT_METHOD) && !is_in_debug_impl(cx, expr) &&
127+
is_expn_of(cx, expr.span, "panic").is_none() {
128+
span_lint(cx, USE_DEBUG, args[0].span, "use of `Debug`-based formatting");
123129
}
124130
}
125131
}
126-
}
132+
}}
127133
}
128134
}
129135

clippy_lints/src/utils/higher.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rustc::hir;
66
use rustc::lint::LateContext;
77
use syntax::ast;
88
use syntax::ptr::P;
9-
use utils::{is_expn_of, match_path, paths};
9+
use utils::{is_expn_of, match_path, match_def_path, resolve_node, paths};
1010

1111
/// Convert a hir binary operator to the corresponding `ast` type.
1212
pub fn binop(op: hir::BinOp_) -> ast::BinOpKind {
@@ -170,9 +170,10 @@ pub fn vec_macro<'e>(cx: &LateContext, expr: &'e hir::Expr) -> Option<VecArgs<'e
170170
if_let_chain!{[
171171
let hir::ExprCall(ref fun, ref args) = expr.node,
172172
let hir::ExprPath(_, ref path) = fun.node,
173-
is_expn_of(cx, fun.span, "vec").is_some()
173+
let Some(fun_def) = resolve_node(cx, fun.id),
174+
is_expn_of(cx, fun.span, "vec").is_some(),
174175
], {
175-
return if match_path(path, &paths::VEC_FROM_ELEM) && args.len() == 2 {
176+
return if match_def_path(cx, fun_def.def_id(), &paths::VEC_FROM_ELEM) && args.len() == 2 {
176177
// `vec![elem; size]` case
177178
Some(VecArgs::Repeat(&args[0], &args[1]))
178179
}

clippy_lints/src/utils/mod.rs

+5
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,11 @@ pub fn implements_trait<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: ty::Ty<'tcx>,
279279
})
280280
}
281281

282+
/// Resolve the definition of a node from its `NodeId`.
283+
pub fn resolve_node(cx: &LateContext, id: NodeId) -> Option<def::Def> {
284+
cx.tcx.def_map.borrow().get(&id).map(|d| d.full_def())
285+
}
286+
282287
/// Match an `Expr` against a chain of methods, and return the matched `Expr`s.
283288
///
284289
/// For example, if `expr` represents the `.baz()` in `foo.bar().baz()`,

clippy_lints/src/utils/paths.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! This module contains paths to types and functions Clippy needs to know about.
22
3-
pub const BEGIN_PANIC: [&'static str; 3] = ["std", "rt", "begin_panic"];
3+
pub const BEGIN_PANIC: [&'static str; 3] = ["std", "panicking", "begin_panic"];
44
pub const BINARY_HEAP: [&'static str; 3] = ["collections", "binary_heap", "BinaryHeap"];
55
pub const BOX: [&'static str; 3] = ["std", "boxed", "Box"];
66
pub const BOX_NEW: [&'static str; 4] = ["std", "boxed", "Box", "new"];
@@ -13,18 +13,18 @@ pub const CMP_MAX: [&'static str; 3] = ["core", "cmp", "max"];
1313
pub const CMP_MIN: [&'static str; 3] = ["core", "cmp", "min"];
1414
pub const COW: [&'static str; 3] = ["collections", "borrow", "Cow"];
1515
pub const CSTRING_NEW: [&'static str; 4] = ["std", "ffi", "CString", "new"];
16-
pub const DEBUG_FMT_METHOD: [&'static str; 4] = ["std", "fmt", "Debug", "fmt"];
16+
pub const DEBUG_FMT_METHOD: [&'static str; 4] = ["core", "fmt", "Debug", "fmt"];
1717
pub const DEFAULT_TRAIT: [&'static str; 3] = ["core", "default", "Default"];
18-
pub const DISPLAY_FMT_METHOD: [&'static str; 4] = ["std", "fmt", "Display", "fmt"];
18+
pub const DISPLAY_FMT_METHOD: [&'static str; 4] = ["core", "fmt", "Display", "fmt"];
1919
pub const DROP: [&'static str; 3] = ["core", "mem", "drop"];
20-
pub const FMT_ARGUMENTS_NEWV1: [&'static str; 4] = ["std", "fmt", "Arguments", "new_v1"];
21-
pub const FMT_ARGUMENTV1_NEW: [&'static str; 4] = ["std", "fmt", "ArgumentV1", "new"];
20+
pub const FMT_ARGUMENTS_NEWV1: [&'static str; 4] = ["core", "fmt", "Arguments", "new_v1"];
21+
pub const FMT_ARGUMENTV1_NEW: [&'static str; 4] = ["core", "fmt", "ArgumentV1", "new"];
2222
pub const HASH: [&'static str; 2] = ["hash", "Hash"];
2323
pub const HASHMAP: [&'static str; 5] = ["std", "collections", "hash", "map", "HashMap"];
2424
pub const HASHMAP_ENTRY: [&'static str; 5] = ["std", "collections", "hash", "map", "Entry"];
2525
pub const HASHSET: [&'static str; 5] = ["std", "collections", "hash", "set", "HashSet"];
2626
pub const INTO_ITERATOR: [&'static str; 4] = ["core", "iter", "traits", "IntoIterator"];
27-
pub const IO_PRINT: [&'static str; 3] = ["std", "io", "_print"];
27+
pub const IO_PRINT: [&'static str; 4] = ["std", "io", "stdio", "_print"];
2828
pub const ITERATOR: [&'static str; 4] = ["core", "iter", "iterator", "Iterator"];
2929
pub const LINKED_LIST: [&'static str; 3] = ["collections", "linked_list", "LinkedList"];
3030
pub const LINT: [&'static str; 3] = ["rustc", "lint", "Lint"];
@@ -64,4 +64,4 @@ pub const STRING: [&'static str; 3] = ["collections", "string", "String"];
6464
pub const TRANSMUTE: [&'static str; 4] = ["core", "intrinsics", "", "transmute"];
6565
pub const VEC: [&'static str; 3] = ["collections", "vec", "Vec"];
6666
pub const VEC_DEQUE: [&'static str; 3] = ["collections", "vec_deque", "VecDeque"];
67-
pub const VEC_FROM_ELEM: [&'static str; 3] = ["std", "vec", "from_elem"];
67+
pub const VEC_FROM_ELEM: [&'static str; 3] = ["collections", "vec", "from_elem"];

0 commit comments

Comments
 (0)