Fix an ICE with continue inside a closure inside a loop condition
This commit is contained in:
parent
f68ee0b4e1
commit
4efd5c75a8
@ -3538,12 +3538,22 @@ impl<'a> LoweringContext<'a> {
|
||||
this.expr_block(block, ThinVec::new())
|
||||
})
|
||||
})
|
||||
},
|
||||
}
|
||||
ExprKind::Closure(
|
||||
capture_clause, asyncness, movability, ref decl, ref body, fn_decl_span) =>
|
||||
{
|
||||
self.with_new_scopes(|this| {
|
||||
if let IsAsync::Async(async_closure_node_id) = asyncness {
|
||||
capture_clause, asyncness, movability, ref decl, ref body, fn_decl_span
|
||||
) => {
|
||||
if let IsAsync::Async(async_closure_node_id) = asyncness {
|
||||
let outer_decl = FnDecl {
|
||||
inputs: decl.inputs.clone(),
|
||||
output: FunctionRetTy::Default(fn_decl_span),
|
||||
variadic: false,
|
||||
};
|
||||
// We need to lower the declaration outside the new scope, because we
|
||||
// have to conserve the state of being inside a loop condition for the
|
||||
// closure argument types.
|
||||
let fn_decl = self.lower_fn_decl(&outer_decl, None, false, false);
|
||||
|
||||
self.with_new_scopes(|this| {
|
||||
// FIXME(cramertj) allow `async` non-`move` closures with
|
||||
if capture_clause == CaptureBy::Ref &&
|
||||
!decl.inputs.is_empty()
|
||||
@ -3563,11 +3573,6 @@ impl<'a> LoweringContext<'a> {
|
||||
|
||||
// Transform `async |x: u8| -> X { ... }` into
|
||||
// `|x: u8| future_from_generator(|| -> X { ... })`
|
||||
let outer_decl = FnDecl {
|
||||
inputs: decl.inputs.clone(),
|
||||
output: FunctionRetTy::Default(fn_decl_span),
|
||||
variadic: false,
|
||||
};
|
||||
let body_id = this.lower_body(Some(&outer_decl), |this| {
|
||||
let async_ret_ty = if let FunctionRetTy::Ty(ty) = &decl.output {
|
||||
Some(&**ty)
|
||||
@ -3581,12 +3586,17 @@ impl<'a> LoweringContext<'a> {
|
||||
});
|
||||
hir::ExprClosure(
|
||||
this.lower_capture_clause(capture_clause),
|
||||
this.lower_fn_decl(&outer_decl, None, false, false),
|
||||
fn_decl,
|
||||
body_id,
|
||||
fn_decl_span,
|
||||
None,
|
||||
)
|
||||
} else {
|
||||
})
|
||||
} else {
|
||||
// Lower outside new scope to preserve `is_in_loop_condition`.
|
||||
let fn_decl = self.lower_fn_decl(decl, None, false, false);
|
||||
|
||||
self.with_new_scopes(|this| {
|
||||
let mut is_generator = false;
|
||||
let body_id = this.lower_body(Some(decl), |this| {
|
||||
let e = this.lower_expr(body);
|
||||
@ -3620,13 +3630,13 @@ impl<'a> LoweringContext<'a> {
|
||||
};
|
||||
hir::ExprClosure(
|
||||
this.lower_capture_clause(capture_clause),
|
||||
this.lower_fn_decl(decl, None, false, false),
|
||||
fn_decl,
|
||||
body_id,
|
||||
fn_decl_span,
|
||||
generator_option,
|
||||
)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
ExprKind::Block(ref blk, opt_label) => {
|
||||
hir::ExprBlock(self.lower_block(blk,
|
||||
|
@ -10,4 +10,6 @@
|
||||
|
||||
fn main() {
|
||||
|_: [_; continue]| {}; //~ ERROR: `continue` outside of loop
|
||||
|
||||
while |_: [_; continue]| {} {} //~ ERROR: `break` or `continue` with no label
|
||||
}
|
||||
|
@ -4,6 +4,13 @@ error[E0268]: `continue` outside of loop
|
||||
LL | |_: [_; continue]| {}; //~ ERROR: `continue` outside of loop
|
||||
| ^^^^^^^^ cannot break outside of a loop
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0590]: `break` or `continue` with no label in the condition of a `while` loop
|
||||
--> $DIR/closure-array-break-length.rs:14:19
|
||||
|
|
||||
LL | while |_: [_; continue]| {} {} //~ ERROR: `break` or `continue` with no label
|
||||
| ^^^^^^^^ unlabeled `continue` in the condition of a `while` loop
|
||||
|
||||
For more information about this error, try `rustc --explain E0268`.
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors occurred: E0268, E0590.
|
||||
For more information about an error, try `rustc --explain E0268`.
|
||||
|
Loading…
Reference in New Issue
Block a user