Skip to content

Commit cc9ae2b

Browse files
committed
Auto merge of #12149 - jonas-schievink:literally-just-a-literal, r=jonas-schievink
fix: split float literal tokens at `.` to fix parsing of tuple field accesses This introduces an `ast::FloatLiteral` node, changes the `FLOAT_LITERAL` token to `FLOAT_LITERAL_PART`, and splits any float literal at the `.` character, into a `FLOAT_LITERAL_PART`, and optional `DOT` and trailing `FLOAT_LITERAL_PART` token. The tokens are reassembled when passing them to a macro as a `tt::Literal`. ~~A slight regression is introduced in how float literals are highlighted: the `.` is now highlighted as an operator. I've tried to fix this but couldn't figure out how to highlight the whole `ast::FloatLiteral` node as a unit.~~ This is fixed Fixes #1109 Fixes #10492 Fixes #12107 Fixes #10560 Fixes #11487
2 parents 7dfd1cb + d974a0b commit cc9ae2b

37 files changed

+503
-122
lines changed

crates/hir-def/src/body/lower.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -972,7 +972,7 @@ impl From<ast::LiteralKind> for Literal {
972972
}
973973
}
974974
LiteralKind::FloatNumber(lit) => {
975-
let ty = lit.suffix().and_then(BuiltinFloat::from_suffix);
975+
let ty = lit.suffix().and_then(|s| BuiltinFloat::from_suffix(&s));
976976
Literal::Float(Default::default(), ty)
977977
}
978978
LiteralKind::ByteString(bs) => {

crates/hir-expand/src/builtin_fn_macro.rs

+15-21
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@ use base_db::{AnchoredPath, Edition, FileId};
44
use cfg::CfgExpr;
55
use either::Either;
66
use mbe::{parse_exprs_with_sep, parse_to_token_tree};
7-
use syntax::{
8-
ast::{self, AstToken},
9-
SmolStr,
10-
};
7+
use syntax::{ast, SmolStr};
118

129
use crate::{db::AstDatabase, name, quote, ExpandError, ExpandResult, MacroCallId, MacroCallLoc};
1310

@@ -358,14 +355,7 @@ fn unreachable_expand(
358355
}
359356

360357
fn unquote_str(lit: &tt::Literal) -> Option<String> {
361-
let lit = ast::make::tokens::literal(&lit.to_string());
362-
let token = ast::String::cast(lit)?;
363-
token.value().map(|it| it.into_owned())
364-
}
365-
366-
fn unquote_byte_string(lit: &tt::Literal) -> Option<Vec<u8>> {
367-
let lit = ast::make::tokens::literal(&lit.to_string());
368-
let token = ast::ByteString::cast(lit)?;
358+
let token = ast::make::literal(&lit.to_string()).as_string()?;
369359
token.value().map(|it| it.into_owned())
370360
}
371361

@@ -442,12 +432,16 @@ fn concat_bytes_expand(
442432
for (i, t) in tt.token_trees.iter().enumerate() {
443433
match t {
444434
tt::TokenTree::Leaf(tt::Leaf::Literal(lit)) => {
445-
let token = ast::make::tokens::literal(&lit.to_string());
446-
match token.kind() {
447-
syntax::SyntaxKind::BYTE => bytes.push(token.text().to_string()),
448-
syntax::SyntaxKind::BYTE_STRING => {
449-
let components = unquote_byte_string(lit).unwrap_or_else(Vec::new);
450-
components.into_iter().for_each(|x| bytes.push(x.to_string()));
435+
let lit = ast::make::literal(&lit.to_string());
436+
match lit.kind() {
437+
ast::LiteralKind::ByteString(s) => {
438+
s.value()
439+
.unwrap_or_default()
440+
.into_iter()
441+
.for_each(|x| bytes.push(x.to_string()));
442+
}
443+
ast::LiteralKind::Byte(_) => {
444+
bytes.push(lit.to_string());
451445
}
452446
_ => {
453447
err.get_or_insert(mbe::ExpandError::UnexpectedToken.into());
@@ -481,10 +475,10 @@ fn concat_bytes_expand_subtree(
481475
for (ti, tt) in tree.token_trees.iter().enumerate() {
482476
match tt {
483477
tt::TokenTree::Leaf(tt::Leaf::Literal(lit)) => {
484-
let lit = ast::make::tokens::literal(&lit.to_string());
478+
let lit = ast::make::literal(&lit.to_string());
485479
match lit.kind() {
486-
syntax::SyntaxKind::BYTE | syntax::SyntaxKind::INT_NUMBER => {
487-
bytes.push(lit.text().to_string())
480+
ast::LiteralKind::IntNumber(_) | ast::LiteralKind::Byte(_) => {
481+
bytes.push(lit.to_string());
488482
}
489483
_ => {
490484
return Err(mbe::ExpandError::UnexpectedToken.into());

crates/hir-ty/src/tests/simple.rs

+11
Original file line numberDiff line numberDiff line change
@@ -2733,3 +2733,14 @@ fn f() {
27332733
"#,
27342734
);
27352735
}
2736+
2737+
#[test]
2738+
fn nested_tuple_index() {
2739+
check_no_mismatches(
2740+
r#"
2741+
fn main() {
2742+
let fld: i32 = ((0,),).0.0;
2743+
}
2744+
"#,
2745+
);
2746+
}

crates/ide-completion/src/completions/dot.rs

+20
Original file line numberDiff line numberDiff line change
@@ -785,4 +785,24 @@ fn main() {
785785
",
786786
)
787787
}
788+
789+
#[test]
790+
fn tuple_index_completion() {
791+
check(
792+
r#"
793+
struct I;
794+
impl I {
795+
fn i_method(&self) {}
796+
}
797+
struct S((), I);
798+
799+
fn f(s: S) {
800+
s.1.$0
801+
}
802+
"#,
803+
expect![[r#"
804+
me i_method() fn(&self)
805+
"#]],
806+
);
807+
}
788808
}

crates/ide-completion/src/completions/postfix.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ mod format_like;
55
use hir::{Documentation, HasAttrs};
66
use ide_db::{imports::insert_use::ImportScope, ty_filter::TryEnum, SnippetCap};
77
use syntax::{
8-
ast::{self, AstNode, AstToken},
8+
ast::{self, AstNode, LiteralKind},
99
SyntaxKind::{EXPR_STMT, STMT_LIST},
1010
TextRange, TextSize,
1111
};
@@ -191,7 +191,7 @@ pub(crate) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
191191
}
192192

193193
if let ast::Expr::Literal(literal) = dot_receiver.clone() {
194-
if let Some(literal_text) = ast::String::cast(literal.token()) {
194+
if let LiteralKind::String(literal_text) = literal.kind() {
195195
add_format_like_completions(acc, ctx, &dot_receiver, cap, &literal_text);
196196
}
197197
}

crates/ide-completion/src/patterns.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ pub(crate) fn determine_location(
230230
let receiver = find_in_original_file(it.expr(), original_file);
231231
let receiver_is_ambiguous_float_literal = if let Some(ast::Expr::Literal(l)) = &receiver {
232232
match l.kind() {
233-
ast::LiteralKind::FloatNumber { .. } => l.token().text().ends_with('.'),
233+
ast::LiteralKind::FloatNumber { .. } => l.to_string().ends_with('.'),
234234
_ => false,
235235
}
236236
} else {

crates/ide/src/syntax_highlighting/highlight.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,15 @@ pub(super) fn token(sema: &Semantics<RootDatabase>, token: SyntaxToken) -> Optio
3030
INT_NUMBER if token.ancestors().nth(1).map(|it| it.kind()) == Some(FIELD_EXPR) => {
3131
SymbolKind::Field.into()
3232
}
33-
INT_NUMBER | FLOAT_NUMBER => HlTag::NumericLiteral.into(),
33+
INT_NUMBER | FLOAT_NUMBER_PART | FLOAT_NUMBER_START_0 | FLOAT_NUMBER_START_1
34+
| FLOAT_NUMBER_START_2 => HlTag::NumericLiteral.into(),
35+
DOT if matches!(
36+
token.prev_token().map(|n| n.kind()),
37+
Some(FLOAT_NUMBER_START_1 | FLOAT_NUMBER_START_2)
38+
) =>
39+
{
40+
HlTag::NumericLiteral.into()
41+
}
3442
BYTE => HlTag::ByteLiteral.into(),
3543
CHAR => HlTag::CharLiteral.into(),
3644
IDENT if token.parent().and_then(ast::TokenTree::cast).is_some() => {

0 commit comments

Comments
 (0)