Rollup merge of #81249 - cjgillot:issue-79537, r=oli-obk
Lower closure prototype after its body. Fixes #79537. r? `@Mark-Simulacrum`
This commit is contained in:
commit
fcf11296f6
3 changed files with 86 additions and 13 deletions
|
@ -776,10 +776,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
body: &Expr,
|
body: &Expr,
|
||||||
fn_decl_span: Span,
|
fn_decl_span: Span,
|
||||||
) -> hir::ExprKind<'hir> {
|
) -> hir::ExprKind<'hir> {
|
||||||
// Lower outside new scope to preserve `is_in_loop_condition`.
|
let (body_id, generator_option) = self.with_new_scopes(move |this| {
|
||||||
let fn_decl = self.lower_fn_decl(decl, None, false, None);
|
|
||||||
|
|
||||||
self.with_new_scopes(move |this| {
|
|
||||||
let prev = this.current_item;
|
let prev = this.current_item;
|
||||||
this.current_item = Some(fn_decl_span);
|
this.current_item = Some(fn_decl_span);
|
||||||
let mut generator_kind = None;
|
let mut generator_kind = None;
|
||||||
|
@ -791,8 +788,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
let generator_option =
|
let generator_option =
|
||||||
this.generator_movability_for_fn(&decl, fn_decl_span, generator_kind, movability);
|
this.generator_movability_for_fn(&decl, fn_decl_span, generator_kind, movability);
|
||||||
this.current_item = prev;
|
this.current_item = prev;
|
||||||
hir::ExprKind::Closure(capture_clause, fn_decl, body_id, fn_decl_span, generator_option)
|
(body_id, generator_option)
|
||||||
})
|
});
|
||||||
|
|
||||||
|
// Lower outside new scope to preserve `is_in_loop_condition`.
|
||||||
|
let fn_decl = self.lower_fn_decl(decl, None, false, None);
|
||||||
|
|
||||||
|
hir::ExprKind::Closure(capture_clause, fn_decl, body_id, fn_decl_span, generator_option)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generator_movability_for_fn(
|
fn generator_movability_for_fn(
|
||||||
|
@ -838,12 +840,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
) -> hir::ExprKind<'hir> {
|
) -> hir::ExprKind<'hir> {
|
||||||
let outer_decl =
|
let outer_decl =
|
||||||
FnDecl { inputs: decl.inputs.clone(), output: FnRetTy::Default(fn_decl_span) };
|
FnDecl { inputs: decl.inputs.clone(), output: FnRetTy::Default(fn_decl_span) };
|
||||||
// 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, None);
|
|
||||||
|
|
||||||
self.with_new_scopes(move |this| {
|
let body_id = self.with_new_scopes(|this| {
|
||||||
// FIXME(cramertj): allow `async` non-`move` closures with arguments.
|
// FIXME(cramertj): allow `async` non-`move` closures with arguments.
|
||||||
if capture_clause == CaptureBy::Ref && !decl.inputs.is_empty() {
|
if capture_clause == CaptureBy::Ref && !decl.inputs.is_empty() {
|
||||||
struct_span_err!(
|
struct_span_err!(
|
||||||
|
@ -874,8 +872,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
);
|
);
|
||||||
this.expr(fn_decl_span, async_body, ThinVec::new())
|
this.expr(fn_decl_span, async_body, ThinVec::new())
|
||||||
});
|
});
|
||||||
hir::ExprKind::Closure(capture_clause, fn_decl, body_id, fn_decl_span, None)
|
body_id
|
||||||
})
|
});
|
||||||
|
|
||||||
|
// 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, None);
|
||||||
|
|
||||||
|
hir::ExprKind::Closure(capture_clause, fn_decl, body_id, fn_decl_span, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Destructure the LHS of complex assignments.
|
/// Destructure the LHS of complex assignments.
|
||||||
|
|
17
src/test/ui/closures/local-type-mix.rs
Normal file
17
src/test/ui/closures/local-type-mix.rs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
// Check that using the parameter name in its type does not ICE.
|
||||||
|
// edition:2018
|
||||||
|
|
||||||
|
#![feature(async_closure)]
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let _ = |x: x| x; //~ ERROR expected type
|
||||||
|
let _ = |x: bool| -> x { x }; //~ ERROR expected type
|
||||||
|
let _ = async move |x: x| x; //~ ERROR expected type
|
||||||
|
let _ = async move |x: bool| -> x { x }; //~ ERROR expected type
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo(x: x) {} //~ ERROR expected type
|
||||||
|
fn foo_ret(x: bool) -> x {} //~ ERROR expected type
|
||||||
|
|
||||||
|
async fn async_foo(x: x) {} //~ ERROR expected type
|
||||||
|
async fn async_foo_ret(x: bool) -> x {} //~ ERROR expected type
|
51
src/test/ui/closures/local-type-mix.stderr
Normal file
51
src/test/ui/closures/local-type-mix.stderr
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
error[E0573]: expected type, found local variable `x`
|
||||||
|
--> $DIR/local-type-mix.rs:7:17
|
||||||
|
|
|
||||||
|
LL | let _ = |x: x| x;
|
||||||
|
| ^ not a type
|
||||||
|
|
||||||
|
error[E0573]: expected type, found local variable `x`
|
||||||
|
--> $DIR/local-type-mix.rs:8:26
|
||||||
|
|
|
||||||
|
LL | let _ = |x: bool| -> x { x };
|
||||||
|
| ^ not a type
|
||||||
|
|
||||||
|
error[E0573]: expected type, found local variable `x`
|
||||||
|
--> $DIR/local-type-mix.rs:9:28
|
||||||
|
|
|
||||||
|
LL | let _ = async move |x: x| x;
|
||||||
|
| ^ not a type
|
||||||
|
|
||||||
|
error[E0573]: expected type, found local variable `x`
|
||||||
|
--> $DIR/local-type-mix.rs:10:37
|
||||||
|
|
|
||||||
|
LL | let _ = async move |x: bool| -> x { x };
|
||||||
|
| ^ not a type
|
||||||
|
|
||||||
|
error[E0573]: expected type, found local variable `x`
|
||||||
|
--> $DIR/local-type-mix.rs:13:11
|
||||||
|
|
|
||||||
|
LL | fn foo(x: x) {}
|
||||||
|
| ^ not a type
|
||||||
|
|
||||||
|
error[E0573]: expected type, found local variable `x`
|
||||||
|
--> $DIR/local-type-mix.rs:14:24
|
||||||
|
|
|
||||||
|
LL | fn foo_ret(x: bool) -> x {}
|
||||||
|
| ^ not a type
|
||||||
|
|
||||||
|
error[E0573]: expected type, found local variable `x`
|
||||||
|
--> $DIR/local-type-mix.rs:16:23
|
||||||
|
|
|
||||||
|
LL | async fn async_foo(x: x) {}
|
||||||
|
| ^ not a type
|
||||||
|
|
||||||
|
error[E0573]: expected type, found local variable `x`
|
||||||
|
--> $DIR/local-type-mix.rs:17:36
|
||||||
|
|
|
||||||
|
LL | async fn async_foo_ret(x: bool) -> x {}
|
||||||
|
| ^ not a type
|
||||||
|
|
||||||
|
error: aborting due to 8 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0573`.
|
Loading…
Add table
Add a link
Reference in a new issue