mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-01 03:03:40 +00:00
Merge PR #374
This commit is contained in:
commit
b3d035d252
46
src/loops.rs
46
src/loops.rs
@ -174,25 +174,31 @@ impl LateLintPass for LoopsPass {
|
|||||||
the loop body.");
|
the loop body.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// extract the first statement (if any) in a block
|
// extract the expression from the first statement (if any) in a block
|
||||||
let inner_stmt = extract_expr_from_first_stmt(block);
|
let inner_stmt_expr = extract_expr_from_first_stmt(block);
|
||||||
// extract a single expression
|
// extract the first expression (if any) from the block
|
||||||
let inner_expr = extract_first_expr(block);
|
let inner_expr = extract_first_expr(block);
|
||||||
let extracted = match inner_stmt {
|
let (extracted, collect_expr) = match inner_stmt_expr {
|
||||||
Some(_) => inner_stmt,
|
Some(_) => (inner_stmt_expr, true), // check if an expression exists in the first statement
|
||||||
None => inner_expr,
|
None => (inner_expr, false), // if not, let's go for the first expression in the block
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(inner) = extracted {
|
if let Some(inner) = extracted {
|
||||||
// collect remaining expressions below the match
|
if let ExprMatch(ref matchexpr, ref arms, ref source) = inner.node {
|
||||||
let other_stuff = block.stmts
|
// collect the remaining statements below the match
|
||||||
|
let mut other_stuff = block.stmts
|
||||||
.iter()
|
.iter()
|
||||||
.skip(1)
|
.skip(1)
|
||||||
.map(|stmt| {
|
.map(|stmt| {
|
||||||
format!("{}", snippet(cx, stmt.span, ".."))
|
format!("{}", snippet(cx, stmt.span, ".."))
|
||||||
}).collect::<Vec<String>>();
|
}).collect::<Vec<String>>();
|
||||||
|
if collect_expr { // if we have a statement which has a match,
|
||||||
|
match block.expr { // then collect the expression (without semicolon) below it
|
||||||
|
Some(ref expr) => other_stuff.push(format!("{}", snippet(cx, expr.span, ".."))),
|
||||||
|
None => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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{..} => if
|
MatchSource::Normal | MatchSource::IfLetDesugar{..} => if
|
||||||
@ -203,7 +209,7 @@ impl LateLintPass for LoopsPass {
|
|||||||
is_break_expr(&arms[1].body)
|
is_break_expr(&arms[1].body)
|
||||||
{
|
{
|
||||||
if in_external_macro(cx, expr.span) { return; }
|
if in_external_macro(cx, expr.span) { return; }
|
||||||
let loop_body = match inner_stmt {
|
let loop_body = match inner_stmt_expr {
|
||||||
// FIXME: should probably be an ellipsis
|
// FIXME: should probably be an ellipsis
|
||||||
// tabbing and newline is probably a bad idea, especially for large blocks
|
// tabbing and newline is probably a bad idea, especially for large blocks
|
||||||
Some(_) => Cow::Owned(format!("{{\n {}\n}}", other_stuff.join("\n "))),
|
Some(_) => Cow::Owned(format!("{{\n {}\n}}", other_stuff.join("\n "))),
|
||||||
@ -321,20 +327,12 @@ fn is_iterable_array(ty: ty::Ty) -> bool {
|
|||||||
|
|
||||||
/// If a block begins with a statement (possibly a `let` binding) and has an expression, return it.
|
/// If a block begins with a statement (possibly a `let` binding) and has an expression, return it.
|
||||||
fn extract_expr_from_first_stmt(block: &Block) -> Option<&Expr> {
|
fn extract_expr_from_first_stmt(block: &Block) -> Option<&Expr> {
|
||||||
match block.expr {
|
if block.stmts.is_empty() { return None; }
|
||||||
Some(_) => None,
|
if let StmtDecl(ref decl, _) = block.stmts[0].node {
|
||||||
None if !block.stmts.is_empty() => match block.stmts[0].node {
|
if let DeclLocal(ref local) = decl.node {
|
||||||
StmtDecl(ref decl, _) => match decl.node {
|
if let Some(ref expr) = local.init { Some(expr) } else { None }
|
||||||
DeclLocal(ref local) => match local.init {
|
} else { None }
|
||||||
Some(ref expr) => Some(expr),
|
} else { None }
|
||||||
None => None,
|
|
||||||
},
|
|
||||||
_ => None,
|
|
||||||
},
|
|
||||||
_ => None,
|
|
||||||
},
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If a block begins with an expression (with or without semicolon), return it.
|
/// If a block begins with an expression (with or without semicolon), return it.
|
||||||
|
@ -33,6 +33,14 @@ fn main() {
|
|||||||
let _x = x;
|
let _x = x;
|
||||||
let _str = "foo";
|
let _str = "foo";
|
||||||
}
|
}
|
||||||
|
loop { //~ERROR
|
||||||
|
let x = match y {
|
||||||
|
Some(x) => x,
|
||||||
|
None => break,
|
||||||
|
};
|
||||||
|
{ let _a = "bar"; };
|
||||||
|
{ let _b = "foobar"; }
|
||||||
|
}
|
||||||
loop { // no error, else branch does something other than break
|
loop { // no error, else branch does something other than break
|
||||||
match y {
|
match y {
|
||||||
Some(_x) => true,
|
Some(_x) => true,
|
||||||
@ -53,7 +61,7 @@ fn main() {
|
|||||||
// cause this function to trigger it
|
// cause this function to trigger it
|
||||||
fn no_panic<T>(slice: &[T]) {
|
fn no_panic<T>(slice: &[T]) {
|
||||||
let mut iter = slice.iter();
|
let mut iter = slice.iter();
|
||||||
loop {
|
loop { //~ERROR
|
||||||
let _ = match iter.next() {
|
let _ = match iter.next() {
|
||||||
Some(ele) => ele,
|
Some(ele) => ele,
|
||||||
None => break
|
None => break
|
||||||
|
Loading…
Reference in New Issue
Block a user