diff options
Diffstat (limited to 'src/tools/rust-analyzer/crates/syntax')
8 files changed, 224 insertions, 56 deletions
diff --git a/src/tools/rust-analyzer/crates/syntax/rust.ungram b/src/tools/rust-analyzer/crates/syntax/rust.ungram index 138ddd208..3603560d3 100644 --- a/src/tools/rust-analyzer/crates/syntax/rust.ungram +++ b/src/tools/rust-analyzer/crates/syntax/rust.ungram @@ -296,7 +296,7 @@ TypeParam = ConstParam = Attr* 'const' Name ':' Type - ('=' default_val:Expr)? + ('=' default_val:ConstArg)? LifetimeParam = Attr* Lifetime (':' TypeBoundList?)? @@ -340,10 +340,10 @@ ExprStmt = Expr = ArrayExpr +| AsmExpr | AwaitExpr | BinExpr | BlockExpr -| BoxExpr | BreakExpr | CallExpr | CastExpr @@ -351,6 +351,7 @@ Expr = | ContinueExpr | FieldExpr | ForExpr +| FormatArgsExpr | IfExpr | IndexExpr | Literal @@ -358,6 +359,7 @@ Expr = | MacroExpr | MatchExpr | MethodCallExpr +| OffsetOfExpr | ParenExpr | PathExpr | PrefixExpr @@ -373,6 +375,21 @@ Expr = | LetExpr | UnderscoreExpr +OffsetOfExpr = + Attr* 'builtin' '#' 'offset_of' '(' Type ',' fields:(NameRef ('.' NameRef)* ) ')' + +AsmExpr = + Attr* 'builtin' '#' 'asm' '(' Expr ')' + +FormatArgsExpr = + Attr* 'builtin' '#' 'format_args' '(' + template:Expr + (',' args:(FormatArgsArg (',' FormatArgsArg)* ','?)? )? + ')' + +FormatArgsArg = + (Name '=')? Expr + MacroExpr = MacroCall @@ -526,9 +543,6 @@ UnderscoreExpr = AwaitExpr = Attr* Expr '.' 'await' -BoxExpr = - Attr* 'box' Expr - //*************************// // Types // //*************************// diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs index 0b27faa53..7ba0d4dc6 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs @@ -709,7 +709,7 @@ impl ConstParam { pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) } pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) } pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) } - pub fn default_val(&self) -> Option<Expr> { support::child(&self.syntax) } + pub fn default_val(&self) -> Option<ConstArg> { support::child(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -805,6 +805,20 @@ impl ArrayExpr { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct AsmExpr { + pub(crate) syntax: SyntaxNode, +} +impl ast::HasAttrs for AsmExpr {} +impl AsmExpr { + pub fn builtin_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![builtin]) } + pub fn pound_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![#]) } + pub fn asm_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![asm]) } + pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) } + pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) } + pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct AwaitExpr { pub(crate) syntax: SyntaxNode, } @@ -823,16 +837,6 @@ impl ast::HasAttrs for BinExpr {} impl BinExpr {} #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct BoxExpr { - pub(crate) syntax: SyntaxNode, -} -impl ast::HasAttrs for BoxExpr {} -impl BoxExpr { - pub fn box_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![box]) } - pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct BreakExpr { pub(crate) syntax: SyntaxNode, } @@ -916,6 +920,24 @@ impl ForExpr { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct FormatArgsExpr { + pub(crate) syntax: SyntaxNode, +} +impl ast::HasAttrs for FormatArgsExpr {} +impl FormatArgsExpr { + pub fn builtin_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![builtin]) } + pub fn pound_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![#]) } + pub fn format_args_token(&self) -> Option<SyntaxToken> { + support::token(&self.syntax, T![format_args]) + } + pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) } + pub fn template(&self) -> Option<Expr> { support::child(&self.syntax) } + pub fn comma_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![,]) } + pub fn args(&self) -> AstChildren<FormatArgsArg> { support::children(&self.syntax) } + pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct IfExpr { pub(crate) syntax: SyntaxNode, } @@ -985,6 +1007,24 @@ impl MethodCallExpr { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct OffsetOfExpr { + pub(crate) syntax: SyntaxNode, +} +impl ast::HasAttrs for OffsetOfExpr {} +impl OffsetOfExpr { + pub fn builtin_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![builtin]) } + pub fn pound_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![#]) } + pub fn offset_of_token(&self) -> Option<SyntaxToken> { + support::token(&self.syntax, T![offset_of]) + } + pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) } + pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) } + pub fn comma_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![,]) } + pub fn fields(&self) -> AstChildren<NameRef> { support::children(&self.syntax) } + pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct ParenExpr { pub(crate) syntax: SyntaxNode, } @@ -1127,6 +1167,16 @@ impl UnderscoreExpr { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct FormatArgsArg { + pub(crate) syntax: SyntaxNode, +} +impl ast::HasName for FormatArgsArg {} +impl FormatArgsArg { + pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) } + pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct StmtList { pub(crate) syntax: SyntaxNode, } @@ -1555,10 +1605,10 @@ pub enum Type { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Expr { ArrayExpr(ArrayExpr), + AsmExpr(AsmExpr), AwaitExpr(AwaitExpr), BinExpr(BinExpr), BlockExpr(BlockExpr), - BoxExpr(BoxExpr), BreakExpr(BreakExpr), CallExpr(CallExpr), CastExpr(CastExpr), @@ -1566,6 +1616,7 @@ pub enum Expr { ContinueExpr(ContinueExpr), FieldExpr(FieldExpr), ForExpr(ForExpr), + FormatArgsExpr(FormatArgsExpr), IfExpr(IfExpr), IndexExpr(IndexExpr), Literal(Literal), @@ -1573,6 +1624,7 @@ pub enum Expr { MacroExpr(MacroExpr), MatchExpr(MatchExpr), MethodCallExpr(MethodCallExpr), + OffsetOfExpr(OffsetOfExpr), ParenExpr(ParenExpr), PathExpr(PathExpr), PrefixExpr(PrefixExpr), @@ -2453,8 +2505,8 @@ impl AstNode for ArrayExpr { } fn syntax(&self) -> &SyntaxNode { &self.syntax } } -impl AstNode for AwaitExpr { - fn can_cast(kind: SyntaxKind) -> bool { kind == AWAIT_EXPR } +impl AstNode for AsmExpr { + fn can_cast(kind: SyntaxKind) -> bool { kind == ASM_EXPR } fn cast(syntax: SyntaxNode) -> Option<Self> { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -2464,8 +2516,8 @@ impl AstNode for AwaitExpr { } fn syntax(&self) -> &SyntaxNode { &self.syntax } } -impl AstNode for BinExpr { - fn can_cast(kind: SyntaxKind) -> bool { kind == BIN_EXPR } +impl AstNode for AwaitExpr { + fn can_cast(kind: SyntaxKind) -> bool { kind == AWAIT_EXPR } fn cast(syntax: SyntaxNode) -> Option<Self> { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -2475,8 +2527,8 @@ impl AstNode for BinExpr { } fn syntax(&self) -> &SyntaxNode { &self.syntax } } -impl AstNode for BoxExpr { - fn can_cast(kind: SyntaxKind) -> bool { kind == BOX_EXPR } +impl AstNode for BinExpr { + fn can_cast(kind: SyntaxKind) -> bool { kind == BIN_EXPR } fn cast(syntax: SyntaxNode) -> Option<Self> { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -2563,6 +2615,17 @@ impl AstNode for ForExpr { } fn syntax(&self) -> &SyntaxNode { &self.syntax } } +impl AstNode for FormatArgsExpr { + fn can_cast(kind: SyntaxKind) -> bool { kind == FORMAT_ARGS_EXPR } + fn cast(syntax: SyntaxNode) -> Option<Self> { + if Self::can_cast(syntax.kind()) { + Some(Self { syntax }) + } else { + None + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} impl AstNode for IfExpr { fn can_cast(kind: SyntaxKind) -> bool { kind == IF_EXPR } fn cast(syntax: SyntaxNode) -> Option<Self> { @@ -2640,6 +2703,17 @@ impl AstNode for MethodCallExpr { } fn syntax(&self) -> &SyntaxNode { &self.syntax } } +impl AstNode for OffsetOfExpr { + fn can_cast(kind: SyntaxKind) -> bool { kind == OFFSET_OF_EXPR } + fn cast(syntax: SyntaxNode) -> Option<Self> { + if Self::can_cast(syntax.kind()) { + Some(Self { syntax }) + } else { + None + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} impl AstNode for ParenExpr { fn can_cast(kind: SyntaxKind) -> bool { kind == PAREN_EXPR } fn cast(syntax: SyntaxNode) -> Option<Self> { @@ -2794,6 +2868,17 @@ impl AstNode for UnderscoreExpr { } fn syntax(&self) -> &SyntaxNode { &self.syntax } } +impl AstNode for FormatArgsArg { + fn can_cast(kind: SyntaxKind) -> bool { kind == FORMAT_ARGS_ARG } + fn cast(syntax: SyntaxNode) -> Option<Self> { + if Self::can_cast(syntax.kind()) { + Some(Self { syntax }) + } else { + None + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} impl AstNode for StmtList { fn can_cast(kind: SyntaxKind) -> bool { kind == STMT_LIST } fn cast(syntax: SyntaxNode) -> Option<Self> { @@ -3373,6 +3458,9 @@ impl AstNode for Type { impl From<ArrayExpr> for Expr { fn from(node: ArrayExpr) -> Expr { Expr::ArrayExpr(node) } } +impl From<AsmExpr> for Expr { + fn from(node: AsmExpr) -> Expr { Expr::AsmExpr(node) } +} impl From<AwaitExpr> for Expr { fn from(node: AwaitExpr) -> Expr { Expr::AwaitExpr(node) } } @@ -3382,9 +3470,6 @@ impl From<BinExpr> for Expr { impl From<BlockExpr> for Expr { fn from(node: BlockExpr) -> Expr { Expr::BlockExpr(node) } } -impl From<BoxExpr> for Expr { - fn from(node: BoxExpr) -> Expr { Expr::BoxExpr(node) } -} impl From<BreakExpr> for Expr { fn from(node: BreakExpr) -> Expr { Expr::BreakExpr(node) } } @@ -3406,6 +3491,9 @@ impl From<FieldExpr> for Expr { impl From<ForExpr> for Expr { fn from(node: ForExpr) -> Expr { Expr::ForExpr(node) } } +impl From<FormatArgsExpr> for Expr { + fn from(node: FormatArgsExpr) -> Expr { Expr::FormatArgsExpr(node) } +} impl From<IfExpr> for Expr { fn from(node: IfExpr) -> Expr { Expr::IfExpr(node) } } @@ -3427,6 +3515,9 @@ impl From<MatchExpr> for Expr { impl From<MethodCallExpr> for Expr { fn from(node: MethodCallExpr) -> Expr { Expr::MethodCallExpr(node) } } +impl From<OffsetOfExpr> for Expr { + fn from(node: OffsetOfExpr) -> Expr { Expr::OffsetOfExpr(node) } +} impl From<ParenExpr> for Expr { fn from(node: ParenExpr) -> Expr { Expr::ParenExpr(node) } } @@ -3474,10 +3565,10 @@ impl AstNode for Expr { matches!( kind, ARRAY_EXPR + | ASM_EXPR | AWAIT_EXPR | BIN_EXPR | BLOCK_EXPR - | BOX_EXPR | BREAK_EXPR | CALL_EXPR | CAST_EXPR @@ -3485,6 +3576,7 @@ impl AstNode for Expr { | CONTINUE_EXPR | FIELD_EXPR | FOR_EXPR + | FORMAT_ARGS_EXPR | IF_EXPR | INDEX_EXPR | LITERAL @@ -3492,6 +3584,7 @@ impl AstNode for Expr { | MACRO_EXPR | MATCH_EXPR | METHOD_CALL_EXPR + | OFFSET_OF_EXPR | PAREN_EXPR | PATH_EXPR | PREFIX_EXPR @@ -3511,10 +3604,10 @@ impl AstNode for Expr { fn cast(syntax: SyntaxNode) -> Option<Self> { let res = match syntax.kind() { ARRAY_EXPR => Expr::ArrayExpr(ArrayExpr { syntax }), + ASM_EXPR => Expr::AsmExpr(AsmExpr { syntax }), AWAIT_EXPR => Expr::AwaitExpr(AwaitExpr { syntax }), BIN_EXPR => Expr::BinExpr(BinExpr { syntax }), BLOCK_EXPR => Expr::BlockExpr(BlockExpr { syntax }), - BOX_EXPR => Expr::BoxExpr(BoxExpr { syntax }), BREAK_EXPR => Expr::BreakExpr(BreakExpr { syntax }), CALL_EXPR => Expr::CallExpr(CallExpr { syntax }), CAST_EXPR => Expr::CastExpr(CastExpr { syntax }), @@ -3522,6 +3615,7 @@ impl AstNode for Expr { CONTINUE_EXPR => Expr::ContinueExpr(ContinueExpr { syntax }), FIELD_EXPR => Expr::FieldExpr(FieldExpr { syntax }), FOR_EXPR => Expr::ForExpr(ForExpr { syntax }), + FORMAT_ARGS_EXPR => Expr::FormatArgsExpr(FormatArgsExpr { syntax }), IF_EXPR => Expr::IfExpr(IfExpr { syntax }), INDEX_EXPR => Expr::IndexExpr(IndexExpr { syntax }), LITERAL => Expr::Literal(Literal { syntax }), @@ -3529,6 +3623,7 @@ impl AstNode for Expr { MACRO_EXPR => Expr::MacroExpr(MacroExpr { syntax }), MATCH_EXPR => Expr::MatchExpr(MatchExpr { syntax }), METHOD_CALL_EXPR => Expr::MethodCallExpr(MethodCallExpr { syntax }), + OFFSET_OF_EXPR => Expr::OffsetOfExpr(OffsetOfExpr { syntax }), PAREN_EXPR => Expr::ParenExpr(ParenExpr { syntax }), PATH_EXPR => Expr::PathExpr(PathExpr { syntax }), PREFIX_EXPR => Expr::PrefixExpr(PrefixExpr { syntax }), @@ -3550,10 +3645,10 @@ impl AstNode for Expr { fn syntax(&self) -> &SyntaxNode { match self { Expr::ArrayExpr(it) => &it.syntax, + Expr::AsmExpr(it) => &it.syntax, Expr::AwaitExpr(it) => &it.syntax, Expr::BinExpr(it) => &it.syntax, Expr::BlockExpr(it) => &it.syntax, - Expr::BoxExpr(it) => &it.syntax, Expr::BreakExpr(it) => &it.syntax, Expr::CallExpr(it) => &it.syntax, Expr::CastExpr(it) => &it.syntax, @@ -3561,6 +3656,7 @@ impl AstNode for Expr { Expr::ContinueExpr(it) => &it.syntax, Expr::FieldExpr(it) => &it.syntax, Expr::ForExpr(it) => &it.syntax, + Expr::FormatArgsExpr(it) => &it.syntax, Expr::IfExpr(it) => &it.syntax, Expr::IndexExpr(it) => &it.syntax, Expr::Literal(it) => &it.syntax, @@ -3568,6 +3664,7 @@ impl AstNode for Expr { Expr::MacroExpr(it) => &it.syntax, Expr::MatchExpr(it) => &it.syntax, Expr::MethodCallExpr(it) => &it.syntax, + Expr::OffsetOfExpr(it) => &it.syntax, Expr::ParenExpr(it) => &it.syntax, Expr::PathExpr(it) => &it.syntax, Expr::PrefixExpr(it) => &it.syntax, @@ -4028,9 +4125,9 @@ impl AstNode for AnyHasAttrs { | TYPE_PARAM | LET_STMT | ARRAY_EXPR + | ASM_EXPR | AWAIT_EXPR | BIN_EXPR - | BOX_EXPR | BREAK_EXPR | CALL_EXPR | CAST_EXPR @@ -4038,12 +4135,14 @@ impl AstNode for AnyHasAttrs { | CONTINUE_EXPR | FIELD_EXPR | FOR_EXPR + | FORMAT_ARGS_EXPR | IF_EXPR | INDEX_EXPR | LITERAL | LOOP_EXPR | MATCH_EXPR | METHOD_CALL_EXPR + | OFFSET_OF_EXPR | PAREN_EXPR | PATH_EXPR | PREFIX_EXPR @@ -4179,6 +4278,7 @@ impl AstNode for AnyHasName { | VARIANT | CONST_PARAM | TYPE_PARAM + | FORMAT_ARGS_ARG | IDENT_PAT ) } @@ -4620,17 +4720,17 @@ impl std::fmt::Display for ArrayExpr { std::fmt::Display::fmt(self.syntax(), f) } } -impl std::fmt::Display for AwaitExpr { +impl std::fmt::Display for AsmExpr { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) } } -impl std::fmt::Display for BinExpr { +impl std::fmt::Display for AwaitExpr { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) } } -impl std::fmt::Display for BoxExpr { +impl std::fmt::Display for BinExpr { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) } @@ -4670,6 +4770,11 @@ impl std::fmt::Display for ForExpr { 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) + } +} impl std::fmt::Display for IfExpr { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) @@ -4705,6 +4810,11 @@ impl std::fmt::Display for MethodCallExpr { std::fmt::Display::fmt(self.syntax(), f) } } +impl std::fmt::Display for OffsetOfExpr { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} impl std::fmt::Display for ParenExpr { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) @@ -4775,6 +4885,11 @@ impl std::fmt::Display for UnderscoreExpr { std::fmt::Display::fmt(self.syntax(), f) } } +impl std::fmt::Display for FormatArgsArg { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} impl std::fmt::Display for StmtList { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs index 4c6db0ef0..17e311c0c 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs @@ -503,11 +503,16 @@ pub fn hacky_block_expr( pub fn expr_unit() -> ast::Expr { expr_from_text("()") } + pub fn expr_literal(text: &str) -> ast::Literal { assert_eq!(text.trim(), text); ast_from_text(&format!("fn f() {{ let _ = {text}; }}")) } +pub fn expr_const_value(text: &str) -> ast::ConstArg { + ast_from_text(&format!("trait Foo<const N: usize = {text}> {{}}")) +} + pub fn expr_empty_block() -> ast::Expr { expr_from_text("{}") } @@ -1100,7 +1105,7 @@ pub mod tokens { pub(super) static SOURCE_FILE: Lazy<Parse<SourceFile>> = Lazy::new(|| { SourceFile::parse( - "const C: <()>::Item = (1 != 1, 2 == 2, 3 < 3, 4 <= 4, 5 > 5, 6 >= 6, !true, *p, &p , &mut p)\n;\n\n", + "const C: <()>::Item = ( true && true , true || true , 1 != 1, 2 == 2, 3 < 3, 4 <= 4, 5 > 5, 6 >= 6, !true, *p, &p , &mut p)\n;\n\n", ) }); diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs index 3308077da..691d0c618 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs @@ -61,6 +61,14 @@ impl ast::BlockExpr { pub fn tail_expr(&self) -> Option<ast::Expr> { self.stmt_list()?.tail_expr() } + /// Block expressions accept outer and inner attributes, but only when they are the outer + /// expression of an expression statement or the final expression of another block expression. + pub fn may_carry_attributes(&self) -> bool { + matches!( + self.syntax().parent().map(|it| it.kind()), + Some(SyntaxKind::BLOCK_EXPR | SyntaxKind::EXPR_STMT) + ) + } } #[derive(Debug, PartialEq, Eq, Clone)] diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs index 4ec388914..8e04ab8be 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs @@ -130,7 +130,8 @@ impl Expr { // ContinueExpr(_) => (0, 0), - ClosureExpr(_) | ReturnExpr(_) | YieldExpr(_) | YeetExpr(_) | BreakExpr(_) => (0, 1), + ClosureExpr(_) | ReturnExpr(_) | YieldExpr(_) | YeetExpr(_) | BreakExpr(_) + | OffsetOfExpr(_) | FormatArgsExpr(_) | AsmExpr(_) => (0, 1), RangeExpr(_) => (5, 5), @@ -160,7 +161,7 @@ impl Expr { CastExpr(_) => (25, 26), - BoxExpr(_) | RefExpr(_) | LetExpr(_) | PrefixExpr(_) => (0, 27), + RefExpr(_) | LetExpr(_) | PrefixExpr(_) => (0, 27), AwaitExpr(_) | CallExpr(_) | MethodCallExpr(_) | IndexExpr(_) | TryExpr(_) | MacroExpr(_) => (29, 0), @@ -202,7 +203,6 @@ impl Expr { let rhs = match self { RefExpr(e) => e.expr(), BinExpr(e) => e.rhs(), - BoxExpr(e) => e.expr(), BreakExpr(e) => e.expr(), LetExpr(e) => e.expr(), RangeExpr(e) => e.end(), @@ -279,7 +279,6 @@ impl Expr { CastExpr(e) => e.as_token(), FieldExpr(e) => e.dot_token(), AwaitExpr(e) => e.dot_token(), - BoxExpr(e) => e.box_token(), BreakExpr(e) => e.break_token(), CallExpr(e) => e.arg_list().and_then(|args| args.l_paren_token()), ClosureExpr(e) => e.param_list().and_then(|params| params.l_paren_token()), @@ -293,7 +292,9 @@ impl Expr { YieldExpr(e) => e.yield_token(), YeetExpr(e) => e.do_token(), LetExpr(e) => e.let_token(), - + OffsetOfExpr(e) => e.builtin_token(), + FormatArgsExpr(e) => e.builtin_token(), + AsmExpr(e) => e.builtin_token(), ArrayExpr(_) | TupleExpr(_) | Literal(_) | PathExpr(_) | ParenExpr(_) | IfExpr(_) | WhileExpr(_) | ForExpr(_) | LoopExpr(_) | MatchExpr(_) | BlockExpr(_) | RecordExpr(_) | UnderscoreExpr(_) | MacroExpr(_) => None, @@ -310,12 +311,12 @@ impl Expr { ArrayExpr(_) | AwaitExpr(_) | BlockExpr(_) | CallExpr(_) | CastExpr(_) | ClosureExpr(_) | FieldExpr(_) | IndexExpr(_) | Literal(_) | LoopExpr(_) | MacroExpr(_) | MethodCallExpr(_) | ParenExpr(_) | PathExpr(_) | RecordExpr(_) - | TryExpr(_) | TupleExpr(_) | UnderscoreExpr(_) => false, + | TryExpr(_) | TupleExpr(_) | UnderscoreExpr(_) | OffsetOfExpr(_) + | FormatArgsExpr(_) | AsmExpr(_) => false, // For BinExpr and RangeExpr this is technically wrong -- the child can be on the left... - BinExpr(_) | RangeExpr(_) | BoxExpr(_) | BreakExpr(_) | ContinueExpr(_) - | PrefixExpr(_) | RefExpr(_) | ReturnExpr(_) | YieldExpr(_) | YeetExpr(_) - | LetExpr(_) => self + BinExpr(_) | RangeExpr(_) | BreakExpr(_) | ContinueExpr(_) | PrefixExpr(_) + | RefExpr(_) | ReturnExpr(_) | YieldExpr(_) | YeetExpr(_) | LetExpr(_) => self .syntax() .parent() .and_then(Expr::cast) diff --git a/src/tools/rust-analyzer/crates/syntax/src/lib.rs b/src/tools/rust-analyzer/crates/syntax/src/lib.rs index 4cd668a0c..27c8a13e5 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/lib.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/lib.rs @@ -195,11 +195,16 @@ impl ast::TokenTree { // Tag the token as joint if it is float with a fractional part // we use this jointness to inform the parser about what token split // event to emit when we encounter a float literal in a field access - if kind == SyntaxKind::FLOAT_NUMBER && !t.text().ends_with('.') { - parser_input.was_joint(); + if kind == SyntaxKind::FLOAT_NUMBER { + if !t.text().ends_with('.') { + parser_input.was_joint(); + } else { + was_joint = false; + } + } else { + was_joint = true; } } - was_joint = true; } } @@ -250,6 +255,7 @@ impl ast::TokenTree { if has_pseudo_dot { assert!(right.is_empty(), "{left}.{right}"); } else { + assert!(!right.is_empty(), "{left}.{right}"); builder.start_node(SyntaxKind::NAME_REF); builder.token(SyntaxKind::INT_NUMBER, right); builder.finish_node(); diff --git a/src/tools/rust-analyzer/crates/syntax/src/tests/ast_src.rs b/src/tools/rust-analyzer/crates/syntax/src/tests/ast_src.rs index e4db33f1c..341bda892 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/tests/ast_src.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/tests/ast_src.rs @@ -70,7 +70,19 @@ pub(crate) const KINDS_SRC: KindsSrc<'_> = KindsSrc { "match", "mod", "move", "mut", "pub", "ref", "return", "self", "Self", "static", "struct", "super", "trait", "true", "try", "type", "unsafe", "use", "where", "while", "yield", ], - contextual_keywords: &["auto", "default", "existential", "union", "raw", "macro_rules", "yeet"], + contextual_keywords: &[ + "auto", + "builtin", + "default", + "existential", + "union", + "raw", + "macro_rules", + "yeet", + "offset_of", + "asm", + "format_args", + ], literals: &["INT_NUMBER", "FLOAT_NUMBER", "CHAR", "BYTE", "STRING", "BYTE_STRING", "C_STRING"], tokens: &["ERROR", "IDENT", "WHITESPACE", "LIFETIME_IDENT", "COMMENT", "SHEBANG"], nodes: &[ @@ -154,7 +166,10 @@ pub(crate) const KINDS_SRC: KindsSrc<'_> = KindsSrc { "RECORD_EXPR", "RECORD_EXPR_FIELD_LIST", "RECORD_EXPR_FIELD", - "BOX_EXPR", + "OFFSET_OF_EXPR", + "ASM_EXPR", + "FORMAT_ARGS_EXPR", + "FORMAT_ARGS_ARG", // postfix "CALL_EXPR", "INDEX_EXPR", diff --git a/src/tools/rust-analyzer/crates/syntax/src/tests/sourcegen_ast.rs b/src/tools/rust-analyzer/crates/syntax/src/tests/sourcegen_ast.rs index c49c5fa10..56227fce9 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/tests/sourcegen_ast.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/tests/sourcegen_ast.rs @@ -623,7 +623,7 @@ fn lower_enum(grammar: &Grammar, rule: &Rule) -> Option<Vec<String>> { } fn lower_rule(acc: &mut Vec<Field>, grammar: &Grammar, label: Option<&String>, rule: &Rule) { - if lower_comma_list(acc, grammar, label, rule) { + if lower_seperated_list(acc, grammar, label, rule) { return; } @@ -689,7 +689,7 @@ fn lower_rule(acc: &mut Vec<Field>, grammar: &Grammar, label: Option<&String>, r } // (T (',' T)* ','?) -fn lower_comma_list( +fn lower_seperated_list( acc: &mut Vec<Field>, grammar: &Grammar, label: Option<&String>, @@ -699,19 +699,23 @@ fn lower_comma_list( Rule::Seq(it) => it, _ => return false, }; - let (node, repeat, trailing_comma) = match rule.as_slice() { - [Rule::Node(node), Rule::Rep(repeat), Rule::Opt(trailing_comma)] => { - (node, repeat, trailing_comma) + let (node, repeat, trailing_sep) = match rule.as_slice() { + [Rule::Node(node), Rule::Rep(repeat), Rule::Opt(trailing_sep)] => { + (node, repeat, Some(trailing_sep)) } + [Rule::Node(node), Rule::Rep(repeat)] => (node, repeat, None), _ => return false, }; let repeat = match &**repeat { Rule::Seq(it) => it, _ => return false, }; - match repeat.as_slice() { - [comma, Rule::Node(n)] if comma == &**trailing_comma && n == node => (), - _ => return false, + if !matches!( + repeat.as_slice(), + [comma, Rule::Node(n)] + if trailing_sep.map_or(true, |it| comma == &**it) && n == node + ) { + return false; } let ty = grammar[*node].name.clone(); let name = label.cloned().unwrap_or_else(|| pluralize(&to_lower_snake_case(&ty))); |