Skip to content

Commit b332f45

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

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
-247
lines changed

crates/hir-def/src/body.rs

Lines changed: 5 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) => {
@@ -159,6 +160,7 @@ impl Body {
159160
)
160161
});
161162
is_async_fn = data.has_async_kw();
163+
is_gen_fn = data.has_gen_kw();
162164
src.map(|it| it.body().map(ast::Expr::from))
163165
}
164166
DefWithBodyId::ConstId(c) => {
@@ -182,7 +184,7 @@ impl Body {
182184
let module = def.module(db);
183185
let expander = Expander::new(db, file_id, module);
184186
let (mut body, mut source_map) =
185-
Body::new(db, def, expander, params, body, module.krate, is_async_fn);
187+
Body::new(db, def, expander, params, body, module.krate, is_async_fn, is_gen_fn);
186188
body.shrink_to_fit();
187189
source_map.shrink_to_fit();
188190

@@ -222,8 +224,9 @@ impl Body {
222224
body: Option<ast::Expr>,
223225
krate: CrateId,
224226
is_async_fn: bool,
227+
is_gen_fn: bool,
225228
) -> (Body, BodySourceMap) {
226-
lower::lower(db, owner, expander, params, body, krate, is_async_fn)
229+
lower::lower(db, owner, expander, params, body, krate, is_async_fn, is_gen_fn)
227230
}
228231

229232
fn shrink_to_fit(&mut self) {

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

Lines changed: 172 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,76 @@ 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+
// gen fn
211+
(false, true) => match body {
208212
Some(e) => {
209-
let syntax_ptr = AstPtr::new(&e);
210213
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-
)
214+
215+
this.alloc_expr_desugared(Expr::Closure {
216+
args: Box::new([]),
217+
arg_types: Box::new([]),
218+
ret_type: None, // FIXME maybe unspecified?
219+
body: expr,
220+
closure_kind: ClosureKind::Coroutine(
221+
crate::hir::CoroutineKind::Desugared(
222+
crate::hir::CoroutineDesugaring::Gen,
223+
crate::hir::CoroutineSource::Fn,
224+
),
225+
Movability::Movable,
226+
),
227+
capture_by: CaptureBy::Ref,
228+
})
215229
}
216230
None => this.missing_expr(),
217-
}
218-
} else {
219-
this.collect_expr_opt(body)
220-
}
221-
});
231+
},
232+
// async fn
233+
(true, false) => match body {
234+
Some(e) => {
235+
let expr = this.collect_expr(e);
236+
237+
this.alloc_expr_desugared(Expr::Closure {
238+
args: Box::new([]),
239+
arg_types: Box::new([]),
240+
ret_type: None, // FIXME maybe unspecified?
241+
body: expr,
242+
closure_kind: ClosureKind::Coroutine(
243+
crate::hir::CoroutineKind::Desugared(
244+
crate::hir::CoroutineDesugaring::Async,
245+
crate::hir::CoroutineSource::Fn,
246+
),
247+
Movability::Movable,
248+
),
249+
capture_by: CaptureBy::Ref,
250+
})
251+
}
252+
None => this.missing_expr(),
253+
},
254+
// async gen fn
255+
(true, true) => match body {
256+
Some(e) => {
257+
let expr = this.collect_expr(e);
258+
259+
this.alloc_expr_desugared(Expr::Closure {
260+
args: Box::new([]),
261+
arg_types: Box::new([]),
262+
ret_type: None, // FIXME maybe unspecified?
263+
body: expr,
264+
closure_kind: ClosureKind::Coroutine(
265+
crate::hir::CoroutineKind::Desugared(
266+
crate::hir::CoroutineDesugaring::AsyncGen,
267+
crate::hir::CoroutineSource::Fn,
268+
),
269+
Movability::Movable,
270+
),
271+
capture_by: CaptureBy::Ref,
272+
})
273+
}
274+
None => this.missing_expr(),
275+
},
276+
});
222277

