Skip to content

Commit 3f42abe

Browse files
committed
Lower closure prototype after its body.
1 parent c5a96fb commit 3f42abe

File tree

3 files changed

+86
-13
lines changed

3 files changed

+86
-13
lines changed

compiler/rustc_ast_lowering/src/expr.rs

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -770,10 +770,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
770770
body: &Expr,
771771
fn_decl_span: Span,
772772
) -> hir::ExprKind<'hir> {
773-
// Lower outside new scope to preserve `is_in_loop_condition`.
774-
let fn_decl = self.lower_fn_decl(decl, None, false, None);
775-
776-
self.with_new_scopes(move |this| {
773+
let (body_id, generator_option) = self.with_new_scopes(move |this| {
777774
let prev = this.current_item;
778775
this.current_item = Some(fn_decl_span);
779776
let mut generator_kind = None;
@@ -785,8 +782,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
785782
let generator_option =
786783
this.generator_movability_for_fn(&decl, fn_decl_span, generator_kind, movability);
787784
this.current_item = prev;
788-
hir::ExprKind::Closure(capture_clause, fn_decl, body_id, fn_decl_span, generator_option)
789-
})
785+
(body_id, generator_option)
786+
});
787+
788+
// Lower outside new scope to preserve `is_in_loop_condition`.
789+
let fn_decl = self.lower_fn_decl(decl, None, false, None);
790+
791+
hir::ExprKind::Closure(capture_clause, fn_decl, body_id, fn_decl_span, generator_option)
790792
}
791793

792794
fn generator_movability_for_fn(
@@ -832,12 +834,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
832834
) -> hir::ExprKind<'hir> {
833835
let outer_decl =
834836
FnDecl { inputs: decl.inputs.clone(), output: FnRetTy::Default(fn_decl_span) };
835-
// We need to lower the declaration outside the new scope, because we
836-
// have to conserve the state of being inside a loop condition for the
837-
// closure argument types.
838-
let fn_decl = self.lower_fn_decl(&outer_decl, None, false, None);
839837

840-
self.with_new_scopes(move |this| {
838+
let body_id = self.with_new_scopes(|this| {
841839
// FIXME(cramertj): allow `async` non-`move` closures with arguments.
842840
if capture_clause == CaptureBy::Ref && !decl.inputs.is_empty() {
843841
struct_span_err!(
@@ -868,8 +866,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
868866
);
869867
this.expr(fn_decl_span, async_body, ThinVec::new())
870868
});
871-
hir::ExprKind::Closure(capture_clause, fn_decl, body_id, fn_decl_span, None)
872-
})
869+
body_id
870+
});
871+
872+
// We need to lower the declaration outside the new scope, because we
873+
// have to conserve the state of being inside a loop condition for the
874+
// closure argument types.
875+
let fn_decl = self.lower_fn_decl(&outer_decl, None, false, None);
876+
877+
hir::ExprKind::Closure(capture_clause, fn_decl, body_id, fn_decl_span, None)
873878
}
874879

875880
/// Destructure the LHS of complex assignments.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Check that using the parameter name in its type does not ICE.
2+
// edition:2018
3+
4+
#![feature(async_closure)]
5+
6+
fn main() {
7+
let _ = |x: x| x; //~ ERROR expected type
8+
let _ = |x: bool| -> x { x }; //~ ERROR expected type
9+
let _ = async move |x: x| x; //~ ERROR expected type
10+
let _ = async move |x: bool| -> x { x }; //~ ERROR expected type
11+
}
12+
13+
fn foo(x: x) {} //~ ERROR expected type
14+
fn foo_ret(x: bool) -> x {} //~ ERROR expected type
15+
16+
async fn async_foo(x: x) {} //~ ERROR expected type
17+
async fn async_foo_ret(x: bool) -> x {} //~ ERROR expected type
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
error[E0573]: expected type, found local variable `x`
2+
--> $DIR/local-type-mix.rs:7:17
3+
|
4+
LL | let _ = |x: x| x;
5+
| ^ not a type
6+
7+
error[E0573]: expected type, found local variable `x`
8+
--> $DIR/local-type-mix.rs:8:26
9+
|
10+
LL | let _ = |x: bool| -> x { x };
11+
| ^ not a type
12+
13+
error[E0573]: expected type, found local variable `x`
14+
--> $DIR/local-type-mix.rs:9:28
15+
|
16+
LL | let _ = async move |x: x| x;
17+
| ^ not a type
18+
19+
error[E0573]: expected type, found local variable `x`
20+
--> $DIR/local-type-mix.rs:10:37
21+
|
22+
LL | let _ = async move |x: bool| -> x { x };
23+
| ^ not a type
24+
25+
error[E0573]: expected type, found local variable `x`
26+
--> $DIR/local-type-mix.rs:13:11
27+
|
28+
LL | fn foo(x: x) {}
29+
| ^ not a type
30+
31+
error[E0573]: expected type, found local variable `x`
32+
--> $DIR/local-type-mix.rs:14:24
33+
|
34+
LL | fn foo_ret(x: bool) -> x {}
35+
| ^ not a type
36+
37+
error[E0573]: expected type, found local variable `x`
38+
--> $DIR/local-type-mix.rs:16:23
39+
|
40+
LL | async fn async_foo(x: x) {}
41+
| ^ not a type
42+
43+
error[E0573]: expected type, found local variable `x`
44+
--> $DIR/local-type-mix.rs:17:36
45+
|
46+
LL | async fn async_foo_ret(x: bool) -> x {}
47+
| ^ not a type
48+
49+
error: aborting due to 8 previous errors
50+
51+
For more information about this error, try `rustc --explain E0573`.

0 commit comments

Comments
 (0)