Skip to content

Commit 67415c7

Browse files
committed
wip
1 parent af6a414 commit 67415c7

File tree

36 files changed

+1140
-133
lines changed

36 files changed

+1140
-133
lines changed

crates/hir-def/src/body.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ impl Body {
126126
let mut params = None;
127127

128128
let mut is_async_fn = false;
129+
let mut is_gen_fn = false;
129130
let InFile { file_id, value: body } = {
130131
match def {
131132
DefWithBodyId::FunctionId(f) => {
@@ -146,7 +147,9 @@ impl Body {
146147
}),
147148
)
148149
});
150+
// FIXME from here we know this only happens for functions, so maybe we can get the blockexpr directly and also onlive provide the keyword values then
149151
is_async_fn = data.has_async_kw();
152+
is_gen_fn = data.has_gen_kw();
150153
src.map(|it| it.body().map(ast::Expr::from))
151154
}
152155
DefWithBodyId::ConstId(c) => {
@@ -169,7 +172,7 @@ impl Body {
169172
let module = def.module(db);
170173
let expander = Expander::new(db, file_id, module);
171174
let (mut body, mut source_map) =
172-
Body::new(db, def, expander, params, body, module.krate, is_async_fn);
175+
Body::new(db, def, expander, params, body, module.krate, is_async_fn, is_gen_fn);
173176
body.shrink_to_fit();
174177
source_map.shrink_to_fit();
175178

@@ -209,8 +212,9 @@ impl Body {
209212
body: Option<ast::Expr>,
210213
krate: CrateId,
211214
is_async_fn: bool,
215+
is_gen_fn: bool,
212216
) -> (Body, BodySourceMap) {
213-
lower::lower(db, owner, expander, params, body, krate, is_async_fn)
217+
lower::lower(db, owner, expander, params, body, krate, is_async_fn, is_gen_fn)
214218
}
215219

216220
fn shrink_to_fit(&mut self) {

crates/hir-def/src/body/lower.rs

Lines changed: 167 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ pub(super) fn lower(
5959
body: Option<ast::Expr>,
6060
krate: CrateId,
6161
is_async_fn: bool,
62+
is_gen_fn: bool,
6263
) -> (Body, BodySourceMap) {
6364
ExprCollector {
6465
db,
@@ -85,7 +86,7 @@ pub(super) fn lower(
8586
label_ribs: Vec::new(),
8687
current_binding_owner: None,
8788
}
88-
.collect(params, body, is_async_fn)
89+
.collect(params, body, is_async_fn, is_gen_fn)
8990
}
9091

9192
struct ExprCollector<'a> {
@@ -191,6 +192,7 @@ impl ExprCollector<'_> {
191192
param_list: Option<(ast::ParamList, impl Iterator<Item = bool>)>,
192193
body: Option<ast::Expr>,
193194
is_async_fn: bool,
195+
is_gen_fn: bool,
194196
) -> (Body, BodySourceMap) {
195197
if let Some((param_list, mut attr_enabled)) = param_list {
196198
if let Some(self_param) =
@@ -212,23 +214,73 @@ impl ExprCollector<'_> {
212214
self.body.params.push(param_pat);
213215
}
214216
};
215-
self.body.body_expr = self.with_label_rib(RibKind::Closure, |this| {
216-
if is_async_fn {
217-
match body {
217+
self.body.body_expr =
218+
self.with_label_rib(RibKind::Closure, |this| match (is_async_fn, is_gen_fn) {
219+
(false, false) => this.collect_expr_opt(body),
220+
(false, true) => match body {
218221
Some(e) => {
219222
let expr = this.collect_expr(e);
220-
this.alloc_expr_desugared(Expr::Async {
221-
id: None,
222-
statements: Box::new([]),
223-
tail: Some(expr),
223+
224+
this.alloc_expr_desugared(Expr::Closure {
225+
args: Box::new([]),
226+
arg_types: Box::new([]),
227+
ret_type: None, // FIXME maybe unspecified?
228+
body: expr,
229+
closure_kind: ClosureKind::Coroutine(
230+
crate::hir::CoroutineKind::Desugared(
231+
crate::hir::CoroutineDesugaring::Gen,
232+
crate::hir::CoroutineSource::Fn,
233+
),
234+
Movability::Movable,
235+
),
236+
capture_by: CaptureBy::Ref,
224237
})
225238
}
226239
None => this.missing_expr(),
227-
}
228-
} else {
229-
this.collect_expr_opt(body)
230-
}
231-
});
240+
},
241+
(true, false) => match body {
242+
Some(e) => {
243+
let expr = this.collect_expr(e);
244+
245+
this.alloc_expr_desugared(Expr::Closure {
246+
args: Box::new([]),
247+
arg_types: Box::new([]),
248+
ret_type: None, // FIXME maybe unspecified?
249+
body: expr,
250+
closure_kind: ClosureKind::Coroutine(
251+
crate::hir::CoroutineKind::Desugared(
252+
crate::hir::CoroutineDesugaring::Async,
253+
crate::hir::CoroutineSource::Fn,
254+
),
255+
Movability::Movable,
256+
),
257+
capture_by: CaptureBy::Ref,
258+
})
259+
}
260+
None => this.missing_expr(),
261+
},
262+
(true, true) => match body {
263+
Some(e) => {
264+
let expr = this.collect_expr(e);
265+
266+
this.alloc_expr_desugared(Expr::Closure {
267+
args: Box::new([]),
268+
arg_types: Box::new([]),
269+
ret_type: None, // FIXME maybe unspecified?
270+
body: expr,
271+
closure_kind: ClosureKind::Coroutine(
272+
crate::hir::CoroutineKind::Desugared(
273+
crate::hir::CoroutineDesugaring::AsyncGen,
274+
crate::hir::CoroutineSource::Fn,
275+
),
276+
Movability::Movable,
277+
),
278+
capture_by: CaptureBy::Ref,
279+
})
280+
}
281+
None => this.missing_expr(),
282+
},
283+
});
232284

233285
(self.body, self.source_map)
234286
}
@@ -268,6 +320,7 @@ impl ExprCollector<'_> {
268320
let expr = self.collect_expr_opt(e.expr());
269321
self.alloc_expr(Expr::Let { pat, expr }, syntax_ptr)
270322
}
323+
// https://github.com/compiler-errors/rust/blob/bd0eec74026d5f967afeadc3611bdb674a7b9de4/compiler/rustc_ast/src/ast.rs#L1430
271324
ast::Expr::BlockExpr(e) => match e.modifier() {
272325
Some(ast::BlockModifier::Try(_)) => self.desugar_try_block(e),
273326
Some(ast::BlockModifier::Unsafe(_)) => {
@@ -288,13 +341,76 @@ impl ExprCollector<'_> {
288341
})
289342
})
290343
}
344+
// https://github.com/compiler-errors/rust/blob/closure-kind/compiler/rustc_ast/src/ast.rs#L1430
345+
// https://github.com/compiler-errors/rust/blob/bd0eec74026d5f967afeadc3611bdb674a7b9de4/compiler/rustc_ast_lowering/src/expr.rs#L186
291346
Some(ast::BlockModifier::Async(_)) => {
292347
self.with_label_rib(RibKind::Closure, |this| {
293-
this.collect_block_(e, |id, statements, tail| Expr::Async {
294-
id,
295-
statements,
296-
tail,
297-
})
348+
let (result_expr_id, _) = this.initialize_binding_owner(syntax_ptr);
349+
350+
let body = this.collect_block(e);
351+
352+
this.body.exprs[result_expr_id] = Expr::Closure {
353+
args: Box::new([]),
354+
arg_types: Box::new([]),
355+
ret_type: None, // FIXME maybe unspecified?
356+
body,
357+
closure_kind: ClosureKind::Coroutine(
358+
crate::hir::CoroutineKind::Desugared(
359+
crate::hir::CoroutineDesugaring::Async,
360+
crate::hir::CoroutineSource::Block,
361+
),
362+
Movability::Movable,
363+
),
364+
capture_by: CaptureBy::Ref,
365+
};
366+
367+
result_expr_id
368+
})
369+
}
370+
Some(ast::BlockModifier::Gen(_)) => self.with_label_rib(RibKind::Closure, |this| {
371+
let (result_expr_id, _) = this.initialize_binding_owner(syntax_ptr);
372+
373+
let body = this.collect_block(e);
374+
375+
this.body.exprs[result_expr_id] = Expr::Closure {
376+
args: Box::new([]),
377+
arg_types: Box::new([]),
378+
ret_type: None, // FIXME maybe unspecified?
379+
body,
380+
closure_kind: ClosureKind::Coroutine(
381+
crate::hir::CoroutineKind::Desugared(
382+
crate::hir::CoroutineDesugaring::Gen,
383+
crate::hir::CoroutineSource::Block,
384+
),
385+
Movability::Movable,
386+
),
387+
capture_by: CaptureBy::Ref,
388+
};
389+
390+
result_expr_id
391+
}),
392+
Some(ast::BlockModifier::AsyncGen(_)) => {
393+
self.with_label_rib(RibKind::Closure, |this| {
394+
let (result_expr_id, _) = this.initialize_binding_owner(syntax_ptr);
395+
396+
let body = this.collect_block(e);
397+
398+
this.body.exprs[result_expr_id] = Expr::Closure {
399+
args: Box::new([]),
400+
arg_types: Box::new([]),
401+
ret_type: None, // FIXME maybe unspecified?
402+
body,
403+
closure_kind: ClosureKind::Coroutine(
404+
crate::hir::CoroutineKind::Desugared(
405+
crate::hir::CoroutineDesugaring::AsyncGen,
406+
crate::hir::CoroutineSource::Block,
407+
),
408+
Movability::Movable,
409+
),
410+
capture_by: CaptureBy::Ref,
411+
};
412+
413+
result_expr_id
298414
})
299415
}
300416
Some(ast::BlockModifier::Const(_)) => {
@@ -504,6 +620,7 @@ impl ExprCollector<'_> {
504620
}
505621
}
506622
ast::Expr::ClosureExpr(e) => self.with_label_rib(RibKind::Closure, |this| {
623+
// here
507624
let (result_expr_id, prev_binding_owner) =
508625
this.initialize_binding_owner(syntax_ptr);
509626
let mut args = Vec::new();
@@ -536,9 +653,39 @@ impl ExprCollector<'_> {
536653
} else {
537654
Movability::Movable
538655
};
539-
ClosureKind::Coroutine(movability)
656+
ClosureKind::Coroutine(crate::hir::CoroutineKind::Coroutine, movability)
540657
} else if e.async_token().is_some() {
541-
ClosureKind::Async
658+
// https://github.com/compiler-errors/rust/blob/bd0eec74026d5f967afeadc3611bdb674a7b9de4/compiler/rustc_ast_lowering/src/expr.rs#L1199 ?
659+
660+
let capture_by =
661+
if e.move_token().is_some() { CaptureBy::Value } else { CaptureBy::Ref };
662+
663+
let inner = Expr::Closure {
664+
args: Box::new([]),
665+
arg_types: Box::new([]),
666+
ret_type: ret_type.clone(),
667+
body,
668+
closure_kind: ClosureKind::Coroutine(
669+
crate::hir::CoroutineKind::Desugared(
670+
crate::hir::CoroutineDesugaring::Async,
671+
crate::hir::CoroutineSource::Closure,
672+
),
673+
Movability::Movable,
674+
),
675+
capture_by,
676+
};
677+
this.is_lowering_coroutine = prev_is_lowering_coroutine;
678+
this.current_binding_owner = prev_binding_owner;
679+
this.current_try_block_label = prev_try_block_label;
680+
this.body.exprs[result_expr_id] = Expr::Closure {
681+
args: args.into(),
682+
arg_types: arg_types.into(),
683+
ret_type,
684+
body: this.alloc_expr_desugared(inner),
685+
closure_kind: ClosureKind::Closure,
686+
capture_by,
687+
};
688+
return result_expr_id;
542689
} else {
543690
ClosureKind::Closure
544691
};

