From d67eabb512a08a451a649c7f20e4e9ae1860a8a0 Mon Sep 17 00:00:00 2001 From: Marcus Klaas de Vries Date: Mon, 14 Jan 2019 20:56:14 +0100 Subject: Fix type inference for raw (byte) strings --- crates/ra_hir/src/ty/tests.rs | 12 ++++-- crates/ra_hir/src/ty/tests/data/literals.txt | 4 +- crates/ra_ide_api/src/hover.rs | 5 +-- crates/ra_syntax/src/ast/generated.rs | 56 ++++++++++++++++++++++++++++ crates/ra_syntax/src/grammar.ron | 4 ++ crates/ra_syntax/src/lexer/strings.rs | 15 +------- 6 files changed, 75 insertions(+), 21 deletions(-) (limited to 'crates') diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index cbdb2a4b7..8aacb1a7f 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs @@ -135,7 +135,7 @@ fn test(a: &u32, b: &mut u32, c: *const u32, d: *mut u32) { #[test] fn infer_literals() { check_inference( - r#" + r##" fn test() { 5i32; "hello"; @@ -146,8 +146,14 @@ fn test() { 5000; false; true; -} -"#, + r#" + //! doc + // non-doc + mod foo {} + "#; + br#"yolo"#; +} +"##, "literals.txt", ); } diff --git a/crates/ra_hir/src/ty/tests/data/literals.txt b/crates/ra_hir/src/ty/tests/data/literals.txt index 6e82f458f..84ee2c11b 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; 111) '{ ...rue; }': () +[11; 201) '{ ...o"#; }': () [17; 21) '5i32': i32 [27; 34) '"hello"': &str [40; 48) 'b"bytes"': &[u8] @@ -8,3 +8,5 @@ [83; 87) '5000': i32 [93; 98) 'false': bool [104; 108) 'true': bool +[114; 182) 'r#" ... "#': &str +[188; 198) 'br#"yolo"#': &[u8] diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide_api/src/hover.rs index d73c5bc31..107b23833 100644 --- a/crates/ra_ide_api/src/hover.rs +++ b/crates/ra_ide_api/src/hover.rs @@ -230,20 +230,19 @@ mod tests { assert_eq!("[unknown]", &type_name); } - // FIXME: improve type_of to make this work #[test] fn test_type_of_for_expr_2() { let (analysis, range) = single_file_with_range( " fn main() { let foo: usize = 1; - let bar = <|>1 + foo_test<|>; + let bar = <|>1 + foo<|>; } ", ); let type_name = analysis.type_of(range).unwrap().unwrap(); - assert_eq!("[unknown]", &type_name); + assert_eq!("usize", &type_name); } } diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index cad845ec0..3471d5226 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs @@ -1422,6 +1422,8 @@ unsafe impl TransparentNewType for LiteralExpr { pub enum LiteralExprKind<'a> { String(&'a String), ByteString(&'a ByteString), + RawString(&'a RawString), + RawByteString(&'a RawByteString), Char(&'a Char), Byte(&'a Byte), IntNumber(&'a IntNumber), @@ -1435,6 +1437,8 @@ impl AstNode for LiteralExpr { match syntax.kind() { | STRING | BYTE_STRING + | RAW_STRING + | RAW_BYTE_STRING | CHAR | BYTE | INT_NUMBER @@ -1453,6 +1457,8 @@ impl LiteralExpr { match self.syntax.kind() { STRING => LiteralExprKind::String(String::cast(&self.syntax).unwrap()), BYTE_STRING => LiteralExprKind::ByteString(ByteString::cast(&self.syntax).unwrap()), + RAW_STRING => LiteralExprKind::RawString(RawString::cast(&self.syntax).unwrap()), + RAW_BYTE_STRING => LiteralExprKind::RawByteString(RawByteString::cast(&self.syntax).unwrap()), CHAR => LiteralExprKind::Char(Char::cast(&self.syntax).unwrap()), BYTE => LiteralExprKind::Byte(Byte::cast(&self.syntax).unwrap()), INT_NUMBER => LiteralExprKind::IntNumber(IntNumber::cast(&self.syntax).unwrap()), @@ -2543,6 +2549,56 @@ impl AstNode for RangePat { impl RangePat {} +// RawByteString +#[derive(Debug, PartialEq, Eq, Hash)] +#[repr(transparent)] +pub struct RawByteString { + pub(crate) syntax: SyntaxNode, +} +unsafe impl TransparentNewType for RawByteString { + type Repr = rowan::SyntaxNode; +} + +impl AstNode for RawByteString { + fn cast(syntax: &SyntaxNode) -> Option<&Self> { + match syntax.kind() { + RAW_BYTE_STRING => Some(RawByteString::from_repr(syntax.into_repr())), + _ => None, + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn to_owned(&self) -> TreeArc { TreeArc::cast(self.syntax.to_owned()) } +} + + +impl ast::AstToken for RawByteString {} +impl RawByteString {} + +// RawString +#[derive(Debug, PartialEq, Eq, Hash)] +#[repr(transparent)] +pub struct RawString { + pub(crate) syntax: SyntaxNode, +} +unsafe impl TransparentNewType for RawString { + type Repr = rowan::SyntaxNode; +} + +impl AstNode for RawString { + fn cast(syntax: &SyntaxNode) -> Option<&Self> { + match syntax.kind() { + RAW_STRING => Some(RawString::from_repr(syntax.into_repr())), + _ => None, + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn to_owned(&self) -> TreeArc { TreeArc::cast(self.syntax.to_owned()) } +} + + +impl ast::AstToken for RawString {} +impl RawString {} + // RefExpr #[derive(Debug, PartialEq, Eq, Hash)] #[repr(transparent)] diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index 34d2a27d1..bd8c5b411 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron @@ -430,7 +430,9 @@ Grammar( "IntNumber": ( traits: ["AstToken"] ), "FloatNumber": ( traits: ["AstToken"] ), "String": ( traits: ["AstToken"] ), + "RawString": ( traits: ["AstToken"] ), "Byte": ( traits: ["AstToken"] ), + "RawByteString": ( traits: ["AstToken"] ), "ByteString": ( traits: ["AstToken"] ), "Char": ( traits: ["AstToken"] ), "TrueKw": ( traits: ["AstToken"] ), @@ -439,6 +441,8 @@ Grammar( enum: [ "String", "ByteString", + "RawString", + "RawByteString", "Char", "Byte", "IntNumber", diff --git a/crates/ra_syntax/src/lexer/strings.rs b/crates/ra_syntax/src/lexer/strings.rs index 5090feae6..0865b7f3b 100644 --- a/crates/ra_syntax/src/lexer/strings.rs +++ b/crates/ra_syntax/src/lexer/strings.rs @@ -49,7 +49,7 @@ pub(crate) fn scan_byte_char_or_string(ptr: &mut Ptr) -> SyntaxKind { BYTE_STRING } 'r' => { - scan_raw_byte_string(ptr); + scan_raw_string(ptr); RAW_BYTE_STRING } _ => unreachable!(), @@ -108,16 +108,3 @@ fn scan_byte(ptr: &mut Ptr) { fn scan_byte_string(ptr: &mut Ptr) { scan_string(ptr) } - -fn scan_raw_byte_string(ptr: &mut Ptr) { - if !ptr.at('"') { - return; - } - ptr.bump(); - - while let Some(c) = ptr.bump() { - if c == '"' { - return; - } - } -} -- cgit v1.2.3