From 3aaaf924cb649ecc3b1a59653f47d1735fa7cb5d Mon Sep 17 00:00:00 2001 From: Leander Tentrup Date: Sun, 7 Jun 2020 22:57:24 +0200 Subject: Fix bug in lexer for format specifier where the `type` and `width` were not correctly distinguished --- crates/ra_ide/src/snapshots/highlight_strings.html | 2 +- crates/ra_syntax/src/ast/tokens.rs | 37 ++++++++++++++-------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/crates/ra_ide/src/snapshots/highlight_strings.html b/crates/ra_ide/src/snapshots/highlight_strings.html index e97192b61..6a5cf0e74 100644 --- a/crates/ra_ide/src/snapshots/highlight_strings.html +++ b/crates/ra_ide/src/snapshots/highlight_strings.html @@ -63,7 +63,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd println!("Hello {:^5}!", "x"); println!("Hello {:>5}!", "x"); println!("Hello {:+}!", 5); - println!("{:#x}!", 27); + println!("{:#x}!", 27); println!("Hello {:05}!", 5); println!("Hello {:05}!", -5); println!("{:#010x}!", 27); diff --git a/crates/ra_syntax/src/ast/tokens.rs b/crates/ra_syntax/src/ast/tokens.rs index 04b0a4480..56378385a 100644 --- a/crates/ra_syntax/src/ast/tokens.rs +++ b/crates/ra_syntax/src/ast/tokens.rs @@ -335,16 +335,26 @@ pub trait HasFormatSpecifier: AstToken { } c if c == '_' || c.is_alphabetic() => { read_identifier(&mut chars, &mut callback); - if chars.peek().and_then(|next| next.1.as_ref().ok()).copied() - != Some('$') - { - continue; - } - skip_char_and_emit( - &mut chars, - FormatSpecifier::DollarSign, - &mut callback, - ); + // can be either width (indicated by dollar sign, or type in which case + // the next sign has to be `}`) + let next = + chars.peek().and_then(|next| next.1.as_ref().ok()).copied(); + match next { + Some('$') => skip_char_and_emit( + &mut chars, + FormatSpecifier::DollarSign, + &mut callback, + ), + Some('}') => { + skip_char_and_emit( + &mut chars, + FormatSpecifier::Close, + &mut callback, + ); + continue; + } + _ => continue, + }; } _ => {} } @@ -416,12 +426,11 @@ pub trait HasFormatSpecifier: AstToken { } } - let mut cloned = chars.clone().take(2); - let first = cloned.next().and_then(|next| next.1.as_ref().ok()).copied(); - if first != Some('}') { + if let Some((_, Ok('}'))) = chars.peek() { + skip_char_and_emit(&mut chars, FormatSpecifier::Close, &mut callback); + } else { continue; } - skip_char_and_emit(&mut chars, FormatSpecifier::Close, &mut callback); } _ => { while let Some((_, Ok(next_char))) = chars.peek() { -- cgit v1.2.3