aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/expr.rs141
-rw-r--r--crates/ra_hir/src/name.rs2
-rw-r--r--crates/ra_hir/src/ty.rs46
-rw-r--r--crates/ra_hir/src/ty/tests.rs5
-rw-r--r--crates/ra_hir/src/ty/tests/data/binary_op.txt86
-rw-r--r--crates/ra_hir/src/ty/tests/data/literals.txt3
-rw-r--r--crates/ra_hir/src/ty/tests/data/tuple.txt18
-rw-r--r--crates/ra_syntax/src/ast.rs46
-rw-r--r--crates/ra_syntax/src/ast/generated.rs132
-rw-r--r--crates/ra_syntax/src/grammar.ron11
-rw-r--r--crates/ra_syntax/src/lib.rs2
-rw-r--r--crates/ra_syntax/src/syntax_kinds/generated.rs2
12 files changed, 283 insertions, 211 deletions
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs
index 3f2689781..2f3432870 100644
--- a/crates/ra_hir/src/expr.rs
+++ b/crates/ra_hir/src/expr.rs
@@ -6,12 +6,11 @@ use rustc_hash::FxHashMap;
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::{ 8use ra_syntax::{
9 SyntaxKind, 9 ast::{self, AstNode, LoopBodyOwner, ArgListOwner, NameOwner, LiteralFlavor}
10 ast::{self, AstNode, LoopBodyOwner, ArgListOwner, NameOwner}
11}; 10};
12 11
13use 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};
14use crate::ty::primitive::{UintTy, IntTy, FloatTy, UncertainIntTy, UncertainFloatTy}; 13use crate::ty::primitive::{UintTy, UncertainIntTy, UncertainFloatTy};
15 14
16#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] 15#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
17pub struct ExprId(RawId); 16pub struct ExprId(RawId);
@@ -649,93 +648,59 @@ impl ExprCollector {
649 let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect(); 648 let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect();
650 self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr) 649 self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr)
651 } 650 }
652 ast::ExprKind::LiteralExpr(e) => { 651 ast::ExprKind::Literal(e) => {
653 if let Some(child) = e.literal() { 652 let child = if let Some(child) = e.literal_expr() {
654 let c = child.syntax(); 653 child
655 let lit = match c.kind() { 654 } else {
656 SyntaxKind::INT_NUMBER => { 655 return self.alloc_expr(Expr::Missing, syntax_ptr);
657 let text = c.text().to_string(); 656 };
658 657 let c = child.syntax();
659 // FIXME: don't do it like this. maybe use something like 658
660 // the IntTy::from_name functions 659 let lit = match child.flavor() {
661 let ty = if text.ends_with("isize") { 660 LiteralFlavor::IntNumber { suffix } => {
662 UncertainIntTy::Signed(IntTy::Isize) 661 let known_name = suffix
663 } else if text.ends_with("i128") { 662 .map(|s| Name::new(s))
664 UncertainIntTy::Signed(IntTy::I128) 663 .and_then(|name| UncertainIntTy::from_name(&name));
665 } else if text.ends_with("i64") { 664
666 UncertainIntTy::Signed(IntTy::I64) 665 if let Some(kn) = known_name {
667 } else if text.ends_with("i32") { 666 Literal::Int(0u64, kn)
668 UncertainIntTy::Signed(IntTy::I32) 667 } else {
669 } else if text.ends_with("i16") { 668 Literal::Int(0u64, UncertainIntTy::Unknown)
670 UncertainIntTy::Signed(IntTy::I16)
671 } else if text.ends_with("i8") {
672 UncertainIntTy::Signed(IntTy::I8)
673 } else if text.ends_with("usize") {
674 UncertainIntTy::Unsigned(UintTy::Usize)
675 } else if text.ends_with("u128") {
676 UncertainIntTy::Unsigned(UintTy::U128)
677 } else if text.ends_with("u64") {
678 UncertainIntTy::Unsigned(UintTy::U64)
679 } else if text.ends_with("u32") {
680 UncertainIntTy::Unsigned(UintTy::U32)
681 } else if text.ends_with("u16") {
682 UncertainIntTy::Unsigned(UintTy::U16)
683 } else if text.ends_with("u8") {
684 UncertainIntTy::Unsigned(UintTy::U8)
685 } else {
686 UncertainIntTy::Unknown
687 };
688
689 // TODO: actually parse integer
690 Literal::Int(0u64, ty)
691 }
692 SyntaxKind::FLOAT_NUMBER => {
693 let text = c.text().to_string();
694
695 // FIXME: don't do it like this. maybe use something like
696 // the IntTy::from_name functions
697 let ty = if text.ends_with("f64") {
698 UncertainFloatTy::Known(FloatTy::F64)
699 } else if text.ends_with("f32") {
700 UncertainFloatTy::Known(FloatTy::F32)
701 } else {
702 UncertainFloatTy::Unknown
703 };
704
705 // TODO: actually parse value
706 Literal::Float(0, ty)
707 }
708 SyntaxKind::STRING => {
709 // FIXME: this likely includes the " characters
710 let text = c.text().to_string();
711 Literal::String(text)
712 }
713 SyntaxKind::TRUE_KW => Literal::Bool(true),
714 SyntaxKind::FALSE_KW => Literal::Bool(false),
715 SyntaxKind::BYTE_STRING => {
716 // FIXME: this is completely incorrect for a variety
717 // of reasons, but at least it gives the right type
718 let bytes = c.text().to_string().into_bytes();
719 Literal::ByteString(bytes)
720 }
721 SyntaxKind::CHAR => {
722 let character = c.text().char_at(1).unwrap_or('X');
723 Literal::Char(character)
724 } 669 }
725 SyntaxKind::BYTE => { 670 }
726 let character = c.text().char_at(1).unwrap_or('X'); 671 LiteralFlavor::FloatNumber { suffix } => {
727 Literal::Int( 672 let known_name = suffix
728 character as u8 as u64, 673 .map(|s| Name::new(s))
729 UncertainIntTy::Unsigned(UintTy::U8), 674 .and_then(|name| UncertainFloatTy::from_name(&name));
730 ) 675
676 if let Some(kn) = known_name {
677 Literal::Float(0u64, kn)
678 } else {
679 Literal::Float(0u64, UncertainFloatTy::Unknown)
731 } 680 }
732 _ => return self.alloc_expr(Expr::Missing, syntax_ptr), 681 }
733 }; 682 LiteralFlavor::ByteString => {
734 683 // FIXME: this is completely incorrect for a variety
735 self.alloc_expr(Expr::Literal(lit), syntax_ptr) 684 // of reasons, but at least it gives the right type
736 } else { 685 let bytes = c.text().to_string().into_bytes();
737 self.alloc_expr(Expr::Missing, syntax_ptr) 686 Literal::ByteString(bytes)
738 } 687 }
688 LiteralFlavor::String => {
689 // FIXME: this likely includes the " characters
690 let text = c.text().to_string();
691 Literal::String(text)
692 }
693 LiteralFlavor::Byte => {
694 let character = c.text().char_at(1).unwrap_or('X');
695 Literal::Int(character as u8 as u64, UncertainIntTy::Unsigned(UintTy::U8))
696 }
697 LiteralFlavor::Bool => Literal::Bool(true),
698 LiteralFlavor::Char => {
699 let character = c.text().char_at(1).unwrap_or('X');
700 Literal::Char(character)
701 }
702 };
703 self.alloc_expr(Expr::Literal(lit), syntax_ptr)
739 } 704 }
740 705
741 // TODO implement HIR for these: 706 // TODO implement HIR for these:
diff --git a/crates/ra_hir/src/name.rs b/crates/ra_hir/src/name.rs
index d9683549c..8d786d2ac 100644
--- a/crates/ra_hir/src/name.rs
+++ b/crates/ra_hir/src/name.rs
@@ -23,7 +23,7 @@ impl fmt::Debug for Name {
23} 23}
24 24
25impl Name { 25impl Name {
26 fn new(text: SmolStr) -> Name { 26 pub(crate) fn new(text: SmolStr) -> Name {
27 Name { text } 27 Name { text }
28 } 28 }
29 29
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index de5ec5b46..b6577ee5e 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -111,7 +111,7 @@ impl UnifyValue for TypeVarValue {
111/// values for general types, and for integer and float variables. The latter 111/// values for general types, and for integer and float variables. The latter
112/// two are used for inference of literal values (e.g. `100` could be one of 112/// two are used for inference of literal values (e.g. `100` could be one of
113/// several integer types). 113/// several integer types).
114#[derive(Clone, PartialEq, Eq, Hash, Debug)] 114#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
115pub enum InferTy { 115pub enum InferTy {
116 TypeVar(TypeVarId), 116 TypeVar(TypeVarId),
117 IntVar(TypeVarId), 117 IntVar(TypeVarId),
@@ -119,6 +119,12 @@ pub enum InferTy {
119} 119}
120 120
121impl InferTy { 121impl InferTy {
122 fn to_inner(self) -> TypeVarId {
123 match self {
124 InferTy::TypeVar(ty) | InferTy::IntVar(ty) | InferTy::FloatVar(ty) => ty,
125 }
126 }
127
122 fn fallback_value(self) -> Ty { 128 fn fallback_value(self) -> Ty {
123 match self { 129 match self {
124 InferTy::TypeVar(..) => Ty::Unknown, 130 InferTy::TypeVar(..) => Ty::Unknown,
@@ -326,18 +332,19 @@ impl Ty {
326 path: &Path, 332 path: &Path,
327 ) -> Cancelable<Self> { 333 ) -> Cancelable<Self> {
328 if let Some(name) = path.as_ident() { 334 if let Some(name) = path.as_ident() {
329 if let Some(KnownName::Bool) = name.as_known_name() { 335 if let Some(int_ty) = primitive::UncertainIntTy::from_name(name) {
330 return Ok(Ty::Bool);
331 } else if let Some(KnownName::Char) = name.as_known_name() {
332 return Ok(Ty::Char);
333 } else if let Some(KnownName::Str) = name.as_known_name() {
334 return Ok(Ty::Str);
335 } else if let Some(int_ty) = primitive::UncertainIntTy::from_name(name) {
336 return Ok(Ty::Int(int_ty)); 336 return Ok(Ty::Int(int_ty));
337 } else if let Some(float_ty) = primitive::UncertainFloatTy::from_name(name) { 337 } else if let Some(float_ty) = primitive::UncertainFloatTy::from_name(name) {
338 return Ok(Ty::Float(float_ty)); 338 return Ok(Ty::Float(float_ty));
339 } else if name.as_known_name() == Some(KnownName::SelfType) { 339 } else if name.as_known_name() == Some(KnownName::SelfType) {
340 return Ty::from_hir_opt(db, module, None, impl_block.map(|i| i.target_type())); 340 return Ty::from_hir_opt(db, module, None, impl_block.map(|i| i.target_type()));
341 } else if let Some(known) = name.as_known_name() {
342 match known {
343 KnownName::Bool => return Ok(Ty::Bool),
344 KnownName::Char => return Ok(Ty::Char),
345 KnownName::Str => return Ok(Ty::Str),
346 _ => {}
347 }
341 } 348 }
342 } 349 }
343 350
@@ -793,10 +800,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
793 /// known type. 800 /// known type.
794 fn resolve_ty_as_possible(&mut self, ty: Ty) -> Ty { 801 fn resolve_ty_as_possible(&mut self, ty: Ty) -> Ty {
795 ty.fold(&mut |ty| match ty { 802 ty.fold(&mut |ty| match ty {
796 Ty::Infer(InferTy::TypeVar(tv)) 803 Ty::Infer(tv) => {
797 | Ty::Infer(InferTy::IntVar(tv)) 804 let inner = tv.to_inner();
798 | Ty::Infer(InferTy::FloatVar(tv)) => { 805 if let Some(known_ty) = self.var_unification_table.probe_value(inner).known() {
799 if let Some(known_ty) = self.var_unification_table.probe_value(tv).known() {
800 // known_ty may contain other variables that are known by now 806 // known_ty may contain other variables that are known by now
801 self.resolve_ty_as_possible(known_ty.clone()) 807 self.resolve_ty_as_possible(known_ty.clone())
802 } else { 808 } else {
@@ -811,8 +817,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
811 /// otherwise, return ty. 817 /// otherwise, return ty.
812 fn resolve_ty_shallow<'b>(&mut self, ty: &'b Ty) -> Cow<'b, Ty> { 818 fn resolve_ty_shallow<'b>(&mut self, ty: &'b Ty) -> Cow<'b, Ty> {
813 match ty { 819 match ty {
814 Ty::Infer(InferTy::TypeVar(tv)) => { 820 Ty::Infer(tv) => {
815 match self.var_unification_table.probe_value(*tv).known() { 821 let inner = tv.to_inner();
822 match self.var_unification_table.probe_value(inner).known() {
816 Some(known_ty) => { 823 Some(known_ty) => {
817 // The known_ty can't be a type var itself 824 // The known_ty can't be a type var itself
818 Cow::Owned(known_ty.clone()) 825 Cow::Owned(known_ty.clone())
@@ -828,16 +835,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
828 /// replaced by Ty::Unknown. 835 /// replaced by Ty::Unknown.
829 fn resolve_ty_completely(&mut self, ty: Ty) -> Ty { 836 fn resolve_ty_completely(&mut self, ty: Ty) -> Ty {
830 ty.fold(&mut |ty| match ty { 837 ty.fold(&mut |ty| match ty {
831 Ty::Infer(i) => { 838 Ty::Infer(tv) => {
832 let tv = match i { 839 let inner = tv.to_inner();
833 InferTy::TypeVar(tv) | InferTy::IntVar(tv) | InferTy::FloatVar(tv) => tv, 840 if let Some(known_ty) = self.var_unification_table.probe_value(inner).known() {
834 };
835
836 if let Some(known_ty) = self.var_unification_table.probe_value(tv).known() {
837 // known_ty may contain other variables that are known by now 841 // known_ty may contain other variables that are known by now
838 self.resolve_ty_completely(known_ty.clone()) 842 self.resolve_ty_completely(known_ty.clone())
839 } else { 843 } else {
840 i.fallback_value() 844 tv.fallback_value()
841 } 845 }
842 } 846 }
843 _ => ty, 847 _ => ty,
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs
index 53ea99874..cbdb2a4b7 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir/src/ty/tests.rs
@@ -145,6 +145,7 @@ fn test() {
145 3.14; 145 3.14;
146 5000; 146 5000;
147 false; 147 false;
148 true;
148} 149}
149"#, 150"#,
150 "literals.txt", 151 "literals.txt",
@@ -199,7 +200,7 @@ fn f(x: bool) -> i32 {
199 0i32 200 0i32
200} 201}
201 202
202fn test() { 203fn test() -> bool {
203 let x = a && b; 204 let x = a && b;
204 let y = true || false; 205 let y = true || false;
205 let z = x == y; 206 let z = x == y;
@@ -296,8 +297,6 @@ fn test(x: &str, y: isize) {
296 let b = (a, x); 297 let b = (a, x);
297 let c = (y, x); 298 let c = (y, x);
298 let d = (c, x); 299 let d = (c, x);
299
300 // we have not infered these case yet.
301 let e = (1, "e"); 300 let e = (1, "e");
302 let f = (e, "d"); 301 let f = (e, "d");
303} 302}
diff --git a/crates/ra_hir/src/ty/tests/data/binary_op.txt b/crates/ra_hir/src/ty/tests/data/binary_op.txt
index 7fdb8a900..58a727691 100644
--- a/crates/ra_hir/src/ty/tests/data/binary_op.txt
+++ b/crates/ra_hir/src/ty/tests/data/binary_op.txt
@@ -1,46 +1,46 @@
1[6; 7) 'x': bool 1[6; 7) 'x': bool
2[22; 34) '{ 0i32 }': i32 2[22; 34) '{ 0i32 }': i32
3[28; 32) '0i32': i32 3[28; 32) '0i32': i32
4[46; 342) '{ ... < 3 }': bool 4[54; 350) '{ ... < 3 }': bool
5[56; 57) 'x': bool 5[64; 65) 'x': bool
6[60; 61) 'a': bool 6[68; 69) 'a': bool
7[60; 66) 'a && b': bool 7[68; 74) 'a && b': bool
8[65; 66) 'b': bool 8[73; 74) 'b': bool
9[76; 77) 'y': bool 9[84; 85) 'y': bool
10[80; 84) 'true': bool 10[88; 92) 'true': bool
11[80; 93) 'true || false': bool 11[88; 101) 'true || false': bool
12[88; 93) 'false': bool 12[96; 101) 'false': bool
13[103; 104) 'z': bool 13[111; 112) 'z': bool
14[107; 108) 'x': bool 14[115; 116) 'x': bool
15[107; 113) 'x == y': bool 15[115; 121) 'x == y': bool
16[112; 113) 'y': bool 16[120; 121) 'y': bool
17[123; 134) 'minus_forty': isize 17[131; 142) 'minus_forty': isize
18[144; 152) '-40isize': isize 18[152; 160) '-40isize': isize
19[145; 152) '40isize': isize 19[153; 160) '40isize': isize
20[162; 163) 'h': bool 20[170; 171) 'h': bool
21[166; 177) 'minus_forty': isize 21[174; 185) 'minus_forty': isize
22[166; 188) 'minus_...ONST_2': bool 22[174; 196) 'minus_...ONST_2': bool
23[181; 188) 'CONST_2': isize 23[189; 196) 'CONST_2': isize
24[198; 199) 'c': i32 24[206; 207) 'c': i32
25[202; 203) 'f': fn(bool) -> i32 25[210; 211) 'f': fn(bool) -> i32
26[202; 211) 'f(z || y)': i32 26[210; 219) 'f(z || y)': i32
27[202; 215) 'f(z || y) + 5': i32 27[210; 223) 'f(z || y) + 5': i32
28[204; 205) 'z': bool 28[212; 213) 'z': bool
29[204; 210) 'z || y': bool 29[212; 218) 'z || y': bool
30[209; 210) 'y': bool 30[217; 218) 'y': bool
31[214; 215) '5': i32 31[222; 223) '5': i32
32[225; 226) 'd': [unknown] 32[233; 234) 'd': [unknown]
33[229; 230) 'b': [unknown] 33[237; 238) 'b': [unknown]
34[240; 241) 'g': () 34[248; 249) 'g': ()
35[244; 255) 'minus_forty': isize 35[252; 263) 'minus_forty': isize
36[244; 260) 'minus_...y ^= i': () 36[252; 268) 'minus_...y ^= i': ()
37[259; 260) 'i': isize 37[267; 268) 'i': isize
38[270; 273) 'ten': usize 38[278; 281) 'ten': usize
39[283; 285) '10': usize 39[291; 293) '10': usize
40[295; 308) 'ten_is_eleven': bool 40[303; 316) 'ten_is_eleven': bool
41[311; 314) 'ten': usize 41[319; 322) 'ten': usize
42[311; 326) 'ten == some_num': bool 42[319; 334) 'ten == some_num': bool
43[318; 326) 'some_num': usize 43[326; 334) 'some_num': usize
44[333; 336) 'ten': usize 44[341; 344) 'ten': usize
45[333; 340) 'ten < 3': bool 45[341; 348) 'ten < 3': bool
46[339; 340) '3': usize 46[347; 348) '3': usize
diff --git a/crates/ra_hir/src/ty/tests/data/literals.txt b/crates/ra_hir/src/ty/tests/data/literals.txt
index 8d6079c98..6e82f458f 100644
--- a/crates/ra_hir/src/ty/tests/data/literals.txt
+++ b/crates/ra_hir/src/ty/tests/data/literals.txt
@@ -1,4 +1,4 @@
1[11; 101) '{ ...lse; }': () 1[11; 111) '{ ...rue; }': ()
2[17; 21) '5i32': i32 2[17; 21) '5i32': i32
3[27; 34) '"hello"': &str 3[27; 34) '"hello"': &str
4[40; 48) 'b"bytes"': &[u8] 4[40; 48) 'b"bytes"': &[u8]
@@ -7,3 +7,4 @@
7[73; 77) '3.14': f64 7[73; 77) '3.14': f64
8[83; 87) '5000': i32 8[83; 87) '5000': i32
9[93; 98) 'false': bool 9[93; 98) 'false': bool
10[104; 108) 'true': bool
diff --git a/crates/ra_hir/src/ty/tests/data/tuple.txt b/crates/ra_hir/src/ty/tests/data/tuple.txt
index 96169180d..a95d3c286 100644
--- a/crates/ra_hir/src/ty/tests/data/tuple.txt
+++ b/crates/ra_hir/src/ty/tests/data/tuple.txt
@@ -1,6 +1,6 @@
1[9; 10) 'x': &str 1[9; 10) 'x': &str
2[18; 19) 'y': isize 2[18; 19) 'y': isize
3[28; 214) '{ ...d"); }': () 3[28; 170) '{ ...d"); }': ()
4[38; 39) 'a': (u32, &str) 4[38; 39) 'a': (u32, &str)
5[55; 63) '(1, "a")': (u32, &str) 5[55; 63) '(1, "a")': (u32, &str)
6[56; 57) '1': u32 6[56; 57) '1': u32
@@ -17,11 +17,11 @@
17[117; 123) '(c, x)': ((isize, &str), &str) 17[117; 123) '(c, x)': ((isize, &str), &str)
18[118; 119) 'c': (isize, &str) 18[118; 119) 'c': (isize, &str)
19[121; 122) 'x': &str 19[121; 122) 'x': &str
20[177; 178) 'e': ([unknown], [unknown]) 20[133; 134) 'e': (i32, &str)
21[181; 189) '(1, "e")': ([unknown], [unknown]) 21[137; 145) '(1, "e")': (i32, &str)
22[182; 183) '1': [unknown] 22[138; 139) '1': i32
23[185; 188) '"e"': [unknown] 23[141; 144) '"e"': &str
24[199; 200) 'f': (([unknown], [unknown]), [unknown]) 24[155; 156) 'f': ((i32, &str), &str)
25[203; 211) '(e, "d")': (([unknown], [unknown]), [unknown]) 25[159; 167) '(e, "d")': ((i32, &str), &str)
26[204; 205) 'e': ([unknown], [unknown]) 26[160; 161) 'e': (i32, &str)
27[207; 210) '"d"': [unknown] 27[163; 166) '"d"': &str
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs
index 8bf439b60..211ba31e5 100644
--- a/crates/ra_syntax/src/ast.rs
+++ b/crates/ra_syntax/src/ast.rs
@@ -609,6 +609,52 @@ impl SelfParam {
609 } 609 }
610} 610}
611 611
612#[derive(Clone, Debug, PartialEq, Eq, Hash)]
613pub enum LiteralFlavor {
614 String,
615 ByteString,
616 Char,
617 Byte,
618 IntNumber { suffix: Option<SmolStr> },
619 FloatNumber { suffix: Option<SmolStr> },
620 Bool,
621}
622
623impl LiteralExpr {
624 pub fn flavor(&self) -> LiteralFlavor {
625 let syntax = self.syntax();
626 match syntax.kind() {
627 INT_NUMBER => {
628 let allowed_suffix_list = [
629 "isize", "i128", "i64", "i32", "i16", "i8", "usize", "u128", "u64", "u32",
630 "u16", "u8",
631 ];
632 let text = syntax.text().to_string();
633 let suffix = allowed_suffix_list
634 .iter()
635 .find(|&s| text.ends_with(s))
636 .map(|&suf| SmolStr::new(suf));
637 LiteralFlavor::IntNumber { suffix: suffix }
638 }
639 FLOAT_NUMBER => {
640 let allowed_suffix_list = ["f64", "f32"];
641 let text = syntax.text().to_string();
642 let suffix = allowed_suffix_list
643 .iter()
644 .find(|&s| text.ends_with(s))
645 .map(|&suf| SmolStr::new(suf));
646 LiteralFlavor::FloatNumber { suffix: suffix }
647 }
648 STRING | RAW_STRING => LiteralFlavor::String,
649 TRUE_KW | FALSE_KW => LiteralFlavor::Bool,
650 BYTE_STRING | RAW_BYTE_STRING => LiteralFlavor::ByteString,
651 CHAR => LiteralFlavor::Char,
652 BYTE => LiteralFlavor::Byte,
653 _ => unreachable!(),
654 }
655 }
656}
657
612#[test] 658#[test]
613fn test_doc_comment_of_items() { 659fn test_doc_comment_of_items() {
614 let file = SourceFile::parse( 660 let file = SourceFile::parse(
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs
index 442659aee..cad845ec0 100644
--- a/crates/ra_syntax/src/ast/generated.rs
+++ b/crates/ra_syntax/src/ast/generated.rs
@@ -664,7 +664,7 @@ pub enum ExprKind<'a> {
664 PrefixExpr(&'a PrefixExpr), 664 PrefixExpr(&'a PrefixExpr),
665 RangeExpr(&'a RangeExpr), 665 RangeExpr(&'a RangeExpr),
666 BinExpr(&'a BinExpr), 666 BinExpr(&'a BinExpr),
667 LiteralExpr(&'a LiteralExpr), 667 Literal(&'a Literal),
668} 668}
669 669
670impl AstNode for Expr { 670impl AstNode for Expr {
@@ -696,7 +696,7 @@ impl AstNode for Expr {
696 | PREFIX_EXPR 696 | PREFIX_EXPR
697 | RANGE_EXPR 697 | RANGE_EXPR
698 | BIN_EXPR 698 | BIN_EXPR
699 | LITERAL_EXPR => Some(Expr::from_repr(syntax.into_repr())), 699 | LITERAL => Some(Expr::from_repr(syntax.into_repr())),
700 _ => None, 700 _ => None,
701 } 701 }
702 } 702 }
@@ -733,7 +733,7 @@ impl Expr {
733 PREFIX_EXPR => ExprKind::PrefixExpr(PrefixExpr::cast(&self.syntax).unwrap()), 733 PREFIX_EXPR => ExprKind::PrefixExpr(PrefixExpr::cast(&self.syntax).unwrap()),
734 RANGE_EXPR => ExprKind::RangeExpr(RangeExpr::cast(&self.syntax).unwrap()), 734 RANGE_EXPR => ExprKind::RangeExpr(RangeExpr::cast(&self.syntax).unwrap()),
735 BIN_EXPR => ExprKind::BinExpr(BinExpr::cast(&self.syntax).unwrap()), 735 BIN_EXPR => ExprKind::BinExpr(BinExpr::cast(&self.syntax).unwrap()),
736 LITERAL_EXPR => ExprKind::LiteralExpr(LiteralExpr::cast(&self.syntax).unwrap()), 736 LITERAL => ExprKind::Literal(Literal::cast(&self.syntax).unwrap()),
737 _ => unreachable!(), 737 _ => unreachable!(),
738 } 738 }
739 } 739 }
@@ -793,6 +793,31 @@ impl AstNode for ExternCrateItem {
793 793
794impl ExternCrateItem {} 794impl ExternCrateItem {}
795 795
796// FalseKw
797#[derive(Debug, PartialEq, Eq, Hash)]
798#[repr(transparent)]
799pub struct FalseKw {
800 pub(crate) syntax: SyntaxNode,
801}
802unsafe impl TransparentNewType for FalseKw {
803 type Repr = rowan::SyntaxNode<RaTypes>;
804}
805
806impl AstNode for FalseKw {
807 fn cast(syntax: &SyntaxNode) -> Option<&Self> {
808 match syntax.kind() {
809 FALSE_KW => Some(FalseKw::from_repr(syntax.into_repr())),
810 _ => None,
811 }
812 }
813 fn syntax(&self) -> &SyntaxNode { &self.syntax }
814 fn to_owned(&self) -> TreeArc<FalseKw> { TreeArc::cast(self.syntax.to_owned()) }
815}
816
817
818impl ast::AstToken for FalseKw {}
819impl FalseKw {}
820
796// FieldExpr 821// FieldExpr
797#[derive(Debug, PartialEq, Eq, Hash)] 822#[derive(Debug, PartialEq, Eq, Hash)]
798#[repr(transparent)] 823#[repr(transparent)]
@@ -867,7 +892,7 @@ impl AstNode for FloatNumber {
867 } 892 }
868 } 893 }
869 fn syntax(&self) -> &SyntaxNode { &self.syntax } 894 fn syntax(&self) -> &SyntaxNode { &self.syntax }
870 fn to_owned(&self) -> TreePtr<FloatNumber> { TreePtr::cast(self.syntax.to_owned()) } 895 fn to_owned(&self) -> TreeArc<FloatNumber> { TreeArc::cast(self.syntax.to_owned()) }
871} 896}
872 897
873 898
@@ -1173,7 +1198,7 @@ impl AstNode for IntNumber {
1173 } 1198 }
1174 } 1199 }
1175 fn syntax(&self) -> &SyntaxNode { &self.syntax } 1200 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1176 fn to_owned(&self) -> TreePtr<IntNumber> { TreePtr::cast(self.syntax.to_owned()) } 1201 fn to_owned(&self) -> TreeArc<IntNumber> { TreeArc::cast(self.syntax.to_owned()) }
1177} 1202}
1178 1203
1179 1204
@@ -1365,25 +1390,10 @@ unsafe impl TransparentNewType for Literal {
1365 type Repr = rowan::SyntaxNode<RaTypes>; 1390 type Repr = rowan::SyntaxNode<RaTypes>;
1366} 1391}
1367 1392
1368#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1369pub enum LiteralKind<'a> {
1370 String(&'a String),
1371 ByteString(&'a ByteString),
1372 Char(&'a Char),
1373 Byte(&'a Byte),
1374 IntNumber(&'a IntNumber),
1375 FloatNumber(&'a FloatNumber),
1376}
1377
1378impl AstNode for Literal { 1393impl AstNode for Literal {
1379 fn cast(syntax: &SyntaxNode) -> Option<&Self> { 1394 fn cast(syntax: &SyntaxNode) -> Option<&Self> {
1380 match syntax.kind() { 1395 match syntax.kind() {
1381 | STRING 1396 LITERAL => Some(Literal::from_repr(syntax.into_repr())),
1382 | BYTE_STRING
1383 | CHAR
1384 | BYTE
1385 | INT_NUMBER
1386 | FLOAT_NUMBER => Some(Literal::from_repr(syntax.into_repr())),
1387 _ => None, 1397 _ => None,
1388 } 1398 }
1389 } 1399 }
@@ -1391,22 +1401,13 @@ impl AstNode for Literal {
1391 fn to_owned(&self) -> TreeArc<Literal> { TreeArc::cast(self.syntax.to_owned()) } 1401 fn to_owned(&self) -> TreeArc<Literal> { TreeArc::cast(self.syntax.to_owned()) }
1392} 1402}
1393 1403
1404
1394impl Literal { 1405impl Literal {
1395 pub fn kind(&self) -> LiteralKind { 1406 pub fn literal_expr(&self) -> Option<&LiteralExpr> {
1396 match self.syntax.kind() { 1407 super::child_opt(self)
1397 STRING => LiteralKind::String(String::cast(&self.syntax).unwrap()),
1398 BYTE_STRING => LiteralKind::ByteString(ByteString::cast(&self.syntax).unwrap()),
1399 CHAR => LiteralKind::Char(Char::cast(&self.syntax).unwrap()),
1400 BYTE => LiteralKind::Byte(Byte::cast(&self.syntax).unwrap()),
1401 INT_NUMBER => LiteralKind::IntNumber(IntNumber::cast(&self.syntax).unwrap()),
1402 FLOAT_NUMBER => LiteralKind::FloatNumber(FloatNumber::cast(&self.syntax).unwrap()),
1403 _ => unreachable!(),
1404 }
1405 } 1408 }
1406} 1409}
1407 1410
1408impl Literal {}
1409
1410// LiteralExpr 1411// LiteralExpr
1411#[derive(Debug, PartialEq, Eq, Hash)] 1412#[derive(Debug, PartialEq, Eq, Hash)]
1412#[repr(transparent)] 1413#[repr(transparent)]
@@ -1417,24 +1418,54 @@ unsafe impl TransparentNewType for LiteralExpr {
1417 type Repr = rowan::SyntaxNode<RaTypes>; 1418 type Repr = rowan::SyntaxNode<RaTypes>;
1418} 1419}
1419 1420
1421#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1422pub enum LiteralExprKind<'a> {
1423 String(&'a String),
1424 ByteString(&'a ByteString),
1425 Char(&'a Char),
1426 Byte(&'a Byte),
1427 IntNumber(&'a IntNumber),
1428 FloatNumber(&'a FloatNumber),
1429 TrueKw(&'a TrueKw),
1430 FalseKw(&'a FalseKw),
1431}
1432
1420impl AstNode for LiteralExpr { 1433impl AstNode for LiteralExpr {
1421 fn cast(syntax: &SyntaxNode) -> Option<&Self> { 1434 fn cast(syntax: &SyntaxNode) -> Option<&Self> {
1422 match syntax.kind() { 1435 match syntax.kind() {
1423 LITERAL_EXPR => Some(LiteralExpr::from_repr(syntax.into_repr())), 1436 | STRING
1437 | BYTE_STRING
1438 | CHAR
1439 | BYTE
1440 | INT_NUMBER
1441 | FLOAT_NUMBER
1442 | TRUE_KW
1443 | FALSE_KW => Some(LiteralExpr::from_repr(syntax.into_repr())),
1424 _ => None, 1444 _ => None,
1425 } 1445 }
1426 } 1446 }
1427 fn syntax(&self) -> &SyntaxNode { &self.syntax } 1447 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1428 fn to_owned(&self) -> TreePtr<LiteralExpr> { TreePtr::cast(self.syntax.to_owned()) } 1448 fn to_owned(&self) -> TreeArc<LiteralExpr> { TreeArc::cast(self.syntax.to_owned()) }
1429} 1449}
1430 1450
1431
1432impl LiteralExpr { 1451impl LiteralExpr {
1433 pub fn literal(&self) -> Option<&Literal> { 1452 pub fn kind(&self) -> LiteralExprKind {
1434 super::child_opt(self) 1453 match self.syntax.kind() {
1454 STRING => LiteralExprKind::String(String::cast(&self.syntax).unwrap()),
1455 BYTE_STRING => LiteralExprKind::ByteString(ByteString::cast(&self.syntax).unwrap()),
1456 CHAR => LiteralExprKind::Char(Char::cast(&self.syntax).unwrap()),
1457 BYTE => LiteralExprKind::Byte(Byte::cast(&self.syntax).unwrap()),
1458 INT_NUMBER => LiteralExprKind::IntNumber(IntNumber::cast(&self.syntax).unwrap()),
1459 FLOAT_NUMBER => LiteralExprKind::FloatNumber(FloatNumber::cast(&self.syntax).unwrap()),
1460 TRUE_KW => LiteralExprKind::TrueKw(TrueKw::cast(&self.syntax).unwrap()),
1461 FALSE_KW => LiteralExprKind::FalseKw(FalseKw::cast(&self.syntax).unwrap()),
1462 _ => unreachable!(),
1463 }
1435 } 1464 }
1436} 1465}
1437 1466
1467impl LiteralExpr {}
1468
1438// LoopExpr 1469// LoopExpr
1439#[derive(Debug, PartialEq, Eq, Hash)] 1470#[derive(Debug, PartialEq, Eq, Hash)]
1440#[repr(transparent)] 1471#[repr(transparent)]
@@ -3025,6 +3056,31 @@ impl ast::AttrsOwner for TraitDef {}
3025impl ast::DocCommentsOwner for TraitDef {} 3056impl ast::DocCommentsOwner for TraitDef {}
3026impl TraitDef {} 3057impl TraitDef {}
3027 3058
3059// TrueKw
3060#[derive(Debug, PartialEq, Eq, Hash)]
3061#[repr(transparent)]
3062pub struct TrueKw {
3063 pub(crate) syntax: SyntaxNode,
3064}
3065unsafe impl TransparentNewType for TrueKw {
3066 type Repr = rowan::SyntaxNode<RaTypes>;
3067}
3068
3069impl AstNode for TrueKw {
3070 fn cast(syntax: &SyntaxNode) -> Option<&Self> {
3071 match syntax.kind() {
3072 TRUE_KW => Some(TrueKw::from_repr(syntax.into_repr())),
3073 _ => None,
3074 }
3075 }
3076 fn syntax(&self) -> &SyntaxNode { &self.syntax }
3077 fn to_owned(&self) -> TreeArc<TrueKw> { TreeArc::cast(self.syntax.to_owned()) }
3078}
3079
3080
3081impl ast::AstToken for TrueKw {}
3082impl TrueKw {}
3083
3028// TryExpr 3084// TryExpr
3029#[derive(Debug, PartialEq, Eq, Hash)] 3085#[derive(Debug, PartialEq, Eq, Hash)]
3030#[repr(transparent)] 3086#[repr(transparent)]
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron
index 49b297696..34d2a27d1 100644
--- a/crates/ra_syntax/src/grammar.ron
+++ b/crates/ra_syntax/src/grammar.ron
@@ -215,7 +215,6 @@ Grammar(
215 "PATH", 215 "PATH",
216 "PATH_SEGMENT", 216 "PATH_SEGMENT",
217 "LITERAL", 217 "LITERAL",
218 "LITERAL_EXPR",
219 "ALIAS", 218 "ALIAS",
220 "VISIBILITY", 219 "VISIBILITY",
221 "WHERE_CLAUSE", 220 "WHERE_CLAUSE",
@@ -434,7 +433,9 @@ Grammar(
434 "Byte": ( traits: ["AstToken"] ), 433 "Byte": ( traits: ["AstToken"] ),
435 "ByteString": ( traits: ["AstToken"] ), 434 "ByteString": ( traits: ["AstToken"] ),
436 "Char": ( traits: ["AstToken"] ), 435 "Char": ( traits: ["AstToken"] ),
437 "Literal": ( 436 "TrueKw": ( traits: ["AstToken"] ),
437 "FalseKw": ( traits: ["AstToken"] ),
438 "LiteralExpr": (
438 enum: [ 439 enum: [
439 "String", 440 "String",
440 "ByteString", 441 "ByteString",
@@ -442,9 +443,11 @@ Grammar(
442 "Byte", 443 "Byte",
443 "IntNumber", 444 "IntNumber",
444 "FloatNumber", 445 "FloatNumber",
446 "TrueKw",
447 "FalseKw",
445 ] 448 ]
446 ), 449 ),
447 "LiteralExpr": (options: ["Literal"]), 450 "Literal": (options: ["LiteralExpr"]),
448 451
449 "Expr": ( 452 "Expr": (
450 enum: [ 453 enum: [
@@ -474,7 +477,7 @@ Grammar(
474 "PrefixExpr", 477 "PrefixExpr",
475 "RangeExpr", 478 "RangeExpr",
476 "BinExpr", 479 "BinExpr",
477 "LiteralExpr", 480 "Literal",
478 ], 481 ],
479 ), 482 ),
480 483
diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs
index 6181df9d7..bc311cbbc 100644
--- a/crates/ra_syntax/src/lib.rs
+++ b/crates/ra_syntax/src/lib.rs
@@ -59,7 +59,7 @@ impl SourceFile {
59 assert_eq!(root.kind(), SyntaxKind::SOURCE_FILE); 59 assert_eq!(root.kind(), SyntaxKind::SOURCE_FILE);
60 TreeArc::cast(root) 60 TreeArc::cast(root)
61 } 61 }
62 62
63 pub fn parse(text: &str) -> TreeArc<SourceFile> { 63 pub fn parse(text: &str) -> TreeArc<SourceFile> {
64 let tokens = tokenize(&text); 64 let tokens = tokenize(&text);
65 let (green, errors) = 65 let (green, errors) =
diff --git a/crates/ra_syntax/src/syntax_kinds/generated.rs b/crates/ra_syntax/src/syntax_kinds/generated.rs
index 46795d6e9..830fac9f4 100644
--- a/crates/ra_syntax/src/syntax_kinds/generated.rs
+++ b/crates/ra_syntax/src/syntax_kinds/generated.rs
@@ -205,7 +205,6 @@ pub enum SyntaxKind {
205 PATH, 205 PATH,
206 PATH_SEGMENT, 206 PATH_SEGMENT,
207 LITERAL, 207 LITERAL,
208 LITERAL_EXPR,
209 ALIAS, 208 ALIAS,
210 VISIBILITY, 209 VISIBILITY,
211 WHERE_CLAUSE, 210 WHERE_CLAUSE,
@@ -468,7 +467,6 @@ impl SyntaxKind {
468 PATH => &SyntaxInfo { name: "PATH" }, 467 PATH => &SyntaxInfo { name: "PATH" },
469 PATH_SEGMENT => &SyntaxInfo { name: "PATH_SEGMENT" }, 468 PATH_SEGMENT => &SyntaxInfo { name: "PATH_SEGMENT" },
470 LITERAL => &SyntaxInfo { name: "LITERAL" }, 469 LITERAL => &SyntaxInfo { name: "LITERAL" },
471 LITERAL_EXPR => &SyntaxInfo { name: "LITERAL_EXPR" },
472 ALIAS => &SyntaxInfo { name: "ALIAS" }, 470 ALIAS => &SyntaxInfo { name: "ALIAS" },
473 VISIBILITY => &SyntaxInfo { name: "VISIBILITY" }, 471 VISIBILITY => &SyntaxInfo { name: "VISIBILITY" },
474 WHERE_CLAUSE => &SyntaxInfo { name: "WHERE_CLAUSE" }, 472 WHERE_CLAUSE => &SyntaxInfo { name: "WHERE_CLAUSE" },