diff --git a/crates/ide-completion/src/completions/postfix.rs b/crates/ide-completion/src/completions/postfix.rs index 7b936f0ff77..cc2a4437000 100644 --- a/crates/ide-completion/src/completions/postfix.rs +++ b/crates/ide-completion/src/completions/postfix.rs @@ -5,7 +5,7 @@ mod format_like; use hir::{Documentation, HasAttrs}; use ide_db::{imports::insert_use::ImportScope, ty_filter::TryEnum, SnippetCap}; use syntax::{ - ast::{self, AstNode, AstToken}, + ast::{self, AstNode, LiteralKind}, SyntaxKind::{EXPR_STMT, STMT_LIST}, TextRange, TextSize, }; @@ -191,7 +191,7 @@ pub(crate) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) { } if let ast::Expr::Literal(literal) = dot_receiver.clone() { - if let Some(literal_text) = ast::String::cast(literal.token()) { + if let LiteralKind::String(literal_text) = literal.kind() { add_format_like_completions(acc, ctx, &dot_receiver, cap, &literal_text); } } diff --git a/crates/ide-completion/src/patterns.rs b/crates/ide-completion/src/patterns.rs index 6fdec783854..c1db8ce4a6c 100644 --- a/crates/ide-completion/src/patterns.rs +++ b/crates/ide-completion/src/patterns.rs @@ -230,7 +230,7 @@ pub(crate) fn determine_location( let receiver = find_in_original_file(it.expr(), original_file); let receiver_is_ambiguous_float_literal = if let Some(ast::Expr::Literal(l)) = &receiver { match l.kind() { - ast::LiteralKind::FloatNumber { .. } => l.token().text().ends_with('.'), + ast::LiteralKind::FloatNumber { .. } => l.to_string().ends_with('.'), _ => false, } } else { diff --git a/crates/syntax/src/ast/expr_ext.rs b/crates/syntax/src/ast/expr_ext.rs index 17785152bc5..23b1145a774 100644 --- a/crates/syntax/src/ast/expr_ext.rs +++ b/crates/syntax/src/ast/expr_ext.rs @@ -8,7 +8,7 @@ use crate::{ operators::{ArithOp, BinaryOp, CmpOp, LogicOp, Ordering, RangeOp, UnaryOp}, support, AstChildren, AstNode, }, - AstToken, + AstToken, SyntaxElement, SyntaxKind::*, SyntaxNode, SyntaxToken, T, }; @@ -289,16 +289,17 @@ pub enum LiteralKind { } impl ast::Literal { - pub fn token(&self) -> SyntaxToken { + pub fn value(&self) -> SyntaxElement { self.syntax() .children_with_tokens() .find(|e| e.kind() != ATTR && !e.kind().is_trivia()) - .and_then(|e| e.into_token()) .unwrap() } - pub fn kind(&self) -> LiteralKind { - let token = self.token(); + let token = match self.value() { + rowan::NodeOrToken::Node(_node) => unreachable!(), + rowan::NodeOrToken::Token(token) => token, + }; if let Some(t) = ast::IntNumber::cast(token.clone()) { return LiteralKind::IntNumber(t); @@ -364,7 +365,7 @@ impl ast::BlockExpr { fn test_literal_with_attr() { let parse = ast::SourceFile::parse(r#"const _: &str = { #[attr] "Hello" };"#); let lit = parse.tree().syntax().descendants().find_map(ast::Literal::cast).unwrap(); - assert_eq!(lit.token().text(), r#""Hello""#); + assert_eq!(lit.value().to_string(), r#""Hello""#); } impl ast::RecordExprField { diff --git a/crates/syntax/src/validation.rs b/crates/syntax/src/validation.rs index c2c2c82e11f..3edca3eb8f9 100644 --- a/crates/syntax/src/validation.rs +++ b/crates/syntax/src/validation.rs @@ -119,8 +119,15 @@ fn validate_literal(literal: ast::Literal, acc: &mut Vec) { text.rfind(end_delimiter).and_then(|end| text.get(prefix_len..end)) } - let token = literal.token(); - let text = token.text(); + let token = literal.value(); + let text; + let text = match &token { + rowan::NodeOrToken::Node(node) => { + text = node.text().to_string(); + &*text + } + rowan::NodeOrToken::Token(token) => token.text(), + }; // FIXME: lift this lambda refactor to `fn` (https://github.com/rust-analyzer/rust-analyzer/pull/2834#discussion_r366199205) let mut push_err = |prefix_len, (off, err): (usize, unescape::EscapeError)| {