Skip to content

Commit 0bb4cbe

Browse files
committed
Merge pull request #377 from Manishearth/rustup
Rust upgrade to rustc 1.5.0-nightly (9d3e79a 2015-10-10)
2 parents 6f84e35 + 4e2b098 commit 0bb4cbe

File tree

6 files changed

+102
-86
lines changed

6 files changed

+102
-86
lines changed

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
7575
reg.register_late_lint_pass(box misc::ModuloOne);
7676
reg.register_late_lint_pass(box unicode::Unicode);
7777
reg.register_late_lint_pass(box strings::StringAdd);
78-
reg.register_late_lint_pass(box returns::ReturnPass);
78+
reg.register_early_lint_pass(box returns::ReturnPass);
7979
reg.register_late_lint_pass(box methods::MethodsPass);
8080
reg.register_late_lint_pass(box shadow::ShadowPass);
8181
reg.register_late_lint_pass(box types::LetPass);

src/returns.rs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
use rustc::lint::*;
2-
use rustc_front::hir::*;
3-
use reexport::*;
2+
use syntax::ast::*;
3+
//use reexport::*;
44
use syntax::codemap::{Span, Spanned};
5-
use rustc_front::visit::FnKind;
5+
use syntax::visit::FnKind;
66

7-
use utils::{span_lint, snippet, match_path, in_external_macro};
7+
use utils::{span_lint, snippet, match_path_ast, in_external_macro};
88

99
declare_lint!(pub NEEDLESS_RETURN, Warn,
1010
"using a return statement like `return expr;` where an expression would suffice");
@@ -17,7 +17,7 @@ pub struct ReturnPass;
1717

