diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-04-01 12:22:31 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-04-01 12:22:31 +0100 |
commit | 67351a011bbaf63617c7fc96884129e9fc39e411 (patch) | |
tree | 6b1fd4e64965edb1de5f18894537d812b13fc73a /crates | |
parent | d03d638cc3803a4994cef01b889cd1eaf20e7e01 (diff) | |
parent | a9d0c9b2a4601835d1dd480b711c5d26f9c97430 (diff) |
Merge #3805
3805: lower literal patterns r=JoshMcguigan a=JoshMcguigan
While working on #3706 I discovered literal patterns weren't being lowered. This PR implements that lowering.
Questions for reviewers:
1. This re-uses the existing conversion from `ast::LiteralKind` to `Literal`, but `ast::LiteralKind` doesn't include information about the actual value of the literal, which causes `Literal` to be created with the default value for the type (rather than the actual value in the source code). Am I correct in thinking that we'd eventually want to change things in such a way that we could initialize the `Literal` with the actual literal value? Is there an existing issue for this, or else perhaps I should create one to discuss how it should be implemented? My main question would be whether `ast::LiteralKind` should be extended to hold the actual value, or if we should provide some other way to get that information from `ast::Literal`?
2. I couldn't find tests which directly cover this, but it does seem to work in #3706. Do we have unit tests for this lowering code?
3. I'm not sure why `lit.literal()` returns an `Option`. Is returning a `Pat::Missing` in the `None` case the right thing to do?
4. I was basically practicing type-system driven development to figure out the transformation from `ast::Pat::LiteralPat` to `Pat::Lit`. I don't have an immediate question here, but I just wanted to ensure this section is looked at closely during review.
Co-authored-by: Josh Mcguigan <[email protected]>
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_hir_def/src/body/lower.rs | 54 |
1 files changed, 33 insertions, 21 deletions
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index e8443dde8..7b809cf4f 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs | |||
@@ -417,26 +417,7 @@ impl ExprCollector<'_> { | |||
417 | } | 417 | } |
418 | } | 418 | } |
419 | 419 | ||
420 | ast::Expr::Literal(e) => { | 420 | ast::Expr::Literal(e) => self.alloc_expr(Expr::Literal(e.kind().into()), syntax_ptr), |
421 | let lit = match e.kind() { | ||
422 | LiteralKind::IntNumber { suffix } => { | ||
423 | let known_name = suffix.and_then(|it| BuiltinInt::from_suffix(&it)); | ||
424 | |||
425 | Literal::Int(Default::default(), known_name) | ||
426 | } | ||
427 | LiteralKind::FloatNumber { suffix } => { | ||
428 | let known_name = suffix.and_then(|it| BuiltinFloat::from_suffix(&it)); | ||
429 | |||
430 | Literal::Float(Default::default(), known_name) | ||
431 | } | ||
432 | LiteralKind::ByteString => Literal::ByteString(Default::default()), | ||
433 | LiteralKind::String => Literal::String(Default::default()), | ||
434 | LiteralKind::Byte => Literal::Int(Default::default(), Some(BuiltinInt::U8)), | ||
435 | LiteralKind::Bool => Literal::Bool(Default::default()), | ||
436 | LiteralKind::Char => Literal::Char(Default::default()), | ||
437 | }; | ||
438 | self.alloc_expr(Expr::Literal(lit), syntax_ptr) | ||
439 | } | ||
440 | ast::Expr::IndexExpr(e) => { | 421 | ast::Expr::IndexExpr(e) => { |
441 | let base = self.collect_expr_opt(e.base()); | 422 | let base = self.collect_expr_opt(e.base()); |
442 | let index = self.collect_expr_opt(e.index()); | 423 | let index = self.collect_expr_opt(e.index()); |
@@ -679,10 +660,19 @@ impl ExprCollector<'_> { | |||
679 | suffix: suffix.into_iter().map(|p| self.collect_pat(p)).collect(), | 660 | suffix: suffix.into_iter().map(|p| self.collect_pat(p)).collect(), |
680 | } | 661 | } |
681 | } | 662 | } |
663 | ast::Pat::LiteralPat(lit) => { | ||
664 | if let Some(ast_lit) = lit.literal() { | ||
665 | let expr = Expr::Literal(ast_lit.kind().into()); | ||
666 | let expr_ptr = AstPtr::new(&ast::Expr::Literal(ast_lit)); | ||
667 | let expr_id = self.alloc_expr(expr, expr_ptr); | ||
668 | Pat::Lit(expr_id) | ||
669 | } else { | ||
670 | Pat::Missing | ||
671 | } | ||
672 | } | ||
682 | 673 | ||
683 | // FIXME: implement | 674 | // FIXME: implement |
684 | ast::Pat::BoxPat(_) => Pat::Missing, | 675 | ast::Pat::BoxPat(_) => Pat::Missing, |
685 | ast::Pat::LiteralPat(_) => Pat::Missing, | ||
686 | ast::Pat::RangePat(_) => Pat::Missing, | 676 | ast::Pat::RangePat(_) => Pat::Missing, |
687 | }; | 677 | }; |
688 | let ptr = AstPtr::new(&pat); | 678 | let ptr = AstPtr::new(&pat); |
@@ -741,3 +731,25 @@ impl From<ast::BinOp> for BinaryOp { | |||
741 | } | 731 | } |
742 | } | 732 | } |
743 | } | 733 | } |
734 | |||
735 | impl From<ast::LiteralKind> for Literal { | ||
736 | fn from(ast_lit_kind: ast::LiteralKind) -> Self { | ||
737 | match ast_lit_kind { | ||
738 | LiteralKind::IntNumber { suffix } => { | ||
739 | let known_name = suffix.and_then(|it| BuiltinInt::from_suffix(&it)); | ||
740 | |||
741 | Literal::Int(Default::default(), known_name) | ||
742 | } | ||
743 | LiteralKind::FloatNumber { suffix } => { | ||
744 | let known_name = suffix.and_then(|it| BuiltinFloat::from_suffix(&it)); | ||
745 | |||
746 | Literal::Float(Default::default(), known_name) | ||
747 | } | ||
748 | LiteralKind::ByteString => Literal::ByteString(Default::default()), | ||
749 | LiteralKind::String => Literal::String(Default::default()), | ||
750 | LiteralKind::Byte => Literal::Int(Default::default(), Some(BuiltinInt::U8)), | ||
751 | LiteralKind::Bool => Literal::Bool(Default::default()), | ||
752 | LiteralKind::Char => Literal::Char(Default::default()), | ||
753 | } | ||
754 | } | ||
755 | } | ||