From a9a6a50c759302e8a8d59bf6c53c72ec804324b3 Mon Sep 17 00:00:00 2001 From: Marcus Klaas de Vries Date: Mon, 14 Jan 2019 19:30:21 +0100 Subject: Fixup tests --- crates/ra_hir/src/expr.rs | 141 ++++++++++---------------- crates/ra_hir/src/name.rs | 2 +- crates/ra_hir/src/ty.rs | 46 +++++---- crates/ra_hir/src/ty/tests.rs | 5 +- crates/ra_hir/src/ty/tests/data/binary_op.txt | 86 ++++++++-------- crates/ra_hir/src/ty/tests/data/literals.txt | 3 +- crates/ra_hir/src/ty/tests/data/tuple.txt | 18 ++-- 7 files changed, 135 insertions(+), 166 deletions(-) (limited to 'crates/ra_hir/src') 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; use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; use ra_db::{LocalSyntaxPtr, Cancelable}; use ra_syntax::{ - SyntaxKind, - ast::{self, AstNode, LoopBodyOwner, ArgListOwner, NameOwner} + ast::{self, AstNode, LoopBodyOwner, ArgListOwner, NameOwner, LiteralFlavor} }; use crate::{Path, type_ref::{Mutability, TypeRef}, Name, HirDatabase, DefId, Def, name::AsName}; -use crate::ty::primitive::{UintTy, IntTy, FloatTy, UncertainIntTy, UncertainFloatTy}; +use crate::ty::primitive::{UintTy, UncertainIntTy, UncertainFloatTy}; #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct ExprId(RawId); @@ -649,93 +648,59 @@ impl ExprCollector { let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect(); self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr) } - ast::ExprKind::LiteralExpr(e) => { - if let Some(child) = e.literal() { - let c = child.syntax(); - let lit = match c.kind() { - SyntaxKind::INT_NUMBER => { - let text = c.text().to_string(); - - // FIXME: don't do it like this. maybe use something like - // the IntTy::from_name functions - let ty = if text.ends_with("isize") { - UncertainIntTy::Signed(IntTy::Isize) - } else if text.ends_with("i128") { - UncertainIntTy::Signed(IntTy::I128) - } else if text.ends_with("i64") { - UncertainIntTy::Signed(IntTy::I64) - } else if text.ends_with("i32") { - UncertainIntTy::Signed(IntTy::I32) - } else if text.ends_with("i16") { - UncertainIntTy::Signed(IntTy::I16) - } else if text.ends_with("i8") { - UncertainIntTy::Signed(IntTy::I8) - } else if text.ends_with("usize") { - UncertainIntTy::Unsigned(UintTy::Usize) - } else if text.ends_with("u128") { - UncertainIntTy::Unsigned(UintTy::U128) - } else if text.ends_with("u64") { - UncertainIntTy::Unsigned(UintTy::U64) - } else if text.ends_with("u32") { - UncertainIntTy::Unsigned(UintTy::U32) - } else if text.ends_with("u16") { - UncertainIntTy::Unsigned(UintTy::U16) - } else if text.ends_with("u8") { - UncertainIntTy::Unsigned(UintTy::U8) - } else { - UncertainIntTy::Unknown - }; - - // TODO: actually parse integer - Literal::Int(0u64, ty) - } - SyntaxKind::FLOAT_NUMBER => { - let text = c.text().to_string(); - - // FIXME: don't do it like this. maybe use something like - // the IntTy::from_name functions - let ty = if text.ends_with("f64") { - UncertainFloatTy::Known(FloatTy::F64) - } else if text.ends_with("f32") { - UncertainFloatTy::Known(FloatTy::F32) - } else { - UncertainFloatTy::Unknown - }; - - // TODO: actually parse value - Literal::Float(0, ty) - } - SyntaxKind::STRING => { - // FIXME: this likely includes the " characters - let text = c.text().to_string(); - Literal::String(text) - } - SyntaxKind::TRUE_KW => Literal::Bool(true), - SyntaxKind::FALSE_KW => Literal::Bool(false), - SyntaxKind::BYTE_STRING => { - // FIXME: this is completely incorrect for a variety - // of reasons, but at least it gives the right type - let bytes = c.text().to_string().into_bytes(); - Literal::ByteString(bytes) - } - SyntaxKind::CHAR => { - let character = c.text().char_at(1).unwrap_or('X'); - Literal::Char(character) + ast::ExprKind::Literal(e) => { + let child = if let Some(child) = e.literal_expr() { + child + } else { + return self.alloc_expr(Expr::Missing, syntax_ptr); + }; + let c = child.syntax(); + + let lit = match child.flavor() { + LiteralFlavor::IntNumber { suffix } => { + let known_name = suffix + .map(|s| Name::new(s)) + .and_then(|name| UncertainIntTy::from_name(&name)); + + if let Some(kn) = known_name { + Literal::Int(0u64, kn) + } else { + Literal::Int(0u64, UncertainIntTy::Unknown) } - SyntaxKind::BYTE => { - let character = c.text().char_at(1).unwrap_or('X'); - Literal::Int( - character as u8 as u64, - UncertainIntTy::Unsigned(UintTy::U8), - ) + } + LiteralFlavor::FloatNumber { suffix } => { + let known_name = suffix + .map(|s| Name::new(s)) + .and_then(|name| UncertainFloatTy::from_name(&name)); + + if let Some(kn) = known_name { + Literal::Float(0u64, kn) + } else { + Literal::Float(0u64, UncertainFloatTy::Unknown) } - _ => return self.alloc_expr(Expr::Missing, syntax_ptr), - }; - - self.alloc_expr(Expr::Literal(lit), syntax_ptr) - } else { - self.alloc_expr(Expr::Missing, syntax_ptr) - } + } + LiteralFlavor::ByteString => { + // FIXME: this is completely incorrect for a variety + // of reasons, but at least it gives the right type + let bytes = c.text().to_string().into_bytes(); + Literal::ByteString(bytes) + } + LiteralFlavor::String => { + // FIXME: this likely includes the " characters + let text = c.text().to_string(); + Literal::String(text) + } + LiteralFlavor::Byte => { + let character = c.text().char_at(1).unwrap_or('X'); + Literal::Int(character as u8 as u64, UncertainIntTy::Unsigned(UintTy::U8)) + } + LiteralFlavor::Bool => Literal::Bool(true), + LiteralFlavor::Char => { + let character = c.text().char_at(1).unwrap_or('X'); + Literal::Char(character) + } + }; + self.alloc_expr(Expr::Literal(lit), syntax_ptr) } // 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 { } impl Name { - fn new(text: SmolStr) -> Name { + pub(crate) fn new(text: SmolStr) -> Name { Name { text } } 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 { /// values for general types, and for integer and float variables. The latter /// two are used for inference of literal values (e.g. `100` could be one of /// several integer types). -#[derive(Clone, PartialEq, Eq, Hash, Debug)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] pub enum InferTy { TypeVar(TypeVarId), IntVar(TypeVarId), @@ -119,6 +119,12 @@ pub enum InferTy { } impl InferTy { + fn to_inner(self) -> TypeVarId { + match self { + InferTy::TypeVar(ty) | InferTy::IntVar(ty) | InferTy::FloatVar(ty) => ty, + } + } + fn fallback_value(self) -> Ty { match self { InferTy::TypeVar(..) => Ty::Unknown, @@ -326,18 +332,19 @@ impl Ty { path: &Path, ) -> Cancelable { if let Some(name) = path.as_ident() { - if let Some(KnownName::Bool) = name.as_known_name() { - return Ok(Ty::Bool); - } else if let Some(KnownName::Char) = name.as_known_name() { - return Ok(Ty::Char); - } else if let Some(KnownName::Str) = name.as_known_name() { - return Ok(Ty::Str); - } else if let Some(int_ty) = primitive::UncertainIntTy::from_name(name) { + if let Some(int_ty) = primitive::UncertainIntTy::from_name(name) { return Ok(Ty::Int(int_ty)); } else if let Some(float_ty) = primitive::UncertainFloatTy::from_name(name) { return Ok(Ty::Float(float_ty)); } else if name.as_known_name() == Some(KnownName::SelfType) { return Ty::from_hir_opt(db, module, None, impl_block.map(|i| i.target_type())); + } else if let Some(known) = name.as_known_name() { + match known { + KnownName::Bool => return Ok(Ty::Bool), + KnownName::Char => return Ok(Ty::Char), + KnownName::Str => return Ok(Ty::Str), + _ => {} + } } } @@ -793,10 +800,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { /// known type. fn resolve_ty_as_possible(&mut self, ty: Ty) -> Ty { ty.fold(&mut |ty| match ty { - Ty::Infer(InferTy::TypeVar(tv)) - | Ty::Infer(InferTy::IntVar(tv)) - | Ty::Infer(InferTy::FloatVar(tv)) => { - if let Some(known_ty) = self.var_unification_table.probe_value(tv).known() { + Ty::Infer(tv) => { + let inner = tv.to_inner(); + if let Some(known_ty) = self.var_unification_table.probe_value(inner).known() { // known_ty may contain other variables that are known by now self.resolve_ty_as_possible(known_ty.clone()) } else { @@ -811,8 +817,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { /// otherwise, return ty. fn resolve_ty_shallow<'b>(&mut self, ty: &'b Ty) -> Cow<'b, Ty> { match ty { - Ty::Infer(InferTy::TypeVar(tv)) => { - match self.var_unification_table.probe_value(*tv).known() { + Ty::Infer(tv) => { + let inner = tv.to_inner(); + match self.var_unification_table.probe_value(inner).known() { Some(known_ty) => { // The known_ty can't be a type var itself Cow::Owned(known_ty.clone()) @@ -828,16 +835,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { /// replaced by Ty::Unknown. fn resolve_ty_completely(&mut self, ty: Ty) -> Ty { ty.fold(&mut |ty| match ty { - Ty::Infer(i) => { - let tv = match i { - InferTy::TypeVar(tv) | InferTy::IntVar(tv) | InferTy::FloatVar(tv) => tv, - }; - - if let Some(known_ty) = self.var_unification_table.probe_value(tv).known() { + Ty::Infer(tv) => { + let inner = tv.to_inner(); + if let Some(known_ty) = self.var_unification_table.probe_value(inner).known() { // known_ty may contain other variables that are known by now self.resolve_ty_completely(known_ty.clone()) } else { - i.fallback_value() + tv.fallback_value() } } _ => 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() { 3.14; 5000; false; + true; } "#, "literals.txt", @@ -199,7 +200,7 @@ fn f(x: bool) -> i32 { 0i32 } -fn test() { +fn test() -> bool { let x = a && b; let y = true || false; let z = x == y; @@ -296,8 +297,6 @@ fn test(x: &str, y: isize) { let b = (a, x); let c = (y, x); let d = (c, x); - - // we have not infered these case yet. let e = (1, "e"); let f = (e, "d"); } 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 @@ [6; 7) 'x': bool [22; 34) '{ 0i32 }': i32 [28; 32) '0i32': i32 -[46; 342) '{ ... < 3 }': bool -[56; 57) 'x': bool -[60; 61) 'a': bool -[60; 66) 'a && b': bool -[65; 66) 'b': bool -[76; 77) 'y': bool -[80; 84) 'true': bool -[80; 93) 'true || false': bool -[88; 93) 'false': bool -[103; 104) 'z': bool -[107; 108) 'x': bool -[107; 113) 'x == y': bool -[112; 113) 'y': bool -[123; 134) 'minus_forty': isize -[144; 152) '-40isize': isize -[145; 152) '40isize': isize -[162; 163) 'h': bool -[166; 177) 'minus_forty': isize -[166; 188) 'minus_...ONST_2': bool -[181; 188) 'CONST_2': isize -[198; 199) 'c': i32 -[202; 203) 'f': fn(bool) -> i32 -[202; 211) 'f(z || y)': i32 -[202; 215) 'f(z || y) + 5': i32 -[204; 205) 'z': bool -[204; 210) 'z || y': bool -[209; 210) 'y': bool -[214; 215) '5': i32 -[225; 226) 'd': [unknown] -[229; 230) 'b': [unknown] -[240; 241) 'g': () -[244; 255) 'minus_forty': isize -[244; 260) 'minus_...y ^= i': () -[259; 260) 'i': isize -[270; 273) 'ten': usize -[283; 285) '10': usize -[295; 308) 'ten_is_eleven': bool -[311; 314) 'ten': usize -[311; 326) 'ten == some_num': bool -[318; 326) 'some_num': usize -[333; 336) 'ten': usize -[333; 340) 'ten < 3': bool -[339; 340) '3': usize +[54; 350) '{ ... < 3 }': bool +[64; 65) 'x': bool +[68; 69) 'a': bool +[68; 74) 'a && b': bool +[73; 74) 'b': bool +[84; 85) 'y': bool +[88; 92) 'true': bool +[88; 101) 'true || false': bool +[96; 101) 'false': bool +[111; 112) 'z': bool +[115; 116) 'x': bool +[115; 121) 'x == y': bool +[120; 121) 'y': bool +[131; 142) 'minus_forty': isize +[152; 160) '-40isize': isize +[153; 160) '40isize': isize +[170; 171) 'h': bool +[174; 185) 'minus_forty': isize +[174; 196) 'minus_...ONST_2': bool +[189; 196) 'CONST_2': isize +[206; 207) 'c': i32 +[210; 211) 'f': fn(bool) -> i32 +[210; 219) 'f(z || y)': i32 +[210; 223) 'f(z || y) + 5': i32 +[212; 213) 'z': bool +[212; 218) 'z || y': bool +[217; 218) 'y': bool +[222; 223) '5': i32 +[233; 234) 'd': [unknown] +[237; 238) 'b': [unknown] +[248; 249) 'g': () +[252; 263) 'minus_forty': isize +[252; 268) 'minus_...y ^= i': () +[267; 268) 'i': isize +[278; 281) 'ten': usize +[291; 293) '10': usize +[303; 316) 'ten_is_eleven': bool +[319; 322) 'ten': usize +[319; 334) 'ten == some_num': bool +[326; 334) 'some_num': usize +[341; 344) 'ten': usize +[341; 348) 'ten < 3': bool +[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 @@ -[11; 101) '{ ...lse; }': () +[11; 111) '{ ...rue; }': () [17; 21) '5i32': i32 [27; 34) '"hello"': &str [40; 48) 'b"bytes"': &[u8] @@ -7,3 +7,4 @@ [73; 77) '3.14': f64 [83; 87) '5000': i32 [93; 98) 'false': bool +[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 @@ [9; 10) 'x': &str [18; 19) 'y': isize -[28; 214) '{ ...d"); }': () +[28; 170) '{ ...d"); }': () [38; 39) 'a': (u32, &str) [55; 63) '(1, "a")': (u32, &str) [56; 57) '1': u32 @@ -17,11 +17,11 @@ [117; 123) '(c, x)': ((isize, &str), &str) [118; 119) 'c': (isize, &str) [121; 122) 'x': &str -[177; 178) 'e': ([unknown], [unknown]) -[181; 189) '(1, "e")': ([unknown], [unknown]) -[182; 183) '1': [unknown] -[185; 188) '"e"': [unknown] -[199; 200) 'f': (([unknown], [unknown]), [unknown]) -[203; 211) '(e, "d")': (([unknown], [unknown]), [unknown]) -[204; 205) 'e': ([unknown], [unknown]) -[207; 210) '"d"': [unknown] +[133; 134) 'e': (i32, &str) +[137; 145) '(1, "e")': (i32, &str) +[138; 139) '1': i32 +[141; 144) '"e"': &str +[155; 156) 'f': ((i32, &str), &str) +[159; 167) '(e, "d")': ((i32, &str), &str) +[160; 161) 'e': (i32, &str) +[163; 166) '"d"': &str -- cgit v1.2.3