223278
(self.body, self.source_map)
224279
}
@@ -258,6 +313,7 @@ impl ExprCollector<'_> {
258313
let expr = self.collect_expr_opt(e.expr());
259314
self.alloc_expr(Expr::Let { pat, expr }, syntax_ptr)
260315
}
316+
// https://github.com/compiler-errors/rust/blob/bd0eec74026d5f967afeadc3611bdb674a7b9de4/compiler/rustc_ast/src/ast.rs#L1430
261317
ast::Expr::BlockExpr(e) => match e.modifier() {
262318
Some(ast::BlockModifier::Try(_)) => self.desugar_try_block(e),
263319
Some(ast::BlockModifier::Unsafe(_)) => {
@@ -278,13 +334,76 @@ impl ExprCollector<'_> {
278334
})
279335
})
280336
}
337+
// https://github.com/compiler-errors/rust/blob/closure-kind/compiler/rustc_ast/src/ast.rs#L1430
338+
// https://github.com/compiler-errors/rust/blob/bd0eec74026d5f967afeadc3611bdb674a7b9de4/compiler/rustc_ast_lowering/src/expr.rs#L186
281339
Some(ast::BlockModifier::Async(_)) => {
282340
self.with_label_rib(RibKind::Closure, |this| {
283-
this.collect_block_(e, |id, statements, tail| Expr::Async {
284-
id,
285-
statements,
286-
tail,
287-
})
341+
let (result_expr_id, _) = this.initialize_binding_owner(syntax_ptr);
342+
343+
let body = this.collect_block(e);
344+
345+
this.body.exprs[result_expr_id] = Expr::Closure {
346+
args: Box::new([]),
347+
arg_types: Box::new([]),
348+
ret_type: None, // FIXME maybe unspecified?
349+
body,
350+
closure_kind: ClosureKind::Coroutine(
351+
crate::hir::CoroutineKind::Desugared(
352+
crate::hir::CoroutineDesugaring::Async,
353+
crate::hir::CoroutineSource::Block,
354+
),
355+
Movability::Movable,
356+
),
357+
capture_by: CaptureBy::Ref,
358+
};
359+
360+
result_expr_id
361+
})
362+
}
363+
Some(ast::BlockModifier::Gen(_)) => self.with_label_rib(RibKind::Closure, |this| {
364+
let (result_expr_id, _) = this.initialize_binding_owner(syntax_ptr);
365+
366+
let body = this.collect_block(e);
367+
368+
this.body.exprs[result_expr_id] = Expr::Closure {
369+
args: Box::new([]),
370+
arg_types: Box::new([]),
371+
ret_type: None, // FIXME maybe unspecified?
372+
body,
373+
closure_kind: ClosureKind::Coroutine(
374+
crate::hir::CoroutineKind::Desugared(
375+
crate::hir::CoroutineDesugaring::Gen,
376+
crate::hir::CoroutineSource::Block,
377+
),
378+
Movability::Movable,
379+
),
380+
capture_by: CaptureBy::Ref,
381+
};
382+
383+
result_expr_id
384+
}),
385+
Some(ast::BlockModifier::AsyncGen(_)) => {
386+
self.with_label_rib(RibKind::Closure, |this| {
387+
let (result_expr_id, _) = this.initialize_binding_owner(syntax_ptr);
388+
389+
let body = this.collect_block(e);
390+
391+
this.body.exprs[result_expr_id] = Expr::Closure {
392+
args: Box::new([]),
393+
arg_types: Box::new([]),
394+
ret_type: None, // FIXME maybe unspecified?
395+
body,
396+
closure_kind: ClosureKind::Coroutine(
397+
crate::hir::CoroutineKind::Desugared(
398+
crate::hir::CoroutineDesugaring::AsyncGen,
399+
crate::hir::CoroutineSource::Block,
400+
),
401+
Movability::Movable,
402+
),
403+
capture_by: CaptureBy::Ref,
404+
};
405+
406+
result_expr_id
288407
})
289408
}
290409
Some(ast::BlockModifier::Const(_)) => {
@@ -301,10 +420,7 @@ impl ExprCollector<'_> {
301420
result_expr_id
302421
})
303422
}
304-
// FIXME
305-
Some(ast::BlockModifier::AsyncGen(_)) | Some(ast::BlockModifier::Gen(_)) | None => {
306-
self.collect_block(e)
307-
}
423+
None => self.collect_block(e),
308424
},
309425
ast::Expr::LoopExpr(e) => {
310426
let label = e.label().map(|label| self.collect_label(label));
@@ -503,6 +619,7 @@ impl ExprCollector<'_> {
503619
}
504620
}
505621
ast::Expr::ClosureExpr(e) => self.with_label_rib(RibKind::Closure, |this| {
622+
// here
506623
let (result_expr_id, prev_binding_owner) =
507624
this.initialize_binding_owner(syntax_ptr);
508625
let mut args = Vec::new();
@@ -535,9 +652,39 @@ impl ExprCollector<'_> {
535652
} else {
536653
Movability::Movable
537654
};
538-
ClosureKind::Coroutine(movability)
655+
ClosureKind::Coroutine(crate::hir::CoroutineKind::Coroutine, movability)
539656
} else if e.async_token().is_some() {
540-
ClosureKind::Async
657+
// https://github.com/compiler-errors/rust/blob/bd0eec74026d5f967afeadc3611bdb674a7b9de4/compiler/rustc_ast_lowering/src/expr.rs#L1199 ?
658+
659+
let capture_by =
660+
if e.move_token().is_some() { CaptureBy::Value } else { CaptureBy::Ref };
661+
662+
let inner = Expr::Closure {
663+
args: Box::new([]),
664+
arg_types: Box::new([]),
665+
ret_type: ret_type.clone(),
666+
body,
667+
closure_kind: ClosureKind::Coroutine(
668+
crate::hir::CoroutineKind::Desugared(
669+
crate::hir::CoroutineDesugaring::Async,
670+
crate::hir::CoroutineSource::Closure,
671+
),
672+
Movability::Movable,
673+
),
674+
capture_by,
675+
};
676+
this.is_lowering_coroutine = prev_is_lowering_coroutine;
677+
this.current_binding_owner = prev_binding_owner;
678+
this.current_try_block_label = prev_try_block_label;
679+
this.body.exprs[result_expr_id] = Expr::Closure {
680+
args: args.into(),
681+
arg_types: arg_types.into(),
682+
ret_type,
683+
body: this.alloc_expr_desugared(inner),
684+
closure_kind: ClosureKind::Closure,
685+
capture_by,
686+
};
687+
return result_expr_id;
541688
} else {
542689
ClosureKind::Closure
543690
};

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)