diff --git a/CHANGES.md b/CHANGES.md
index 5c5978a3c5..ebbb186ef6 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -13,6 +13,7 @@ Core Grammars:
- fix(ex) adds support for `?'` char literal and missing `defguardp` keyword [Kevin Bloch][]
- fix(diff) fix unified diff hunk header regex to allow unpaired numbers [Chris Wilson][]
- enh(php) support single line and hash comments in attributes, constructor and functions [Antoine Musso][]
+- fix(rust) ensure brackets are balanced within attributes [ewwwin][]
CONTRIBUTORS
@@ -23,6 +24,7 @@ CONTRIBUTORS
[Chris Wilson]: https://github.com/sushicw
[Antoine Musso]: https://github.com/hashar
[Chester Moses]: https://github.com/Chester-Moses-HCL
+[ewwwin]: https://github.com/ewwwin
## Version 11.11.1
diff --git a/src/languages/rust.js b/src/languages/rust.js
index 13e7be19f2..4c665cb69a 100644
--- a/src/languages/rust.js
+++ b/src/languages/rust.js
@@ -25,6 +25,12 @@ export default function(hljs) {
IDENT_RE,
regex.lookahead(/\s*\(/))
};
+ const META_STRING = {
+ className: 'string',
+ begin: /"/,
+ end: /"/,
+ contains: [ hljs.BACKSLASH_ESCAPE ]
+ };
const NUMBER_SUFFIX = '([ui](8|16|32|64|128|size)|f(32|64))\?';
const KEYWORDS = [
"abstract",
@@ -246,12 +252,26 @@ export default function(hljs) {
begin: '#!?\\[',
end: '\\]',
contains: [
+ META_STRING,
{
- className: 'string',
- begin: /"/,
- end: /"/,
+ relevance: 0,
+ variants: [
+ {
+ begin: /\(/,
+ end: /\)/
+ },
+ {
+ begin: /\[/,
+ end: /\]/
+ },
+ {
+ begin: /\{/,
+ end: /\}/
+ }
+ ],
contains: [
- hljs.BACKSLASH_ESCAPE
+ 'self',
+ META_STRING
]
}
]
diff --git a/test/markup/rust/attributes.expect.txt b/test/markup/rust/attributes.expect.txt
new file mode 100644
index 0000000000..3b5be79b72
--- /dev/null
+++ b/test/markup/rust/attributes.expect.txt
@@ -0,0 +1,18 @@
+#[foo]
+#![foo]
+
+#[foo(bar)]
+#[foo = bar]
+#[foo("a \"b\" c")]
+#[foo(bar = [a, b, c])]
+#[foo[bar]]
+#[foo{bar}]
+
+#![no_std]
+#[doc = "example"]
+#[allow(unused, clippy::inline_always)]
+#[macro_use(foo, bar)]
+#[link(name = "CoreFoundation", kind = "framework")]
+
+#[rtic::app(device = lm3s6965, dispatchers = [UART0, UART1])]
+#[task(binds = USB_OTG1, local = [poller])]
diff --git a/test/markup/rust/attributes.txt b/test/markup/rust/attributes.txt
new file mode 100644
index 0000000000..eb7680a785
--- /dev/null
+++ b/test/markup/rust/attributes.txt
@@ -0,0 +1,18 @@
+#[foo]
+#![foo]
+
+#[foo(bar)]
+#[foo = bar]
+#[foo("a \"b\" c")]
+#[foo(bar = [a, b, c])]
+#[foo[bar]]
+#[foo{bar}]
+
+#![no_std]
+#[doc = "example"]
+#[allow(unused, clippy::inline_always)]
+#[macro_use(foo, bar)]
+#[link(name = "CoreFoundation", kind = "framework")]
+
+#[rtic::app(device = lm3s6965, dispatchers = [UART0, UART1])]
+#[task(binds = USB_OTG1, local = [poller])]