First try for a fix for rustc 1.18.0-nightly (5c94997b6 2017-03-30

This commit is contained in:
Enrico Schmitz 2017-03-31 19:23:35 +02:00 committed by Enrico Schmitz
parent 9c3c938761
commit 8f9fb97eb6
17 changed files with 61 additions and 72 deletions

View File

@ -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| {

View File

@ -313,10 +313,10 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
}
}
fn ifthenelse(&mut self, cond: &Expr, then: &Block, otherwise: &Option<P<Expr>>) -> Option<Constant> {
fn ifthenelse(&mut self, cond: &Expr, then: &P<Expr>, otherwise: &Option<P<Expr>>) -> Option<Constant> {
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))
}

View File

@ -225,9 +225,11 @@ fn if_sequence(mut expr: &Expr) -> (SmallVector<&Expr>, SmallVector<&Block>) {
let mut conds = SmallVector::new();
let mut blocks = 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);
//FIXME
//blocks.push(&**then_expr);
//FIXME
if let Some(ref else_expr) = *else_expr {
expr = else_expr;
@ -239,7 +241,9 @@ fn if_sequence(mut expr: &Expr) -> (SmallVector<&Expr>, SmallVector<&Block>) {
// final `else {..}`
if !blocks.is_empty() {
if let ExprBlock(ref block) = expr.node {
blocks.push(&**block);
//FIXME
//blocks.push(&**block);
//FIXME
}
}

View File

@ -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,7 @@ 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();
let mut visitor = InsertVisitor {
cx: cx,
@ -58,7 +57,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) {

View File

@ -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;
@ -100,12 +100,11 @@ impl EarlyLintPass for Formatting {
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);
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,
@ -128,7 +127,7 @@ fn check_else_if(cx: &EarlyContext, expr: &ast::Expr) {
if unsugar_if(else_).is_some() && !differing_macro_contexts(then.span, else_.span) && !in_macro(cx, 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
// its 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,
@ -178,7 +177,7 @@ fn check_consecutive_ifs(cx: &EarlyContext, first: &ast::Expr, second: &ast::Exp
if !differing_macro_contexts(first.span, second.span) && !in_macro(cx, 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') {

View File

@ -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));
});

View File

@ -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,9 @@ 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),
!used_in_expr(cx, def_id, value),
!used_in_expr(cx, def_id, &**then),
], {
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 {
@ -105,9 +104,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LetIfSeq {
mut=mutability,
name=name.node,
cond=snippet(cx, cond.span, "_"),
then=if then.stmts.len() > 1 { " ..;" } else { "" },
then={ "" },
else=if default_multi_stmts { " ..;" } else { "" },
value=snippet(cx, value.span, "<value>"),
value=snippet(cx, then.span, "<value>"),
default=snippet(cx, default.span, "<default>"),
);
span_lint_and_then(cx,

View File

@ -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,

View File

@ -499,9 +499,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(_)))
})
expr.span.ctxt.outer().expn_info().map(|info| {
matches!(info.callee.format, ExpnFormat::MacroAttribute(_))
}).unwrap_or(false)
}
/// Test whether `def` is a variable defined outside a macro.

View File

@ -76,7 +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); });
};
match (fetch_bool_block(then_block), fetch_bool_expr(else_expr)) {
match (fetch_bool_expr(&**then_block), fetch_bool_expr(else_expr)) {
(RetBool(true), RetBool(true)) |
(Bool(true), Bool(true)) => {
span_lint(cx,

View File

@ -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);
}

View File

@ -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.
///
@ -124,7 +124,7 @@ fn check_manual_swap(cx: &LateContext, block: &Block) {
}
};
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 +163,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,

View File

@ -97,7 +97,7 @@ impl<'a, 'tcx: 'a> 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);
}

View File

@ -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,

View File

@ -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 {
@ -112,18 +112,12 @@ 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,
span.ctxt.outer().expn_info().map(|info| {
match info.callee.format {// don't treat range expressions desugared to structs as "in_macro"
ExpnFormat::CompilerDesugaring(name) => name != "...",
_ => true,
}
})
}).unwrap_or(false)
}
/// Returns true if the macro that expanded the crate was outside of the current crate or was a
@ -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(|info| in_macro_ext(cx, &info)).unwrap_or(false)
}
/// Check if a `DefId`'s path matches the given absolute type path usage.
@ -695,10 +687,8 @@ fn parse_attrs<F: FnMut(u64)>(sess: &Session, attrs: &[ast::Attribute], name: &'
/// See also `is_direct_expn_of`.
pub fn is_expn_of(cx: &LateContext, mut span: Span, name: &str) -> Option<Span> {
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),
@ -716,10 +706,8 @@ pub fn is_expn_of(cx: &LateContext, mut span: Span, name: &str) -> Option<Span>
/// `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<Span> {
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 => Some(new_span),

View File

@ -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 `<std macros>:`
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()