diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs index 646bcdad5ff..1c4ac3c6261 100644 --- a/clippy_lints/src/attrs.rs +++ b/clippy_lints/src/attrs.rs @@ -215,7 +215,7 @@ fn is_relevant_expr(tcx: ty::TyCtxt, tables: &ty::TypeckTables, expr: &Expr) -> } fn check_attrs(cx: &LateContext, span: Span, name: &Name, attrs: &[Attribute]) { - if in_macro(cx, span) { + if in_macro(span) { return; } diff --git a/clippy_lints/src/block_in_if_condition.rs b/clippy_lints/src/block_in_if_condition.rs index f41d29c569d..cabffa8e969 100644 --- a/clippy_lints/src/block_in_if_condition.rs +++ b/clippy_lints/src/block_in_if_condition.rs @@ -84,7 +84,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BlockInIfCondition { if let Some(ref ex) = block.expr { // don't dig into the expression here, just suggest that they remove // the block - if in_macro(cx, expr.span) || differing_macro_contexts(expr.span, ex.span) { + if in_macro(expr.span) || differing_macro_contexts(expr.span, ex.span) { return; } span_help_and_lint(cx, @@ -97,7 +97,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BlockInIfCondition { } } else { let span = block.expr.as_ref().map_or_else(|| block.stmts[0].span, |e| e.span); - if in_macro(cx, span) || differing_macro_contexts(expr.span, span) { + if in_macro(span) || differing_macro_contexts(expr.span, span) { return; } // move block higher diff --git a/clippy_lints/src/booleans.rs b/clippy_lints/src/booleans.rs index 7ab3af17f4b..fd357feab6b 100644 --- a/clippy_lints/src/booleans.rs +++ b/clippy_lints/src/booleans.rs @@ -93,7 +93,7 @@ impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> { fn run(&mut self, e: &'v Expr) -> Result { // prevent folding of `cfg!` macros and the like - if !in_macro(self.cx, e.span) { + if !in_macro(e.span) { match e.node { ExprUnary(UnNot, ref inner) => return Ok(Bool::Not(box self.run(inner)?)), ExprBinary(binop, ref lhs, ref rhs) => { @@ -394,7 +394,7 @@ impl<'a, 'tcx> NonminimalBoolVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor<'tcx> for NonminimalBoolVisitor<'a, 'tcx> { fn visit_expr(&mut self, e: &'tcx Expr) { - if in_macro(self.cx, e.span) { + if in_macro(e.span) { return; } match e.node { diff --git a/clippy_lints/src/collapsible_if.rs b/clippy_lints/src/collapsible_if.rs index 85bd419df73..06db5319d21 100644 --- a/clippy_lints/src/collapsible_if.rs +++ b/clippy_lints/src/collapsible_if.rs @@ -78,7 +78,7 @@ impl LintPass for CollapsibleIf { impl EarlyLintPass for CollapsibleIf { fn check_expr(&mut self, cx: &EarlyContext, expr: &ast::Expr) { - if !in_macro(cx, expr.span) { + if !in_macro(expr.span) { check_if(cx, expr) } } @@ -103,8 +103,8 @@ fn check_if(cx: &EarlyContext, expr: &ast::Expr) { fn check_collapsible_maybe_if_let(cx: &EarlyContext, else_: &ast::Expr) { if_let_chain! {[ let ast::ExprKind::Block(ref block) = else_.node, - let Some(ref else_) = expr_block(block), - !in_macro(cx, else_.span), + let Some(else_) = expr_block(block), + !in_macro(else_.span), ], { match else_.node { ast::ExprKind::If(..) | ast::ExprKind::IfLet(..) => { @@ -125,7 +125,7 @@ fn check_collapsible_no_if_let(cx: &EarlyContext, expr: &ast::Expr, check: &ast: let Some(inner) = expr_block(then), let ast::ExprKind::If(ref check_inner, ref content, None) = inner.node, ], { - if expr.span.expn_id != inner.span.expn_id { + if expr.span.ctxt != inner.span.ctxt { return; } span_lint_and_then(cx, COLLAPSIBLE_IF, expr.span, "this if statement can be collapsed", |db| { diff --git a/clippy_lints/src/consts.rs b/clippy_lints/src/consts.rs index 7be6f6bf0d6..316a7afdc3a 100644 --- a/clippy_lints/src/consts.rs +++ b/clippy_lints/src/consts.rs @@ -313,10 +313,10 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> { } } - fn ifthenelse(&mut self, cond: &Expr, then: &Block, otherwise: &Option>) -> Option { + fn ifthenelse(&mut self, cond: &Expr, then: &P, otherwise: &Option>) -> Option { if let Some(Constant::Bool(b)) = self.expr(cond) { if b { - self.block(then) + self.expr(&**then) } else { otherwise.as_ref().and_then(|expr| self.expr(expr)) } diff --git a/clippy_lints/src/copies.rs b/clippy_lints/src/copies.rs index 253e7e160fa..ea7bbfe81e0 100644 --- a/clippy_lints/src/copies.rs +++ b/clippy_lints/src/copies.rs @@ -111,7 +111,7 @@ impl LintPass for CopyAndPaste { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CopyAndPaste { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) { - if !in_macro(cx, expr.span) { + if !in_macro(expr.span) { // skip ifs directly in else, it will be checked in the parent if if let Some(&Expr { node: ExprIf(_, _, Some(ref else_expr)), .. }) = get_parent_expr(cx, expr) { if else_expr.id == expr.id { @@ -223,11 +223,15 @@ fn lint_match_arms(cx: &LateContext, expr: &Expr) { /// `if a { c } else if b { d } else { e }`. fn if_sequence(mut expr: &Expr) -> (SmallVector<&Expr>, SmallVector<&Block>) { let mut conds = SmallVector::new(); - let mut blocks = SmallVector::new(); + let mut blocks : SmallVector<&Block> = SmallVector::new(); - while let ExprIf(ref cond, ref then_block, ref else_expr) = expr.node { + while let ExprIf(ref cond, ref then_expr, ref else_expr) = expr.node { conds.push(&**cond); - blocks.push(&**then_block); + if let ExprBlock(ref block) = then_expr.node { + blocks.push(block); + } else { + panic!("ExprIf node is not an ExprBlock"); + } if let Some(ref else_expr) = *else_expr { expr = else_expr; @@ -311,10 +315,10 @@ fn search_same(exprs: &[T], hash: Hash, eq: Eq) -> Option<(&T, &T)> return None; } else if exprs.len() == 2 { return if eq(&exprs[0], &exprs[1]) { - Some((&exprs[0], &exprs[1])) - } else { - None - }; + Some((&exprs[0], &exprs[1])) + } else { + None + }; } let mut map: HashMap<_, Vec<&_>> = HashMap::with_capacity(exprs.len()); diff --git a/clippy_lints/src/cyclomatic_complexity.rs b/clippy_lints/src/cyclomatic_complexity.rs index 03882a0acf5..ed836af4403 100644 --- a/clippy_lints/src/cyclomatic_complexity.rs +++ b/clippy_lints/src/cyclomatic_complexity.rs @@ -42,7 +42,7 @@ impl LintPass for CyclomaticComplexity { impl CyclomaticComplexity { fn check<'a, 'tcx: 'a>(&mut self, cx: &'a LateContext<'a, 'tcx>, body: &'tcx Body, span: Span) { - if in_macro(cx, span) { + if in_macro(span) { return; } diff --git a/clippy_lints/src/entry.rs b/clippy_lints/src/entry.rs index 860003587bc..06e9268d22a 100644 --- a/clippy_lints/src/entry.rs +++ b/clippy_lints/src/entry.rs @@ -1,5 +1,5 @@ use rustc::hir::*; -use rustc::hir::intravisit::{Visitor, walk_expr, walk_block, NestedVisitorMap}; +use rustc::hir::intravisit::{Visitor, walk_expr, NestedVisitorMap}; use rustc::lint::*; use syntax::codemap::Span; use utils::SpanlessEq; @@ -46,8 +46,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for HashMapLint { if let Some((ty, map, key)) = check_cond(cx, check) { // in case of `if !m.contains_key(&k) { m.insert(k, v); }` // we can give a better error message - let sole_expr = else_block.is_none() && - ((then_block.expr.is_some() as usize) + then_block.stmts.len() == 1); + let sole_expr = { + else_block.is_none() && + if let ExprBlock(ref then_block) = then_block.node { + (then_block.expr.is_some() as usize) + then_block.stmts.len() == 1 + } else { + true + } + }; let mut visitor = InsertVisitor { cx: cx, @@ -58,7 +64,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for HashMapLint { sole_expr: sole_expr, }; - walk_block(&mut visitor, then_block); + walk_expr(&mut visitor, &**then_block); } } else if let Some(ref else_block) = *else_block { if let Some((ty, map, key)) = check_cond(cx, check) { diff --git a/clippy_lints/src/enum_variants.rs b/clippy_lints/src/enum_variants.rs index d0c75125df0..16a2e021723 100644 --- a/clippy_lints/src/enum_variants.rs +++ b/clippy_lints/src/enum_variants.rs @@ -228,7 +228,7 @@ impl EarlyLintPass for EnumVariantNames { let item_name = item.ident.name.as_str(); let item_name_chars = item_name.chars().count(); let item_camel = to_camel_case(&item_name); - if !in_macro(cx, item.span) { + if !in_macro(item.span) { if let Some(&(ref mod_name, ref mod_camel)) = self.modules.last() { // constants don't have surrounding modules if !mod_camel.is_empty() { diff --git a/clippy_lints/src/format.rs b/clippy_lints/src/format.rs index 32e02e30b79..bcbb8b1cccd 100644 --- a/clippy_lints/src/format.rs +++ b/clippy_lints/src/format.rs @@ -40,7 +40,7 @@ impl LintPass for Pass { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) { - if let Some(span) = is_expn_of(cx, expr.span, "format") { + if let Some(span) = is_expn_of(expr.span, "format") { match expr.node { // `format!("{}", foo)` expansion ExprCall(ref fun, ref args) => { diff --git a/clippy_lints/src/formatting.rs b/clippy_lints/src/formatting.rs index 90c0a5a9172..7fa8c3deb99 100644 --- a/clippy_lints/src/formatting.rs +++ b/clippy_lints/src/formatting.rs @@ -1,6 +1,6 @@ use rustc::lint::*; -use syntax::codemap::mk_sp; use syntax::ast; +use syntax_pos::{Span, NO_EXPANSION}; use utils::{differing_macro_contexts, in_macro, snippet_opt, span_note_and_lint}; use syntax::ptr::P; @@ -99,13 +99,12 @@ impl EarlyLintPass for Formatting { /// Implementation of the `SUSPICIOUS_ASSIGNMENT_FORMATTING` lint. fn check_assign(cx: &EarlyContext, expr: &ast::Expr) { if let ast::ExprKind::Assign(ref lhs, ref rhs) = expr.node { - if !differing_macro_contexts(lhs.span, rhs.span) && !in_macro(cx, lhs.span) { - let eq_span = mk_sp(lhs.span.hi, rhs.span.lo); - + if !differing_macro_contexts(lhs.span, rhs.span) && !in_macro(lhs.span) { + let eq_span = Span { lo: lhs.span.hi, hi: rhs.span.lo, ctxt: NO_EXPANSION }; if let ast::ExprKind::Unary(op, ref sub_rhs) = rhs.node { if let Some(eq_snippet) = snippet_opt(cx, eq_span) { let op = ast::UnOp::to_string(op); - let eqop_span = mk_sp(lhs.span.hi, sub_rhs.span.lo); + let eqop_span= Span { lo: lhs.span.hi, hi: sub_rhs.span.lo, ctxt: NO_EXPANSION }; if eq_snippet.ends_with('=') { span_note_and_lint(cx, SUSPICIOUS_ASSIGNMENT_FORMATTING, @@ -125,10 +124,10 @@ fn check_assign(cx: &EarlyContext, expr: &ast::Expr) { /// Implementation of the `SUSPICIOUS_ELSE_FORMATTING` lint for weird `else if`. fn check_else_if(cx: &EarlyContext, expr: &ast::Expr) { if let Some((then, &Some(ref else_))) = unsugar_if(expr) { - if unsugar_if(else_).is_some() && !differing_macro_contexts(then.span, else_.span) && !in_macro(cx, then.span) { + if unsugar_if(else_).is_some() && !differing_macro_contexts(then.span, else_.span) && !in_macro(then.span) { // this will be a span from the closing ‘}’ of the “then” block (excluding) to the // “if” of the “else if” block (excluding) - let else_span = mk_sp(then.span.hi, else_.span.lo); + let else_span = Span { lo: then.span.hi, hi: else_.span.lo, ctxt: NO_EXPANSION }; // the snippet should look like " else \n " with maybe comments anywhere // it’s bad when there is a ‘\n’ after the “else” @@ -155,9 +154,9 @@ fn check_array(cx: &EarlyContext, expr: &ast::Expr) { for element in array { if let ast::ExprKind::Binary(ref op, ref lhs, _) = element.node { if !differing_macro_contexts(lhs.span, op.span) { - let space_span = mk_sp(lhs.span.hi, op.span.lo); + let space_span = Span { lo: lhs.span.hi, hi: op.span.lo, ctxt: NO_EXPANSION }; if let Some(space_snippet) = snippet_opt(cx, space_span) { - let lint_span = mk_sp(lhs.span.hi, lhs.span.hi); + let lint_span = Span { lo: lhs.span.hi, hi: lhs.span.hi, ctxt: NO_EXPANSION }; if space_snippet.contains('\n') { span_note_and_lint(cx, POSSIBLE_MISSING_COMMA, @@ -175,10 +174,10 @@ fn check_array(cx: &EarlyContext, expr: &ast::Expr) { /// Implementation of the `SUSPICIOUS_ELSE_FORMATTING` lint for consecutive ifs. fn check_consecutive_ifs(cx: &EarlyContext, first: &ast::Expr, second: &ast::Expr) { - if !differing_macro_contexts(first.span, second.span) && !in_macro(cx, first.span) && + if !differing_macro_contexts(first.span, second.span) && !in_macro(first.span) && unsugar_if(first).is_some() && unsugar_if(second).is_some() { // where the else would be - let else_span = mk_sp(first.span.hi, second.span.lo); + let else_span = Span { lo: first.span.hi, hi: second.span.lo, ctxt: NO_EXPANSION }; if let Some(else_snippet) = snippet_opt(cx, else_span) { if !else_snippet.contains('\n') { diff --git a/clippy_lints/src/identity_op.rs b/clippy_lints/src/identity_op.rs index 82db13b1025..e57feaa5937 100644 --- a/clippy_lints/src/identity_op.rs +++ b/clippy_lints/src/identity_op.rs @@ -33,7 +33,7 @@ impl LintPass for IdentityOp { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IdentityOp { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) { - if in_macro(cx, e.span) { + if in_macro(e.span) { return; } if let ExprBinary(ref cmp, ref left, ref right) = e.node { diff --git a/clippy_lints/src/if_let_redundant_pattern_matching.rs b/clippy_lints/src/if_let_redundant_pattern_matching.rs index 921cd7f8885..8d6a28e62db 100644 --- a/clippy_lints/src/if_let_redundant_pattern_matching.rs +++ b/clippy_lints/src/if_let_redundant_pattern_matching.rs @@ -75,7 +75,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { let span = Span { lo: expr.span.lo, hi: op.span.hi, - expn_id: expr.span.expn_id, + ctxt: expr.span.ctxt, }; db.span_suggestion(span, "try this", format!("if {}.{}", snippet(cx, op.span, "_"), good_method)); }); diff --git a/clippy_lints/src/items_after_statements.rs b/clippy_lints/src/items_after_statements.rs index 5789f6a5f80..b3561720cc7 100644 --- a/clippy_lints/src/items_after_statements.rs +++ b/clippy_lints/src/items_after_statements.rs @@ -42,7 +42,7 @@ impl LintPass for ItemsAfterStatements { impl EarlyLintPass for ItemsAfterStatements { fn check_block(&mut self, cx: &EarlyContext, item: &Block) { - if in_macro(cx, item.span) { + if in_macro(item.span) { return; } @@ -55,7 +55,7 @@ impl EarlyLintPass for ItemsAfterStatements { // lint on all further items for stmt in stmts { if let StmtKind::Item(ref it) = *stmt { - if in_macro(cx, it.span) { + if in_macro(it.span) { return; } if let ItemKind::MacroDef(..) = it.node { diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs index 3c7b139cbd7..92fa1324324 100644 --- a/clippy_lints/src/len_zero.rs +++ b/clippy_lints/src/len_zero.rs @@ -61,7 +61,7 @@ impl LintPass for LenZero { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LenZero { fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item) { - if in_macro(cx, item.span) { + if in_macro(item.span) { return; } @@ -73,7 +73,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LenZero { } fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) { - if in_macro(cx, expr.span) { + if in_macro(expr.span) { return; } diff --git a/clippy_lints/src/let_if_seq.rs b/clippy_lints/src/let_if_seq.rs index cfc8d4bbd68..6fbe47c9e65 100644 --- a/clippy_lints/src/let_if_seq.rs +++ b/clippy_lints/src/let_if_seq.rs @@ -1,6 +1,6 @@ use rustc::lint::*; use rustc::hir; -use syntax::codemap; +use syntax_pos::{Span, NO_EXPANSION}; use utils::{snippet, span_lint_and_then}; /// **What it does:** Checks for variable declarations immediately followed by a @@ -69,10 +69,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LetIfSeq { let hir::StmtExpr(ref if_, _) = expr.node, let hir::ExprIf(ref cond, ref then, ref else_) = if_.node, !used_in_expr(cx, def_id, cond), - let Some(value) = check_assign(cx, def_id, then), + let hir::ExprBlock(ref then) = then.node, + let Some(value) = check_assign(cx, def_id, &*then), !used_in_expr(cx, def_id, value), ], { - let span = codemap::mk_sp(stmt.span.lo, if_.span.hi); + let span = Span { lo: stmt.span.lo, hi: if_.span.hi, ctxt: NO_EXPANSION }; let (default_multi_stmts, default) = if let Some(ref else_) = *else_ { if let hir::ExprBlock(ref else_) = else_.node { diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs index ff57afb7324..d7760a30622 100644 --- a/clippy_lints/src/loops.rs +++ b/clippy_lints/src/loops.rs @@ -894,7 +894,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> { match def { Def::Local(..) | Def::Upvar(..) => { let def_id = def.def_id(); - let node_id = self.cx.tcx.hir.as_local_node_id(def_id).unwrap(); + let node_id = self.cx.tcx.hir.as_local_node_id(def_id).expect("local/upvar are local nodes"); let extent = self.cx.tcx.region_maps.var_scope(node_id); self.indexed.insert(seqvar.segments[0].name, Some(extent)); diff --git a/clippy_lints/src/matches.rs b/clippy_lints/src/matches.rs index 46dd5464881..f8f50bfb853 100644 --- a/clippy_lints/src/matches.rs +++ b/clippy_lints/src/matches.rs @@ -342,7 +342,7 @@ fn check_wild_err_arm(cx: &LateContext, ex: &Expr, arms: &[Arm]) { path_str == "Err", inner.iter().any(|pat| pat.node == PatKind::Wild), let ExprBlock(ref block) = arm.body.node, - is_panic_block(cx, block) + is_panic_block(block) ], { // `Err(_)` arm with `panic!` found span_note_and_lint(cx, @@ -359,13 +359,13 @@ fn check_wild_err_arm(cx: &LateContext, ex: &Expr, arms: &[Arm]) { } // If the block contains only a `panic!` macro (as expression or statement) -fn is_panic_block(cx: &LateContext, block: &Block) -> bool { +fn is_panic_block(block: &Block) -> bool { match (&block.expr, block.stmts.len(), block.stmts.first()) { (&Some(ref exp), 0, _) => { - is_expn_of(cx, exp.span, "panic").is_some() && is_expn_of(cx, exp.span, "unreachable").is_none() + is_expn_of(exp.span, "panic").is_some() && is_expn_of(exp.span, "unreachable").is_none() }, (&None, 1, Some(stmt)) => { - is_expn_of(cx, stmt.span, "panic").is_some() && is_expn_of(cx, stmt.span, "unreachable").is_none() + is_expn_of(stmt.span, "panic").is_some() && is_expn_of(stmt.span, "unreachable").is_none() }, _ => false, } diff --git a/clippy_lints/src/methods.rs b/clippy_lints/src/methods.rs index 3d5ba695d4b..53b9b1b83ec 100644 --- a/clippy_lints/src/methods.rs +++ b/clippy_lints/src/methods.rs @@ -554,7 +554,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { // ^ required because `cyclomatic_complexity` attribute shows up as unused #[cyclomatic_complexity = "30"] fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr) { - if in_macro(cx, expr.span) { + if in_macro(expr.span) { return; } @@ -649,7 +649,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { if name == method_name && sig.decl.inputs.len() == n_args && out_type.matches(&sig.decl.output) && - self_kind.matches(&first_arg_ty, &first_arg, &self_ty, false) { + self_kind.matches(first_arg_ty, first_arg, self_ty, false) { span_lint(cx, SHOULD_IMPLEMENT_TRAIT, implitem.span, &format!( "defining a method called `{}` on this type; consider implementing \ the `{}` trait or choosing a less ambiguous name", name, trait_name)); @@ -662,7 +662,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { for &(ref conv, self_kinds) in &CONVENTIONS { if_let_chain! {[ conv.check(&name.as_str()), - !self_kinds.iter().any(|k| k.matches(&first_arg_ty, &first_arg, &self_ty, is_copy)), + !self_kinds.iter().any(|k| k.matches(first_arg_ty, first_arg, self_ty, is_copy)), ], { let lint = if item.vis == hir::Visibility::Public { WRONG_PUB_SELF_CONVENTION @@ -1065,7 +1065,7 @@ fn lint_map_unwrap_or(cx: &LateContext, expr: &hir::Expr, map_args: &[hir::Expr] // lint, with note if neither arg is > 1 line and both map() and // unwrap_or() have the same span let multiline = map_snippet.lines().count() > 1 || unwrap_snippet.lines().count() > 1; - let same_span = map_args[1].span.expn_id == unwrap_args[1].span.expn_id; + let same_span = map_args[1].span.ctxt == unwrap_args[1].span.ctxt; if same_span && !multiline { span_note_and_lint(cx, OPTION_MAP_UNWRAP_OR, @@ -1094,7 +1094,7 @@ fn lint_map_unwrap_or_else(cx: &LateContext, expr: &hir::Expr, map_args: &[hir:: // lint, with note if neither arg is > 1 line and both map() and // unwrap_or_else() have the same span let multiline = map_snippet.lines().count() > 1 || unwrap_snippet.lines().count() > 1; - let same_span = map_args[1].span.expn_id == unwrap_args[1].span.expn_id; + let same_span = map_args[1].span.ctxt == unwrap_args[1].span.ctxt; if same_span && !multiline { span_note_and_lint(cx, OPTION_MAP_UNWRAP_OR_ELSE, diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs index a029a9c4dda..e84fd196874 100644 --- a/clippy_lints/src/misc.rs +++ b/clippy_lints/src/misc.rs @@ -326,7 +326,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { }, _ => {}, } - if in_attributes_expansion(cx, expr) { + if in_attributes_expansion(expr) { // Don't lint things expanded by #[derive(...)], etc return; } @@ -498,9 +498,9 @@ fn is_used(cx: &LateContext, expr: &Expr) -> bool { /// Test whether an expression is in a macro expansion (e.g. something generated by /// `#[derive(...)`] or the like). -fn in_attributes_expansion(cx: &LateContext, expr: &Expr) -> bool { - cx.sess().codemap().with_expn_info(expr.span.expn_id, |info_opt| { - info_opt.map_or(false, |info| matches!(info.callee.format, ExpnFormat::MacroAttribute(_))) +fn in_attributes_expansion(expr: &Expr) -> bool { + expr.span.ctxt.outer().expn_info().map_or(false, |info| { + matches!(info.callee.format, ExpnFormat::MacroAttribute(_)) }) } @@ -510,7 +510,7 @@ fn non_macro_local(cx: &LateContext, def: &def::Def) -> bool { def::Def::Local(id) | def::Def::Upvar(id, _, _) => { if let Some(span) = cx.tcx.hir.span_if_local(id) { - !in_macro(cx, span) + !in_macro(span) } else { true } diff --git a/clippy_lints/src/missing_doc.rs b/clippy_lints/src/missing_doc.rs index 75cc588119f..1249b638a08 100644 --- a/clippy_lints/src/missing_doc.rs +++ b/clippy_lints/src/missing_doc.rs @@ -73,7 +73,7 @@ impl MissingDoc { return; } - if in_macro(cx, sp) { + if in_macro(sp) { return; } diff --git a/clippy_lints/src/needless_bool.rs b/clippy_lints/src/needless_bool.rs index c9ade60c339..53b26fc1276 100644 --- a/clippy_lints/src/needless_bool.rs +++ b/clippy_lints/src/needless_bool.rs @@ -76,6 +76,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBool { "this if-then-else expression returns a bool literal", |db| { db.span_suggestion(e.span, "you can reduce it to", hint); }); }; + if let ExprBlock(ref then_block) = then_block.node { match (fetch_bool_block(then_block), fetch_bool_expr(else_expr)) { (RetBool(true), RetBool(true)) | (Bool(true), Bool(true)) => { @@ -97,6 +98,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBool { (Bool(false), Bool(true)) => reduce(false, true), _ => (), } + } else { + panic!("IfExpr 'then' node is not an ExprBlock"); + } } } } diff --git a/clippy_lints/src/needless_borrow.rs b/clippy_lints/src/needless_borrow.rs index 8071f2903a9..740dd2bcb3f 100644 --- a/clippy_lints/src/needless_borrow.rs +++ b/clippy_lints/src/needless_borrow.rs @@ -36,7 +36,7 @@ impl LintPass for NeedlessBorrow { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBorrow { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) { - if in_macro(cx, e.span) { + if in_macro(e.span) { return; } if let ExprAddrOf(MutImmutable, ref inner) = e.node { @@ -55,7 +55,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBorrow { } } fn check_pat(&mut self, cx: &LateContext<'a, 'tcx>, pat: &'tcx Pat) { - if in_macro(cx, pat.span) { + if in_macro(pat.span) { return; } if_let_chain! {[ diff --git a/clippy_lints/src/needless_pass_by_value.rs b/clippy_lints/src/needless_pass_by_value.rs index ed495e7e567..28129484a37 100644 --- a/clippy_lints/src/needless_pass_by_value.rs +++ b/clippy_lints/src/needless_pass_by_value.rs @@ -55,7 +55,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue { span: Span, node_id: NodeId ) { - if in_macro(cx, span) { + if in_macro(span) { return; } diff --git a/clippy_lints/src/no_effect.rs b/clippy_lints/src/no_effect.rs index f53fcb60706..4796243770c 100644 --- a/clippy_lints/src/no_effect.rs +++ b/clippy_lints/src/no_effect.rs @@ -41,7 +41,7 @@ declare_lint! { } fn has_no_effect(cx: &LateContext, expr: &Expr) -> bool { - if in_macro(cx, expr.span) { + if in_macro(expr.span) { return false; } match expr.node { @@ -110,7 +110,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { } else if let Some(reduced) = reduce_expression(cx, expr) { let mut snippet = String::new(); for e in reduced { - if in_macro(cx, e.span) { + if in_macro(e.span) { return; } if let Some(snip) = snippet_opt(cx, e.span) { @@ -132,7 +132,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { fn reduce_expression<'a>(cx: &LateContext, expr: &'a Expr) -> Option> { - if in_macro(cx, expr.span) { + if in_macro(expr.span) { return None; } match expr.node { diff --git a/clippy_lints/src/non_expressive_names.rs b/clippy_lints/src/non_expressive_names.rs index a195673a53b..67f1aaa27ab 100644 --- a/clippy_lints/src/non_expressive_names.rs +++ b/clippy_lints/src/non_expressive_names.rs @@ -135,7 +135,7 @@ impl<'a, 'tcx, 'b> SimilarNamesNameVisitor<'a, 'tcx, 'b> { } } fn check_name(&mut self, span: Span, name: Name) { - if in_macro(self.0.cx, span) { + if in_macro(span) { return; } let interned_name = name.as_str(); diff --git a/clippy_lints/src/panic.rs b/clippy_lints/src/panic.rs index 1e97d44ff7d..8db7de30f7c 100644 --- a/clippy_lints/src/panic.rs +++ b/clippy_lints/src/panic.rs @@ -42,7 +42,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { let ExprPath(ref qpath) = fun.node, match_def_path(cx.tcx, resolve_node(cx, qpath, fun.id).def_id(), &paths::BEGIN_PANIC), let ExprLit(ref lit) = params[0].node, - is_direct_expn_of(cx, params[0].span, "panic").is_some(), + is_direct_expn_of(params[0].span, "panic").is_some(), let LitKind::Str(ref string, _) = lit.node, let Some(par) = string.as_str().find('{'), string.as_str()[par..].contains('}') diff --git a/clippy_lints/src/partialeq_ne_impl.rs b/clippy_lints/src/partialeq_ne_impl.rs index 6989eb79f8e..5fee08a0c49 100644 --- a/clippy_lints/src/partialeq_ne_impl.rs +++ b/clippy_lints/src/partialeq_ne_impl.rs @@ -40,7 +40,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { if_let_chain! {[ let ItemImpl(_, _, _, Some(ref trait_ref), _, ref impl_items) = item.node, !is_automatically_derived(&*item.attrs), - trait_ref.path.def.def_id() == cx.tcx.lang_items.eq_trait().unwrap(), + let Some(eq_trait) = cx.tcx.lang_items.eq_trait(), + trait_ref.path.def.def_id() == eq_trait ], { for impl_item in impl_items { if impl_item.name == "ne" { diff --git a/clippy_lints/src/print.rs b/clippy_lints/src/print.rs index 0776b660b41..a6eb5c5dfda 100644 --- a/clippy_lints/src/print.rs +++ b/clippy_lints/src/print.rs @@ -77,9 +77,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { // Search for `std::io::_print(..)` which is unique in a // `print!` expansion. if match_def_path(cx.tcx, fun_id, &paths::IO_PRINT) { - if let Some(span) = is_expn_of(cx, expr.span, "print") { + if let Some(span) = is_expn_of(expr.span, "print") { // `println!` uses `print!`. - let (span, name) = match is_expn_of(cx, span, "println") { + let (span, name) = match is_expn_of(span, "println") { Some(span) => (span, "println"), None => (span, "print"), }; @@ -125,7 +125,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { if let ExprPath(ref qpath) = args[1].node { let def_id = cx.tables.qpath_def(qpath, args[1].id).def_id(); if match_def_path(cx.tcx, def_id, &paths::DEBUG_FMT_METHOD) && !is_in_debug_impl(cx, expr) && - is_expn_of(cx, expr.span, "panic").is_none() { + is_expn_of(expr.span, "panic").is_none() { span_lint(cx, USE_DEBUG, args[0].span, "use of `Debug`-based formatting"); } } diff --git a/clippy_lints/src/ranges.rs b/clippy_lints/src/ranges.rs index aa190402f29..5b7cb9aa86f 100644 --- a/clippy_lints/src/ranges.rs +++ b/clippy_lints/src/ranges.rs @@ -66,7 +66,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StepByZero { let ExprMethodCall( Spanned { node: iter_name, .. }, _, ref iter_args ) = *iter, iter_name == "iter", // 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(start), end: Some(end), .. }) = higher::range(zip_arg), is_integer_literal(start, 0), // .len() call let ExprMethodCall(Spanned { node: len_name, .. }, _, ref len_args) = end.node, diff --git a/clippy_lints/src/regex.rs b/clippy_lints/src/regex.rs index 2808dfd3546..cdaf51d6646 100644 --- a/clippy_lints/src/regex.rs +++ b/clippy_lints/src/regex.rs @@ -91,7 +91,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { self.last.is_none(), let Some(ref expr) = block.expr, match_type(cx, cx.tables.expr_ty(expr), &paths::REGEX), - let Some(span) = is_expn_of(cx, expr.span, "regex"), + let Some(span) = is_expn_of(expr.span, "regex"), ], { if !self.spans.contains(&span) { span_lint(cx, diff --git a/clippy_lints/src/returns.rs b/clippy_lints/src/returns.rs index 031e3f8cf2c..16f582c77c9 100644 --- a/clippy_lints/src/returns.rs +++ b/clippy_lints/src/returns.rs @@ -107,7 +107,7 @@ impl ReturnPass { // we need both a let-binding stmt and an expr if_let_chain! {[ - let Some(ref retexpr) = it.next_back(), + let Some(retexpr) = it.next_back(), let ast::StmtKind::Expr(ref retexpr) = retexpr.node, let Some(stmt) = it.next_back(), let ast::StmtKind::Local(ref local) = stmt.node, diff --git a/clippy_lints/src/shadow.rs b/clippy_lints/src/shadow.rs index 62ef155c321..58eb4aafa2b 100644 --- a/clippy_lints/src/shadow.rs +++ b/clippy_lints/src/shadow.rs @@ -305,7 +305,7 @@ fn check_expr<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr, bindings: }, ExprIf(ref cond, ref then, ref otherwise) => { check_expr(cx, cond, bindings); - check_block(cx, then, bindings); + check_expr(cx, &**then, bindings); if let Some(ref o) = *otherwise { check_expr(cx, o, bindings); } diff --git a/clippy_lints/src/should_assert_eq.rs b/clippy_lints/src/should_assert_eq.rs index 372ee210336..59532f3d440 100644 --- a/clippy_lints/src/should_assert_eq.rs +++ b/clippy_lints/src/should_assert_eq.rs @@ -36,7 +36,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ShouldAssertEq { let ExprIf(ref cond, ..) = e.node, let ExprUnary(UnOp::UnNot, ref cond) = cond.node, let ExprBinary(ref binop, ref expr1, ref expr2) = cond.node, - is_direct_expn_of(cx, e.span, "assert").is_some(), + is_direct_expn_of(e.span, "assert").is_some(), let Some(debug_trait) = cx.tcx.lang_items.debug_trait(), ], { let sugg = match binop.node { diff --git a/clippy_lints/src/strings.rs b/clippy_lints/src/strings.rs index 0e4bf017f3f..646ba598f81 100644 --- a/clippy_lints/src/strings.rs +++ b/clippy_lints/src/strings.rs @@ -146,7 +146,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringLitAsBytes { if name.node == "as_bytes" { if let ExprLit(ref lit) = args[0].node { if let LitKind::Str(ref lit_content, _) = lit.node { - if lit_content.as_str().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(args[0].span) { span_lint_and_then(cx, STRING_LIT_AS_BYTES, e.span, diff --git a/clippy_lints/src/swap.rs b/clippy_lints/src/swap.rs index e1f4f164696..b2c56fe8bf3 100644 --- a/clippy_lints/src/swap.rs +++ b/clippy_lints/src/swap.rs @@ -1,9 +1,9 @@ use rustc::hir::*; use rustc::lint::*; use rustc::ty; -use syntax::codemap::mk_sp; use utils::{differing_macro_contexts, match_type, paths, snippet, span_lint_and_then, walk_ptrs_ty, SpanlessEq}; use utils::sugg::Sugg; +use syntax_pos::{Span, NO_EXPANSION}; /// **What it does:** Checks for manual swapping. /// @@ -115,16 +115,14 @@ fn check_manual_swap(cx: &LateContext, block: &Block) { } else { (false, "".to_owned(), "".to_owned()) } + } else if let (Some(first), Some(second)) = (Sugg::hir_opt(cx, lhs1), Sugg::hir_opt(cx, rhs1)) { + (true, format!(" `{}` and `{}`", first, second), + format!("std::mem::swap({}, {})", first.mut_addr(), second.mut_addr())) } else { - if let (Some(first), Some(second)) = (Sugg::hir_opt(cx, lhs1), Sugg::hir_opt(cx, rhs1)) { - (true, format!(" `{}` and `{}`", first, second), - format!("std::mem::swap({}, {})", first.mut_addr(), second.mut_addr())) - } else { - (true, "".to_owned(), "".to_owned()) - } + (true, "".to_owned(), "".to_owned()) }; - let span = mk_sp(w[0].span.lo, second.span.hi); + let span = Span { lo: w[0].span.lo, hi: second.span.hi, ctxt: NO_EXPANSION}; span_lint_and_then(cx, MANUAL_SWAP, @@ -163,7 +161,7 @@ fn check_suspicious_swap(cx: &LateContext, block: &Block) { ("".to_owned(), "".to_owned(), "".to_owned()) }; - let span = mk_sp(first.span.lo, second.span.hi); + let span = Span{ lo: first.span.lo, hi: second.span.hi, ctxt: NO_EXPANSION}; span_lint_and_then(cx, ALMOST_SWAPPED, diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs index 7ec69314621..005c508f123 100644 --- a/clippy_lints/src/types.rs +++ b/clippy_lints/src/types.rs @@ -107,7 +107,7 @@ fn check_fn_decl(cx: &LateContext, decl: &FnDecl) { } fn check_ty(cx: &LateContext, ast_ty: &Ty) { - if in_macro(cx, ast_ty.span) { + if in_macro(ast_ty.span) { return; } match ast_ty.node { @@ -118,7 +118,7 @@ fn check_ty(cx: &LateContext, ast_ty: &Ty) { let last = last_path_segment(qpath); if_let_chain! {[ let PathParameters::AngleBracketedParameters(ref ag) = last.parameters, - let Some(ref vec) = ag.types.get(0), + let Some(vec) = ag.types.get(0), let TyPath(ref qpath) = vec.node, let def::Def::Struct(..) = cx.tables.qpath_def(qpath, vec.id), let Some(did) = opt_def_id(cx.tables.qpath_def(qpath, vec.id)), @@ -199,7 +199,7 @@ fn check_let_unit(cx: &LateContext, decl: &Decl) { let bindtype = &cx.tables.pat_ty(&local.pat).sty; match *bindtype { ty::TyTuple(slice, _) if slice.is_empty() => { - if in_external_macro(cx, decl.span) || in_macro(cx, local.pat.span) { + if in_external_macro(cx, decl.span) || in_macro(local.pat.span) { return; } if higher::is_from_for_desugar(decl) { @@ -261,7 +261,7 @@ impl LintPass for UnitCmp { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnitCmp { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) { - if in_macro(cx, expr.span) { + if in_macro(expr.span) { return; } if let ExprBinary(ref cmp, ref left, _) = expr.node { @@ -694,7 +694,7 @@ impl<'a, 'tcx> TypeComplexityPass { } fn check_type(&self, cx: &LateContext<'a, 'tcx>, ty: &'tcx Ty) { - if in_macro(cx, ty.span) { + if in_macro(ty.span) { return; } let score = { @@ -797,7 +797,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CharLitAsU8 { if let ExprCast(ref e, _) = expr.node { if let ExprLit(ref l) = e.node { if let LitKind::Char(_) = l.node { - if ty::TyUint(UintTy::U8) == cx.tables.expr_ty(expr).sty && !in_macro(cx, expr.span) { + if ty::TyUint(UintTy::U8) == cx.tables.expr_ty(expr).sty && !in_macro(expr.span) { let msg = "casting character literal to u8. `char`s \ are 4 bytes wide in rust, so casting to u8 \ truncates them"; @@ -971,7 +971,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AbsurdExtremeComparisons { if let ExprBinary(ref cmp, ref lhs, ref rhs) = expr.node { if let Some((culprit, result)) = detect_absurd_comparison(cx, cmp.node, lhs, rhs) { - if !in_macro(cx, expr.span) { + if !in_macro(expr.span) { let msg = "this comparison involving the minimum or maximum element for this \ type contains a case that is always true or always false"; diff --git a/clippy_lints/src/unused_label.rs b/clippy_lints/src/unused_label.rs index e004b80323e..15f327fb5c2 100644 --- a/clippy_lints/src/unused_label.rs +++ b/clippy_lints/src/unused_label.rs @@ -50,7 +50,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedLabel { span: Span, fn_id: ast::NodeId ) { - if in_macro(cx, span) { + if in_macro(span) { return; } diff --git a/clippy_lints/src/utils/higher.rs b/clippy_lints/src/utils/higher.rs index 1358e1f28f2..10a1c18e182 100644 --- a/clippy_lints/src/utils/higher.rs +++ b/clippy_lints/src/utils/higher.rs @@ -156,7 +156,7 @@ pub fn vec_macro<'e>(cx: &LateContext, expr: &'e hir::Expr) -> Option SpanlessEq<'a, 'tcx> { }, (&ExprIndex(ref la, ref li), &ExprIndex(ref ra, ref ri)) => self.eq_expr(la, ra) && self.eq_expr(li, ri), (&ExprIf(ref lc, ref lt, ref le), &ExprIf(ref rc, ref rt, ref re)) => { - self.eq_expr(lc, rc) && self.eq_block(lt, rt) && both(le, re, |l, r| self.eq_expr(l, r)) + self.eq_expr(lc, rc) && self.eq_expr(&**lt, &**rt) && both(le, re, |l, r| self.eq_expr(l, r)) }, (&ExprLit(ref l), &ExprLit(ref r)) => l.node == r.node, (&ExprLoop(ref lb, ref ll, ref lls), &ExprLoop(ref rb, ref rl, ref rls)) => { @@ -395,7 +395,7 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> { let c: fn(_, _, _) -> _ = ExprIf; c.hash(&mut self.s); self.hash_expr(cond); - self.hash_block(t); + self.hash_expr(&**t); if let Some(ref e) = *e { self.hash_expr(e); } diff --git a/clippy_lints/src/utils/internal_lints.rs b/clippy_lints/src/utils/internal_lints.rs index 41e9d777363..038dfc01d13 100644 --- a/clippy_lints/src/utils/internal_lints.rs +++ b/clippy_lints/src/utils/internal_lints.rs @@ -128,7 +128,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LintWithoutLintPass { // not able to capture the error. // Therefore, we need to climb the macro expansion tree and find the // actual span that invoked `declare_lint!`: - let lint_span = cx.sess().codemap().source_callsite(lint_span); + let lint_span = lint_span.ctxt.outer().expn_info().map(|ei| ei.call_site).expect("unable to get call_site"); if !self.registered_lints.contains(lint_name) { span_lint(cx, diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index 1eed85c9fe0..db595b07969 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -97,7 +97,7 @@ pub mod higher; /// Returns true if the two spans come from differing expansions (i.e. one is from a macro and one /// isn't). pub fn differing_macro_contexts(lhs: Span, rhs: Span) -> bool { - rhs.expn_id != lhs.expn_id + rhs.ctxt != lhs.ctxt } pub fn in_constant(cx: &LateContext, id: NodeId) -> bool { @@ -111,17 +111,11 @@ pub fn in_constant(cx: &LateContext, id: NodeId) -> bool { } /// Returns true if this `expn_info` was expanded by any macro. -pub fn in_macro<'a, T: LintContext<'a>>(cx: &T, span: Span) -> bool { - cx.sess().codemap().with_expn_info(span.expn_id, |info| { - match info { - Some(info) => { - match info.callee.format { - // don't treat range expressions desugared to structs as "in_macro" - ExpnFormat::CompilerDesugaring(name) => name != "...", - _ => true, - } - }, - None => false, +pub fn in_macro(span: Span) -> bool { + span.ctxt.outer().expn_info().map_or(false, |info| { + match info.callee.format {// don't treat range expressions desugared to structs as "in_macro" + ExpnFormat::CompilerDesugaring(name) => name != "...", + _ => true, } }) } @@ -131,22 +125,20 @@ pub fn in_macro<'a, T: LintContext<'a>>(cx: &T, span: Span) -> bool { pub fn in_external_macro<'a, T: LintContext<'a>>(cx: &T, span: Span) -> bool { /// Invokes `in_macro` with the expansion info of the given span slightly heavy, try to use /// this after other checks have already happened. - fn in_macro_ext<'a, T: LintContext<'a>>(cx: &T, opt_info: Option<&ExpnInfo>) -> bool { + fn in_macro_ext<'a, T: LintContext<'a>>(cx: &T, info: &ExpnInfo) -> bool { // no ExpnInfo = no macro - opt_info.map_or(false, |info| { - if let ExpnFormat::MacroAttribute(..) = info.callee.format { - // these are all plugins - return true; - } - // no span for the callee = external macro - info.callee.span.map_or(true, |span| { - // no snippet = external macro or compiler-builtin expansion - cx.sess().codemap().span_to_snippet(span).ok().map_or(true, |code| !code.starts_with("macro_rules")) - }) + if let ExpnFormat::MacroAttribute(..) = info.callee.format { + // these are all plugins + return true; + } + // no span for the callee = external macro + info.callee.span.map_or(true, |span| { + // no snippet = external macro or compiler-builtin expansion + cx.sess().codemap().span_to_snippet(span).ok().map_or(true, |code| !code.starts_with("macro_rules")) }) } - cx.sess().codemap().with_expn_info(span.expn_id, |info| in_macro_ext(cx, info)) + span.ctxt.outer().expn_info().map_or(false, |info| in_macro_ext(cx, &info)) } /// Check if a `DefId`'s path matches the given absolute type path usage. @@ -365,6 +357,9 @@ pub fn method_chain_args<'a>(expr: &'a Expr, methods: &[&str]) -> Option first if let ExprMethodCall(ref name, _, ref args) = current.node { if name.node == *method_name { + if args.iter().any(|e| in_macro(e.span)) { + return None; + } matched.push(&**args); // build up `matched` backwards current = &args[0] // go to parent expression } else { @@ -693,12 +688,10 @@ fn parse_attrs(sess: &Session, attrs: &[ast::Attribute], name: &' /// Return the pre-expansion span if is this comes from an expansion of the macro `name`. /// See also `is_direct_expn_of`. -pub fn is_expn_of(cx: &LateContext, mut span: Span, name: &str) -> Option { +pub fn is_expn_of(mut span: Span, name: &str) -> Option { loop { - let span_name_span = cx.tcx - .sess - .codemap() - .with_expn_info(span.expn_id, |expn| expn.map(|ei| (ei.callee.name(), ei.call_site))); + let span_name_span = span.ctxt.outer() + .expn_info().map(|ei| (ei.callee.name(), ei.call_site)); match span_name_span { Some((mac_name, new_span)) if mac_name == name => return Some(new_span), @@ -715,11 +708,9 @@ pub fn is_expn_of(cx: &LateContext, mut span: Span, name: &str) -> Option /// ``` /// `42` is considered expanded from `foo!` and `bar!` by `is_expn_of` but only `bar!` by /// `is_direct_expn_of`. -pub fn is_direct_expn_of(cx: &LateContext, span: Span, name: &str) -> Option { - let span_name_span = cx.tcx - .sess - .codemap() - .with_expn_info(span.expn_id, |expn| expn.map(|ei| (ei.callee.name(), ei.call_site))); +pub fn is_direct_expn_of(span: Span, name: &str) -> Option { + let span_name_span = span.ctxt.outer() + .expn_info().map(|ei| (ei.callee.name(), ei.call_site)); match span_name_span { Some((mac_name, new_span)) if mac_name == name => Some(new_span), diff --git a/clippy_lints/src/vec.rs b/clippy_lints/src/vec.rs index 3b9e38cb66b..da65474ed96 100644 --- a/clippy_lints/src/vec.rs +++ b/clippy_lints/src/vec.rs @@ -50,7 +50,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { is_copy(cx, vec_type(cx.tables.expr_ty_adjusted(arg)), cx.tcx.hir.get_parent(expr.id)), ], { // report the error around the `vec!` not inside `:` - let span = cx.sess().codemap().source_callsite(arg.span); + let span = arg.span.ctxt.outer().expn_info().map(|info| info.call_site).expect("unable to get call_site"); check_vec_macro(cx, &vec_args, span); }} } @@ -70,7 +70,7 @@ fn check_vec_macro(cx: &LateContext, vec_args: &higher::VecArgs, span: Span) { let span = Span { lo: args[0].span.lo, hi: last.span.hi, - expn_id: args[0].span.expn_id, + ctxt: args[0].span.ctxt, }; format!("&[{}]", snippet(cx, span, "..")).into() diff --git a/rls.toml b/rls.toml new file mode 100644 index 00000000000..62f1434c0ab --- /dev/null +++ b/rls.toml @@ -0,0 +1 @@ +build_lib = true \ No newline at end of file diff --git a/tests/run-pass/mut_mut_macro.rs b/tests/run-pass/mut_mut_macro.rs index 9f63a6b2d73..a6473b0f909 100644 --- a/tests/run-pass/mut_mut_macro.rs +++ b/tests/run-pass/mut_mut_macro.rs @@ -20,13 +20,12 @@ fn main() { lazy_static! { static ref MUT_MAP : HashMap = { let mut m = HashMap::new(); - let mut zero = &mut &mut "zero"; m.insert(0, "zero"); m }; static ref MUT_COUNT : usize = MUT_MAP.len(); } - assert!(*MUT_COUNT == 1); + assert_eq!(*MUT_COUNT, 1); // FIXME: don't lint in array length, requires `check_body` //let _ = [""; (42.0 < std::f32::NAN) as usize]; } diff --git a/tests/ui/panic.stderr b/tests/ui/panic.stderr index e77add7a32a..e69de29bb2d 100644 --- a/tests/ui/panic.stderr +++ b/tests/ui/panic.stderr @@ -1,26 +0,0 @@ -error: you probably are missing some parameter in your format string - --> $DIR/panic.rs:8:16 - | -8 | panic!("{}"); - | ^^^^ - | -note: lint level defined here - --> $DIR/panic.rs:4:9 - | -4 | #![deny(panic_params)] - | ^^^^^^^^^^^^ - -error: you probably are missing some parameter in your format string - --> $DIR/panic.rs:10:16 - | -10 | panic!("{:?}"); - | ^^^^^^ - -error: you probably are missing some parameter in your format string - --> $DIR/panic.rs:12:23 - | -12 | assert!(true, "here be missing values: {}"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 3 previous errors -