diff --git a/crates/ide/src/syntax_highlighting/highlight.rs b/crates/ide/src/syntax_highlighting/highlight.rs index f061e8637ec..2e3271dc315 100644 --- a/crates/ide/src/syntax_highlighting/highlight.rs +++ b/crates/ide/src/syntax_highlighting/highlight.rs @@ -31,6 +31,9 @@ pub(super) fn token(sema: &Semantics, token: SyntaxToken) -> Optio SymbolKind::Field.into() } INT_NUMBER | FLOAT_NUMBER_PART => HlTag::NumericLiteral.into(), + DOT if token.parent().map(|n| n.kind()) == Some(FLOAT_LITERAL) => { + HlTag::NumericLiteral.into() + } BYTE => HlTag::ByteLiteral.into(), CHAR => HlTag::CharLiteral.into(), IDENT if token.parent().and_then(ast::TokenTree::cast).is_some() => { diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html b/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html index 329184730e0..d7d6c79e3d3 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html @@ -119,13 +119,13 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd println!("Hello {:05}!", 5); println!("Hello {:05}!", -5); println!("{:#010x}!", 27); - println!("Hello {0} is {1:.5}", "x", 0.01); - println!("Hello {1} is {2:.0$}", 5, "x", 0.01); - println!("Hello {0} is {2:.1$}", "x", 5, 0.01); - println!("Hello {} is {:.*}", "x", 5, 0.01); - println!("Hello {} is {2:.*}", "x", 5, 0.01); - println!("Hello {} is {number:.prec$}", "x", prec = 5, number = 0.01); - println!("{}, `{name:.*}` has 3 fractional digits", "Hello", 3, name=1234.56); + println!("Hello {0} is {1:.5}", "x", 0.01); + println!("Hello {1} is {2:.0$}", 5, "x", 0.01); + println!("Hello {0} is {2:.1$}", "x", 5, 0.01); + println!("Hello {} is {:.*}", "x", 5, 0.01); + println!("Hello {} is {2:.*}", "x", 5, 0.01); + println!("Hello {} is {number:.prec$}", "x", prec = 5, number = 0.01); + println!("{}, `{name:.*}` has 3 fractional digits", "Hello", 3, name=1234.56); println!("{}, `{name:.*}` has 3 characters", "Hello", 3, name="1234.56"); println!("{}, `{name:>8.*}` has 3 right-aligned characters", "Hello", 3, name="1234.56"); println!("Hello {{}}"); diff --git a/crates/parser/src/grammar/expressions.rs b/crates/parser/src/grammar/expressions.rs index 4189ec41b3f..cb384cce815 100644 --- a/crates/parser/src/grammar/expressions.rs +++ b/crates/parser/src/grammar/expressions.rs @@ -3,7 +3,7 @@ mod atom; use super::*; pub(crate) use self::atom::{block_expr, match_arm_list}; -pub(super) use self::atom::{literal, LITERAL_FIRST}; +pub(super) use self::atom::{float_literal, literal, LITERAL_FIRST}; #[derive(PartialEq, Eq)] pub(super) enum Semicolon { diff --git a/crates/parser/src/grammar/expressions/atom.rs b/crates/parser/src/grammar/expressions/atom.rs index 07b0a2aee58..d7a06917178 100644 --- a/crates/parser/src/grammar/expressions/atom.rs +++ b/crates/parser/src/grammar/expressions/atom.rs @@ -30,16 +30,7 @@ pub(crate) fn literal(p: &mut Parser) -> Option { } let m = p.start(); if p.at(FLOAT_NUMBER_PART) { - // Floats can be up to 3 tokens: 2 `FLOAT_NUMBER_PART`s separated by 1 `DOT` - let f = p.start(); - p.bump(FLOAT_NUMBER_PART); - if p.at(DOT) { - p.bump(DOT); - if p.at(FLOAT_NUMBER_PART) { - p.bump(FLOAT_NUMBER_PART); - } - } - f.complete(p, FLOAT_LITERAL); + float_literal(p); } else { // Everything else is just one token. p.bump_any(); @@ -47,6 +38,19 @@ pub(crate) fn literal(p: &mut Parser) -> Option { Some(m.complete(p, LITERAL)) } +pub(crate) fn float_literal(p: &mut Parser) { + // Floats can be up to 3 tokens: 2 `FLOAT_NUMBER_PART`s separated by 1 `DOT` + let f = p.start(); + p.bump(FLOAT_NUMBER_PART); + if p.at(DOT) { + p.bump(DOT); + if p.at(FLOAT_NUMBER_PART) { + p.bump(FLOAT_NUMBER_PART); + } + } + f.complete(p, FLOAT_LITERAL); +} + // E.g. for after the break in `if break {}`, this should not match pub(super) const ATOM_EXPR_FIRST: TokenSet = LITERAL_FIRST.union(paths::PATH_FIRST).union(TokenSet::new(&[ diff --git a/crates/parser/src/grammar/items.rs b/crates/parser/src/grammar/items.rs index 7bfd9ef8c8a..3d2f788e9a4 100644 --- a/crates/parser/src/grammar/items.rs +++ b/crates/parser/src/grammar/items.rs @@ -9,7 +9,7 @@ pub(crate) use self::{ traits::assoc_item_list, use_item::use_tree_list, }; -use super::*; +use super::{expressions::float_literal, *}; // test mod_contents // fn foo() {} @@ -457,6 +457,9 @@ pub(crate) fn token_tree(p: &mut Parser) { return; } T![')'] | T![']'] => p.err_and_bump("unmatched brace"), + FLOAT_NUMBER_PART => { + float_literal(p); + } _ => p.bump_any(), } } diff --git a/crates/parser/test_data/parser/err/0023_mismatched_paren.rast b/crates/parser/test_data/parser/err/0023_mismatched_paren.rast index f57e58a4b7f..a13dcd77f54 100644 --- a/crates/parser/test_data/parser/err/0023_mismatched_paren.rast +++ b/crates/parser/test_data/parser/err/0023_mismatched_paren.rast @@ -32,9 +32,10 @@ SOURCE_FILE INT_NUMBER "1" COMMA "," WHITESPACE " " - FLOAT_NUMBER_PART "2" - DOT "." - FLOAT_NUMBER_PART "0" + FLOAT_LITERAL + FLOAT_NUMBER_PART "2" + DOT "." + FLOAT_NUMBER_PART "0" WHITESPACE "\n " R_CURLY "}" WHITESPACE " "