Skip to content

Commit

Permalink
[Rust] Support macro repetitions inside structs
Browse files Browse the repository at this point in the history
This only addresses a specific case of macro repetitions inside the
struct body and similar changes to other statements with body blocks
are likely also necessary, but I'm keeping the change to a limited in
order to observe its effects first. Further reports of such issues can
be handled analogously.
  • Loading branch information
FichteFoll committed Jan 28, 2024
1 parent 0647aa3 commit 6922860
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 8 deletions.
30 changes: 22 additions & 8 deletions Rust/Rust.sublime-syntax
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,11 @@ contexts:
# however then we run into infinite recursion. It needs to be a prototype
# since macro_rules! allows constructing new code, thus the metavariables
# can be inserted in just about any position in the syntax.
- match: '\${{identifier}}'
# See also: https://doc.rust-lang.org/reference/macros-by-example.html
- match: \${{identifier}}
scope: variable.other.rust
- match: \$\(
scope: punctuation.section.interpolation.begin.rust

statements:
# This isn't really just "statements", it also includes all types,
Expand Down Expand Up @@ -818,21 +821,21 @@ contexts:
- include: comments
- include: attributes
- include: visibility
- match: '{{identifier}}(?=\s*:)'
- match: '{{identifier}}'
scope: variable.other.member.rust
- match: ':'
scope: punctuation.separator.rust
push:
- match: ','
scope: punctuation.separator.rust
pop: true
- match: '(?=\})'
pop: true
- include: comments
- match: ':'
scope: punctuation.separator.rust
- include: types
- match: '(?=\S)'
# Abort for an invalid match.
pop: true
- include: else-pop
# Abort for an invalid match.
- include: else-pop

##[ UNIONS ]#################################################################

Expand Down Expand Up @@ -1116,7 +1119,7 @@ contexts:
pop: true
- match: '\S'
# This is intended to help make it evident when you forget a semicolon.
scope: invalid.illegal.rust
scope: invalid.illegal.expected-semi-colon.rust

##[ IMPL DEFINITIONS ]######################################################

Expand Down Expand Up @@ -1790,9 +1793,20 @@ contexts:
scope: invalid.illegal.rust

else-pop:
- include: macro-repetition-end
- match: (?=\S)
pop: true

immediately-pop:
- include: macro-repetition-end
- match: ''
pop: true

macro-repetition-end:
# This is basically a prototype but needs to be appended to the end of a context.
# See also: https://doc.rust-lang.org/reference/macros-by-example.html#repetitions
- match: (\))([,;])?([*+?])
captures:
1: punctuation.section.interpolation.end.rust
2: punctuation.separator.rust
3: keyword.operator.other.repetition.rust
47 changes: 47 additions & 0 deletions Rust/tests/syntax_test_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,3 +384,50 @@ macro_rules! designators {
// ^^ meta.macro meta.macro.transcribers
}
//<- meta.macro punctuation.section.block.end

/*******************************************************************/
// Nested multi-line statements
macro_rules! test {
($($name:ident),+$(,)?) => {
pub struct Foo {
$(
// ^^ meta.macro meta.macro.transcribers meta.struct meta.block punctuation.section.interpolation.begin.rust
pub $name : Option<String>
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.macro meta.macro.transcribers meta.struct meta.block
// ^^^ storage.modifier.rust
// ^^^^^ variable.other.rust
// ^ punctuation.separator.rust
// ^^^^^^ support.type.rust
),+
// ^^^^ meta.macro meta.macro.transcribers meta.struct meta.block
// ^ punctuation.section.interpolation.end.rust
// ^ punctuation.separator.rust
// ^ keyword.operator.other.repetition.rust
}
// ^ meta.macro meta.macro.transcribers meta.struct meta.block punctuation.section.block.end.rust

pub async fn thing() -> () {}
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.macro meta.macro.transcribers
// ^^^ storage.modifier.rust
// ^^^^^ keyword.control.rust
// ^^ storage.type.function.rust
// ^^^^^ entity.name.function.rust
// ^^ meta.function meta.function.parameters
// ^^^^^ meta.function meta.function.return-type
// ^^ punctuation.separator.rust
// ^^ meta.group
// ^^ meta.function meta.block
}
// ^ meta.macro meta.macro.transcribers punctuation.section.block.end.rust
}
// <- meta.macro punctuation.section.block.end.rust

/*******************************************************************/
// Not part of a macro
some()?;
// ^ punctuation.section.group.end.rust
// ^ keyword.operator.rust

(a)+(b);
//^ punctuation.section.group.end.rust
// ^ keyword.operator.arithmetic.rust

0 comments on commit 6922860

Please sign in to comment.