mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-12-18 00:53:31 +00:00
rustfmt all the things
This commit is contained in:
parent
cd12a2369a
commit
a878916ad5
41 changed files with 375 additions and 275 deletions
|
@ -78,17 +78,16 @@ impl LateLintPass for ArrayIndexing {
|
||||||
|
|
||||||
// Index is a constant range
|
// Index is a constant range
|
||||||
if let Some(range) = utils::unsugar_range(index) {
|
if let Some(range) = utils::unsugar_range(index) {
|
||||||
let start = range.start.map(|start|
|
let start = range.start
|
||||||
eval_const_expr_partial(cx.tcx, start, ExprTypeChecked, None)).map(|v| v.ok());
|
.map(|start| eval_const_expr_partial(cx.tcx, start, ExprTypeChecked, None))
|
||||||
let end = range.end.map(|end|
|
.map(|v| v.ok());
|
||||||
eval_const_expr_partial(cx.tcx, end, ExprTypeChecked, None)).map(|v| v.ok());
|
let end = range.end
|
||||||
|
.map(|end| eval_const_expr_partial(cx.tcx, end, ExprTypeChecked, None))
|
||||||
|
.map(|v| v.ok());
|
||||||
|
|
||||||
if let Some((start, end)) = to_const_range(start, end, range.limits, size) {
|
if let Some((start, end)) = to_const_range(start, end, range.limits, size) {
|
||||||
if start > size || end > size {
|
if start > size || end > size {
|
||||||
utils::span_lint(cx,
|
utils::span_lint(cx, OUT_OF_BOUNDS_INDEXING, e.span, "range is out of bounds");
|
||||||
OUT_OF_BOUNDS_INDEXING,
|
|
||||||
e.span,
|
|
||||||
"range is out of bounds");
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -111,9 +110,7 @@ impl LateLintPass for ArrayIndexing {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an option containing a tuple with the start and end (exclusive) of the range.
|
/// Returns an option containing a tuple with the start and end (exclusive) of the range.
|
||||||
fn to_const_range(start: Option<Option<ConstVal>>,
|
fn to_const_range(start: Option<Option<ConstVal>>, end: Option<Option<ConstVal>>, limits: RangeLimits,
|
||||||
end: Option<Option<ConstVal>>,
|
|
||||||
limits: RangeLimits,
|
|
||||||
array_size: ConstInt)
|
array_size: ConstInt)
|
||||||
-> Option<(ConstInt, ConstInt)> {
|
-> Option<(ConstInt, ConstInt)> {
|
||||||
let start = match start {
|
let start = match start {
|
||||||
|
@ -131,7 +128,7 @@ fn to_const_range(start: Option<Option<ConstVal>>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(_) => return None,
|
Some(_) => return None,
|
||||||
None => array_size
|
None => array_size,
|
||||||
};
|
};
|
||||||
|
|
||||||
Some((start, end))
|
Some((start, end))
|
||||||
|
|
|
@ -115,7 +115,8 @@ fn is_relevant_block(block: &Block) -> bool {
|
||||||
for stmt in &block.stmts {
|
for stmt in &block.stmts {
|
||||||
match stmt.node {
|
match stmt.node {
|
||||||
StmtDecl(_, _) => return true,
|
StmtDecl(_, _) => return true,
|
||||||
StmtExpr(ref expr, _) | StmtSemi(ref expr, _) => {
|
StmtExpr(ref expr, _) |
|
||||||
|
StmtSemi(ref expr, _) => {
|
||||||
return is_relevant_expr(expr);
|
return is_relevant_expr(expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@ struct NonminimalBoolVisitor<'a, 'tcx: 'a>(&'a LateContext<'a, 'tcx>);
|
||||||
use quine_mc_cluskey::Bool;
|
use quine_mc_cluskey::Bool;
|
||||||
struct Hir2Qmm<'a, 'tcx: 'a, 'v> {
|
struct Hir2Qmm<'a, 'tcx: 'a, 'v> {
|
||||||
terminals: Vec<&'v Expr>,
|
terminals: Vec<&'v Expr>,
|
||||||
cx: &'a LateContext<'a, 'tcx>
|
cx: &'a LateContext<'a, 'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> {
|
impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> {
|
||||||
|
@ -75,17 +75,17 @@ impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> {
|
||||||
match binop.node {
|
match binop.node {
|
||||||
BiOr => return Ok(Bool::Or(self.extract(BiOr, &[lhs, rhs], Vec::new())?)),
|
BiOr => return Ok(Bool::Or(self.extract(BiOr, &[lhs, rhs], Vec::new())?)),
|
||||||
BiAnd => return Ok(Bool::And(self.extract(BiAnd, &[lhs, rhs], Vec::new())?)),
|
BiAnd => return Ok(Bool::And(self.extract(BiAnd, &[lhs, rhs], Vec::new())?)),
|
||||||
_ => {},
|
_ => (),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
ExprLit(ref lit) => {
|
ExprLit(ref lit) => {
|
||||||
match lit.node {
|
match lit.node {
|
||||||
LitKind::Bool(true) => return Ok(Bool::True),
|
LitKind::Bool(true) => return Ok(Bool::True),
|
||||||
LitKind::Bool(false) => return Ok(Bool::False),
|
LitKind::Bool(false) => return Ok(Bool::False),
|
||||||
_ => {},
|
_ => (),
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
_ => {},
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (n, expr) in self.terminals.iter().enumerate() {
|
for (n, expr) in self.terminals.iter().enumerate() {
|
||||||
|
@ -95,11 +95,13 @@ impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> {
|
||||||
}
|
}
|
||||||
let negated = match e.node {
|
let negated = match e.node {
|
||||||
ExprBinary(binop, ref lhs, ref rhs) => {
|
ExprBinary(binop, ref lhs, ref rhs) => {
|
||||||
let mk_expr = |op| Expr {
|
let mk_expr = |op| {
|
||||||
|
Expr {
|
||||||
id: DUMMY_NODE_ID,
|
id: DUMMY_NODE_ID,
|
||||||
span: DUMMY_SP,
|
span: DUMMY_SP,
|
||||||
attrs: None,
|
attrs: None,
|
||||||
node: ExprBinary(dummy_spanned(op), lhs.clone(), rhs.clone()),
|
node: ExprBinary(dummy_spanned(op), lhs.clone(), rhs.clone()),
|
||||||
|
}
|
||||||
};
|
};
|
||||||
match binop.node {
|
match binop.node {
|
||||||
BiEq => mk_expr(BiNe),
|
BiEq => mk_expr(BiNe),
|
||||||
|
@ -110,7 +112,7 @@ impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> {
|
||||||
BiLe => mk_expr(BiGt),
|
BiLe => mk_expr(BiGt),
|
||||||
_ => continue,
|
_ => continue,
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
_ => continue,
|
_ => continue,
|
||||||
};
|
};
|
||||||
if SpanlessEq::new(self.cx).ignore_fn().eq_expr(&negated, expr) {
|
if SpanlessEq::new(self.cx).ignore_fn().eq_expr(&negated, expr) {
|
||||||
|
@ -137,17 +139,17 @@ fn suggest(cx: &LateContext, suggestion: &Bool, terminals: &[&Expr]) -> String {
|
||||||
True => {
|
True => {
|
||||||
s.push_str("true");
|
s.push_str("true");
|
||||||
s
|
s
|
||||||
},
|
}
|
||||||
False => {
|
False => {
|
||||||
s.push_str("false");
|
s.push_str("false");
|
||||||
s
|
s
|
||||||
},
|
}
|
||||||
Not(ref inner) => {
|
Not(ref inner) => {
|
||||||
match **inner {
|
match **inner {
|
||||||
And(_) | Or(_) => {
|
And(_) | Or(_) => {
|
||||||
s.push('!');
|
s.push('!');
|
||||||
recurse(true, cx, inner, terminals, s)
|
recurse(true, cx, inner, terminals, s)
|
||||||
},
|
}
|
||||||
Term(n) => {
|
Term(n) => {
|
||||||
if let ExprBinary(binop, ref lhs, ref rhs) = terminals[n as usize].node {
|
if let ExprBinary(binop, ref lhs, ref rhs) = terminals[n as usize].node {
|
||||||
let op = match binop.node {
|
let op = match binop.node {
|
||||||
|
@ -159,8 +161,8 @@ fn suggest(cx: &LateContext, suggestion: &Bool, terminals: &[&Expr]) -> String {
|
||||||
BiGe => " < ",
|
BiGe => " < ",
|
||||||
_ => {
|
_ => {
|
||||||
s.push('!');
|
s.push('!');
|
||||||
return recurse(true, cx, inner, terminals, s)
|
return recurse(true, cx, inner, terminals, s);
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
s.push_str(&snip(lhs));
|
s.push_str(&snip(lhs));
|
||||||
s.push_str(op);
|
s.push_str(op);
|
||||||
|
@ -170,13 +172,13 @@ fn suggest(cx: &LateContext, suggestion: &Bool, terminals: &[&Expr]) -> String {
|
||||||
s.push('!');
|
s.push('!');
|
||||||
recurse(false, cx, inner, terminals, s)
|
recurse(false, cx, inner, terminals, s)
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
_ => {
|
_ => {
|
||||||
s.push('!');
|
s.push('!');
|
||||||
recurse(false, cx, inner, terminals, s)
|
recurse(false, cx, inner, terminals, s)
|
||||||
},
|
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
}
|
||||||
And(ref v) => {
|
And(ref v) => {
|
||||||
if brackets {
|
if brackets {
|
||||||
s.push('(');
|
s.push('(');
|
||||||
|
@ -198,7 +200,7 @@ fn suggest(cx: &LateContext, suggestion: &Bool, terminals: &[&Expr]) -> String {
|
||||||
s.push(')');
|
s.push(')');
|
||||||
}
|
}
|
||||||
s
|
s
|
||||||
},
|
}
|
||||||
Or(ref v) => {
|
Or(ref v) => {
|
||||||
if brackets {
|
if brackets {
|
||||||
s.push('(');
|
s.push('(');
|
||||||
|
@ -212,7 +214,7 @@ fn suggest(cx: &LateContext, suggestion: &Bool, terminals: &[&Expr]) -> String {
|
||||||
s.push(')');
|
s.push(')');
|
||||||
}
|
}
|
||||||
s
|
s
|
||||||
},
|
}
|
||||||
Term(n) => {
|
Term(n) => {
|
||||||
if brackets {
|
if brackets {
|
||||||
if let ExprBinary(..) = terminals[n as usize].node {
|
if let ExprBinary(..) = terminals[n as usize].node {
|
||||||
|
@ -243,13 +245,13 @@ fn simple_negate(b: Bool) -> Bool {
|
||||||
*el = simple_negate(::std::mem::replace(el, True));
|
*el = simple_negate(::std::mem::replace(el, True));
|
||||||
}
|
}
|
||||||
Or(v)
|
Or(v)
|
||||||
},
|
}
|
||||||
Or(mut v) => {
|
Or(mut v) => {
|
||||||
for el in &mut v {
|
for el in &mut v {
|
||||||
*el = simple_negate(::std::mem::replace(el, True));
|
*el = simple_negate(::std::mem::replace(el, True));
|
||||||
}
|
}
|
||||||
And(v)
|
And(v)
|
||||||
},
|
}
|
||||||
Not(inner) => *inner,
|
Not(inner) => *inner,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -271,13 +273,13 @@ fn terminal_stats(b: &Bool) -> Stats {
|
||||||
_ => stats.negations += 1,
|
_ => stats.negations += 1,
|
||||||
}
|
}
|
||||||
recurse(inner, stats);
|
recurse(inner, stats);
|
||||||
},
|
}
|
||||||
And(ref v) | Or(ref v) => {
|
And(ref v) | Or(ref v) => {
|
||||||
stats.ops += v.len() - 1;
|
stats.ops += v.len() - 1;
|
||||||
for inner in v {
|
for inner in v {
|
||||||
recurse(inner, stats);
|
recurse(inner, stats);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Term(n) => stats.terminals[n as usize] += 1,
|
Term(n) => stats.terminals[n as usize] += 1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -306,7 +308,7 @@ impl<'a, 'tcx> NonminimalBoolVisitor<'a, 'tcx> {
|
||||||
let mut simplified = expr.simplify();
|
let mut simplified = expr.simplify();
|
||||||
for simple in Bool::Not(Box::new(expr.clone())).simplify() {
|
for simple in Bool::Not(Box::new(expr.clone())).simplify() {
|
||||||
match simple {
|
match simple {
|
||||||
Bool::Not(_) | Bool::True | Bool::False => {},
|
Bool::Not(_) | Bool::True | Bool::False => {}
|
||||||
_ => simplified.push(Bool::Not(Box::new(simple.clone()))),
|
_ => simplified.push(Bool::Not(Box::new(simple.clone()))),
|
||||||
}
|
}
|
||||||
let simple_negated = simple_negate(simple);
|
let simple_negated = simple_negate(simple);
|
||||||
|
@ -325,16 +327,25 @@ impl<'a, 'tcx> NonminimalBoolVisitor<'a, 'tcx> {
|
||||||
continue 'simplified;
|
continue 'simplified;
|
||||||
}
|
}
|
||||||
if stats.terminals[i] != 0 && simplified_stats.terminals[i] == 0 {
|
if stats.terminals[i] != 0 && simplified_stats.terminals[i] == 0 {
|
||||||
span_lint_and_then(self.0, LOGIC_BUG, e.span, "this boolean expression contains a logic bug", |db| {
|
span_lint_and_then(self.0,
|
||||||
db.span_help(h2q.terminals[i].span, "this expression can be optimized out by applying boolean operations to the outer expression");
|
LOGIC_BUG,
|
||||||
db.span_suggestion(e.span, "it would look like the following", suggest(self.0, suggestion, &h2q.terminals));
|
e.span,
|
||||||
|
"this boolean expression contains a logic bug",
|
||||||
|
|db| {
|
||||||
|
db.span_help(h2q.terminals[i].span,
|
||||||
|
"this expression can be optimized out by applying \
|
||||||
|
boolean operations to the outer expression");
|
||||||
|
db.span_suggestion(e.span,
|
||||||
|
"it would look like the following",
|
||||||
|
suggest(self.0, suggestion, &h2q.terminals));
|
||||||
});
|
});
|
||||||
// don't also lint `NONMINIMAL_BOOL`
|
// don't also lint `NONMINIMAL_BOOL`
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// if the number of occurrences of a terminal decreases or any of the stats decreases while none increases
|
// if the number of occurrences of a terminal decreases or any of the stats decreases while none increases
|
||||||
improvement |= (stats.terminals[i] > simplified_stats.terminals[i]) ||
|
improvement |= (stats.terminals[i] > simplified_stats.terminals[i]) ||
|
||||||
(stats.negations > simplified_stats.negations && stats.ops == simplified_stats.ops) ||
|
(stats.negations > simplified_stats.negations &&
|
||||||
|
stats.ops == simplified_stats.ops) ||
|
||||||
(stats.ops > simplified_stats.ops && stats.negations == simplified_stats.negations);
|
(stats.ops > simplified_stats.ops && stats.negations == simplified_stats.negations);
|
||||||
}
|
}
|
||||||
if improvement {
|
if improvement {
|
||||||
|
@ -342,9 +353,15 @@ impl<'a, 'tcx> NonminimalBoolVisitor<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !improvements.is_empty() {
|
if !improvements.is_empty() {
|
||||||
span_lint_and_then(self.0, NONMINIMAL_BOOL, e.span, "this boolean expression can be simplified", |db| {
|
span_lint_and_then(self.0,
|
||||||
|
NONMINIMAL_BOOL,
|
||||||
|
e.span,
|
||||||
|
"this boolean expression can be simplified",
|
||||||
|
|db| {
|
||||||
for suggestion in &improvements {
|
for suggestion in &improvements {
|
||||||
db.span_suggestion(e.span, "try", suggest(self.0, suggestion, &h2q.terminals));
|
db.span_suggestion(e.span,
|
||||||
|
"try",
|
||||||
|
suggest(self.0, suggestion, &h2q.terminals));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -354,7 +371,9 @@ impl<'a, 'tcx> NonminimalBoolVisitor<'a, 'tcx> {
|
||||||
|
|
||||||
impl<'a, 'v, 'tcx> Visitor<'v> for NonminimalBoolVisitor<'a, 'tcx> {
|
impl<'a, 'v, 'tcx> Visitor<'v> for NonminimalBoolVisitor<'a, 'tcx> {
|
||||||
fn visit_expr(&mut self, e: &'v Expr) {
|
fn visit_expr(&mut self, e: &'v Expr) {
|
||||||
if in_macro(self.0, e.span) { return }
|
if in_macro(self.0, e.span) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
match e.node {
|
match e.node {
|
||||||
ExprBinary(binop, _, _) if binop.node == BiOr || binop.node == BiAnd => self.bool_expr(e),
|
ExprBinary(binop, _, _) if binop.node == BiOr || binop.node == BiAnd => self.bool_expr(e),
|
||||||
ExprUnary(UnNot, ref inner) => {
|
ExprUnary(UnNot, ref inner) => {
|
||||||
|
@ -363,7 +382,7 @@ impl<'a, 'v, 'tcx> Visitor<'v> for NonminimalBoolVisitor<'a, 'tcx> {
|
||||||
} else {
|
} else {
|
||||||
walk_expr(self, e);
|
walk_expr(self, e);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
_ => walk_expr(self, e),
|
_ => walk_expr(self, e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,7 +85,9 @@ impl PartialEq for Constant {
|
||||||
(&Constant::Str(ref ls, ref l_sty), &Constant::Str(ref rs, ref r_sty)) => ls == rs && l_sty == r_sty,
|
(&Constant::Str(ref ls, ref l_sty), &Constant::Str(ref rs, ref r_sty)) => ls == rs && l_sty == r_sty,
|
||||||
(&Constant::Binary(ref l), &Constant::Binary(ref r)) => l == r,
|
(&Constant::Binary(ref l), &Constant::Binary(ref r)) => l == r,
|
||||||
(&Constant::Char(l), &Constant::Char(r)) => l == r,
|
(&Constant::Char(l), &Constant::Char(r)) => l == r,
|
||||||
(&Constant::Int(l), &Constant::Int(r)) => l.is_negative() == r.is_negative() && l.to_u64_unchecked() == r.to_u64_unchecked(),
|
(&Constant::Int(l), &Constant::Int(r)) => {
|
||||||
|
l.is_negative() == r.is_negative() && l.to_u64_unchecked() == r.to_u64_unchecked()
|
||||||
|
}
|
||||||
(&Constant::Float(ref ls, _), &Constant::Float(ref rs, _)) => {
|
(&Constant::Float(ref ls, _), &Constant::Float(ref rs, _)) => {
|
||||||
// we want `Fw32 == FwAny` and `FwAny == Fw64`, by transitivity we must have
|
// we want `Fw32 == FwAny` and `FwAny == Fw64`, by transitivity we must have
|
||||||
// `Fw32 == Fw64` so don’t compare them
|
// `Fw32 == Fw64` so don’t compare them
|
||||||
|
@ -131,7 +133,8 @@ impl Hash for Constant {
|
||||||
Constant::Bool(b) => {
|
Constant::Bool(b) => {
|
||||||
b.hash(state);
|
b.hash(state);
|
||||||
}
|
}
|
||||||
Constant::Vec(ref v) | Constant::Tuple(ref v) => {
|
Constant::Vec(ref v) |
|
||||||
|
Constant::Tuple(ref v) => {
|
||||||
v.hash(state);
|
v.hash(state);
|
||||||
}
|
}
|
||||||
Constant::Repeat(ref c, l) => {
|
Constant::Repeat(ref c, l) => {
|
||||||
|
@ -186,12 +189,16 @@ fn lit_to_constant(lit: &LitKind) -> Constant {
|
||||||
LitKind::Int(value, LitIntType::Unsigned(UintTy::U16)) => Constant::Int(ConstInt::U16(value as u16)),
|
LitKind::Int(value, LitIntType::Unsigned(UintTy::U16)) => Constant::Int(ConstInt::U16(value as u16)),
|
||||||
LitKind::Int(value, LitIntType::Unsigned(UintTy::U32)) => Constant::Int(ConstInt::U32(value as u32)),
|
LitKind::Int(value, LitIntType::Unsigned(UintTy::U32)) => Constant::Int(ConstInt::U32(value as u32)),
|
||||||
LitKind::Int(value, LitIntType::Unsigned(UintTy::U64)) => Constant::Int(ConstInt::U64(value as u64)),
|
LitKind::Int(value, LitIntType::Unsigned(UintTy::U64)) => Constant::Int(ConstInt::U64(value as u64)),
|
||||||
LitKind::Int(value, LitIntType::Unsigned(UintTy::Us)) => Constant::Int(ConstInt::Usize(ConstUsize::Us32(value as u32))),
|
LitKind::Int(value, LitIntType::Unsigned(UintTy::Us)) => {
|
||||||
|
Constant::Int(ConstInt::Usize(ConstUsize::Us32(value as u32)))
|
||||||
|
}
|
||||||
LitKind::Int(value, LitIntType::Signed(IntTy::I8)) => Constant::Int(ConstInt::I8(value as i8)),
|
LitKind::Int(value, LitIntType::Signed(IntTy::I8)) => Constant::Int(ConstInt::I8(value as i8)),
|
||||||
LitKind::Int(value, LitIntType::Signed(IntTy::I16)) => Constant::Int(ConstInt::I16(value as i16)),
|
LitKind::Int(value, LitIntType::Signed(IntTy::I16)) => Constant::Int(ConstInt::I16(value as i16)),
|
||||||
LitKind::Int(value, LitIntType::Signed(IntTy::I32)) => Constant::Int(ConstInt::I32(value as i32)),
|
LitKind::Int(value, LitIntType::Signed(IntTy::I32)) => Constant::Int(ConstInt::I32(value as i32)),
|
||||||
LitKind::Int(value, LitIntType::Signed(IntTy::I64)) => Constant::Int(ConstInt::I64(value as i64)),
|
LitKind::Int(value, LitIntType::Signed(IntTy::I64)) => Constant::Int(ConstInt::I64(value as i64)),
|
||||||
LitKind::Int(value, LitIntType::Signed(IntTy::Is)) => Constant::Int(ConstInt::Isize(ConstIsize::Is32(value as i32))),
|
LitKind::Int(value, LitIntType::Signed(IntTy::Is)) => {
|
||||||
|
Constant::Int(ConstInt::Isize(ConstIsize::Is32(value as i32)))
|
||||||
|
}
|
||||||
LitKind::Float(ref is, ty) => Constant::Float(is.to_string(), ty.into()),
|
LitKind::Float(ref is, ty) => Constant::Float(is.to_string(), ty.into()),
|
||||||
LitKind::FloatUnsuffixed(ref is) => Constant::Float(is.to_string(), FloatWidth::Any),
|
LitKind::FloatUnsuffixed(ref is) => Constant::Float(is.to_string(), FloatWidth::Any),
|
||||||
LitKind::Bool(b) => Constant::Bool(b),
|
LitKind::Bool(b) => Constant::Bool(b),
|
||||||
|
@ -324,7 +331,11 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn binop(&mut self, op: BinOp, left: &Expr, right: &Expr) -> Option<Constant> {
|
fn binop(&mut self, op: BinOp, left: &Expr, right: &Expr) -> Option<Constant> {
|
||||||
let l = if let Some(l) = self.expr(left) { l } else { return None; };
|
let l = if let Some(l) = self.expr(left) {
|
||||||
|
l
|
||||||
|
} else {
|
||||||
|
return None;
|
||||||
|
};
|
||||||
let r = self.expr(right);
|
let r = self.expr(right);
|
||||||
match (op.node, l, r) {
|
match (op.node, l, r) {
|
||||||
(BiAdd, Constant::Int(l), Some(Constant::Int(r))) => (l + r).ok().map(Constant::Int),
|
(BiAdd, Constant::Int(l), Some(Constant::Int(r))) => (l + r).ok().map(Constant::Int),
|
||||||
|
|
|
@ -185,7 +185,8 @@ fn if_sequence(mut expr: &Expr) -> (SmallVector<&Expr>, SmallVector<&Block>) {
|
||||||
fn bindings<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, pat: &Pat) -> HashMap<InternedString, ty::Ty<'tcx>> {
|
fn bindings<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, pat: &Pat) -> HashMap<InternedString, ty::Ty<'tcx>> {
|
||||||
fn bindings_impl<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, pat: &Pat, map: &mut HashMap<InternedString, ty::Ty<'tcx>>) {
|
fn bindings_impl<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, pat: &Pat, map: &mut HashMap<InternedString, ty::Ty<'tcx>>) {
|
||||||
match pat.node {
|
match pat.node {
|
||||||
PatKind::Box(ref pat) | PatKind::Ref(ref pat, _) => bindings_impl(cx, pat, map),
|
PatKind::Box(ref pat) |
|
||||||
|
PatKind::Ref(ref pat, _) => bindings_impl(cx, pat, map),
|
||||||
PatKind::TupleStruct(_, Some(ref pats)) => {
|
PatKind::TupleStruct(_, Some(ref pats)) => {
|
||||||
for pat in pats {
|
for pat in pats {
|
||||||
bindings_impl(cx, pat, map);
|
bindings_impl(cx, pat, map);
|
||||||
|
|
|
@ -60,12 +60,7 @@ impl CyclomaticComplexity {
|
||||||
tcx: &cx.tcx,
|
tcx: &cx.tcx,
|
||||||
};
|
};
|
||||||
helper.visit_block(block);
|
helper.visit_block(block);
|
||||||
let CCHelper {
|
let CCHelper { match_arms, divergence, short_circuits, .. } = helper;
|
||||||
match_arms,
|
|
||||||
divergence,
|
|
||||||
short_circuits,
|
|
||||||
..
|
|
||||||
} = helper;
|
|
||||||
|
|
||||||
if cc + divergence < match_arms + short_circuits {
|
if cc + divergence < match_arms + short_circuits {
|
||||||
report_cc_bug(cx, cc, match_arms, divergence, short_circuits, span);
|
report_cc_bug(cx, cc, match_arms, divergence, short_circuits, span);
|
||||||
|
@ -132,7 +127,8 @@ impl<'a, 'b, 'tcx> Visitor<'a> for CCHelper<'b, 'tcx> {
|
||||||
walk_expr(self, e);
|
walk_expr(self, e);
|
||||||
let ty = self.tcx.node_id_to_type(callee.id);
|
let ty = self.tcx.node_id_to_type(callee.id);
|
||||||
match ty.sty {
|
match ty.sty {
|
||||||
ty::TyFnDef(_, _, ty) | ty::TyFnPtr(ty) if ty.sig.skip_binder().output.diverges() => {
|
ty::TyFnDef(_, _, ty) |
|
||||||
|
ty::TyFnPtr(ty) if ty.sig.skip_binder().output.diverges() => {
|
||||||
self.divergence += 1;
|
self.divergence += 1;
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
|
@ -143,7 +139,7 @@ impl<'a, 'b, 'tcx> Visitor<'a> for CCHelper<'b, 'tcx> {
|
||||||
walk_expr(self, e);
|
walk_expr(self, e);
|
||||||
match op.node {
|
match op.node {
|
||||||
BiAnd | BiOr => self.short_circuits += 1,
|
BiAnd | BiOr => self.short_circuits += 1,
|
||||||
_ => {},
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => walk_expr(self, e),
|
_ => walk_expr(self, e),
|
||||||
|
|
|
@ -142,7 +142,7 @@ pub fn check_doc(cx: &EarlyContext, valid_idents: &[String], doc: &str, span: Sp
|
||||||
}
|
}
|
||||||
'`' => {
|
'`' => {
|
||||||
current_word_begin = jump_to!(chars, '`', len);
|
current_word_begin = jump_to!(chars, '`', len);
|
||||||
},
|
}
|
||||||
'[' => {
|
'[' => {
|
||||||
let end = jump_to!(chars, ']', len);
|
let end = jump_to!(chars, ']', len);
|
||||||
let link_text = &doc[current_word_begin + 1..end];
|
let link_text = &doc[current_word_begin + 1..end];
|
||||||
|
@ -223,6 +223,9 @@ fn check_word(cx: &EarlyContext, valid_idents: &[String], word: &str, span: Span
|
||||||
}
|
}
|
||||||
|
|
||||||
if has_underscore(word) || word.contains("::") || is_camel_case(word) {
|
if has_underscore(word) || word.contains("::") || is_camel_case(word) {
|
||||||
span_lint(cx, DOC_MARKDOWN, span, &format!("you should put `{}` between ticks in the documentation", word));
|
span_lint(cx,
|
||||||
|
DOC_MARKDOWN,
|
||||||
|
span,
|
||||||
|
&format!("you should put `{}` between ticks in the documentation", word));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,8 @@ fn check_closure(cx: &LateContext, expr: &Expr) {
|
||||||
let fn_ty = cx.tcx.expr_ty(caller);
|
let fn_ty = cx.tcx.expr_ty(caller);
|
||||||
match fn_ty.sty {
|
match fn_ty.sty {
|
||||||
// Is it an unsafe function? They don't implement the closure traits
|
// Is it an unsafe function? They don't implement the closure traits
|
||||||
ty::TyFnDef(_, _, fn_ty) | ty::TyFnPtr(fn_ty) => {
|
ty::TyFnDef(_, _, fn_ty) |
|
||||||
|
ty::TyFnPtr(fn_ty) => {
|
||||||
if fn_ty.unsafety == Unsafety::Unsafe ||
|
if fn_ty.unsafety == Unsafety::Unsafe ||
|
||||||
fn_ty.sig.skip_binder().output == ty::FnOutput::FnDiverging {
|
fn_ty.sig.skip_binder().output == ty::FnOutput::FnDiverging {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -31,9 +31,7 @@ pub struct Functions {
|
||||||
|
|
||||||
impl Functions {
|
impl Functions {
|
||||||
pub fn new(threshold: u64) -> Functions {
|
pub fn new(threshold: u64) -> Functions {
|
||||||
Functions {
|
Functions { threshold: threshold }
|
||||||
threshold: threshold
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +47,8 @@ impl LateLintPass for Functions {
|
||||||
|
|
||||||
if let Some(NodeItem(ref item)) = cx.tcx.map.find(cx.tcx.map.get_parent_node(nodeid)) {
|
if let Some(NodeItem(ref item)) = cx.tcx.map.find(cx.tcx.map.get_parent_node(nodeid)) {
|
||||||
match item.node {
|
match item.node {
|
||||||
hir::ItemImpl(_, _, _, Some(_), _, _) | hir::ItemDefaultImpl(..) => return,
|
hir::ItemImpl(_, _, _, Some(_), _, _) |
|
||||||
|
hir::ItemDefaultImpl(..) => return,
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,7 +67,9 @@ impl Functions {
|
||||||
fn check_arg_number(&self, cx: &LateContext, decl: &hir::FnDecl, span: Span) {
|
fn check_arg_number(&self, cx: &LateContext, decl: &hir::FnDecl, span: Span) {
|
||||||
let args = decl.inputs.len() as u64;
|
let args = decl.inputs.len() as u64;
|
||||||
if args > self.threshold {
|
if args > self.threshold {
|
||||||
span_lint(cx, TOO_MANY_ARGUMENTS, span,
|
span_lint(cx,
|
||||||
|
TOO_MANY_ARGUMENTS,
|
||||||
|
span,
|
||||||
&format!("this function has to many arguments ({}/{})", args, self.threshold));
|
&format!("this function has to many arguments ({}/{})", args, self.threshold));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,15 +37,15 @@ impl EarlyLintPass for IfNotElse {
|
||||||
item.span,
|
item.span,
|
||||||
"Unnecessary boolean `not` operation",
|
"Unnecessary boolean `not` operation",
|
||||||
"remove the `!` and swap the blocks of the if/else");
|
"remove the `!` and swap the blocks of the if/else");
|
||||||
},
|
}
|
||||||
ExprKind::Binary(ref kind, _, _) if kind.node == BinOpKind::Ne => {
|
ExprKind::Binary(ref kind, _, _) if kind.node == BinOpKind::Ne => {
|
||||||
span_help_and_lint(cx,
|
span_help_and_lint(cx,
|
||||||
IF_NOT_ELSE,
|
IF_NOT_ELSE,
|
||||||
item.span,
|
item.span,
|
||||||
"Unnecessary `!=` operation",
|
"Unnecessary `!=` operation",
|
||||||
"change to `==` and swap the blocks of the if/else");
|
"change to `==` and swap the blocks of the if/else");
|
||||||
},
|
}
|
||||||
_ => {},
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -199,7 +199,8 @@ fn has_is_empty(cx: &LateContext, expr: &Expr) -> bool {
|
||||||
.map_or(false, |ids| ids.iter().any(|i| is_is_empty(cx, i)))
|
.map_or(false, |ids| ids.iter().any(|i| is_is_empty(cx, i)))
|
||||||
}
|
}
|
||||||
ty::TyProjection(_) => ty.ty_to_def_id().map_or(false, |id| has_is_empty_impl(cx, &id)),
|
ty::TyProjection(_) => ty.ty_to_def_id().map_or(false, |id| has_is_empty_impl(cx, &id)),
|
||||||
ty::TyEnum(ref id, _) | ty::TyStruct(ref id, _) => has_is_empty_impl(cx, &id.did),
|
ty::TyEnum(ref id, _) |
|
||||||
|
ty::TyStruct(ref id, _) => has_is_empty_impl(cx, &id.did),
|
||||||
ty::TyArray(..) | ty::TyStr => true,
|
ty::TyArray(..) | ty::TyStr => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,7 +127,7 @@ fn could_use_elision<'a, T: Iterator<Item = &'a Lifetime>>(cx: &LateContext, fun
|
||||||
match slf.node {
|
match slf.node {
|
||||||
SelfRegion(ref opt_lt, _, _) => input_visitor.record(opt_lt),
|
SelfRegion(ref opt_lt, _, _) => input_visitor.record(opt_lt),
|
||||||
SelfExplicit(ref ty, _) => walk_ty(&mut input_visitor, ty),
|
SelfExplicit(ref ty, _) => walk_ty(&mut input_visitor, ty),
|
||||||
_ => {}
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// extract lifetimes in input argument types
|
// extract lifetimes in input argument types
|
||||||
|
@ -243,7 +243,8 @@ impl<'v, 't> RefVisitor<'v, 't> {
|
||||||
if params.lifetimes.is_empty() {
|
if params.lifetimes.is_empty() {
|
||||||
if let Some(def) = self.cx.tcx.def_map.borrow().get(&ty.id).map(|r| r.full_def()) {
|
if let Some(def) = self.cx.tcx.def_map.borrow().get(&ty.id).map(|r| r.full_def()) {
|
||||||
match def {
|
match def {
|
||||||
Def::TyAlias(def_id) | Def::Struct(def_id) => {
|
Def::TyAlias(def_id) |
|
||||||
|
Def::Struct(def_id) => {
|
||||||
let type_scheme = self.cx.tcx.lookup_item_type(def_id);
|
let type_scheme = self.cx.tcx.lookup_item_type(def_id);
|
||||||
for _ in type_scheme.generics.regions.as_slice() {
|
for _ in type_scheme.generics.regions.as_slice() {
|
||||||
self.record(&None);
|
self.record(&None);
|
||||||
|
@ -255,7 +256,7 @@ impl<'v, 't> RefVisitor<'v, 't> {
|
||||||
self.record(&None);
|
self.record(&None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -277,7 +278,7 @@ impl<'v, 't> Visitor<'v> for RefVisitor<'v, 't> {
|
||||||
TyPath(_, ref path) => {
|
TyPath(_, ref path) => {
|
||||||
self.collect_anonymous_lifetimes(path, ty);
|
self.collect_anonymous_lifetimes(path, ty);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => (),
|
||||||
}
|
}
|
||||||
walk_ty(self, ty);
|
walk_ty(self, ty);
|
||||||
}
|
}
|
||||||
|
@ -353,7 +354,7 @@ fn report_extra_lifetimes(cx: &LateContext, func: &FnDecl, generics: &Generics,
|
||||||
match slf.node {
|
match slf.node {
|
||||||
SelfRegion(Some(ref lt), _, _) => checker.visit_lifetime(lt),
|
SelfRegion(Some(ref lt), _, _) => checker.visit_lifetime(lt),
|
||||||
SelfExplicit(ref t, _) => walk_ty(&mut checker, t),
|
SelfExplicit(ref t, _) => walk_ty(&mut checker, t),
|
||||||
_ => {}
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
src/loops.rs
10
src/loops.rs
|
@ -14,8 +14,8 @@ use std::collections::HashMap;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
|
|
||||||
use utils::{snippet, span_lint, get_parent_expr, match_trait_method, match_type, in_external_macro,
|
use utils::{snippet, span_lint, get_parent_expr, match_trait_method, match_type, in_external_macro,
|
||||||
span_help_and_lint, is_integer_literal, get_enclosing_block, span_lint_and_then,
|
span_help_and_lint, is_integer_literal, get_enclosing_block, span_lint_and_then, unsugar_range,
|
||||||
unsugar_range, walk_ptrs_ty, recover_for_loop};
|
walk_ptrs_ty, recover_for_loop};
|
||||||
use utils::paths;
|
use utils::paths;
|
||||||
use utils::UnsugaredRange;
|
use utils::UnsugaredRange;
|
||||||
|
|
||||||
|
@ -247,7 +247,8 @@ impl LateLintPass for LoopsPass {
|
||||||
if let ExprMatch(ref matchexpr, ref arms, ref source) = inner.node {
|
if let ExprMatch(ref matchexpr, ref arms, ref source) = inner.node {
|
||||||
// ensure "if let" compatible match structure
|
// ensure "if let" compatible match structure
|
||||||
match *source {
|
match *source {
|
||||||
MatchSource::Normal | MatchSource::IfLetDesugar{..} => {
|
MatchSource::Normal |
|
||||||
|
MatchSource::IfLetDesugar { .. } => {
|
||||||
if arms.len() == 2 && arms[0].pats.len() == 1 && arms[0].guard.is_none() &&
|
if arms.len() == 2 && arms[0].pats.len() == 1 && arms[0].guard.is_none() &&
|
||||||
arms[1].pats.len() == 1 && arms[1].guard.is_none() &&
|
arms[1].pats.len() == 1 && arms[1].guard.is_none() &&
|
||||||
is_break_expr(&arms[1].body) {
|
is_break_expr(&arms[1].body) {
|
||||||
|
@ -779,7 +780,8 @@ fn extract_first_expr(block: &Block) -> Option<&Expr> {
|
||||||
Some(ref expr) => Some(expr),
|
Some(ref expr) => Some(expr),
|
||||||
None if !block.stmts.is_empty() => {
|
None if !block.stmts.is_empty() => {
|
||||||
match block.stmts[0].node {
|
match block.stmts[0].node {
|
||||||
StmtExpr(ref expr, _) | StmtSemi(ref expr, _) => Some(expr),
|
StmtExpr(ref expr, _) |
|
||||||
|
StmtSemi(ref expr, _) => Some(expr),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -252,19 +252,20 @@ fn check_match_bool(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr) {
|
||||||
|
|
||||||
if let Some((ref true_expr, ref false_expr)) = exprs {
|
if let Some((ref true_expr, ref false_expr)) = exprs {
|
||||||
match (is_unit_expr(true_expr), is_unit_expr(false_expr)) {
|
match (is_unit_expr(true_expr), is_unit_expr(false_expr)) {
|
||||||
(false, false) =>
|
(false, false) => {
|
||||||
Some(format!("if {} {} else {}",
|
Some(format!("if {} {} else {}",
|
||||||
snippet(cx, ex.span, "b"),
|
snippet(cx, ex.span, "b"),
|
||||||
expr_block(cx, true_expr, None, ".."),
|
expr_block(cx, true_expr, None, ".."),
|
||||||
expr_block(cx, false_expr, None, ".."))),
|
expr_block(cx, false_expr, None, "..")))
|
||||||
(false, true) =>
|
}
|
||||||
Some(format!("if {} {}",
|
(false, true) => {
|
||||||
snippet(cx, ex.span, "b"),
|
Some(format!("if {} {}", snippet(cx, ex.span, "b"), expr_block(cx, true_expr, None, "..")))
|
||||||
expr_block(cx, true_expr, None, ".."))),
|
}
|
||||||
(true, false) =>
|
(true, false) => {
|
||||||
Some(format!("try\nif !{} {}",
|
Some(format!("try\nif !{} {}",
|
||||||
snippet(cx, ex.span, "b"),
|
snippet(cx, ex.span, "b"),
|
||||||
expr_block(cx, false_expr, None, ".."))),
|
expr_block(cx, false_expr, None, "..")))
|
||||||
|
}
|
||||||
(true, true) => None,
|
(true, true) => None,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -312,9 +313,7 @@ fn check_match_ref_pats(cx: &LateContext, ex: &Expr, arms: &[Arm], source: Match
|
||||||
expr.span,
|
expr.span,
|
||||||
"you don't need to add `&` to both the expression and the patterns",
|
"you don't need to add `&` to both the expression and the patterns",
|
||||||
|db| {
|
|db| {
|
||||||
db.span_suggestion(expr.span,
|
db.span_suggestion(expr.span, "try", template);
|
||||||
"try",
|
|
||||||
template);
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
let template = match_template(cx, expr.span, source, "*", ex);
|
let template = match_template(cx, expr.span, source, "*", ex);
|
||||||
|
@ -324,7 +323,8 @@ fn check_match_ref_pats(cx: &LateContext, ex: &Expr, arms: &[Arm], source: Match
|
||||||
"you don't need to add `&` to all patterns",
|
"you don't need to add `&` to all patterns",
|
||||||
|db| {
|
|db| {
|
||||||
db.span_suggestion(expr.span,
|
db.span_suggestion(expr.span,
|
||||||
"instead of prefixing all patterns with `&`, you can dereference the expression",
|
"instead of prefixing all patterns with `&`, you can \
|
||||||
|
dereference the expression",
|
||||||
template);
|
template);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -373,7 +373,8 @@ type TypedRanges = Vec<SpannedRange<ConstInt>>;
|
||||||
/// Get all `Int` ranges or all `Uint` ranges. Mixed types are an error anyway and other types than
|
/// Get all `Int` ranges or all `Uint` ranges. Mixed types are an error anyway and other types than
|
||||||
/// `Uint` and `Int` probably don't make sense.
|
/// `Uint` and `Int` probably don't make sense.
|
||||||
fn type_ranges(ranges: &[SpannedRange<ConstVal>]) -> TypedRanges {
|
fn type_ranges(ranges: &[SpannedRange<ConstVal>]) -> TypedRanges {
|
||||||
ranges.iter().filter_map(|range| {
|
ranges.iter()
|
||||||
|
.filter_map(|range| {
|
||||||
if let (ConstVal::Integral(start), ConstVal::Integral(end)) = range.node {
|
if let (ConstVal::Integral(start), ConstVal::Integral(end)) = range.node {
|
||||||
Some(SpannedRange {
|
Some(SpannedRange {
|
||||||
span: range.span,
|
span: range.span,
|
||||||
|
@ -416,7 +417,7 @@ fn match_template(cx: &LateContext, span: Span, source: MatchSource, op: &str, e
|
||||||
MatchSource::IfLetDesugar { .. } => format!("if let .. = {}{} {{ .. }}", op, expr_snippet),
|
MatchSource::IfLetDesugar { .. } => format!("if let .. = {}{} {{ .. }}", op, expr_snippet),
|
||||||
MatchSource::WhileLetDesugar => format!("while let .. = {}{} {{ .. }}", op, expr_snippet),
|
MatchSource::WhileLetDesugar => format!("while let .. = {}{} {{ .. }}", op, expr_snippet),
|
||||||
MatchSource::ForLoopDesugar => span_bug!(span, "for loop desugared to match with &-patterns!"),
|
MatchSource::ForLoopDesugar => span_bug!(span, "for loop desugared to match with &-patterns!"),
|
||||||
MatchSource::TryDesugar => span_bug!(span, "`?` operator desugared to match with &-patterns!")
|
MatchSource::TryDesugar => span_bug!(span, "`?` operator desugared to match with &-patterns!"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -432,13 +433,15 @@ pub fn overlapping<T>(ranges: &[SpannedRange<T>]) -> Option<(&SpannedRange<T>, &
|
||||||
impl<'a, T: Copy> Kind<'a, T> {
|
impl<'a, T: Copy> Kind<'a, T> {
|
||||||
fn range(&self) -> &'a SpannedRange<T> {
|
fn range(&self) -> &'a SpannedRange<T> {
|
||||||
match *self {
|
match *self {
|
||||||
Kind::Start(_, r) | Kind::End(_, r) => r,
|
Kind::Start(_, r) |
|
||||||
|
Kind::End(_, r) => r,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn value(self) -> T {
|
fn value(self) -> T {
|
||||||
match self {
|
match self {
|
||||||
Kind::Start(t, _) | Kind::End(t, _) => t,
|
Kind::Start(t, _) |
|
||||||
|
Kind::End(t, _) => t,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -436,7 +436,8 @@ impl LateLintPass for MethodsPass {
|
||||||
}
|
}
|
||||||
|
|
||||||
let ret_ty = return_ty(cx, implitem.id);
|
let ret_ty = return_ty(cx, implitem.id);
|
||||||
if &name.as_str() == &"new" && !ret_ty.map_or(false, |ret_ty| ret_ty.walk().any(|t| same_tys(cx, t, ty, implitem.id))) {
|
if &name.as_str() == &"new" &&
|
||||||
|
!ret_ty.map_or(false, |ret_ty| 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,
|
||||||
sig.explicit_self.span,
|
sig.explicit_self.span,
|
||||||
|
@ -946,7 +947,8 @@ impl SelfKind {
|
||||||
(&SelfKind::Ref, &SelfRegion(_, Mutability::MutImmutable, _)) |
|
(&SelfKind::Ref, &SelfRegion(_, Mutability::MutImmutable, _)) |
|
||||||
(&SelfKind::RefMut, &SelfRegion(_, Mutability::MutMutable, _)) |
|
(&SelfKind::RefMut, &SelfRegion(_, Mutability::MutMutable, _)) |
|
||||||
(&SelfKind::No, &SelfStatic) => true,
|
(&SelfKind::No, &SelfStatic) => true,
|
||||||
(&SelfKind::Ref, &SelfValue(_)) | (&SelfKind::RefMut, &SelfValue(_)) => allow_value_for_ref,
|
(&SelfKind::Ref, &SelfValue(_)) |
|
||||||
|
(&SelfKind::RefMut, &SelfValue(_)) => allow_value_for_ref,
|
||||||
(_, &SelfExplicit(ref ty, _)) => self.matches_explicit_type(ty, allow_value_for_ref),
|
(_, &SelfExplicit(ref ty, _)) => self.matches_explicit_type(ty, allow_value_for_ref),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,9 @@ impl LateLintPass for MinMaxPass {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
match (outer_max, outer_c.partial_cmp(&inner_c)) {
|
match (outer_max, outer_c.partial_cmp(&inner_c)) {
|
||||||
(_, None) | (MinMax::Max, Some(Ordering::Less)) | (MinMax::Min, Some(Ordering::Greater)) => (),
|
(_, None) |
|
||||||
|
(MinMax::Max, Some(Ordering::Less)) |
|
||||||
|
(MinMax::Min, Some(Ordering::Greater)) => (),
|
||||||
_ => {
|
_ => {
|
||||||
span_lint(cx, MIN_MAX, expr.span, "this min/max combination leads to constant result");
|
span_lint(cx, MIN_MAX, expr.span, "this min/max combination leads to constant result");
|
||||||
}
|
}
|
||||||
|
|
|
@ -422,7 +422,8 @@ impl LateLintPass for UsedUnderscoreBinding {
|
||||||
fn is_used(cx: &LateContext, expr: &Expr) -> bool {
|
fn is_used(cx: &LateContext, expr: &Expr) -> bool {
|
||||||
if let Some(ref parent) = get_parent_expr(cx, expr) {
|
if let Some(ref parent) = get_parent_expr(cx, expr) {
|
||||||
match parent.node {
|
match parent.node {
|
||||||
ExprAssign(_, ref rhs) | ExprAssignOp(_, _, ref rhs) => **rhs == *expr,
|
ExprAssign(_, ref rhs) |
|
||||||
|
ExprAssignOp(_, _, ref rhs) => **rhs == *expr,
|
||||||
_ => is_used(cx, &parent),
|
_ => is_used(cx, &parent),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -47,14 +47,15 @@ impl LateLintPass for UnnecessaryMutPassed {
|
||||||
let method_type = borrowed_table.method_map.get(&method_call).expect("This should never happen.");
|
let method_type = borrowed_table.method_map.get(&method_call).expect("This should never happen.");
|
||||||
check_arguments(cx, &arguments, method_type.ty, &name.node.as_str())
|
check_arguments(cx, &arguments, method_type.ty, &name.node.as_str())
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_arguments(cx: &LateContext, arguments: &[P<Expr>], type_definition: &TyS, name: &str) {
|
fn check_arguments(cx: &LateContext, arguments: &[P<Expr>], type_definition: &TyS, name: &str) {
|
||||||
match type_definition.sty {
|
match type_definition.sty {
|
||||||
TypeVariants::TyFnDef(_, _, ref fn_type) | TypeVariants::TyFnPtr(ref fn_type) => {
|
TypeVariants::TyFnDef(_, _, ref fn_type) |
|
||||||
|
TypeVariants::TyFnPtr(ref fn_type) => {
|
||||||
let parameters = &fn_type.sig.skip_binder().inputs;
|
let parameters = &fn_type.sig.skip_binder().inputs;
|
||||||
for (argument, parameter) in arguments.iter().zip(parameters.iter()) {
|
for (argument, parameter) in arguments.iter().zip(parameters.iter()) {
|
||||||
match parameter.sty {
|
match parameter.sty {
|
||||||
|
@ -67,7 +68,7 @@ fn check_arguments(cx: &LateContext, arguments: &[P<Expr>], type_definition: &Ty
|
||||||
&format!("The function/method \"{}\" doesn't need a mutable reference", name));
|
&format!("The function/method \"{}\" doesn't need a mutable reference", name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,8 @@ impl LateLintPass for NeedlessBool {
|
||||||
span_lint_and_then(cx,
|
span_lint_and_then(cx,
|
||||||
NEEDLESS_BOOL,
|
NEEDLESS_BOOL,
|
||||||
e.span,
|
e.span,
|
||||||
"this if-then-else expression returns a bool literal", |db| {
|
"this if-then-else expression returns a bool literal",
|
||||||
|
|db| {
|
||||||
db.span_suggestion(e.span, "you can reduce it to", hint);
|
db.span_suggestion(e.span, "you can reduce it to", hint);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -155,7 +156,8 @@ enum Expression {
|
||||||
fn fetch_bool_block(block: &Block) -> Expression {
|
fn fetch_bool_block(block: &Block) -> Expression {
|
||||||
match (&*block.stmts, block.expr.as_ref()) {
|
match (&*block.stmts, block.expr.as_ref()) {
|
||||||
([], Some(e)) => fetch_bool_expr(&**e),
|
([], Some(e)) => fetch_bool_expr(&**e),
|
||||||
([ref e], None) => if let StmtSemi(ref e, _) = e.node {
|
([ref e], None) => {
|
||||||
|
if let StmtSemi(ref e, _) = e.node {
|
||||||
if let ExprRet(_) = e.node {
|
if let ExprRet(_) = e.node {
|
||||||
fetch_bool_expr(&**e)
|
fetch_bool_expr(&**e)
|
||||||
} else {
|
} else {
|
||||||
|
@ -163,7 +165,8 @@ fn fetch_bool_block(block: &Block) -> Expression {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Expression::Other
|
Expression::Other
|
||||||
},
|
}
|
||||||
|
}
|
||||||
_ => Expression::Other,
|
_ => Expression::Other,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,11 +180,13 @@ fn fetch_bool_expr(expr: &Expr) -> Expression {
|
||||||
} else {
|
} else {
|
||||||
Expression::Other
|
Expression::Other
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
ExprRet(Some(ref expr)) => match fetch_bool_expr(expr) {
|
ExprRet(Some(ref expr)) => {
|
||||||
|
match fetch_bool_expr(expr) {
|
||||||
Expression::Bool(value) => Expression::RetBool(value),
|
Expression::Bool(value) => Expression::RetBool(value),
|
||||||
_ => Expression::Other,
|
_ => Expression::Other,
|
||||||
},
|
}
|
||||||
|
}
|
||||||
_ => Expression::Other,
|
_ => Expression::Other,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,8 @@ fn has_no_effect(cx: &LateContext, expr: &Expr) -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Expr_::ExprBlock(ref block) => {
|
Expr_::ExprBlock(ref block) => {
|
||||||
block.stmts.is_empty() && if let Some(ref expr) = block.expr {
|
block.stmts.is_empty() &&
|
||||||
|
if let Some(ref expr) = block.expr {
|
||||||
has_no_effect(cx, expr)
|
has_no_effect(cx, expr)
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
|
|
@ -57,6 +57,7 @@ struct SimilarNamesLocalVisitor<'a, 'b: 'a> {
|
||||||
|
|
||||||
// this list contains lists of names that are allowed to be similar
|
// this list contains lists of names that are allowed to be similar
|
||||||
// the assumption is that no name is ever contained in multiple lists.
|
// the assumption is that no name is ever contained in multiple lists.
|
||||||
|
#[cfg_attr(rustfmt, rustfmt_skip)]
|
||||||
const WHITELIST: &'static [&'static [&'static str]] = &[
|
const WHITELIST: &'static [&'static [&'static str]] = &[
|
||||||
&["parsed", "parser"],
|
&["parsed", "parser"],
|
||||||
&["lhs", "rhs"],
|
&["lhs", "rhs"],
|
||||||
|
@ -112,8 +113,7 @@ impl<'a, 'b, 'c> SimilarNamesNameVisitor<'a, 'b, 'c> {
|
||||||
span_lint(self.0.cx,
|
span_lint(self.0.cx,
|
||||||
MANY_SINGLE_CHAR_NAMES,
|
MANY_SINGLE_CHAR_NAMES,
|
||||||
span,
|
span,
|
||||||
&format!("{}th binding whose name is just one char",
|
&format!("{}th binding whose name is just one char", self.0.single_char_names.len()));
|
||||||
self.0.single_char_names.len()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn check_name(&mut self, span: Span, name: Name) {
|
fn check_name(&mut self, span: Span, name: Name) {
|
||||||
|
@ -162,7 +162,8 @@ impl<'a, 'b, 'c> SimilarNamesNameVisitor<'a, 'b, 'c> {
|
||||||
} else {
|
} else {
|
||||||
let second_last_i = interned_chars.next_back().expect("we know we have at least three chars");
|
let second_last_i = interned_chars.next_back().expect("we know we have at least three chars");
|
||||||
let second_last_e = existing_chars.next_back().expect("we know we have at least three chars");
|
let second_last_e = existing_chars.next_back().expect("we know we have at least three chars");
|
||||||
if !eq_or_numeric(second_last_i, second_last_e) || second_last_i == '_' || !interned_chars.zip(existing_chars).all(|(i, e)| eq_or_numeric(i, e)) {
|
if !eq_or_numeric(second_last_i, second_last_e) || second_last_i == '_' ||
|
||||||
|
!interned_chars.zip(existing_chars).all(|(i, e)| eq_or_numeric(i, e)) {
|
||||||
// allowed similarity foo_x, foo_y
|
// allowed similarity foo_x, foo_y
|
||||||
// or too many chars differ (foo_x, boo_y) or (foox, booy)
|
// or too many chars differ (foo_x, boo_y) or (foox, booy)
|
||||||
continue;
|
continue;
|
||||||
|
@ -172,7 +173,8 @@ impl<'a, 'b, 'c> SimilarNamesNameVisitor<'a, 'b, 'c> {
|
||||||
} else {
|
} else {
|
||||||
let second_i = interned_chars.next().expect("we know we have at least two chars");
|
let second_i = interned_chars.next().expect("we know we have at least two chars");
|
||||||
let second_e = existing_chars.next().expect("we know we have at least two chars");
|
let second_e = existing_chars.next().expect("we know we have at least two chars");
|
||||||
if !eq_or_numeric(second_i, second_e) || second_i == '_' || !interned_chars.zip(existing_chars).all(|(i, e)| eq_or_numeric(i, e)) {
|
if !eq_or_numeric(second_i, second_e) || second_i == '_' ||
|
||||||
|
!interned_chars.zip(existing_chars).all(|(i, e)| eq_or_numeric(i, e)) {
|
||||||
// allowed similarity x_foo, y_foo
|
// allowed similarity x_foo, y_foo
|
||||||
// or too many chars differ (x_foo, y_boo) or (xfoo, yboo)
|
// or too many chars differ (x_foo, y_boo) or (xfoo, yboo)
|
||||||
continue;
|
continue;
|
||||||
|
@ -187,8 +189,9 @@ impl<'a, 'b, 'c> SimilarNamesNameVisitor<'a, 'b, 'c> {
|
||||||
|diag| {
|
|diag| {
|
||||||
diag.span_note(existing_name.span, "existing binding defined here");
|
diag.span_note(existing_name.span, "existing binding defined here");
|
||||||
if let Some(split) = split_at {
|
if let Some(split) = split_at {
|
||||||
diag.span_help(span, &format!("separate the discriminating character \
|
diag.span_help(span,
|
||||||
by an underscore like: `{}_{}`",
|
&format!("separate the discriminating character by an \
|
||||||
|
underscore like: `{}_{}`",
|
||||||
&interned_name[..split],
|
&interned_name[..split],
|
||||||
&interned_name[split..]));
|
&interned_name[split..]));
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,7 +96,7 @@ fn get_open_options(cx: &LateContext, argument: &Expr, options: &mut Vec<(OpenOp
|
||||||
"write" => {
|
"write" => {
|
||||||
options.push((OpenOption::Write, argument_option));
|
options.push((OpenOption::Write, argument_option));
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
get_open_options(cx, &arguments[0], options);
|
get_open_options(cx, &arguments[0], options);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use rustc::lint::*;
|
use rustc::lint::*;
|
||||||
use rustc::hir::*;
|
use rustc::hir::*;
|
||||||
use utils::{span_lint};
|
use utils::span_lint;
|
||||||
|
|
||||||
/// **What it does:** This lint finds classic underflow / overflow checks.
|
/// **What it does:** This lint finds classic underflow / overflow checks.
|
||||||
///
|
///
|
||||||
|
|
|
@ -75,7 +75,9 @@ impl EarlyLintPass for Precedence {
|
||||||
if let Some(slf) = args.first() {
|
if let Some(slf) = args.first() {
|
||||||
if let ExprKind::Lit(ref lit) = slf.node {
|
if let ExprKind::Lit(ref lit) = slf.node {
|
||||||
match lit.node {
|
match lit.node {
|
||||||
LitKind::Int(..) | LitKind::Float(..) | LitKind::FloatUnsuffixed(..) => {
|
LitKind::Int(..) |
|
||||||
|
LitKind::Float(..) |
|
||||||
|
LitKind::FloatUnsuffixed(..) => {
|
||||||
span_lint(cx,
|
span_lint(cx,
|
||||||
PRECEDENCE,
|
PRECEDENCE,
|
||||||
expr.span,
|
expr.span,
|
||||||
|
|
|
@ -71,7 +71,7 @@ impl ReturnPass {
|
||||||
self.check_final_expr(cx, &arm.body);
|
self.check_final_expr(cx, &arm.body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,8 @@ fn check_block(cx: &LateContext, block: &Block, bindings: &mut Vec<(Name, Span)>
|
||||||
for stmt in &block.stmts {
|
for stmt in &block.stmts {
|
||||||
match stmt.node {
|
match stmt.node {
|
||||||
StmtDecl(ref decl, _) => check_decl(cx, decl, bindings),
|
StmtDecl(ref decl, _) => check_decl(cx, decl, bindings),
|
||||||
StmtExpr(ref e, _) | StmtSemi(ref e, _) => check_expr(cx, e, bindings),
|
StmtExpr(ref e, _) |
|
||||||
|
StmtSemi(ref e, _) => check_expr(cx, e, bindings),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(ref o) = block.expr {
|
if let Some(ref o) = block.expr {
|
||||||
|
@ -109,7 +110,8 @@ fn check_decl(cx: &LateContext, decl: &Decl, bindings: &mut Vec<(Name, Span)>) {
|
||||||
|
|
||||||
fn is_binding(cx: &LateContext, pat: &Pat) -> bool {
|
fn is_binding(cx: &LateContext, pat: &Pat) -> bool {
|
||||||
match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
|
match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
|
||||||
Some(Def::Variant(..)) | Some(Def::Struct(..)) => false,
|
Some(Def::Variant(..)) |
|
||||||
|
Some(Def::Struct(..)) => false,
|
||||||
_ => true,
|
_ => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -251,7 +253,8 @@ fn check_expr(cx: &LateContext, expr: &Expr, bindings: &mut Vec<(Name, Span)>) {
|
||||||
ExprTupField(ref e, _) |
|
ExprTupField(ref e, _) |
|
||||||
ExprAddrOf(_, ref e) |
|
ExprAddrOf(_, ref e) |
|
||||||
ExprBox(ref e) => check_expr(cx, e, bindings),
|
ExprBox(ref e) => check_expr(cx, e, bindings),
|
||||||
ExprBlock(ref block) | ExprLoop(ref block, _) => check_block(cx, block, bindings),
|
ExprBlock(ref block) |
|
||||||
|
ExprLoop(ref block, _) => check_block(cx, block, bindings),
|
||||||
// ExprCall
|
// ExprCall
|
||||||
// ExprMethodCall
|
// ExprMethodCall
|
||||||
ExprVec(ref v) | ExprTup(ref v) => {
|
ExprVec(ref v) | ExprTup(ref v) => {
|
||||||
|
|
|
@ -145,8 +145,7 @@ impl LateLintPass for StringLitAsBytes {
|
||||||
e.span,
|
e.span,
|
||||||
"calling `as_bytes()` on a string literal",
|
"calling `as_bytes()` on a string literal",
|
||||||
|db| {
|
|db| {
|
||||||
let sugg = format!("b{}",
|
let sugg = format!("b{}", snippet(cx, args[0].span, r#""foo""#));
|
||||||
snippet(cx, args[0].span, r#""foo""#));
|
|
||||||
db.span_suggestion(e.span,
|
db.span_suggestion(e.span,
|
||||||
"consider using a byte string literal instead",
|
"consider using a byte string literal instead",
|
||||||
sugg);
|
sugg);
|
||||||
|
|
|
@ -18,8 +18,7 @@ declare_lint! {
|
||||||
|
|
||||||
fn is_temporary(expr: &Expr) -> bool {
|
fn is_temporary(expr: &Expr) -> bool {
|
||||||
match expr.node {
|
match expr.node {
|
||||||
ExprStruct(..) |
|
ExprStruct(..) | ExprTup(..) => true,
|
||||||
ExprTup(..) => true,
|
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,7 +36,8 @@ impl LateLintPass for TemporaryAssignmentPass {
|
||||||
fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
|
fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
|
||||||
if let ExprAssign(ref target, _) = expr.node {
|
if let ExprAssign(ref target, _) = expr.node {
|
||||||
match target.node {
|
match target.node {
|
||||||
ExprField(ref base, _) | ExprTupField(ref base, _) => {
|
ExprField(ref base, _) |
|
||||||
|
ExprTupField(ref base, _) => {
|
||||||
if is_temporary(base) && !is_adjusted(cx, base) {
|
if is_temporary(base) && !is_adjusted(cx, base) {
|
||||||
span_lint(cx, TEMPORARY_ASSIGNMENT, expr.span, "assignment to temporary");
|
span_lint(cx, TEMPORARY_ASSIGNMENT, expr.span, "assignment to temporary");
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,11 +52,7 @@ pub struct Transmute;
|
||||||
|
|
||||||
impl LintPass for Transmute {
|
impl LintPass for Transmute {
|
||||||
fn get_lints(&self) -> LintArray {
|
fn get_lints(&self) -> LintArray {
|
||||||
lint_array! [
|
lint_array![CROSSPOINTER_TRANSMUTE, TRANSMUTE_PTR_TO_REF, USELESS_TRANSMUTE]
|
||||||
CROSSPOINTER_TRANSMUTE,
|
|
||||||
TRANSMUTE_PTR_TO_REF,
|
|
||||||
USELESS_TRANSMUTE
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,12 +75,16 @@ impl LateLintPass for Transmute {
|
||||||
span_lint(cx,
|
span_lint(cx,
|
||||||
CROSSPOINTER_TRANSMUTE,
|
CROSSPOINTER_TRANSMUTE,
|
||||||
e.span,
|
e.span,
|
||||||
&format!("transmute from a type (`{}`) to a pointer to that type (`{}`)", from_ty, to_ty));
|
&format!("transmute from a type (`{}`) to a pointer to that type (`{}`)",
|
||||||
|
from_ty,
|
||||||
|
to_ty));
|
||||||
} else if is_ptr_to(from_ty, to_ty) {
|
} else if is_ptr_to(from_ty, to_ty) {
|
||||||
span_lint(cx,
|
span_lint(cx,
|
||||||
CROSSPOINTER_TRANSMUTE,
|
CROSSPOINTER_TRANSMUTE,
|
||||||
e.span,
|
e.span,
|
||||||
&format!("transmute from a type (`{}`) to the type that it points to (`{}`)", from_ty, to_ty));
|
&format!("transmute from a type (`{}`) to the type that it points to (`{}`)",
|
||||||
|
from_ty,
|
||||||
|
to_ty));
|
||||||
} else {
|
} else {
|
||||||
check_ptr_to_ref(cx, from_ty, to_ty, e, &args[0]);
|
check_ptr_to_ref(cx, from_ty, to_ty, e, &args[0]);
|
||||||
}
|
}
|
||||||
|
@ -102,10 +102,7 @@ fn is_ptr_to(from: ty::Ty, to: ty::Ty) -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_ptr_to_ref<'tcx>(cx: &LateContext,
|
fn check_ptr_to_ref<'tcx>(cx: &LateContext, from_ty: ty::Ty<'tcx>, to_ty: ty::Ty<'tcx>, e: &Expr, arg: &Expr) {
|
||||||
from_ty: ty::Ty<'tcx>,
|
|
||||||
to_ty: ty::Ty<'tcx>,
|
|
||||||
e: &Expr, arg: &Expr) {
|
|
||||||
if let TyRawPtr(ref from_pty) = from_ty.sty {
|
if let TyRawPtr(ref from_pty) = from_ty.sty {
|
||||||
if let TyRef(_, ref to_rty) = to_ty.sty {
|
if let TyRef(_, ref to_rty) = to_ty.sty {
|
||||||
let mess = format!("transmute from a pointer type (`{}`) to a reference type (`{}`)",
|
let mess = format!("transmute from a pointer type (`{}`) to a reference type (`{}`)",
|
||||||
|
@ -122,8 +119,7 @@ fn check_ptr_to_ref<'tcx>(cx: &LateContext,
|
||||||
|
|
||||||
let sugg = if from_pty.ty == to_rty.ty {
|
let sugg = if from_pty.ty == to_rty.ty {
|
||||||
format!("{}{}", deref, arg)
|
format!("{}{}", deref, arg)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
format!("{}({} as {} {})", deref, arg, cast, to_rty.ty)
|
format!("{}({} as {} {})", deref, arg, cast, to_rty.ty)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
66
src/types.rs
66
src/types.rs
|
@ -248,7 +248,8 @@ fn int_ty_to_nbits(typ: &ty::TyS) -> usize {
|
||||||
|
|
||||||
fn is_isize_or_usize(typ: &ty::TyS) -> bool {
|
fn is_isize_or_usize(typ: &ty::TyS) -> bool {
|
||||||
match typ.sty {
|
match typ.sty {
|
||||||
ty::TyInt(IntTy::Is) | ty::TyUint(UintTy::Us) => true,
|
ty::TyInt(IntTy::Is) |
|
||||||
|
ty::TyUint(UintTy::Us) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -536,9 +537,7 @@ impl<'v> Visitor<'v> for TypeComplexityVisitor {
|
||||||
fn visit_ty(&mut self, ty: &'v Ty) {
|
fn visit_ty(&mut self, ty: &'v Ty) {
|
||||||
let (add_score, sub_nest) = match ty.node {
|
let (add_score, sub_nest) = match ty.node {
|
||||||
// _, &x and *x have only small overhead; don't mess with nesting level
|
// _, &x and *x have only small overhead; don't mess with nesting level
|
||||||
TyInfer |
|
TyInfer | TyPtr(..) | TyRptr(..) => (1, 0),
|
||||||
TyPtr(..) |
|
|
||||||
TyRptr(..) => (1, 0),
|
|
||||||
|
|
||||||
// the "normal" components of a type: named types, arrays/tuples
|
// the "normal" components of a type: named types, arrays/tuples
|
||||||
TyPath(..) |
|
TyPath(..) |
|
||||||
|
@ -702,14 +701,12 @@ fn detect_extreme_expr<'a>(cx: &LateContext, expr: &'a Expr) -> Option<ExtremeEx
|
||||||
|
|
||||||
let which = match (ty, cv) {
|
let which = match (ty, cv) {
|
||||||
(&ty::TyBool, Bool(false)) |
|
(&ty::TyBool, Bool(false)) |
|
||||||
|
|
||||||
(&ty::TyInt(IntTy::Is), Integral(Isize(Is32(::std::i32::MIN)))) |
|
(&ty::TyInt(IntTy::Is), Integral(Isize(Is32(::std::i32::MIN)))) |
|
||||||
(&ty::TyInt(IntTy::Is), Integral(Isize(Is64(::std::i64::MIN)))) |
|
(&ty::TyInt(IntTy::Is), Integral(Isize(Is64(::std::i64::MIN)))) |
|
||||||
(&ty::TyInt(IntTy::I8), Integral(I8(::std::i8::MIN))) |
|
(&ty::TyInt(IntTy::I8), Integral(I8(::std::i8::MIN))) |
|
||||||
(&ty::TyInt(IntTy::I16), Integral(I16(::std::i16::MIN))) |
|
(&ty::TyInt(IntTy::I16), Integral(I16(::std::i16::MIN))) |
|
||||||
(&ty::TyInt(IntTy::I32), Integral(I32(::std::i32::MIN))) |
|
(&ty::TyInt(IntTy::I32), Integral(I32(::std::i32::MIN))) |
|
||||||
(&ty::TyInt(IntTy::I64), Integral(I64(::std::i64::MIN))) |
|
(&ty::TyInt(IntTy::I64), Integral(I64(::std::i64::MIN))) |
|
||||||
|
|
||||||
(&ty::TyUint(UintTy::Us), Integral(Usize(Us32(::std::u32::MIN)))) |
|
(&ty::TyUint(UintTy::Us), Integral(Usize(Us32(::std::u32::MIN)))) |
|
||||||
(&ty::TyUint(UintTy::Us), Integral(Usize(Us64(::std::u64::MIN)))) |
|
(&ty::TyUint(UintTy::Us), Integral(Usize(Us64(::std::u64::MIN)))) |
|
||||||
(&ty::TyUint(UintTy::U8), Integral(U8(::std::u8::MIN))) |
|
(&ty::TyUint(UintTy::U8), Integral(U8(::std::u8::MIN))) |
|
||||||
|
@ -718,14 +715,12 @@ fn detect_extreme_expr<'a>(cx: &LateContext, expr: &'a Expr) -> Option<ExtremeEx
|
||||||
(&ty::TyUint(UintTy::U64), Integral(U64(::std::u64::MIN))) => Minimum,
|
(&ty::TyUint(UintTy::U64), Integral(U64(::std::u64::MIN))) => Minimum,
|
||||||
|
|
||||||
(&ty::TyBool, Bool(true)) |
|
(&ty::TyBool, Bool(true)) |
|
||||||
|
|
||||||
(&ty::TyInt(IntTy::Is), Integral(Isize(Is32(::std::i32::MAX)))) |
|
(&ty::TyInt(IntTy::Is), Integral(Isize(Is32(::std::i32::MAX)))) |
|
||||||
(&ty::TyInt(IntTy::Is), Integral(Isize(Is64(::std::i64::MAX)))) |
|
(&ty::TyInt(IntTy::Is), Integral(Isize(Is64(::std::i64::MAX)))) |
|
||||||
(&ty::TyInt(IntTy::I8), Integral(I8(::std::i8::MAX))) |
|
(&ty::TyInt(IntTy::I8), Integral(I8(::std::i8::MAX))) |
|
||||||
(&ty::TyInt(IntTy::I16), Integral(I16(::std::i16::MAX))) |
|
(&ty::TyInt(IntTy::I16), Integral(I16(::std::i16::MAX))) |
|
||||||
(&ty::TyInt(IntTy::I32), Integral(I32(::std::i32::MAX))) |
|
(&ty::TyInt(IntTy::I32), Integral(I32(::std::i32::MAX))) |
|
||||||
(&ty::TyInt(IntTy::I64), Integral(I64(::std::i64::MAX))) |
|
(&ty::TyInt(IntTy::I64), Integral(I64(::std::i64::MAX))) |
|
||||||
|
|
||||||
(&ty::TyUint(UintTy::Us), Integral(Usize(Us32(::std::u32::MAX)))) |
|
(&ty::TyUint(UintTy::Us), Integral(Usize(Us32(::std::u32::MAX)))) |
|
||||||
(&ty::TyUint(UintTy::Us), Integral(Usize(Us64(::std::u64::MAX)))) |
|
(&ty::TyUint(UintTy::Us), Integral(Usize(Us64(::std::u64::MAX)))) |
|
||||||
(&ty::TyUint(UintTy::U8), Integral(U8(::std::u8::MAX))) |
|
(&ty::TyUint(UintTy::U8), Integral(U8(::std::u8::MAX))) |
|
||||||
|
@ -847,20 +842,24 @@ fn numeric_cast_precast_bounds<'a>(cx: &LateContext, expr: &'a Expr) -> Option<(
|
||||||
|
|
||||||
if let ExprCast(ref cast_exp, _) = expr.node {
|
if let ExprCast(ref cast_exp, _) = expr.node {
|
||||||
match cx.tcx.expr_ty(cast_exp).sty {
|
match cx.tcx.expr_ty(cast_exp).sty {
|
||||||
TyInt(int_ty) => Some(match int_ty {
|
TyInt(int_ty) => {
|
||||||
|
Some(match int_ty {
|
||||||
IntTy::I8 => (FullInt::S(i8::min_value() as i64), FullInt::S(i8::max_value() as i64)),
|
IntTy::I8 => (FullInt::S(i8::min_value() as i64), FullInt::S(i8::max_value() as i64)),
|
||||||
IntTy::I16 => (FullInt::S(i16::min_value() as i64), FullInt::S(i16::max_value() as i64)),
|
IntTy::I16 => (FullInt::S(i16::min_value() as i64), FullInt::S(i16::max_value() as i64)),
|
||||||
IntTy::I32 => (FullInt::S(i32::min_value() as i64), FullInt::S(i32::max_value() as i64)),
|
IntTy::I32 => (FullInt::S(i32::min_value() as i64), FullInt::S(i32::max_value() as i64)),
|
||||||
IntTy::I64 => (FullInt::S(i64::min_value() as i64), FullInt::S(i64::max_value() as i64)),
|
IntTy::I64 => (FullInt::S(i64::min_value() as i64), FullInt::S(i64::max_value() as i64)),
|
||||||
IntTy::Is => (FullInt::S(isize::min_value() as i64), FullInt::S(isize::max_value() as i64)),
|
IntTy::Is => (FullInt::S(isize::min_value() as i64), FullInt::S(isize::max_value() as i64)),
|
||||||
}),
|
})
|
||||||
TyUint(uint_ty) => Some(match uint_ty {
|
}
|
||||||
|
TyUint(uint_ty) => {
|
||||||
|
Some(match uint_ty {
|
||||||
UintTy::U8 => (FullInt::U(u8::min_value() as u64), FullInt::U(u8::max_value() as u64)),
|
UintTy::U8 => (FullInt::U(u8::min_value() as u64), FullInt::U(u8::max_value() as u64)),
|
||||||
UintTy::U16 => (FullInt::U(u16::min_value() as u64), FullInt::U(u16::max_value() as u64)),
|
UintTy::U16 => (FullInt::U(u16::min_value() as u64), FullInt::U(u16::max_value() as u64)),
|
||||||
UintTy::U32 => (FullInt::U(u32::min_value() as u64), FullInt::U(u32::max_value() as u64)),
|
UintTy::U32 => (FullInt::U(u32::min_value() as u64), FullInt::U(u32::max_value() as u64)),
|
||||||
UintTy::U64 => (FullInt::U(u64::min_value() as u64), FullInt::U(u64::max_value() as u64)),
|
UintTy::U64 => (FullInt::U(u64::min_value() as u64), FullInt::U(u64::max_value() as u64)),
|
||||||
UintTy::Us => (FullInt::U(usize::min_value() as u64), FullInt::U(usize::max_value() as u64)),
|
UintTy::Us => (FullInt::U(usize::min_value() as u64), FullInt::U(usize::max_value() as u64)),
|
||||||
}),
|
})
|
||||||
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -885,28 +884,25 @@ fn node_as_const_fullint(cx: &LateContext, expr: &Expr) -> Option<FullInt> {
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Err(_) => None,
|
Err(_) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn err_upcast_comparison(cx: &LateContext, span: &Span, expr: &Expr, always: bool) {
|
fn err_upcast_comparison(cx: &LateContext, span: &Span, expr: &Expr, always: bool) {
|
||||||
if let ExprCast(ref cast_val, _) = expr.node {
|
if let ExprCast(ref cast_val, _) = expr.node {
|
||||||
span_lint(
|
span_lint(cx,
|
||||||
cx,
|
|
||||||
INVALID_UPCAST_COMPARISONS,
|
INVALID_UPCAST_COMPARISONS,
|
||||||
*span,
|
*span,
|
||||||
&format!(
|
&format!(
|
||||||
"because of the numeric bounds on `{}` prior to casting, this expression is always {}",
|
"because of the numeric bounds on `{}` prior to casting, this expression is always {}",
|
||||||
snippet(cx, cast_val.span, "the expression"),
|
snippet(cx, cast_val.span, "the expression"),
|
||||||
if always { "true" } else { "false" },
|
if always { "true" } else { "false" },
|
||||||
)
|
));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn upcast_comparison_bounds_err(
|
fn upcast_comparison_bounds_err(cx: &LateContext, span: &Span, rel: comparisons::Rel,
|
||||||
cx: &LateContext, span: &Span, rel: comparisons::Rel,
|
|
||||||
lhs_bounds: Option<(FullInt, FullInt)>, lhs: &Expr, rhs: &Expr, invert: bool) {
|
lhs_bounds: Option<(FullInt, FullInt)>, lhs: &Expr, rhs: &Expr, invert: bool) {
|
||||||
use utils::comparisons::*;
|
use utils::comparisons::*;
|
||||||
|
|
||||||
|
@ -917,14 +913,38 @@ fn upcast_comparison_bounds_err(
|
||||||
err_upcast_comparison(cx, &span, lhs, rel == Rel::Ne);
|
err_upcast_comparison(cx, &span, lhs, rel == Rel::Ne);
|
||||||
}
|
}
|
||||||
} else if match rel {
|
} else if match rel {
|
||||||
Rel::Lt => if invert { norm_rhs_val < lb } else { ub < norm_rhs_val },
|
Rel::Lt => {
|
||||||
Rel::Le => if invert { norm_rhs_val <= lb } else { ub <= norm_rhs_val },
|
if invert {
|
||||||
|
norm_rhs_val < lb
|
||||||
|
} else {
|
||||||
|
ub < norm_rhs_val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Rel::Le => {
|
||||||
|
if invert {
|
||||||
|
norm_rhs_val <= lb
|
||||||
|
} else {
|
||||||
|
ub <= norm_rhs_val
|
||||||
|
}
|
||||||
|
}
|
||||||
Rel::Eq | Rel::Ne => unreachable!(),
|
Rel::Eq | Rel::Ne => unreachable!(),
|
||||||
} {
|
} {
|
||||||
err_upcast_comparison(cx, &span, lhs, true)
|
err_upcast_comparison(cx, &span, lhs, true)
|
||||||
} else if match rel {
|
} else if match rel {
|
||||||
Rel::Lt => if invert { norm_rhs_val >= ub } else { lb >= norm_rhs_val },
|
Rel::Lt => {
|
||||||
Rel::Le => if invert { norm_rhs_val > ub } else { lb > norm_rhs_val },
|
if invert {
|
||||||
|
norm_rhs_val >= ub
|
||||||
|
} else {
|
||||||
|
lb >= norm_rhs_val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Rel::Le => {
|
||||||
|
if invert {
|
||||||
|
norm_rhs_val > ub
|
||||||
|
} else {
|
||||||
|
lb > norm_rhs_val
|
||||||
|
}
|
||||||
|
}
|
||||||
Rel::Eq | Rel::Ne => unreachable!(),
|
Rel::Eq | Rel::Ne => unreachable!(),
|
||||||
} {
|
} {
|
||||||
err_upcast_comparison(cx, &span, lhs, false)
|
err_upcast_comparison(cx, &span, lhs, false)
|
||||||
|
|
|
@ -8,7 +8,8 @@ use toml;
|
||||||
pub fn conf_file(args: &[ptr::P<ast::MetaItem>]) -> Result<Option<token::InternedString>, (&'static str, codemap::Span)> {
|
pub fn conf_file(args: &[ptr::P<ast::MetaItem>]) -> Result<Option<token::InternedString>, (&'static str, codemap::Span)> {
|
||||||
for arg in args {
|
for arg in args {
|
||||||
match arg.node {
|
match arg.node {
|
||||||
ast::MetaItemKind::Word(ref name) | ast::MetaItemKind::List(ref name, _) => {
|
ast::MetaItemKind::Word(ref name) |
|
||||||
|
ast::MetaItemKind::List(ref name, _) => {
|
||||||
if name == &"conf_file" {
|
if name == &"conf_file" {
|
||||||
return Err(("`conf_file` must be a named value", arg.span));
|
return Err(("`conf_file` must be a named value", arg.span));
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,9 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
|
||||||
(&ExprBlock(ref l), &ExprBlock(ref r)) => self.eq_block(l, r),
|
(&ExprBlock(ref l), &ExprBlock(ref r)) => self.eq_block(l, r),
|
||||||
(&ExprBinary(l_op, ref ll, ref lr), &ExprBinary(r_op, ref rl, ref rr)) => {
|
(&ExprBinary(l_op, ref ll, ref lr), &ExprBinary(r_op, ref rl, ref rr)) => {
|
||||||
l_op.node == r_op.node && self.eq_expr(ll, rl) && self.eq_expr(lr, rr) ||
|
l_op.node == r_op.node && self.eq_expr(ll, rl) && self.eq_expr(lr, rr) ||
|
||||||
swap_binop(l_op.node, ll, lr).map_or(false, |(l_op, ll, lr)| l_op == r_op.node && self.eq_expr(ll, rl) && self.eq_expr(lr, rr))
|
swap_binop(l_op.node, ll, lr).map_or(false, |(l_op, ll, lr)| {
|
||||||
|
l_op == r_op.node && self.eq_expr(ll, rl) && self.eq_expr(lr, rr)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
(&ExprBreak(li), &ExprBreak(ri)) => both(&li, &ri, |l, r| l.node.name.as_str() == r.node.name.as_str()),
|
(&ExprBreak(li), &ExprBreak(ri)) => both(&li, &ri, |l, r| l.node.name.as_str() == r.node.name.as_str()),
|
||||||
(&ExprBox(ref l), &ExprBox(ref r)) => self.eq_expr(l, r),
|
(&ExprBox(ref l), &ExprBox(ref r)) => self.eq_expr(l, r),
|
||||||
|
@ -114,8 +116,7 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
|
||||||
both(l_qself, r_qself, |l, r| self.eq_qself(l, r)) && self.eq_path(l_subpath, r_subpath)
|
both(l_qself, r_qself, |l, r| self.eq_qself(l, r)) && self.eq_path(l_subpath, r_subpath)
|
||||||
}
|
}
|
||||||
(&ExprStruct(ref l_path, ref lf, ref lo), &ExprStruct(ref r_path, ref rf, ref ro)) => {
|
(&ExprStruct(ref l_path, ref lf, ref lo), &ExprStruct(ref r_path, ref rf, ref ro)) => {
|
||||||
self.eq_path(l_path, r_path) &&
|
self.eq_path(l_path, r_path) && both(lo, ro, |l, r| self.eq_expr(l, r)) &&
|
||||||
both(lo, ro, |l, r| self.eq_expr(l, r)) &&
|
|
||||||
over(lf, rf, |l, r| self.eq_field(l, r))
|
over(lf, rf, |l, r| self.eq_field(l, r))
|
||||||
}
|
}
|
||||||
(&ExprTup(ref l_tup), &ExprTup(ref r_tup)) => self.eq_exprs(l_tup, r_tup),
|
(&ExprTup(ref l_tup), &ExprTup(ref r_tup)) => self.eq_exprs(l_tup, r_tup),
|
||||||
|
|
|
@ -144,7 +144,8 @@ pub fn match_def_path(cx: &LateContext, def_id: DefId, path: &[&str]) -> bool {
|
||||||
/// Check if type is struct or enum type with given def path.
|
/// Check if type is struct or enum type with given def path.
|
||||||
pub fn match_type(cx: &LateContext, ty: ty::Ty, path: &[&str]) -> bool {
|
pub fn match_type(cx: &LateContext, ty: ty::Ty, path: &[&str]) -> bool {
|
||||||
match ty.sty {
|
match ty.sty {
|
||||||
ty::TyEnum(ref adt, _) | ty::TyStruct(ref adt, _) => match_def_path(cx, adt.did, path),
|
ty::TyEnum(ref adt, _) |
|
||||||
|
ty::TyStruct(ref adt, _) => match_def_path(cx, adt.did, path),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -517,7 +518,8 @@ pub fn span_lint_and_then<'a, T: LintContext, F>(cx: &'a T, lint: &'static Lint,
|
||||||
/// Return the base type for references and raw pointers.
|
/// Return the base type for references and raw pointers.
|
||||||
pub fn walk_ptrs_ty(ty: ty::Ty) -> ty::Ty {
|
pub fn walk_ptrs_ty(ty: ty::Ty) -> ty::Ty {
|
||||||
match ty.sty {
|
match ty.sty {
|
||||||
ty::TyRef(_, ref tm) | ty::TyRawPtr(ref tm) => walk_ptrs_ty(tm.ty),
|
ty::TyRef(_, ref tm) |
|
||||||
|
ty::TyRawPtr(ref tm) => walk_ptrs_ty(tm.ty),
|
||||||
_ => ty,
|
_ => ty,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -526,7 +528,8 @@ pub fn walk_ptrs_ty(ty: ty::Ty) -> ty::Ty {
|
||||||
pub fn walk_ptrs_ty_depth(ty: ty::Ty) -> (ty::Ty, usize) {
|
pub fn walk_ptrs_ty_depth(ty: ty::Ty) -> (ty::Ty, usize) {
|
||||||
fn inner(ty: ty::Ty, depth: usize) -> (ty::Ty, usize) {
|
fn inner(ty: ty::Ty, depth: usize) -> (ty::Ty, usize) {
|
||||||
match ty.sty {
|
match ty.sty {
|
||||||
ty::TyRef(_, ref tm) | ty::TyRawPtr(ref tm) => inner(tm.ty, depth + 1),
|
ty::TyRef(_, ref tm) |
|
||||||
|
ty::TyRawPtr(ref tm) => inner(tm.ty, depth + 1),
|
||||||
_ => (ty, depth),
|
_ => (ty, depth),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -730,22 +733,46 @@ pub fn unsugar_range(expr: &Expr) -> Option<UnsugaredRange> {
|
||||||
match unwrap_unstable(&expr).node {
|
match unwrap_unstable(&expr).node {
|
||||||
ExprPath(None, ref path) => {
|
ExprPath(None, ref path) => {
|
||||||
if match_path(path, &paths::RANGE_FULL) {
|
if match_path(path, &paths::RANGE_FULL) {
|
||||||
Some(UnsugaredRange { start: None, end: None, limits: RangeLimits::HalfOpen })
|
Some(UnsugaredRange {
|
||||||
|
start: None,
|
||||||
|
end: None,
|
||||||
|
limits: RangeLimits::HalfOpen,
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExprStruct(ref path, ref fields, None) => {
|
ExprStruct(ref path, ref fields, None) => {
|
||||||
if match_path(path, &paths::RANGE_FROM) {
|
if match_path(path, &paths::RANGE_FROM) {
|
||||||
Some(UnsugaredRange { start: get_field("start", fields), end: None, limits: RangeLimits::HalfOpen })
|
Some(UnsugaredRange {
|
||||||
|
start: get_field("start", fields),
|
||||||
|
end: None,
|
||||||
|
limits: RangeLimits::HalfOpen,
|
||||||
|
})
|
||||||
} else if match_path(path, &paths::RANGE_INCLUSIVE_NON_EMPTY) {
|
} else if match_path(path, &paths::RANGE_INCLUSIVE_NON_EMPTY) {
|
||||||
Some(UnsugaredRange { start: get_field("start", fields), end: get_field("end", fields), limits: RangeLimits::Closed })
|
Some(UnsugaredRange {
|
||||||
|
start: get_field("start", fields),
|
||||||
|
end: get_field("end", fields),
|
||||||
|
limits: RangeLimits::Closed,
|
||||||
|
})
|
||||||
} else if match_path(path, &paths::RANGE) {
|
} else if match_path(path, &paths::RANGE) {
|
||||||
Some(UnsugaredRange { start: get_field("start", fields), end: get_field("end", fields), limits: RangeLimits::HalfOpen })
|
Some(UnsugaredRange {
|
||||||
|
start: get_field("start", fields),
|
||||||
|
end: get_field("end", fields),
|
||||||
|
limits: RangeLimits::HalfOpen,
|
||||||
|
})
|
||||||
} else if match_path(path, &paths::RANGE_TO_INCLUSIVE) {
|
} else if match_path(path, &paths::RANGE_TO_INCLUSIVE) {
|
||||||
Some(UnsugaredRange { start: None, end: get_field("end", fields), limits: RangeLimits::Closed })
|
Some(UnsugaredRange {
|
||||||
|
start: None,
|
||||||
|
end: get_field("end", fields),
|
||||||
|
limits: RangeLimits::Closed,
|
||||||
|
})
|
||||||
} else if match_path(path, &paths::RANGE_TO) {
|
} else if match_path(path, &paths::RANGE_TO) {
|
||||||
Some(UnsugaredRange { start: None, end: get_field("end", fields), limits: RangeLimits::HalfOpen })
|
Some(UnsugaredRange {
|
||||||
|
start: None,
|
||||||
|
end: get_field("end", fields),
|
||||||
|
limits: RangeLimits::HalfOpen,
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,8 +63,7 @@ fn check_vec_macro(cx: &LateContext, expr: &Expr, vec: &Expr) {
|
||||||
};
|
};
|
||||||
|
|
||||||
format!("&[{}]", snippet(cx, span, "..")).into()
|
format!("&[{}]", snippet(cx, span, "..")).into()
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
"&[]".into()
|
"&[]".into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue