aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/expr.rs
diff options
context:
space:
mode:
authorMarcus Klaas de Vries <[email protected]>2019-01-10 12:54:58 +0000
committerMarcus Klaas de Vries <[email protected]>2019-01-14 12:52:55 +0000
commita6146d35b1615cf5fb908b29f34e58bfde3bf96d (patch)
tree70613ee98eee67c1df6aff1e663be75a33c348f4 /crates/ra_hir/src/expr.rs
parent8caff4e03475c20392f13e8c6ad469bd01a4b4ce (diff)
Implement type inference for literals (WIP)
Diffstat (limited to 'crates/ra_hir/src/expr.rs')
-rw-r--r--crates/ra_hir/src/expr.rs78
1 files changed, 76 insertions, 2 deletions
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs
index f0936e9f3..e07725d05 100644
--- a/crates/ra_hir/src/expr.rs
+++ b/crates/ra_hir/src/expr.rs
@@ -5,7 +5,10 @@ use rustc_hash::FxHashMap;
5 5
6use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; 6use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap};
7use ra_db::{LocalSyntaxPtr, Cancelable}; 7use ra_db::{LocalSyntaxPtr, Cancelable};
8use ra_syntax::ast::{self, AstNode, LoopBodyOwner, ArgListOwner, NameOwner}; 8use ra_syntax::{
9 SyntaxKind,
10 ast::{self, AstNode, LoopBodyOwner, ArgListOwner, NameOwner}
11};
9 12
10use crate::{Path, type_ref::{Mutability, TypeRef}, Name, HirDatabase, DefId, Def, name::AsName}; 13use crate::{Path, type_ref::{Mutability, TypeRef}, Name, HirDatabase, DefId, Def, name::AsName};
11 14
@@ -104,6 +107,19 @@ impl BodySyntaxMapping {
104} 107}
105 108
106#[derive(Debug, Clone, Eq, PartialEq)] 109#[derive(Debug, Clone, Eq, PartialEq)]
110pub enum Literal {
111 String(String),
112 ByteString(Vec<u8>),
113 Char(char),
114 Bool(bool),
115 Byte(u8),
116 Int, // this and float need additional information
117 Float,
118 Tuple { values: Vec<ExprId> },
119 Array { values: Vec<ExprId> },
120}
121
122#[derive(Debug, Clone, Eq, PartialEq)]
107pub enum Expr { 123pub enum Expr {
108 /// This is produced if syntax tree does not have a required expression piece. 124 /// This is produced if syntax tree does not have a required expression piece.
109 Missing, 125 Missing,
@@ -186,6 +202,7 @@ pub enum Expr {
186 Tuple { 202 Tuple {
187 exprs: Vec<ExprId>, 203 exprs: Vec<ExprId>,
188 }, 204 },
205 Literal(Literal),
189} 206}
190 207
191pub use ra_syntax::ast::PrefixOp as UnaryOp; 208pub use ra_syntax::ast::PrefixOp as UnaryOp;
@@ -305,6 +322,20 @@ impl Expr {
305 f(*expr); 322 f(*expr);
306 } 323 }
307 } 324 }
325 Expr::Literal(l) => match l {
326 Literal::Array { values } | Literal::Tuple { values } => {
327 for &val in values {
328 f(val);
329 }
330 }
331 Literal::String(..)
332 | Literal::ByteString(..)
333 | Literal::Byte(..)
334 | Literal::Bool(..)
335 | Literal::Char(..)
336 | Literal::Int
337 | Literal::Float => {}
338 },
308 } 339 }
309 } 340 }
310} 341}
@@ -633,13 +664,56 @@ impl ExprCollector {
633 let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect(); 664 let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect();
634 self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr) 665 self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr)
635 } 666 }
667 ast::ExprKind::Literal(e) => {
668 let child = e.syntax().children().next();
669
670 if let Some(c) = child {
671 let lit = match c.kind() {
672 SyntaxKind::INT_NUMBER => Literal::Int,
673 SyntaxKind::FLOAT_NUMBER => Literal::Float,
674 SyntaxKind::STRING => {
675 // FIXME: this likely includes the " characters
676 let text = c.text().to_string();
677 Literal::String(text)
678 }
679 SyntaxKind::ARRAY_EXPR => {
680 // TODO: recursively call to self
681 Literal::Array { values: vec![] }
682 }
683 SyntaxKind::PAREN_EXPR => {
684 // TODO: recursively call to self
685 Literal::Tuple { values: vec![] }
686 }
687 SyntaxKind::TRUE_KW => Literal::Bool(true),
688 SyntaxKind::FALSE_KW => Literal::Bool(false),
689 SyntaxKind::BYTE_STRING => {
690 // FIXME: this is completely incorrect for a variety
691 // of reasons, but at least it gives the right type
692 let bytes = c.text().to_string().into_bytes();
693 Literal::ByteString(bytes)
694 }
695 SyntaxKind::CHAR => {
696 let character = c.text().char_at(1).unwrap_or('X');
697 Literal::Char(character)
698 }
699 SyntaxKind::BYTE => {
700 let character = c.text().char_at(1).unwrap_or('X');
701 Literal::Byte(character as u8)
702 }
703 _ => return self.alloc_expr(Expr::Missing, syntax_ptr),
704 };
705
706 self.alloc_expr(Expr::Literal(lit), syntax_ptr)
707 } else {
708 self.alloc_expr(Expr::Missing, syntax_ptr)
709 }
710 }
636 711
637 // TODO implement HIR for these: 712 // TODO implement HIR for these:
638 ast::ExprKind::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), 713 ast::ExprKind::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
639 ast::ExprKind::IndexExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), 714 ast::ExprKind::IndexExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
640 ast::ExprKind::ArrayExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), 715 ast::ExprKind::ArrayExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
641 ast::ExprKind::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), 716 ast::ExprKind::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
642 ast::ExprKind::Literal(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
643 } 717 }
644 } 718 }
645 719