Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions crates/hir-def/src/expr_store/lower/format_args.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
//! Lowering of `format_args!()`.

use base_db::FxIndexSet;
use hir_expand::name::Name;
use hir_expand::name::{AsName, Name};
use intern::{Symbol, sym};
use span::SyntaxContext;
use syntax::{AstPtr, AstToken as _, ast};
use syntax::{
AstPtr, AstToken as _,
ast::{self, HasName},
};

use crate::{
expr_store::{HygieneId, lower::ExprCollector, path::Path},
Expand All @@ -29,8 +32,8 @@ impl<'db> ExprCollector<'db> {
f.args().for_each(|arg| {
let expr = arg.expr();
args.add(FormatArgument {
kind: match arg.arg_name() {
Some(name) => FormatArgumentKind::Named(Name::new_root(name.name().text())),
kind: match arg.name() {
Some(name) => FormatArgumentKind::Named(name.as_name()),
None => FormatArgumentKind::Normal,
},
syntax: expr.as_ref().map(AstPtr::new),
Expand Down
22 changes: 11 additions & 11 deletions crates/ide/src/syntax_highlighting/test_data/highlight_strings.html

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions crates/parser/src/grammar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,12 @@ fn name(p: &mut Parser<'_>) {
name_r(p, TokenSet::EMPTY);
}

fn name_any_identifier(p: &mut Parser<'_>) {
let m = p.start();
p.bump_remap_any_ident();
m.complete(p, NAME);
}

fn name_ref_or_self(p: &mut Parser<'_>) {
if matches!(p.current(), T![ident] | T![self]) {
let m = p.start();
Expand Down
12 changes: 7 additions & 5 deletions crates/parser/src/grammar/expressions/atom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,10 +291,8 @@ fn builtin_expr(p: &mut Parser<'_>) -> Option<CompletedMarker> {
while !p.at(EOF) && !p.at(T![')']) {
let m = p.start();
if p.current().is_any_identifier() && p.nth_at(1, T![=]) && !p.nth_at(2, T![=]) {
let m = p.start();
p.bump_any();
name_any_identifier(p);
p.bump(T![=]);
m.complete(p, FORMAT_ARGS_ARG_NAME);
}
if expr(p).is_none() {
m.abandon(p);
Expand Down Expand Up @@ -376,8 +374,12 @@ pub(crate) fn parse_asm_expr(p: &mut Parser<'_>, m: Marker) -> Option<CompletedM
}

// Parse operand names
if p.at(T![ident]) && p.nth_at(1, T![=]) {
name(p);
if p.current().is_any_identifier() && p.nth_at(1, T![=]) {
// test asm_keyword_name
// fn foo() {
// builtin # asm("", fn = const 0);
// }
name_any_identifier(p);
p.bump(T![=]);
allow_templates = false;
}
Expand Down
6 changes: 6 additions & 0 deletions crates/parser/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,12 @@ impl<'t> Parser<'t> {
true
}

/// This consumes the next token as an identifier, even if it is a strict keyword.
pub(crate) fn bump_remap_any_ident(&mut self) {
assert!(self.current().is_any_identifier());
self.bump_remap(T![ident]);
}

fn at_composite2(&self, n: usize, k1: SyntaxKind, k2: SyntaxKind) -> bool {
self.inp.kind(self.pos + n) == k1
&& self.inp.kind(self.pos + n + 1) == k2
Expand Down
2 changes: 0 additions & 2 deletions crates/parser/src/syntax_kind/generated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,6 @@ pub enum SyntaxKind {
FN,
FN_PTR_TYPE,
FORMAT_ARGS_ARG,
FORMAT_ARGS_ARG_NAME,
FORMAT_ARGS_EXPR,
FOR_BINDER,
FOR_EXPR,
Expand Down Expand Up @@ -402,7 +401,6 @@ impl SyntaxKind {
| FN
| FN_PTR_TYPE
| FORMAT_ARGS_ARG
| FORMAT_ARGS_ARG_NAME
| FORMAT_ARGS_EXPR
| FOR_BINDER
| FOR_EXPR
Expand Down
4 changes: 4 additions & 0 deletions crates/parser/test_data/generated/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ mod ok {
#[test]
fn asm_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/asm_expr.rs"); }
#[test]
fn asm_keyword_name() {
run_and_expect_no_errors("test_data/parser/inline/ok/asm_keyword_name.rs");
}
#[test]
fn asm_kinds() { run_and_expect_no_errors("test_data/parser/inline/ok/asm_kinds.rs"); }
#[test]
fn asm_label() { run_and_expect_no_errors("test_data/parser/inline/ok/asm_label.rs"); }
Expand Down
42 changes: 42 additions & 0 deletions crates/parser/test_data/parser/inline/ok/asm_keyword_name.rast
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
SOURCE_FILE
FN
FN_KW "fn"
WHITESPACE " "
NAME
IDENT "foo"
PARAM_LIST
L_PAREN "("
R_PAREN ")"
WHITESPACE " "
BLOCK_EXPR
STMT_LIST
L_CURLY "{"
WHITESPACE "\n "
EXPR_STMT
ASM_EXPR
BUILTIN_KW "builtin"
WHITESPACE " "
POUND "#"
WHITESPACE " "
ASM_KW "asm"
L_PAREN "("
LITERAL
STRING "\"\""
COMMA ","
WHITESPACE " "
ASM_OPERAND_NAMED
NAME
IDENT "fn"
WHITESPACE " "
EQ "="
WHITESPACE " "
ASM_CONST
CONST_KW "const"
WHITESPACE " "
LITERAL
INT_NUMBER "0"
R_PAREN ")"
SEMICOLON ";"
WHITESPACE "\n"
R_CURLY "}"
WHITESPACE "\n"
3 changes: 3 additions & 0 deletions crates/parser/test_data/parser/inline/ok/asm_keyword_name.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn foo() {
builtin # asm("", fn = const 0);
}
6 changes: 3 additions & 3 deletions crates/parser/test_data/parser/inline/ok/builtin_expr.rast
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ SOURCE_FILE
COMMA ","
WHITESPACE " "
FORMAT_ARGS_ARG
FORMAT_ARGS_ARG_NAME
NAME
IDENT "a"
WHITESPACE " "
EQ "="
WHITESPACE " "
EQ "="
WHITESPACE " "
BIN_EXPR
LITERAL
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ SOURCE_FILE
COMMA ","
WHITESPACE " "
FORMAT_ARGS_ARG
FORMAT_ARGS_ARG_NAME
TYPE_KW "type"
EQ "="
NAME
IDENT "type"
EQ "="
LITERAL
INT_NUMBER "1"
R_PAREN ")"
Expand Down
5 changes: 1 addition & 4 deletions crates/syntax/rust.ungram
Original file line number Diff line number Diff line change
Expand Up @@ -488,10 +488,7 @@ FormatArgsExpr =
')'

FormatArgsArg =
arg_name:FormatArgsArgName? Expr

FormatArgsArgName =
'=' // This also has a name, but it's any token and we can't put it here
(Name '=')? Expr

MacroExpr =
MacroCall
Expand Down
50 changes: 6 additions & 44 deletions crates/syntax/src/ast/generated/nodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -723,16 +723,10 @@ impl ForType {
pub struct FormatArgsArg {
pub(crate) syntax: SyntaxNode,
}
impl ast::HasName for FormatArgsArg {}
impl FormatArgsArg {
#[inline]
pub fn arg_name(&self) -> Option<FormatArgsArgName> { support::child(&self.syntax) }
#[inline]
pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
}
pub struct FormatArgsArgName {
pub(crate) syntax: SyntaxNode,
}
impl FormatArgsArgName {
#[inline]
pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
}
Expand Down Expand Up @@ -4105,38 +4099,6 @@ impl fmt::Debug for FormatArgsArg {
f.debug_struct("FormatArgsArg").field("syntax", &self.syntax).finish()
}
}
impl AstNode for FormatArgsArgName {
#[inline]
fn kind() -> SyntaxKind
where
Self: Sized,
{
FORMAT_ARGS_ARG_NAME
}
#[inline]
fn can_cast(kind: SyntaxKind) -> bool { kind == FORMAT_ARGS_ARG_NAME }
#[inline]
fn cast(syntax: SyntaxNode) -> Option<Self> {
if Self::can_cast(syntax.kind()) { Some(Self { syntax }) } else { None }
}
#[inline]
fn syntax(&self) -> &SyntaxNode { &self.syntax }
}
impl hash::Hash for FormatArgsArgName {
fn hash<H: hash::Hasher>(&self, state: &mut H) { self.syntax.hash(state); }
}
impl Eq for FormatArgsArgName {}
impl PartialEq for FormatArgsArgName {
fn eq(&self, other: &Self) -> bool { self.syntax == other.syntax }
}
impl Clone for FormatArgsArgName {
fn clone(&self) -> Self { Self { syntax: self.syntax.clone() } }
}
impl fmt::Debug for FormatArgsArgName {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("FormatArgsArgName").field("syntax", &self.syntax).finish()
}
}
impl AstNode for FormatArgsExpr {
#[inline]
fn kind() -> SyntaxKind
Expand Down Expand Up @@ -9810,6 +9772,7 @@ impl AstNode for AnyHasName {
| CONST_PARAM
| ENUM
| FN
| FORMAT_ARGS_ARG
| IDENT_PAT
| MACRO_DEF
| MACRO_RULES
Expand Down Expand Up @@ -9868,6 +9831,10 @@ impl From<Fn> for AnyHasName {
#[inline]
fn from(node: Fn) -> AnyHasName { AnyHasName { syntax: node.syntax } }
}
impl From<FormatArgsArg> for AnyHasName {
#[inline]
fn from(node: FormatArgsArg) -> AnyHasName { AnyHasName { syntax: node.syntax } }
}
impl From<IdentPat> for AnyHasName {
#[inline]
fn from(node: IdentPat) -> AnyHasName { AnyHasName { syntax: node.syntax } }
Expand Down Expand Up @@ -10434,11 +10401,6 @@ impl std::fmt::Display for FormatArgsArg {
std::fmt::Display::fmt(self.syntax(), f)
}
}
impl std::fmt::Display for FormatArgsArgName {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(self.syntax(), f)
}
}
impl std::fmt::Display for FormatArgsExpr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(self.syntax(), f)
Expand Down
9 changes: 0 additions & 9 deletions crates/syntax/src/ast/node_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1169,15 +1169,6 @@ impl From<ast::AssocItem> for ast::AnyHasAttrs {
}
}

impl ast::FormatArgsArgName {
/// This is not a [`ast::Name`], because the name may be a keyword.
pub fn name(&self) -> SyntaxToken {
let name = self.syntax.first_token().unwrap();
assert!(name.kind().is_any_identifier());
name
}
}

impl ast::OrPat {
pub fn leading_pipe(&self) -> Option<SyntaxToken> {
self.syntax
Expand Down