Skip to content

Commit 36aa3c3

Browse files
mohe2015Veykril
authored andcommitted
Implement gen blocks and functions
1 parent fa5ff86 commit 36aa3c3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1384
-274
lines changed

crates/hir-def/src/body.rs

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

133133
let mut is_async_fn = false;
134+
let mut is_gen_fn = false;
134135
let InFile { file_id, value: body } = {
135136
match def {
136137
DefWithBodyId::FunctionId(f) => {
@@ -158,7 +159,9 @@ impl Body {
158159
}),
159160
)
160161
});
162+
// 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
161163
is_async_fn = data.has_async_kw();
164+
is_gen_fn = data.has_gen_kw();
162165
src.map(|it| it.body().map(ast::Expr::from))
163166
}
164167
DefWithBodyId::ConstId(c) => {
@@ -182,7 +185,7 @@ impl Body {
182185
let module = def.module(db);
183186
let expander = Expander::new(db, file_id, module);
184187
let (mut body, mut source_map) =
185-
Body::new(db, def, expander, params, body, module.krate, is_async_fn);
188+
Body::new(db, def, expander, params, body, module.krate, is_async_fn, is_gen_fn);
186189
body.shrink_to_fit();
187190
source_map.shrink_to_fit();
188191

@@ -222,8 +225,9 @@ impl Body {
222225
body: Option<ast::Expr>,
223226
krate: CrateId,
224227
is_async_fn: bool,
228+
is_gen_fn: bool,
225229
) -> (Body, BodySourceMap) {
226-
lower::lower(db, owner, expander, params, body, krate, is_async_fn)
230+
lower::lower(db, owner, expander, params, body, krate, is_async_fn, is_gen_fn)
227231
}
228232

229233
fn shrink_to_fit(&mut self) {

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

Lines changed: 169 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ pub(super) fn lower(
5757
body: Option<ast::Expr>,
5858
krate: CrateId,
5959
is_async_fn: bool,
60+
is_gen_fn: bool,
6061
) -> (Body, BodySourceMap) {
6162
ExprCollector {
6263
db,
@@ -73,7 +74,7 @@ pub(super) fn lower(
7374
label_ribs: Vec::new(),
7475
current_binding_owner: None,
7576
}
76-
.collect(params, body, is_async_fn)
77+
.collect(params, body, is_async_fn, is_gen_fn)
7778
}
7879

7980
struct ExprCollector<'a> {
@@ -179,6 +180,7 @@ impl ExprCollector<'_> {
179180
param_list: Option<(ast::ParamList, impl Iterator<Item = bool>)>,
180181
body: Option<ast::Expr>,
181182
is_async_fn: bool,
183+
is_gen_fn: bool,
182184
) -> (Body, BodySourceMap) {
183185
if let Some((param_list, mut attr_enabled)) = param_list {
184186
let mut params = vec![];
@@ -202,23 +204,73 @@ impl ExprCollector<'_> {
202204
}
203205
self.body.params = params.into_boxed_slice();
204206
};
205-
self.body.body_expr = self.with_label_rib(RibKind::Closure, |this| {
206-
if is_async_fn {
207-
match body {
207+
self.body.body_expr =
208+
self.with_label_rib(RibKind::Closure, |this| match (is_async_fn, is_gen_fn) {
209+
(false, false) => this.collect_expr_opt(body),
210+
(false, true) => match body {
208211
Some(e) => {
209-
let syntax_ptr = AstPtr::new(&e);
210212
let expr = this.collect_expr(e);
211-
this.alloc_expr_desugared_with_ptr(
212-
Expr::Async { id: None, statements: Box::new([]), tail: Some(expr) },
213-
syntax_ptr,
214-
)
213+
214+
this.alloc_expr_desugared(Expr::Closure {
215+
args: Box::new([]),
216+
arg_types: Box::new([]),
217+
ret_type: None, // FIXME maybe unspecified?
218+
body: expr,
219+
closure_kind: ClosureKind::Coroutine(
220+
crate::hir::CoroutineKind::Desugared(
221+
crate::hir::CoroutineDesugaring::Gen,
222+
crate::hir::CoroutineSource::Fn,
223+
),
224+
Movability::Movable,
225+
),
226+
capture_by: CaptureBy::Ref,
227+
})
215228
}
216229
None => this.missing_expr(),
217-
}
218-
} else {
219-
this.collect_expr_opt(body)
220-
}
221-
});
230+
},
231+
(true, false) => match body {
232+
Some(e) => {
233+
let expr = this.collect_expr(e);
234+
235+
this.alloc_expr_desugared(Expr::Closure {
236+
args: Box::new([]),
237+
arg_types: Box::new([]),
238+
ret_type: None, // FIXME maybe unspecified?
239+
body: expr,
240+
closure_kind: ClosureKind::Coroutine(
241+
crate::hir::CoroutineKind::Desugared(
242+
crate::hir::CoroutineDesugaring::Async,
243+
crate::hir::CoroutineSource::Fn,
244+
),
245+
Movability::Movable,
246+
),
247+
capture_by: CaptureBy::Ref,
248+
})
249+
}
250+
None => this.missing_expr(),
251+
},
252+
(true, true) => match body {
253+
Some(e) => {
254+
let expr = this.collect_expr(e);
255+
256+
this.alloc_expr_desugared(Expr::Closure {
257+
args: Box::new([]),
258+
arg_types: Box::new([]),
259+
ret_type: None, // FIXME maybe unspecified?
260+
body: expr,
261+
closure_kind: ClosureKind::Coroutine(
262+
crate::hir::CoroutineKind::Desugared(
263+
crate::hir::CoroutineDesugaring::AsyncGen,
264+
crate::hir::CoroutineSource::Fn,
265+
),
266+
Movability::Movable,
267+
),
268+
capture_by: CaptureBy::Ref,
269+
})
270+
}
271+
None => this.missing_expr(),
272+
},
273+
});
222274

223275
(self.body, self.source_map)
224276
}
@@ -258,6 +310,7 @@ impl ExprCollector<'_> {
258310
let expr = self.collect_expr_opt(e.expr());
259311
self.alloc_expr(Expr::Let { pat, expr }, syntax_ptr)
260312
}
313+
// https://github.com/compiler-errors/rust/blob/bd0eec74026d5f967afeadc3611bdb674a7b9de4/compiler/rustc_ast/src/ast.rs#L1430
261314
ast::Expr::BlockExpr(e) => match e.modifier() {
262315
Some(ast::BlockModifier::Try(_)) => self.desugar_try_block(e),
263316
Some(ast::BlockModifier::Unsafe(_)) => {
@@ -278,13 +331,76 @@ impl ExprCollector<'_> {
278331
})
279332
})
280333
}
334+
// https://github.com/compiler-errors/rust/blob/closure-kind/compiler/rustc_ast/src/ast.rs#L1430
335+
// https://github.com/compiler-errors/rust/blob/bd0eec74026d5f967afeadc3611bdb674a7b9de4/compiler/rustc_ast_lowering/src/expr.rs#L186
281336
Some(ast::BlockModifier::Async(_)) => {
282337
self.with_label_rib(RibKind::Closure, |this| {
283-
this.collect_block_(e, |id, statements, tail| Expr::Async {
284-
id,
285-
statements,
286-
tail,
287-
})
338+
let (result_expr_id, _) = this.initialize_binding_owner(syntax_ptr);
339+
340+
let body = this.collect_block(e);
341+
342+
this.body.exprs[result_expr_id] = Expr::Closure {
343+
args: Box::new([]),
344+
arg_types: Box::new([]),
345+
ret_type: None, // FIXME maybe unspecified?
346+
body,
347+
closure_kind: ClosureKind::Coroutine(
348+
crate::hir::CoroutineKind::Desugared(
349+
crate::hir::CoroutineDesugaring::Async,
350+
crate::hir::CoroutineSource::Block,
351+
),
352+
Movability::Movable,
353+
),
354+
capture_by: CaptureBy::Ref,
355+
};
356+
357+
result_expr_id
358+
})
359+
}
360+
Some(ast::BlockModifier::Gen(_)) => self.with_label_rib(RibKind::Closure, |this| {
361+
let (result_expr_id, _) = this.initialize_binding_owner(syntax_ptr);
362+
363+
let body = this.collect_block(e);
364+
365+
this.body.exprs[result_expr_id] = Expr::Closure {
366+
args: Box::new([]),
367+
arg_types: Box::new([]),
368+
ret_type: None, // FIXME maybe unspecified?
369+
body,
370+
closure_kind: ClosureKind::Coroutine(
371+
crate::hir::CoroutineKind::Desugared(
372+
crate::hir::CoroutineDesugaring::Gen,
373+
crate::hir::CoroutineSource::Block,
374+
),
375+
Movability::Movable,
376+
),
377+
capture_by: CaptureBy::Ref,
378+
};
379+
380+
result_expr_id
381+
}),
382+
Some(ast::BlockModifier::AsyncGen(_)) => {
383+
self.with_label_rib(RibKind::Closure, |this| {
384+
let (result_expr_id, _) = this.initialize_binding_owner(syntax_ptr);
385+
386+
let body = this.collect_block(e);
387+
388+
this.body.exprs[result_expr_id] = Expr::Closure {
389+
args: Box::new([]),
390+
arg_types: Box::new([]),
391+
ret_type: None, // FIXME maybe unspecified?
392+
body,
393+
closure_kind: ClosureKind::Coroutine(
394+
crate::hir::CoroutineKind::Desugared(
395+
crate::hir::CoroutineDesugaring::AsyncGen,
396+
crate::hir::CoroutineSource::Block,
397+
),
398+
Movability::Movable,
399+
),
400+
capture_by: CaptureBy::Ref,
401+
};
402+
403+
result_expr_id
288404
})
289405
}
290406
Some(ast::BlockModifier::Const(_)) => {
@@ -301,10 +417,7 @@ impl ExprCollector<'_> {
301417
result_expr_id
302418
})
303419
}
304-
// FIXME
305-
Some(ast::BlockModifier::AsyncGen(_)) | Some(ast::BlockModifier::Gen(_)) | None => {
306-
self.collect_block(e)
307-
}
420+
None => self.collect_block(e),
308421
},
309422
ast::Expr::LoopExpr(e) => {
310423
let label = e.label().map(|label| self.collect_label(label));
@@ -503,6 +616,7 @@ impl ExprCollector<'_> {
503616
}
504617
}
505618
ast::Expr::ClosureExpr(e) => self.with_label_rib(RibKind::Closure, |this| {
619+
// here
506620
let (result_expr_id, prev_binding_owner) =
507621
this.initialize_binding_owner(syntax_ptr);
508622
let mut args = Vec::new();
@@ -535,9 +649,39 @@ impl ExprCollector<'_> {
535649
} else {
536650
Movability::Movable
537651
};
538-
ClosureKind::Coroutine(movability)
652+
ClosureKind::Coroutine(crate::hir::CoroutineKind::Coroutine, movability)
539653
} else if e.async_token().is_some() {
540-
ClosureKind::Async
654+
// https://github.com/compiler-errors/rust/blob/bd0eec74026d5f967afeadc3611bdb674a7b9de4/compiler/rustc_ast_lowering/src/expr.rs#L1199 ?
655+
656+
let capture_by =
657+
if e.move_token().is_some() { CaptureBy::Value } else { CaptureBy::Ref };
658+
659+
let inner = Expr::Closure {
660+
args: Box::new([]),
661+
arg_types: Box::new([]),
662+
ret_type: ret_type.clone(),
663+
body,
664+
closure_kind: ClosureKind::Coroutine(
665+
crate::hir::CoroutineKind::Desugared(
666+
crate::hir::CoroutineDesugaring::Async,
667+
crate::hir::CoroutineSource::Closure,
668+
),
669+
Movability::Movable,
670+
),
671+
capture_by,
672+
};
673+
this.is_lowering_coroutine = prev_is_lowering_coroutine;
674+
this.current_binding_owner = prev_binding_owner;
675+
this.current_try_block_label = prev_try_block_label;
676+
this.body.exprs[result_expr_id] = Expr::Closure {
677+
args: args.into(),
678+
arg_types: arg_types.into(),
679+
ret_type,
680+
body: this.alloc_expr_desugared(inner),
681+
closure_kind: ClosureKind::Closure,
682+
capture_by,
683+
};
684+
return result_expr_id;
541685
} else {
542686
ClosureKind::Closure
543687
};

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

