Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/hir-def/src/body/lower.rs2
-rw-r--r--crates/hir-expand/src/builtin_fn_macro.rs36
-rw-r--r--crates/parser/src/grammar/expressions/atom.rs8
-rw-r--r--crates/parser/src/syntax_kind/generated.rs3
-rw-r--r--crates/parser/test_data/parser/inline/ok/0085_expr_literals.rast3
-rw-r--r--crates/parser/test_data/parser/ok/0056_neq_in_type.rast6
-rw-r--r--crates/syntax/rust.ungram5
-rw-r--r--crates/syntax/src/ast/expr_ext.rs31
-rw-r--r--crates/syntax/src/ast/generated/nodes.rs26
-rw-r--r--crates/syntax/src/ast/make.rs13
-rw-r--r--crates/syntax/src/ast/token_ext.rs27
-rw-r--r--crates/syntax/src/tests/ast_src.rs1
-rw-r--r--crates/syntax/src/tests/sourcegen_ast.rs1
13 files changed, 113 insertions, 49 deletions
diff --git a/crates/hir-def/src/body/lower.rs b/crates/hir-def/src/body/lower.rs
index e8303ec40f..84662aa277 100644
--- a/crates/hir-def/src/body/lower.rs
+++ b/crates/hir-def/src/body/lower.rs
@@ -972,7 +972,7 @@ impl From<ast::LiteralKind> for Literal {
}
}
LiteralKind::FloatNumber(lit) => {
- let ty = lit.suffix().and_then(BuiltinFloat::from_suffix);
+ let ty = lit.suffix().and_then(|s| BuiltinFloat::from_suffix(&s));
Literal::Float(Default::default(), ty)
}
LiteralKind::ByteString(bs) => {
diff --git a/crates/hir-expand/src/builtin_fn_macro.rs b/crates/hir-expand/src/builtin_fn_macro.rs
index 8d2352f06e..45eb660a6c 100644
--- a/crates/hir-expand/src/builtin_fn_macro.rs
+++ b/crates/hir-expand/src/builtin_fn_macro.rs
@@ -4,10 +4,7 @@ use base_db::{AnchoredPath, Edition, FileId};
use cfg::CfgExpr;
use either::Either;
use mbe::{parse_exprs_with_sep, parse_to_token_tree};
-use syntax::{
- ast::{self, AstToken},
- SmolStr,
-};
+use syntax::{ast, SmolStr};
use crate::{db::AstDatabase, name, quote, ExpandError, ExpandResult, MacroCallId, MacroCallLoc};
@@ -358,14 +355,7 @@ fn unreachable_expand(
}
fn unquote_str(lit: &tt::Literal) -> Option<String> {
- let lit = ast::make::tokens::literal(&lit.to_string());
- let token = ast::String::cast(lit)?;
- token.value().map(|it| it.into_owned())
-}
-
-fn unquote_byte_string(lit: &tt::Literal) -> Option<Vec<u8>> {
- let lit = ast::make::tokens::literal(&lit.to_string());
- let token = ast::ByteString::cast(lit)?;
+ let token = ast::make::literal(&lit.to_string()).as_string()?;
token.value().map(|it| it.into_owned())
}
@@ -442,12 +432,16 @@ fn concat_bytes_expand(
for (i, t) in tt.token_trees.iter().enumerate() {
match t {
tt::TokenTree::Leaf(tt::Leaf::Literal(lit)) => {
- let token = ast::make::tokens::literal(&lit.to_string());
- match token.kind() {
- syntax::SyntaxKind::BYTE => bytes.push(token.text().to_string()),
- syntax::SyntaxKind::BYTE_STRING => {
- let components = unquote_byte_string(lit).unwrap_or_else(Vec::new);
- components.into_iter().for_each(|x| bytes.push(x.to_string()));
+ let lit = ast::make::literal(&lit.to_string());
+ match lit.kind() {
+ ast::LiteralKind::ByteString(s) => {
+ s.value()
+ .unwrap_or_default()
+ .into_iter()
+ .for_each(|x| bytes.push(x.to_string()));
+ }
+ ast::LiteralKind::Byte => {
+ bytes.push(lit.to_string());
}
_ => {
err.get_or_insert(mbe::ExpandError::UnexpectedToken.into());
@@ -481,10 +475,10 @@ fn concat_bytes_expand_subtree(
for (ti, tt) in tree.token_trees.iter().enumerate() {
match tt {
tt::TokenTree::Leaf(tt::Leaf::Literal(lit)) => {
- let lit = ast::make::tokens::literal(&lit.to_string());
+ let lit = ast::make::literal(&lit.to_string());
match lit.kind() {
- syntax::SyntaxKind::BYTE | syntax::SyntaxKind::INT_NUMBER => {
- bytes.push(lit.text().to_string())
+ ast::LiteralKind::IntNumber(_) | ast::LiteralKind::Byte => {
+ bytes.push(lit.to_string());
}
_ => {
return Err(mbe::ExpandError::UnexpectedToken.into());
diff --git a/crates/parser/src/grammar/expressions/atom.rs b/crates/parser/src/grammar/expressions/atom.rs
index 10e5d897e0..37f8a7e3b7 100644
--- a/crates/parser/src/grammar/expressions/atom.rs
+++ b/crates/parser/src/grammar/expressions/atom.rs
@@ -29,7 +29,13 @@ pub(crate) fn literal(p: &mut Parser) -> Option<CompletedMarker> {
return None;
}
let m = p.start();
- p.bump_any();
+ if p.at(FLOAT_NUMBER) {
+ let f = p.start();
+ p.bump(FLOAT_NUMBER);
+ f.complete(p, FLOAT_LITERAL);
+ } else {
+ p.bump_any();
+ }
Some(m.complete(p, LITERAL))
}
diff --git a/crates/parser/src/syntax_kind/generated.rs b/crates/parser/src/syntax_kind/generated.rs
index 628fa745e7..47bf4ba92b 100644
--- a/crates/parser/src/syntax_kind/generated.rs
+++ b/crates/parser/src/syntax_kind/generated.rs
@@ -227,6 +227,7 @@ pub enum SyntaxKind {
PATH,
PATH_SEGMENT,
LITERAL,
+ FLOAT_LITERAL,
RENAME,
VISIBILITY,
WHERE_CLAUSE,
@@ -386,5 +387,5 @@ impl SyntaxKind {
}
}
#[macro_export]
-macro_rules ! T { [;] => { $ crate :: SyntaxKind :: SEMICOLON } ; [,] => { $ crate :: SyntaxKind :: COMMA } ; ['('] => { $ crate :: SyntaxKind :: L_PAREN } ; [')'] => { $ crate :: SyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: SyntaxKind :: L_CURLY } ; ['}'] => { $ crate :: SyntaxKind :: R_CURLY } ; ['['] => { $ crate :: SyntaxKind :: L_BRACK } ; [']'] => { $ crate :: SyntaxKind :: R_BRACK } ; [<] => { $ crate :: SyntaxKind :: L_ANGLE } ; [>] => { $ crate :: SyntaxKind :: R_ANGLE } ; [@] => { $ crate :: SyntaxKind :: AT } ; [#] => { $ crate :: SyntaxKind :: POUND } ; [~] => { $ crate :: SyntaxKind :: TILDE } ; [?] => { $ crate :: SyntaxKind :: QUESTION } ; [$] => { $ crate :: SyntaxKind :: DOLLAR } ; [&] => { $ crate :: SyntaxKind :: AMP } ; [|] => { $ crate :: SyntaxKind :: PIPE } ; [+] => { $ crate :: SyntaxKind :: PLUS } ; [*] => { $ crate :: SyntaxKind :: STAR } ; [/] => { $ crate :: SyntaxKind :: SLASH } ; [^] => { $ crate :: SyntaxKind :: CARET } ; [%] => { $ crate :: SyntaxKind :: PERCENT } ; [_] => { $ crate :: SyntaxKind :: UNDERSCORE } ; [.] => { $ crate :: SyntaxKind :: DOT } ; [..] => { $ crate :: SyntaxKind :: DOT2 } ; [...] => { $ crate :: SyntaxKind :: DOT3 } ; [..=] => { $ crate :: SyntaxKind :: DOT2EQ } ; [:] => { $ crate :: SyntaxKind :: COLON } ; [::] => { $ crate :: SyntaxKind :: COLON2 } ; [=] => { $ crate :: SyntaxKind :: EQ } ; [==] => { $ crate :: SyntaxKind :: EQ2 } ; [=>] => { $ crate :: SyntaxKind :: FAT_ARROW } ; [!] => { $ crate :: SyntaxKind :: BANG } ; [!=] => { $ crate :: SyntaxKind :: NEQ } ; [-] => { $ crate :: SyntaxKind :: MINUS } ; [->] => { $ crate :: SyntaxKind :: THIN_ARROW } ; [<=] => { $ crate :: SyntaxKind :: LTEQ } ; [>=] => { $ crate :: SyntaxKind :: GTEQ } ; [+=] => { $ crate :: SyntaxKind :: PLUSEQ } ; [-=] => { $ crate :: SyntaxKind :: MINUSEQ } ; [|=] => { $ crate :: SyntaxKind :: PIPEEQ } ; [&=] => { $ crate :: SyntaxKind :: AMPEQ } ; [^=] => { $ crate :: SyntaxKind :: CARETEQ } ; [/=] => { $ crate :: SyntaxKind :: SLASHEQ } ; [*=] => { $ crate :: SyntaxKind :: STAREQ } ; [%=] => { $ crate :: SyntaxKind :: PERCENTEQ } ; [&&] => { $ crate :: SyntaxKind :: AMP2 } ; [||] => { $ crate :: SyntaxKind :: PIPE2 } ; [<<] => { $ crate :: SyntaxKind :: SHL } ; [>>] => { $ crate :: SyntaxKind :: SHR } ; [<<=] => { $ crate :: SyntaxKind :: SHLEQ } ; [>>=] => { $ crate :: SyntaxKind :: SHREQ } ; [as] => { $ crate :: SyntaxKind :: AS_KW } ; [async] => { $ crate :: SyntaxKind :: ASYNC_KW } ; [await] => { $ crate :: SyntaxKind :: AWAIT_KW } ; [box] => { $ crate :: SyntaxKind :: BOX_KW } ; [break] => { $ crate :: SyntaxKind :: BREAK_KW } ; [const] => { $ crate :: SyntaxKind :: CONST_KW } ; [continue] => { $ crate :: SyntaxKind :: CONTINUE_KW } ; [crate] => { $ crate :: SyntaxKind :: CRATE_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [else] => { $ crate :: SyntaxKind :: ELSE_KW } ; [enum] => { $ crate :: SyntaxKind :: ENUM_KW } ; [extern] => { $ crate :: SyntaxKind :: EXTERN_KW } ; [false] => { $ crate :: SyntaxKind :: FALSE_KW } ; [fn] => { $ crate :: SyntaxKind :: FN_KW } ; [for] => { $ crate :: SyntaxKind :: FOR_KW } ; [if] => { $ crate :: SyntaxKind :: IF_KW } ; [impl] => { $ crate :: SyntaxKind :: IMPL_KW } ; [in] => { $ crate :: SyntaxKind :: IN_KW } ; [let] => { $ crate :: SyntaxKind :: LET_KW } ; [loop] => { $ crate :: SyntaxKind :: LOOP_KW } ; [macro] => { $ crate :: SyntaxKind :: MACRO_KW } ; [match] => { $ crate :: SyntaxKind :: MATCH_KW } ; [mod] => { $ crate :: SyntaxKind :: MOD_KW } ; [move] => { $ crate :: SyntaxKind :: MOVE_KW } ; [mut] => { $ crate :: SyntaxKind :: MUT_KW } ; [pub] => { $ crate :: SyntaxKind :: PUB_KW } ; [ref] => { $ crate :: SyntaxKind :: REF_KW } ; [return] => { $ crate :: SyntaxKind :: RETURN_KW } ; [self] => { $ crate :: SyntaxKind :: SELF_KW } ; [Self] => { $ crate :: SyntaxKind :: SELF_TYPE_KW } ; [static] => { $ crate :: SyntaxKind :: STATIC_KW } ; [struct] => { $ crate :: SyntaxKind :: STRUCT_KW } ; [super] => { $ crate :: SyntaxKind :: SUPER_KW } ; [trait] => { $ crate :: SyntaxKind :: TRAIT_KW } ; [true] => { $ crate :: SyntaxKind :: TRUE_KW } ; [try] => { $ crate :: SyntaxKind :: TRY_KW } ; [type] => { $ crate :: SyntaxKind :: TYPE_KW } ; [unsafe] => { $ crate :: SyntaxKind :: UNSAFE_KW } ; [use] => { $ crate :: SyntaxKind :: USE_KW } ; [where] => { $ crate :: SyntaxKind :: WHERE_KW } ; [while] => { $ crate :: SyntaxKind :: WHILE_KW } ; [yield] => { $ crate :: SyntaxKind :: YIELD_KW } ; [auto] => { $ crate :: SyntaxKind :: AUTO_KW } ; [default] => { $ crate :: SyntaxKind :: DEFAULT_KW } ; [existential] => { $ crate :: SyntaxKind :: EXISTENTIAL_KW } ; [union] => { $ crate :: SyntaxKind :: UNION_KW } ; [raw] => { $ crate :: SyntaxKind :: RAW_KW } ; [macro_rules] => { $ crate :: SyntaxKind :: MACRO_RULES_KW } ; [lifetime_ident] => { $ crate :: SyntaxKind :: LIFETIME_IDENT } ; [ident] => { $ crate :: SyntaxKind :: IDENT } ; [shebang] => { $ crate :: SyntaxKind :: SHEBANG } ; }
+macro_rules ! T { [;] => { $ crate :: SyntaxKind :: SEMICOLON } ; [,] => { $ crate :: SyntaxKind :: COMMA } ; ['('] => { $ crate :: SyntaxKind :: L_PAREN } ; [')'] => { $ crate :: SyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: SyntaxKind :: L_CURLY } ; ['}'] => { $ crate :: SyntaxKind :: R_CURLY } ; ['['] => { $ crate :: SyntaxKind :: L_BRACK } ; [']'] => { $ crate :: SyntaxKind :: R_BRACK } ; [<] => { $ crate :: SyntaxKind :: L_ANGLE } ; [>] => { $ crate :: SyntaxKind :: R_ANGLE } ; [@] => { $ crate :: SyntaxKind :: AT } ; [#] => { $ crate :: SyntaxKind :: POUND } ; [~] => { $ crate :: SyntaxKind :: TILDE } ; [?] => { $ crate :: SyntaxKind :: QUESTION } ; [$] => { $ crate :: SyntaxKind :: DOLLAR } ; [&] => { $ crate :: SyntaxKind :: AMP } ; [|] => { $ crate :: SyntaxKind :: PIPE } ; [+] => { $ crate :: SyntaxKind :: PLUS } ; [*] => { $ crate :: SyntaxKind :: STAR } ; [/] => { $ crate :: SyntaxKind :: SLASH } ; [^] => { $ crate :: SyntaxKind :: CARET } ; [%] => { $ crate :: SyntaxKind :: PERCENT } ; [_] => { $ crate :: SyntaxKind :: UNDERSCORE } ; [.] => { $ crate :: SyntaxKind :: DOT } ; [..] => { $ crate :: SyntaxKind :: DOT2 } ; [...] => { $ crate :: SyntaxKind :: DOT3 } ; [..=] => { $ crate :: SyntaxKind :: DOT2EQ } ; [:] => { $ crate :: SyntaxKind :: COLON } ; [::] => { $ crate :: SyntaxKind :: COLON2 } ; [=] => { $ crate :: SyntaxKind :: EQ } ; [==] => { $ crate :: SyntaxKind :: EQ2 } ; [=>] => { $ crate :: SyntaxKind :: FAT_ARROW } ; [!] => { $ crate :: SyntaxKind :: BANG } ; [!=] => { $ crate :: SyntaxKind :: NEQ } ; [-] => { $ crate :: SyntaxKind :: MINUS } ; [->] => { $ crate :: SyntaxKind :: THIN_ARROW } ; [<=] => { $ crate :: SyntaxKind :: LTEQ } ; [>=] => { $ crate :: SyntaxKind :: GTEQ } ; [+=] => { $ crate :: SyntaxKind :: PLUSEQ } ; [-=] => { $ crate :: SyntaxKind :: MINUSEQ } ; [|=] => { $ crate :: SyntaxKind :: PIPEEQ } ; [&=] => { $ crate :: SyntaxKind :: AMPEQ } ; [^=] => { $ crate :: SyntaxKind :: CARETEQ } ; [/=] => { $ crate :: SyntaxKind :: SLASHEQ } ; [*=] => { $ crate :: SyntaxKind :: STAREQ } ; [%=] => { $ crate :: SyntaxKind :: PERCENTEQ } ; [&&] => { $ crate :: SyntaxKind :: AMP2 } ; [||] => { $ crate :: SyntaxKind :: PIPE2 } ; [<<] => { $ crate :: SyntaxKind :: SHL } ; [>>] => { $ crate :: SyntaxKind :: SHR } ; [<<=] => { $ crate :: SyntaxKind :: SHLEQ } ; [>>=] => { $ crate :: SyntaxKind :: SHREQ } ; [as] => { $ crate :: SyntaxKind :: AS_KW } ; [async] => { $ crate :: SyntaxKind :: ASYNC_KW } ; [await] => { $ crate :: SyntaxKind :: AWAIT_KW } ; [box] => { $ crate :: SyntaxKind :: BOX_KW } ; [break] => { $ crate :: SyntaxKind :: BREAK_KW } ; [const] => { $ crate :: SyntaxKind :: CONST_KW } ; [continue] => { $ crate :: SyntaxKind :: CONTINUE_KW } ; [crate] => { $ crate :: SyntaxKind :: CRATE_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [else] => { $ crate :: SyntaxKind :: ELSE_KW } ; [enum] => { $ crate :: SyntaxKind :: ENUM_KW } ; [extern] => { $ crate :: SyntaxKind :: EXTERN_KW } ; [false] => { $ crate :: SyntaxKind :: FALSE_KW } ; [fn] => { $ crate :: SyntaxKind :: FN_KW } ; [for] => { $ crate :: SyntaxKind :: FOR_KW } ; [if] => { $ crate :: SyntaxKind :: IF_KW } ; [impl] => { $ crate :: SyntaxKind :: IMPL_KW } ; [in] => { $ crate :: SyntaxKind :: IN_KW } ; [let] => { $ crate :: SyntaxKind :: LET_KW } ; [loop] => { $ crate :: SyntaxKind :: LOOP_KW } ; [macro] => { $ crate :: SyntaxKind :: MACRO_KW } ; [match] => { $ crate :: SyntaxKind :: MATCH_KW } ; [mod] => { $ crate :: SyntaxKind :: MOD_KW } ; [move] => { $ crate :: SyntaxKind :: MOVE_KW } ; [mut] => { $ crate :: SyntaxKind :: MUT_KW } ; [pub] => { $ crate :: SyntaxKind :: PUB_KW } ; [ref] => { $ crate :: SyntaxKind :: REF_KW } ; [return] => { $ crate :: SyntaxKind :: RETURN_KW } ; [self] => { $ crate :: SyntaxKind :: SELF_KW } ; [Self] => { $ crate :: SyntaxKind :: SELF_TYPE_KW } ; [static] => { $ crate :: SyntaxKind :: STATIC_KW } ; [struct] => { $ crate :: SyntaxKind :: STRUCT_KW } ; [super] => { $ crate :: SyntaxKind :: SUPER_KW } ; [trait] => { $ crate :: SyntaxKind :: TRAIT_KW } ; [true] => { $ crate :: SyntaxKind :: TRUE_KW } ; [try] => { $ crate :: SyntaxKind :: TRY_KW } ; [type] => { $ crate :: SyntaxKind :: TYPE_KW } ; [unsafe] => { $ crate :: SyntaxKind :: UNSAFE_KW } ; [use] => { $ crate :: SyntaxKind :: USE_KW } ; [where] => { $ crate :: SyntaxKind :: WHERE_KW } ; [while] => { $ crate :: SyntaxKind :: WHILE_KW } ; [yield] => { $ crate :: SyntaxKind :: YIELD_KW } ; [auto] => { $ crate :: SyntaxKind :: AUTO_KW } ; [default] => { $ crate :: SyntaxKind :: DEFAULT_KW } ; [existential] => { $ crate :: SyntaxKind :: EXISTENTIAL_KW } ; [union] => { $ crate :: SyntaxKind :: UNION_KW } ; [raw] => { $ crate :: SyntaxKind :: RAW_KW } ; [macro_rules] => { $ crate :: SyntaxKind :: MACRO_RULES_KW } ; [lifetime_ident] => { $ crate :: SyntaxKind :: LIFETIME_IDENT } ; [ident] => { $ crate :: SyntaxKind :: IDENT } ; [shebang] => { $ crate :: SyntaxKind :: SHEBANG } ; [float_number] => { $ crate :: SyntaxKind :: FLOAT_NUMBER } ; }
pub use T;
diff --git a/crates/parser/test_data/parser/inline/ok/0085_expr_literals.rast b/crates/parser/test_data/parser/inline/ok/0085_expr_literals.rast
index 403c265ea3..065af27f10 100644
--- a/crates/parser/test_data/parser/inline/ok/0085_expr_literals.rast
+++ b/crates/parser/test_data/parser/inline/ok/0085_expr_literals.rast
@@ -57,7 +57,8 @@ SOURCE_FILE
EQ "="
WHITESPACE " "
LITERAL
- FLOAT_NUMBER "2.0"
+ FLOAT_LITERAL
+ FLOAT_NUMBER "2.0"
SEMICOLON ";"
WHITESPACE "\n "
LET_STMT
diff --git a/crates/parser/test_data/parser/ok/0056_neq_in_type.rast b/crates/parser/test_data/parser/ok/0056_neq_in_type.rast
index 55ce31275f..903a1507d0 100644
--- a/crates/parser/test_data/parser/ok/0056_neq_in_type.rast
+++ b/crates/parser/test_data/parser/ok/0056_neq_in_type.rast
@@ -19,7 +19,8 @@ SOURCE_FILE
CAST_EXPR
METHOD_CALL_EXPR
LITERAL
- FLOAT_NUMBER "1.0f32"
+ FLOAT_LITERAL
+ FLOAT_NUMBER "1.0f32"
DOT "."
NAME_REF
IDENT "floor"
@@ -40,7 +41,8 @@ SOURCE_FILE
CAST_EXPR
METHOD_CALL_EXPR
LITERAL
- FLOAT_NUMBER "1.0f32"
+ FLOAT_LITERAL
+ FLOAT_NUMBER "1.0f32"
DOT "."
NAME_REF
IDENT "floor"
diff --git a/crates/syntax/rust.ungram b/crates/syntax/rust.ungram
index 62aa478399..4b3e483bff 100644
--- a/crates/syntax/rust.ungram
+++ b/crates/syntax/rust.ungram
@@ -365,13 +365,16 @@ MacroExpr =
Literal =
Attr* value:(
- 'int_number' | 'float_number'
+ 'int_number' | FloatLiteral
| 'string' | 'raw_string'
| 'byte_string' | 'raw_byte_string'
| 'true' | 'false'
| 'char' | 'byte'
)
+FloatLiteral =
+ 'float_number'
+
PathExpr =
Attr* Path
diff --git a/crates/syntax/src/ast/expr_ext.rs b/crates/syntax/src/ast/expr_ext.rs
index 23b1145a77..f4bff80c4c 100644
--- a/crates/syntax/src/ast/expr_ext.rs
+++ b/crates/syntax/src/ast/expr_ext.rs
@@ -282,7 +282,7 @@ pub enum LiteralKind {
String(ast::String),
ByteString(ast::ByteString),
IntNumber(ast::IntNumber),
- FloatNumber(ast::FloatNumber),
+ FloatNumber(ast::FloatLiteral),
Char(ast::Char),
Byte(ast::Byte),
Bool(bool),
@@ -297,16 +297,17 @@ impl ast::Literal {
}
pub fn kind(&self) -> LiteralKind {
let token = match self.value() {
- rowan::NodeOrToken::Node(_node) => unreachable!(),
+ rowan::NodeOrToken::Node(node) => {
+ return LiteralKind::FloatNumber(
+ ast::FloatLiteral::cast(node).expect("unreachable"),
+ );
+ }
rowan::NodeOrToken::Token(token) => token,
};
if let Some(t) = ast::IntNumber::cast(token.clone()) {
return LiteralKind::IntNumber(t);
}
- if let Some(t) = ast::FloatNumber::cast(token.clone()) {
- return LiteralKind::FloatNumber(t);
- }
if let Some(t) = ast::String::cast(token.clone()) {
return LiteralKind::String(t);
}
@@ -326,6 +327,26 @@ impl ast::Literal {
_ => unreachable!(),
}
}
+
+ pub fn as_string(&self) -> Option<ast::String> {
+ match self.kind() {
+ LiteralKind::String(it) => Some(it),
+ _ => None,
+ }
+ }
+
+ pub fn as_byte_string(&self) -> Option<ast::ByteString> {
+ match self.kind() {
+ LiteralKind::ByteString(it) => Some(it),
+ _ => None,
+ }
+ }
+}
+
+impl ast::FloatLiteral {
+ pub fn suffix(&self) -> Option<String> {
+ ast::FloatNumber::cast(self.syntax().last_token()?)?.suffix().map(|s| s.to_string())
+ }
}
pub enum BlockModifier {
diff --git a/crates/syntax/src/ast/generated/nodes.rs b/crates/syntax/src/ast/generated/nodes.rs
index cf90ba64cf..b294849937 100644
--- a/crates/syntax/src/ast/generated/nodes.rs
+++ b/crates/syntax/src/ast/generated/nodes.rs
@@ -1086,6 +1086,16 @@ impl UnderscoreExpr {
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct FloatLiteral {
+ pub(crate) syntax: SyntaxNode,
+}
+impl FloatLiteral {
+ pub fn float_number_token(&self) -> Option<SyntaxToken> {
+ support::token(&self.syntax, T![float_number])
+ }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct StmtList {
pub(crate) syntax: SyntaxNode,
}
@@ -2719,6 +2729,17 @@ impl AstNode for UnderscoreExpr {
}
fn syntax(&self) -> &SyntaxNode { &self.syntax }
}
+impl AstNode for FloatLiteral {
+ fn can_cast(kind: SyntaxKind) -> bool { kind == FLOAT_LITERAL }
+ fn cast(syntax: SyntaxNode) -> Option<Self> {
+ if Self::can_cast(syntax.kind()) {
+ Some(Self { syntax })
+ } else {
+ None
+ }
+ }
+ fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
impl AstNode for StmtList {
fn can_cast(kind: SyntaxKind) -> bool { kind == STMT_LIST }
fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -4608,6 +4629,11 @@ impl std::fmt::Display for UnderscoreExpr {
std::fmt::Display::fmt(self.syntax(), f)
}
}
+impl std::fmt::Display for FloatLiteral {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ std::fmt::Display::fmt(self.syntax(), f)
+ }
+}
impl std::fmt::Display for StmtList {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(self.syntax(), f)
diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs
index 5908dda8e6..846f4f3c71 100644
--- a/crates/syntax/src/ast/make.rs
+++ b/crates/syntax/src/ast/make.rs
@@ -799,6 +799,11 @@ pub fn struct_(
))
}
+pub fn literal(text: &str) -> ast::Literal {
+ assert_eq!(text.trim(), text);
+ ast_from_text(&format!("fn f() {{ let _ = {}; }}", text))
+}
+
#[track_caller]
fn ast_from_text<N: AstNode>(text: &str) -> N {
let parse = SourceFile::parse(text);
@@ -827,7 +832,7 @@ pub fn token(kind: SyntaxKind) -> SyntaxToken {
pub mod tokens {
use once_cell::sync::Lazy;
- use crate::{ast, AstNode, Parse, SourceFile, SyntaxKind::*, SyntaxToken};
+ use crate::{AstNode, Parse, SourceFile, SyntaxKind::*, SyntaxToken};
pub(super) static SOURCE_FILE: Lazy<Parse<SourceFile>> = Lazy::new(|| {
SourceFile::parse(
@@ -858,12 +863,6 @@ pub mod tokens {
sf.syntax().first_child_or_token().unwrap().into_token().unwrap()
}
- pub fn literal(text: &str) -> SyntaxToken {
- assert_eq!(text.trim(), text);
- let lit: ast::Literal = super::ast_from_text(&format!("fn f() {{ let _ = {}; }}", text));
- lit.syntax().first_child_or_token().unwrap().into_token().unwrap()
- }
-
pub fn single_newline() -> SyntaxToken {
let res = SOURCE_FILE
.tree()
diff --git a/crates/syntax/src/ast/token_ext.rs b/crates/syntax/src/ast/token_ext.rs
index 4b6dc236b5..3063396b44 100644
--- a/crates/syntax/src/ast/token_ext.rs
+++ b/crates/syntax/src/ast/token_ext.rs
@@ -355,14 +355,24 @@ impl Radix {
#[cfg(test)]
mod tests {
- use crate::ast::{self, make, FloatNumber, IntNumber};
+ use crate::ast::{self, make};
fn check_float_suffix<'a>(lit: &str, expected: impl Into<Option<&'a str>>) {
- assert_eq!(FloatNumber { syntax: make::tokens::literal(lit) }.suffix(), expected.into());
+ let suffix = match make::literal(lit).kind() {
+ ast::LiteralKind::FloatNumber(f) => f.suffix(),
+ // `1f32` lexes as an INT_NUMBER
+ ast::LiteralKind::IntNumber(i) => i.suffix().map(|s| s.to_string()),
+ e => unreachable!("{e:?}"),
+ };
+ assert_eq!(suffix.as_deref(), expected.into());
}
fn check_int_suffix<'a>(lit: &str, expected: impl Into<Option<&'a str>>) {
- assert_eq!(IntNumber { syntax: make::tokens::literal(lit) }.suffix(), expected.into());
+ let i = match make::literal(lit).kind() {
+ ast::LiteralKind::IntNumber(i) => i,
+ _ => unreachable!(),
+ };
+ assert_eq!(i.suffix(), expected.into());
}
#[test]
@@ -390,12 +400,11 @@ mod tests {
}
fn check_string_value<'a>(lit: &str, expected: impl Into<Option<&'a str>>) {
- assert_eq!(
- ast::String { syntax: make::tokens::literal(&format!("\"{}\"", lit)) }
- .value()
- .as_deref(),
- expected.into()
- );
+ let s = match make::literal(&format!("\"{}\"", lit)).kind() {
+ ast::LiteralKind::String(s) => s,
+ _ => unreachable!(),
+ };
+ assert_eq!(s.value().as_deref(), expected.into());
}
#[test]
diff --git a/crates/syntax/src/tests/ast_src.rs b/crates/syntax/src/tests/ast_src.rs
index 2f6932a1ad..964bd6c8b3 100644
--- a/crates/syntax/src/tests/ast_src.rs
+++ b/crates/syntax/src/tests/ast_src.rs
@@ -183,6 +183,7 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc {
"PATH",
"PATH_SEGMENT",
"LITERAL",
+ "FLOAT_LITERAL",
"RENAME",
"VISIBILITY",
"WHERE_CLAUSE",
diff --git a/crates/syntax/src/tests/sourcegen_ast.rs b/crates/syntax/src/tests/sourcegen_ast.rs
index 4cfb8075cb..e18f575e37 100644
--- a/crates/syntax/src/tests/sourcegen_ast.rs
+++ b/crates/syntax/src/tests/sourcegen_ast.rs
@@ -462,6 +462,7 @@ fn generate_syntax_kinds(grammar: KindsSrc<'_>) -> String {
[lifetime_ident] => { $crate::SyntaxKind::LIFETIME_IDENT };
[ident] => { $crate::SyntaxKind::IDENT };
[shebang] => { $crate::SyntaxKind::SHEBANG };
+ [float_number] => { $crate::SyntaxKind::FLOAT_NUMBER };
}
pub use T;
};