Skip to content

Commit

Permalink
Merge pull request #1656 from dtolnay/breakreturn
Browse files Browse the repository at this point in the history
Parse struct expressions eagerly within break and return
  • Loading branch information
dtolnay committed May 15, 2024
2 parents c644808 + a77992d commit e7a4d7f
Showing 1 changed file with 14 additions and 27 deletions.
41 changes: 14 additions & 27 deletions src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1740,7 +1740,7 @@ pub(crate) mod parsing {
} else if input.peek(Token![continue]) {
input.parse().map(Expr::Continue)
} else if input.peek(Token![return]) {
expr_return(input, allow_struct).map(Expr::Return)
input.parse().map(Expr::Return)
} else if input.peek(token::Bracket) {
array_or_repeat(input)
} else if input.peek(Token![let]) {
Expand Down Expand Up @@ -2374,8 +2374,17 @@ pub(crate) mod parsing {
#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for ExprReturn {
fn parse(input: ParseStream) -> Result<Self> {
let allow_struct = AllowStruct(true);
expr_return(input, allow_struct)
Ok(ExprReturn {
attrs: Vec::new(),
return_token: input.parse()?,
expr: {
if can_begin_expr(input) {
Some(input.parse()?)
} else {
None
}
},
})
}
}

Expand Down Expand Up @@ -2601,7 +2610,7 @@ pub(crate) mod parsing {
if label.is_some() && ahead.peek(Token![:]) {
// Not allowed: `break 'label: loop {...}`
// Parentheses are required. `break ('label: loop {...})`
let _ = ambiguous_expr(input, allow_struct)?;
let _: Expr = input.parse()?;
let start_span = label.unwrap().apostrophe;
let end_span = input.cursor().prev_span();
return Err(crate::error::new2(
Expand All @@ -2613,8 +2622,7 @@ pub(crate) mod parsing {

input.advance_to(&ahead);
let expr = if can_begin_expr(input) && (allow_struct.0 || !input.peek(token::Brace)) {
let expr = ambiguous_expr(input, allow_struct)?;
Some(Box::new(expr))
Some(input.parse()?)
} else {
None
};
Expand All @@ -2627,27 +2635,6 @@ pub(crate) mod parsing {
})
}

#[cfg(feature = "full")]
fn expr_return(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprReturn> {
Ok(ExprReturn {
attrs: Vec::new(),
return_token: input.parse()?,
expr: {
if can_begin_expr(input) {
// NOTE: return is greedy and eats blocks after it even when in a
// position where structs are not allowed, such as in if statement
// conditions. For example:
//
// if return { println!("A") } {} // Prints "A"
let expr = ambiguous_expr(input, allow_struct)?;
Some(Box::new(expr))
} else {
None
}
},
})
}

#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for FieldValue {
fn parse(input: ParseStream) -> Result<Self> {
Expand Down

0 comments on commit e7a4d7f

Please sign in to comment.