1818
impl ReturnPass {
1919
// Check the final stmt or expr in a block for unnecessary return.
20-
fn check_block_return(&mut self, cx: &LateContext, block: &Block) {
20+
fn check_block_return(&mut self, cx: &EarlyContext, block: &Block) {
2121
if let Some(ref expr) = block.expr {
2222
self.check_final_expr(cx, expr);
2323
} else if let Some(stmt) = block.stmts.last() {
@@ -30,7 +30,7 @@ impl ReturnPass {
3030
}
3131

3232
// Check a the final expression in a block if it's a return.
33-
fn check_final_expr(&mut self, cx: &LateContext, expr: &Expr) {
33+
fn check_final_expr(&mut self, cx: &EarlyContext, expr: &Expr) {
3434
match expr.node {
3535
// simple return is always "bad"
3636
ExprRet(Some(ref inner)) => {
@@ -48,7 +48,7 @@ impl ReturnPass {
4848
self.check_final_expr(cx, elsexpr);
4949
}
5050
// a match expr, check all arms
51-
ExprMatch(_, ref arms, _) => {
51+
ExprMatch(_, ref arms) => {
5252
for arm in arms {
5353
self.check_final_expr(cx, &arm.body);
5454
}
@@ -57,7 +57,7 @@ impl ReturnPass {
5757
}
5858
}
5959

60-
fn emit_return_lint(&mut self, cx: &LateContext, spans: (Span, Span)) {
60+
fn emit_return_lint(&mut self, cx: &EarlyContext, spans: (Span, Span)) {
6161
if in_external_macro(cx, spans.1) {return;}
6262
span_lint(cx, NEEDLESS_RETURN, spans.0, &format!(
6363
"unneeded return statement. Consider using `{}` \
@@ -66,7 +66,7 @@ impl ReturnPass {
6666
}
6767

6868
// Check for "let x = EXPR; x"
69-
fn check_let_return(&mut self, cx: &LateContext, block: &Block) {
69+
fn check_let_return(&mut self, cx: &EarlyContext, block: &Block) {
7070
// we need both a let-binding stmt and an expr
7171
if_let_chain! {
7272
[
@@ -77,14 +77,14 @@ impl ReturnPass {
7777
let Some(ref initexpr) = local.init,
7878
let PatIdent(_, Spanned { node: id, .. }, _) = local.pat.node,
7979
let ExprPath(_, ref path) = retexpr.node,
80-
match_path(path, &[&id.name.as_str()])
80+
match_path_ast(path, &[&id.name.as_str()])
8181
], {
8282
self.emit_let_lint(cx, retexpr.span, initexpr.span);
8383
}
8484
}
8585
}
8686

87-
fn emit_let_lint(&mut self, cx: &LateContext, lint_span: Span, note_span: Span) {
87+
fn emit_let_lint(&mut self, cx: &EarlyContext, lint_span: Span, note_span: Span) {
8888
if in_external_macro(cx, note_span) {return;}
8989
span_lint(cx, LET_AND_RETURN, lint_span,
9090
"returning the result of a let binding from a block. \
@@ -102,13 +102,13 @@ impl LintPass for ReturnPass {
102102
}
103103
}
104104

105-
impl LateLintPass for ReturnPass {
106-
fn check_fn(&mut self, cx: &LateContext, _: FnKind, _: &FnDecl,
105+
impl EarlyLintPass for ReturnPass {
106+
fn check_fn(&mut self, cx: &EarlyContext, _: FnKind, _: &FnDecl,
107107
block: &Block, _: Span, _: NodeId) {
108108
self.check_block_return(cx, block);
109109
}
110110

111-
fn check_block(&mut self, cx: &LateContext, block: &Block) {
111+
fn check_block(&mut self, cx: &EarlyContext, block: &Block) {
112112
self.check_let_return(cx, block);
113113
}
114114
}

src/shadow.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc_front::visit::FnKind;
77
use rustc::lint::*;
88
use rustc::middle::def::Def::{DefVariant, DefStruct};
99

10-
use utils::{in_external_macro, snippet, span_lint, span_note_and_lint};
10+
use utils::{is_from_for_desugar, in_external_macro, snippet, span_lint, span_note_and_lint};
1111

1212
declare_lint!(pub SHADOW_SAME, Allow,
1313
"rebinding a name to itself, e.g. `let mut x = &mut x`");
@@ -60,6 +60,7 @@ fn check_block(cx: &LateContext, block: &Block, bindings: &mut Vec<(Name, Span)>
6060

6161
fn check_decl(cx: &LateContext, decl: &Decl, bindings: &mut Vec<(Name, Span)>) {
6262
if in_external_macro(cx, decl.span) { return; }
63+
if is_from_for_desugar(decl) { return; }
6364
if let DeclLocal(ref local) = decl.node {
6465
let Local{ ref pat, ref ty, ref init, id: _, span } = **local;
6566
if let &Some(ref t) = ty { check_ty(cx, t, bindings) }

src/types.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ use syntax::ast::IntTy::*;
99
use syntax::ast::UintTy::*;
1010
use syntax::ast::FloatTy::*;
1111

12-
use utils::{match_type, snippet, span_lint, span_help_and_lint, in_macro, in_external_macro};
12+
use utils::{match_type, snippet, span_lint, span_help_and_lint};
13+
use utils::{is_from_for_desugar, in_macro, in_external_macro};
1314
use utils::{LL_PATH, VEC_PATH};
1415

1516
/// Handles all the linting of funky types
@@ -61,9 +62,10 @@ fn check_let_unit(cx: &LateContext, decl: &Decl) {
6162
if *bindtype == ty::TyTuple(vec![]) {
6263
if in_external_macro(cx, decl.span) ||
6364
in_macro(cx, local.pat.span) { return; }
64-
span_lint(cx, LET_UNIT_VALUE, decl.span, &format!(
65-
"this let-binding has unit value. Consider omitting `let {} =`",
66-
snippet(cx, local.pat.span, "..")));
65+
if is_from_for_desugar(decl) { return; }
66+
span_lint(cx, LET_UNIT_VALUE, decl.span, &format!(
67+
"this let-binding has unit value. Consider omitting `let {} =`",
68+
snippet(cx, local.pat.span, "..")));
6769
}
6870
}
6971
}

src/utils.rs

Lines changed: 76 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use rustc::middle::def_id::DefId;
77
use rustc::middle::ty;
88
use std::borrow::Cow;
99
use syntax::ast::Lit_::*;
10+
use syntax::ast;
1011

1112
// module DefPaths for certain structs/enums we check for
1213
pub const OPTION_PATH: [&'static str; 3] = ["core", "option", "Option"];
@@ -15,15 +16,56 @@ pub const STRING_PATH: [&'static str; 3] = ["collections", "string", "String"];
1516
pub const VEC_PATH: [&'static str; 3] = ["collections", "vec", "Vec"];
1617
pub const LL_PATH: [&'static str; 3] = ["collections", "linked_list", "LinkedList"];
1718

19+
/// Produce a nested chain of if-lets and ifs from the patterns:
20+
///
21+
/// if_let_chain! {
22+
/// [
23+
/// Some(y) = x,
24+
/// y.len() == 2,
25+
/// Some(z) = y,
26+
/// ],
27+
/// {
28+
/// block
29+
/// }
30+
/// }
31+
///
32+
/// becomes
33+
///
34+
/// if let Some(y) = x {
35+
/// if y.len() == 2 {
36+
/// if let Some(z) = y {
37+
/// block
38+
/// }
39+
/// }
40+
/// }
41+
#[macro_export]
42+
macro_rules! if_let_chain {
43+
([let $pat:pat = $expr:expr, $($tt:tt)+], $block:block) => {
44+
if let $pat = $expr {
45+
if_let_chain!{ [$($tt)+], $block }
46+
}
47+
};
48+
([let $pat:pat = $expr:expr], $block:block) => {
49+
if let $pat = $expr {
50+
$block
51+
}
52+
};
53+
([$expr:expr, $($tt:tt)+], $block:block) => {
54+
if $expr {
55+
if_let_chain!{ [$($tt)+], $block }
56+
}
57+
};
58+
([$expr:expr], $block:block) => {
59+
if $expr {
60+
$block
61+
}
62+
};
63+
}
64+
1865
/// returns true this expn_info was expanded by any macro
1966
pub fn in_macro(cx: &LateContext, span: Span) -> bool {
2067
cx.sess().codemap().with_expn_info(span.expn_id,
21-
|info| info.map_or(false, |i| {
22-
match i.callee.format {
23-
ExpnFormat::CompilerExpansion(..) => false,
24-
_ => true,
25-
}
26-
}))
68+
|info| info.is_some())
2769
}
2870

2971
/// returns true if the macro that expanded the crate was outside of
@@ -34,17 +76,9 @@ pub fn in_external_macro<T: LintContext>(cx: &T, span: Span) -> bool {
3476
fn in_macro_ext<T: LintContext>(cx: &T, opt_info: Option<&ExpnInfo>) -> bool {
3577
// no ExpnInfo = no macro
3678
opt_info.map_or(false, |info| {
37-
match info.callee.format {
38-
ExpnFormat::CompilerExpansion(..) => {
39-
if info.callee.name().as_str() == "closure expansion" {
40-
return false;
41-
}
42-
},
43-
ExpnFormat::MacroAttribute(..) => {
44-
// these are all plugins
45-
return true;
46-
},
47-
_ => (),
79+
if let ExpnFormat::MacroAttribute(..) = info.callee.format {
80+
// these are all plugins
81+
return true;
4882
}
4983
// no span for the callee = external macro
5084
info.callee.span.map_or(true, |span| {
@@ -102,6 +136,13 @@ pub fn match_path(path: &Path, segments: &[&str]) -> bool {
102136
|(a, b)| a.identifier.name.as_str() == *b)
103137
}
104138

139+
/// match a Path against a slice of segment string literals, e.g.
140+
/// `match_path(path, &["std", "rt", "begin_unwind"])`
141+
pub fn match_path_ast(path: &ast::Path, segments: &[&str]) -> bool {
142+
path.segments.iter().rev().zip(segments.iter().rev()).all(
143+
|(a, b)| a.identifier.name.as_str() == *b)
144+
}
145+
105146
/// get the name of the item the expression is in, if available
106147
pub fn get_item_name(cx: &LateContext, expr: &Expr) -> Option<Name> {
107148
let parent_id = cx.tcx.map.get_parent(expr.id);
@@ -115,6 +156,24 @@ pub fn get_item_name(cx: &LateContext, expr: &Expr) -> Option<Name> {
115156
}
116157
}
117158

159+
/// checks if a `let` decl is from a for loop desugaring
160+
pub fn is_from_for_desugar(decl: &Decl) -> bool {
161+
if_let_chain! {
162+
[
163+
let DeclLocal(ref loc) = decl.node,
164+
let Some(ref expr) = loc.init,
165+
// FIXME: This should check for MatchSource::ForLoop
166+
// but right now there's a bug where the match source isn't
167+
// set during lowering
168+
// https://github.com/rust-lang/rust/pull/28973
169+
let ExprMatch(_, _, _) = expr.node
170+
],
171+
{ return true; }
172+
};
173+
false
174+
}
175+
176+
118177
/// convert a span to a code snippet if available, otherwise use default, e.g.
119178
/// `snippet(cx, expr.span, "..")`
120179
pub fn snippet<'a, T: LintContext>(cx: &T, span: Span, default: &'a str) -> Cow<'a, str> {
@@ -262,49 +321,3 @@ pub fn is_integer_literal(expr: &Expr, value: u64) -> bool
262321
}
263322
false
264323
}
265-
266-
/// Produce a nested chain of if-lets and ifs from the patterns:
267-
///
268-
/// if_let_chain! {
269-
/// [
270-
/// Some(y) = x,
271-
/// y.len() == 2,
272-
/// Some(z) = y,
273-
/// ],
274-
/// {
275-
/// block
276-
/// }
277-
/// }
278-
///
279-
/// becomes
280-
///
281-
/// if let Some(y) = x {
282-
/// if y.len() == 2 {
283-
/// if let Some(z) = y {
284-
/// block
285-
/// }
286-
/// }
287-
/// }
288-
#[macro_export]
289-
macro_rules! if_let_chain {
290-
([let $pat:pat = $expr:expr, $($tt:tt)+], $block:block) => {
291-
if let $pat = $expr {
292-
if_let_chain!{ [$($tt)+], $block }
293-
}
294-
};
295-
([let $pat:pat = $expr:expr], $block:block) => {
296-
if let $pat = $expr {
297-
$block
298-
}
299-
};
300-
([$expr:expr, $($tt:tt)+], $block:block) => {
301-
if $expr {
302-
if_let_chain!{ [$($tt)+], $block }
303-
}
304-
};
305-
([$expr:expr], $block:block) => {
306-
if $expr {
307-
$block
308-
}
309-
};
310-
}

tests/compile-fail/strings.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
fn add_only() { // ignores assignment distinction
77
let mut x = "".to_owned();
88

9-
for _ in (1..3) {
9+
for _ in 1..3 {
1010
x = x + "."; //~ERROR you added something to a string.
1111
}
1212

@@ -20,7 +20,7 @@ fn add_only() { // ignores assignment distinction
2020
fn add_assign_only() {
2121
let mut x = "".to_owned();
2222

23-
for _ in (1..3) {
23+
for _ in 1..3 {
2424
x = x + "."; //~ERROR you assigned the result of adding something to this string.
2525
}
2626

@@ -34,7 +34,7 @@ fn add_assign_only() {
3434
fn both() {
3535
let mut x = "".to_owned();
3636

37-
for _ in (1..3) {
37+
for _ in 1..3 {
3838
x = x + "."; //~ERROR you assigned the result of adding something to this string.
3939
}
4040

0 commit comments

Comments
 (0)