implement while let desugaring

This commit is contained in:
Aleksey Kladov 2019-08-07 15:14:22 +02:00
parent 39967a85e1
commit 6efc79b89d
4 changed files with 76 additions and 21 deletions

View file

@ -11,17 +11,16 @@ use ra_syntax::{
},
AstNode, AstPtr, SyntaxNodePtr,
};
use test_utils::tested_by;
use crate::{
name::{AsName, SELF_PARAM},
path::GenericArgs,
ty::primitive::{FloatTy, IntTy, UncertainFloatTy, UncertainIntTy},
type_ref::{Mutability, TypeRef},
DefWithBody, Either, HasSource, HirDatabase, HirFileId, MacroCallLoc, MacroFileKind, Name,
Path, Resolver,
};
use crate::{
path::GenericArgs,
ty::primitive::{FloatTy, IntTy, UncertainFloatTy, UncertainIntTy},
};
pub use self::scope::ExprScopes;
@ -603,17 +602,30 @@ where
self.alloc_expr(Expr::Loop { body }, syntax_ptr)
}
ast::ExprKind::WhileExpr(e) => {
let condition = if let Some(condition) = e.condition() {
if condition.pat().is_none() {
self.collect_expr_opt(condition.expr())
} else {
// FIXME handle while let
return self.alloc_expr(Expr::Missing, syntax_ptr);
}
} else {
self.exprs.alloc(Expr::Missing)
};
let body = self.collect_block_opt(e.loop_body());
let condition = match e.condition() {
None => self.exprs.alloc(Expr::Missing),
Some(condition) => match condition.pat() {
None => self.collect_expr_opt(condition.expr()),
// if let -- desugar to match
Some(pat) => {
tested_by!(infer_while_let);
let pat = self.collect_pat(pat);
let match_expr = self.collect_expr_opt(condition.expr());
let placeholder_pat = self.pats.alloc(Pat::Missing);
let break_ = self.exprs.alloc(Expr::Break { expr: None });
let arms = vec![
MatchArm { pats: vec![pat], expr: body, guard: None },
MatchArm { pats: vec![placeholder_pat], expr: break_, guard: None },
];
let match_expr =
self.exprs.alloc(Expr::Match { expr: match_expr, arms });
return self.alloc_expr(Expr::Loop { body: match_expr }, syntax_ptr);
}
},
};
self.alloc_expr(Expr::While { condition, body }, syntax_ptr)
}
ast::ExprKind::ForExpr(e) => {