aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/expr.rs
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-01-14 20:58:20 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-01-14 20:58:20 +0000
commite8e82ce032f8678929b015e6f70ac060bb2cf94c (patch)
tree9fb158e9f7115bb70cf2b8623b70710c55497ed4 /crates/ra_hir/src/expr.rs
parent784ff638e549a27503b719e5c2f0009b40d25364 (diff)
parent37ba237e6686d94783d1f025d23823ad7c0cb0c8 (diff)
Merge #485
485: Add type inference for a bunch of primitives r=flodiebold a=marcusklaas This PR adds inference for `&str`, `&[u8]`, `char`, `bool`, floats and integers. For floats and integers it uses type variables to infer the exact type, i.e. `u32`, from context when it's not annotated explicitly. I'm not quite happy with the implementation yet, but I think it mostly works now. Co-authored-by: Marcus Klaas de Vries <[email protected]>
Diffstat (limited to 'crates/ra_hir/src/expr.rs')
-rw-r--r--crates/ra_hir/src/expr.rs56
1 files changed, 54 insertions, 2 deletions
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs
index f0936e9f3..5081466a2 100644
--- a/crates/ra_hir/src/expr.rs
+++ b/crates/ra_hir/src/expr.rs
@@ -5,9 +5,12 @@ 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 ast::{self, AstNode, LoopBodyOwner, ArgListOwner, NameOwner, LiteralFlavor}
10};
9 11
10use crate::{Path, type_ref::{Mutability, TypeRef}, Name, HirDatabase, DefId, Def, name::AsName}; 12use crate::{Path, type_ref::{Mutability, TypeRef}, Name, HirDatabase, DefId, Def, name::AsName};
13use crate::ty::primitive::{UintTy, UncertainIntTy, UncertainFloatTy};
11 14
12#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] 15#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
13pub struct ExprId(RawId); 16pub struct ExprId(RawId);
@@ -104,6 +107,16 @@ 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 Int(u64, UncertainIntTy),
116 Float(u64, UncertainFloatTy), // FIXME: f64 is not Eq
117}
118
119#[derive(Debug, Clone, Eq, PartialEq)]
107pub enum Expr { 120pub enum Expr {
108 /// This is produced if syntax tree does not have a required expression piece. 121 /// This is produced if syntax tree does not have a required expression piece.
109 Missing, 122 Missing,
@@ -186,6 +199,7 @@ pub enum Expr {
186 Tuple { 199 Tuple {
187 exprs: Vec<ExprId>, 200 exprs: Vec<ExprId>,
188 }, 201 },
202 Literal(Literal),
189} 203}
190 204
191pub use ra_syntax::ast::PrefixOp as UnaryOp; 205pub use ra_syntax::ast::PrefixOp as UnaryOp;
@@ -305,6 +319,7 @@ impl Expr {
305 f(*expr); 319 f(*expr);
306 } 320 }
307 } 321 }
322 Expr::Literal(_) => {}
308 } 323 }
309 } 324 }
310} 325}
@@ -633,13 +648,50 @@ impl ExprCollector {
633 let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect(); 648 let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect();
634 self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr) 649 self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr)
635 } 650 }
651 ast::ExprKind::Literal(e) => {
652 let child = if let Some(child) = e.literal_expr() {
653 child
654 } else {
655 return self.alloc_expr(Expr::Missing, syntax_ptr);
656 };
657
658 let lit = match child.flavor() {
659 LiteralFlavor::IntNumber { suffix } => {
660 let known_name = suffix
661 .map(|s| Name::new(s))
662 .and_then(|name| UncertainIntTy::from_name(&name));
663
664 Literal::Int(
665 Default::default(),
666 known_name.unwrap_or(UncertainIntTy::Unknown),
667 )
668 }
669 LiteralFlavor::FloatNumber { suffix } => {
670 let known_name = suffix
671 .map(|s| Name::new(s))
672 .and_then(|name| UncertainFloatTy::from_name(&name));
673
674 Literal::Float(
675 Default::default(),
676 known_name.unwrap_or(UncertainFloatTy::Unknown),
677 )
678 }
679 LiteralFlavor::ByteString => Literal::ByteString(Default::default()),
680 LiteralFlavor::String => Literal::String(Default::default()),
681 LiteralFlavor::Byte => {
682 Literal::Int(Default::default(), UncertainIntTy::Unsigned(UintTy::U8))
683 }
684 LiteralFlavor::Bool => Literal::Bool(Default::default()),
685 LiteralFlavor::Char => Literal::Char(Default::default()),
686 };
687 self.alloc_expr(Expr::Literal(lit), syntax_ptr)
688 }
636 689
637 // TODO implement HIR for these: 690 // TODO implement HIR for these:
638 ast::ExprKind::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), 691 ast::ExprKind::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
639 ast::ExprKind::IndexExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), 692 ast::ExprKind::IndexExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
640 ast::ExprKind::ArrayExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), 693 ast::ExprKind::ArrayExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
641 ast::ExprKind::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), 694 ast::ExprKind::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
642 ast::ExprKind::Literal(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
643 } 695 }
644 } 696 }
645 697