crates/hir-def/src/body/pretty.rs

Lines changed: 38 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ use syntax::ast::HasName;
77

88
use crate::{
99
hir::{
10-
Array, BindingAnnotation, BindingId, CaptureBy, ClosureKind, Literal, LiteralOrConst,
11-
Movability, Statement,
10+
Array, BindingAnnotation, BindingId, CaptureBy, ClosureKind, CoroutineDesugaring,
11+
CoroutineKind, Literal, LiteralOrConst, Movability, Statement,
1212
},
1313
pretty::{print_generic_args, print_path, print_type_ref},
1414
type_ref::TypeRef,
@@ -383,38 +383,55 @@ impl Printer<'_> {
383383
w!(self, "]");
384384
}
385385
Expr::Closure { args, arg_types, ret_type, body, closure_kind, capture_by } => {
386+
if let ClosureKind::Coroutine(_, Movability::Static) = closure_kind {
387+
w!(self, "static ");
388+
}
386389
match closure_kind {
387-
ClosureKind::Coroutine(Movability::Static) => {
388-
w!(self, "static ");
389-
}
390-
ClosureKind::Async => {
390+
ClosureKind::Coroutine(
391+
CoroutineKind::Desugared(CoroutineDesugaring::Async, _),
392+
_,
393+
) => {
391394
w!(self, "async ");
392395
}
393-
_ => (),
396+
ClosureKind::Coroutine(
397+
CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _),
398+
_,
399+
) => {
400+
w!(self, "async gen ");
401+
}
402+
ClosureKind::Coroutine(
403+
CoroutineKind::Desugared(CoroutineDesugaring::Gen, _),
404+
_,
405+
) => {
406+
w!(self, "gen ");
407+
}
408+
_ => {}
394409
}
395410
match capture_by {
396411
CaptureBy::Value => {
397412
w!(self, "move ");
398413
}
399414
CaptureBy::Ref => (),
400415
}
401-
w!(self, "|");
402-
for (i, (pat, ty)) in args.iter().zip(arg_types.iter()).enumerate() {
403-
if i != 0 {
404-
w!(self, ", ");
416+
if let ClosureKind::Closure = closure_kind {
417+
w!(self, "|");
418+
for (i, (pat, ty)) in args.iter().zip(arg_types.iter()).enumerate() {
419+
if i != 0 {
420+
w!(self, ", ");
421+
}
422+
self.print_pat(*pat);
423+
if let Some(ty) = ty {
424+
w!(self, ": ");
425+
self.print_type_ref(ty);
426+
}
405427
}
406-
self.print_pat(*pat);
407-
if let Some(ty) = ty {
408-
w!(self, ": ");
409-
self.print_type_ref(ty);
428+
w!(self, "|");
429+
if let Some(ret_ty) = ret_type {
430+
w!(self, " -> ");
431+
self.print_type_ref(ret_ty);
410432
}
433+
self.whitespace();
411434
}
412-
w!(self, "|");
413-
if let Some(ret_ty) = ret_type {
414-
w!(self, " -> ");
415-
self.print_type_ref(ret_ty);
416-
}
417-
self.whitespace();
418435
self.print_expr(*body);
419436
}
420437
Expr::Tuple { exprs, is_assignee_expr: _ } => {
@@ -454,9 +471,6 @@ impl Printer<'_> {
454471
Expr::Unsafe { id: _, statements, tail } => {
455472
self.print_block(Some("unsafe "), statements, tail);
456473
}
457-
Expr::Async { id: _, statements, tail } => {
458-
self.print_block(Some("async "), statements, tail);
459-
}
460474
Expr::Const(id) => {
461475
w!(self, "const {{ /* {id:?} */ }}");
462476
}

crates/hir-def/src/body/scope.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ fn compute_expr_scopes(expr: ExprId, body: &Body, scopes: &mut ExprScopes, scope
220220
Expr::Const(_) => {
221221
// FIXME: This is broken.
222222
}
223-
Expr::Unsafe { id, statements, tail } | Expr::Async { id, statements, tail } => {
223+
Expr::Unsafe { id, statements, tail } => {
224224
let mut scope = scopes.new_block_scope(*scope, *id, None);
225225
// Overwrite the old scope for the block expr, so that every block scope can be found
226226
// via the block itself (important for blocks that only contain items, no expressions).

0 commit comments

Comments
 (0)