Lines changed: 38 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use itertools::Itertools;
66

77
use crate::{
88
hir::{
9-
Array, BindingAnnotation, CaptureBy, ClosureKind, Literal, LiteralOrConst, Movability,
10-
Statement,
9+
Array, BindingAnnotation, BindingId, CaptureBy, ClosureKind, CoroutineDesugaring,
10+
CoroutineKind, Literal, LiteralOrConst, Movability, Statement,
1111
},
1212
pretty::{print_generic_args, print_path, print_type_ref},
1313
type_ref::TypeRef,
@@ -400,38 +400,55 @@ impl Printer<'_> {
400400
w!(self, "]");
401401
}
402402
Expr::Closure { args, arg_types, ret_type, body, closure_kind, capture_by } => {
403+
if let ClosureKind::Coroutine(_, Movability::Static) = closure_kind {
404+
w!(self, "static ");
405+
}
403406
match closure_kind {
404-
ClosureKind::Coroutine(Movability::Static) => {
405-
w!(self, "static ");
406-
}
407-
ClosureKind::Async => {
407+
ClosureKind::Coroutine(
408+
CoroutineKind::Desugared(CoroutineDesugaring::Async, _),
409+
_,
410+
) => {
408411
w!(self, "async ");
409412
}
410-
_ => (),
413+
ClosureKind::Coroutine(
414+
CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _),
415+
_,
416+
) => {
417+
w!(self, "async gen ");
418+
}
419+
ClosureKind::Coroutine(
420+
CoroutineKind::Desugared(CoroutineDesugaring::Gen, _),
421+
_,
422+
) => {
423+
w!(self, "gen ");
424+
}
425+
_ => {}
411426
}
412427
match capture_by {
413428
CaptureBy::Value => {
414429
w!(self, "move ");
415430
}
416431
CaptureBy::Ref => (),
417432
}
418-
w!(self, "|");
419-
for (i, (pat, ty)) in args.iter().zip(arg_types.iter()).enumerate() {
420-
if i != 0 {
421-
w!(self, ", ");
433+
if let ClosureKind::Closure = closure_kind {
434+
w!(self, "|");
435+
for (i, (pat, ty)) in args.iter().zip(arg_types.iter()).enumerate() {
436+
if i != 0 {
437+
w!(self, ", ");
438+
}
439+
self.print_pat(*pat);
440+
if let Some(ty) = ty {
441+
w!(self, ": ");
442+
self.print_type_ref(ty);
443+
}
422444
}
423-
self.print_pat(*pat);
424-
if let Some(ty) = ty {
425-
w!(self, ": ");
426-
self.print_type_ref(ty);
445+
w!(self, "|");
446+
if let Some(ret_ty) = ret_type {
447+
w!(self, " -> ");
448+
self.print_type_ref(ret_ty);
427449
}
450+
self.whitespace();
428451
}
429-
w!(self, "|");
430-
if let Some(ret_ty) = ret_type {
431-
w!(self, " -> ");
432-
self.print_type_ref(ret_ty);
433-
}
434-
self.whitespace();
435452
self.print_expr(*body);
436453
}
437454
Expr::Tuple { exprs, is_assignee_expr: _ } => {
@@ -471,9 +488,6 @@ impl Printer<'_> {
471488
Expr::Unsafe { id: _, statements, tail } => {
472489
self.print_block(Some("unsafe "), statements, tail);
473490
}
474-
Expr::Async { id: _, statements, tail } => {
475-
self.print_block(Some("async "), statements, tail);
476-
}
477491
Expr::Const(id) => {
478492
w!(self, "const {{ /* {id:?} */ }}");
479493
}

0 commit comments

Comments
 (0)