Skip to content

Commit fcf1129

Browse files
Rollup merge of #81249 - cjgillot:issue-79537, r=oli-obk
Lower closure prototype after its body. Fixes #79537. r? `@Mark-Simulacrum`
2 parents c4830da + 3f42abe commit fcf1129

File tree

3 files changed

+86
-13
lines changed

3 files changed

+86
-13
lines changed

compiler/rustc_ast_lowering/src/expr.rs

+18-13
Original file line numberDiff line numberDiff line change
@@ -776,10 +776,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
776776
body: &Expr,
777777
fn_decl_span: Span,
778778
) -> hir::ExprKind<'hir> {
779-
// Lower outside new scope to preserve `is_in_loop_condition`.
780-
let fn_decl = self.lower_fn_decl(decl, None, false, None);
781-
782-
self.with_new_scopes(move |this| {
779+
let (body_id, generator_option) = self.with_new_scopes(move |this| {
783780
let prev = this.current_item;
784781
this.current_item = Some(fn_decl_span);
785782
let mut generator_kind = None;
@@ -791,8 +788,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
791788
let generator_option =
792789
this.generator_movability_for_fn(&decl, fn_decl_span, generator_kind, movability);
793790
this.current_item = prev;
794-
hir::ExprKind::Closure(capture_clause, fn_decl, body_id, fn_decl_span, generator_option)
795-
})
791+
(body_id, generator_option)
792+
});
793+
794+
// Lower outside new scope to preserve `is_in_loop_condition`.
795+
let fn_decl = self.lower_fn_decl(decl, None, false, None);
796+
797+
hir::ExprKind::Closure(capture_clause, fn_decl, body_id, fn_decl_span, generator_option)
796798
}
797799

798800
fn generator_movability_for_fn(
@@ -838,12 +840,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
838840
) -> hir::ExprKind<'hir> {
839841
let outer_decl =
840842
FnDecl { inputs: decl.inputs.clone(), output: FnRetTy::Default(fn_decl_span) };
841-
// We need to lower the declaration outside the new scope, because we
842-
// have to conserve the state of being inside a loop condition for the
843-
// closure argument types.
844-
let fn_decl = self.lower_fn_decl(&outer_decl, None, false, None);
845843

846-
self.with_new_scopes(move |this| {
844+
let body_id = self.with_new_scopes(|this| {
847845
// FIXME(cramertj): allow `async` non-`move` closures with arguments.
848846
if capture_clause == CaptureBy::Ref && !decl.inputs.is_empty() {
849847
struct_span_err!(
@@ -874,8 +872,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
874872
);
875873
this.expr(fn_decl_span, async_body, ThinVec::new())
876874
});
877-
hir::ExprKind::Closure(capture_clause, fn_decl, body_id, fn_decl_span, None)
878-
})
875+
body_id
876+
});
877+
878+
// We need to lower the declaration outside the new scope, because we
879+
// have to conserve the state of being inside a loop condition for the
880+
// closure argument types.
881+
let fn_decl = self.lower_fn_decl(&outer_decl, None, false, None);
882+
883+
hir::ExprKind::Closure(capture_clause, fn_decl, body_id, fn_decl_span, None)
879884
}
880885

881886
/// Destructure the LHS of complex assignments.
+17
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
+51
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)