Lower generator expression to HIR

This commit is contained in:
Ryo Yoshida 2022-09-05 22:43:26 +09:00
parent 6dfd8aebdf
commit ba64c93a44
No known key found for this signature in database
GPG key ID: E25698A930586171
4 changed files with 43 additions and 5 deletions

View file

@ -29,8 +29,9 @@ use crate::{
builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint},
db::DefDatabase,
expr::{
dummy_expr_id, Array, BindingAnnotation, Expr, ExprId, FloatTypeWrapper, Label, LabelId,
Literal, MatchArm, Pat, PatId, RecordFieldPat, RecordLitField, Statement,
dummy_expr_id, Array, BindingAnnotation, ClosureKind, Expr, ExprId, FloatTypeWrapper,
Label, LabelId, Literal, MatchArm, Movability, Pat, PatId, RecordFieldPat, RecordLitField,
Statement,
},
intern::Interned,
item_scope::BuiltinShadowMode,
@ -97,6 +98,7 @@ pub(super) fn lower(
name_to_pat_grouping: Default::default(),
is_lowering_inside_or_pat: false,
is_lowering_assignee_expr: false,
is_lowering_generator: false,
}
.collect(params, body)
}
@ -111,6 +113,7 @@ struct ExprCollector<'a> {
name_to_pat_grouping: FxHashMap<Name, Vec<PatId>>,
is_lowering_inside_or_pat: bool,
is_lowering_assignee_expr: bool,
is_lowering_generator: bool,
}
impl ExprCollector<'_> {
@ -358,6 +361,7 @@ impl ExprCollector<'_> {
self.alloc_expr(Expr::Return { expr }, syntax_ptr)
}
ast::Expr::YieldExpr(e) => {
self.is_lowering_generator = true;
let expr = e.expr().map(|e| self.collect_expr(e));
self.alloc_expr(Expr::Yield { expr }, syntax_ptr)
}
@ -459,13 +463,31 @@ impl ExprCollector<'_> {
.ret_type()
.and_then(|r| r.ty())
.map(|it| Interned::new(TypeRef::from_ast(&self.ctx(), it)));
let prev_is_lowering_generator = self.is_lowering_generator;
self.is_lowering_generator = false;
let body = self.collect_expr_opt(e.body());
let closure_kind = if self.is_lowering_generator {
let movability = if e.static_token().is_some() {
Movability::Static
} else {
Movability::Movable
};
ClosureKind::Generator(movability)
} else {
ClosureKind::Closure
};
self.is_lowering_generator = prev_is_lowering_generator;
self.alloc_expr(
Expr::Closure {
args: args.into(),
arg_types: arg_types.into(),
ret_type,
body,
closure_kind,
},
syntax_ptr,
)

View file

@ -3,7 +3,7 @@
use std::fmt::{self, Write};
use crate::{
expr::{Array, BindingAnnotation, Literal, Statement},
expr::{Array, BindingAnnotation, ClosureKind, Literal, Movability, Statement},
pretty::{print_generic_args, print_path, print_type_ref},
type_ref::TypeRef,
};
@ -350,7 +350,10 @@ impl<'a> Printer<'a> {
self.print_expr(*index);
w!(self, "]");
}
Expr::Closure { args, arg_types, ret_type, body } => {
Expr::Closure { args, arg_types, ret_type, body, closure_kind } => {
if let ClosureKind::Generator(Movability::Static) = closure_kind {
w!(self, "static ");
}
w!(self, "|");
for (i, (pat, ty)) in args.iter().zip(arg_types.iter()).enumerate() {
if i != 0 {

View file

@ -198,6 +198,7 @@ pub enum Expr {
arg_types: Box<[Option<Interned<TypeRef>>]>,
ret_type: Option<Interned<TypeRef>>,
body: ExprId,
closure_kind: ClosureKind,
},
Tuple {
exprs: Box<[ExprId]>,
@ -211,6 +212,18 @@ pub enum Expr {
Underscore,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ClosureKind {
Closure,
Generator(Movability),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Movability {
Static,
Movable,
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum Array {
ElementList { elements: Box<[ExprId]>, is_assignee_expr: bool },

View file

@ -216,7 +216,7 @@ impl<'a> InferenceContext<'a> {
self.diverges = Diverges::Maybe;
TyBuilder::unit()
}
Expr::Closure { body, args, ret_type, arg_types } => {
Expr::Closure { body, args, ret_type, arg_types, closure_kind: _ } => {
assert_eq!(args.len(), arg_types.len());
let mut sig_tys = Vec::new();