diff --git a/crates/ra_ide/src/snapshots/highlighting.html b/crates/ra_ide/src/snapshots/highlighting.html
index 4c27aade4025..635fe5cf9ddf 100644
--- a/crates/ra_ide/src/snapshots/highlighting.html
+++ b/crates/ra_ide/src/snapshots/highlighting.html
@@ -33,6 +33,16 @@
pub y: i32,
}
+trait Bar {
+ fn bar(&self) -> i32;
+}
+
+impl Bar for Foo {
+ fn bar(&self) -> i32 {
+ self.x
+ }
+}
+
static mut STATIC_MUT: i32 = 0;
fn foo<'a, T>() -> T {
@@ -63,6 +73,10 @@
STATIC_MUT = 1;
}
+ for e in vec {
+
+ }
+
let mut x = 42;
let y = &mut x;
let z = &y;
diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs
index d53a39f57b52..be57eeb0abea 100644
--- a/crates/ra_ide/src/syntax_highlighting.rs
+++ b/crates/ra_ide/src/syntax_highlighting.rs
@@ -403,12 +403,13 @@ fn highlight_element(
T![break]
| T![continue]
| T![else]
- | T![for]
| T![if]
| T![loop]
| T![match]
| T![return]
- | T![while] => h | HighlightModifier::ControlFlow,
+ | T![while]
+ | T![in] => h | HighlightModifier::ControlFlow,
+ T![for] if !is_child_of_impl(element) => h | HighlightModifier::ControlFlow,
T![unsafe] => h | HighlightModifier::Unsafe,
_ => h,
}
@@ -432,6 +433,13 @@ fn highlight_element(
}
}
+fn is_child_of_impl(element: SyntaxElement) -> bool {
+ match element.parent() {
+ Some(e) => e.kind() == IMPL_DEF,
+ _ => false,
+ }
+}
+
fn highlight_name(db: &RootDatabase, def: Definition) -> Highlight {
match def {
Definition::Macro(_) => HighlightTag::Macro,
diff --git a/crates/ra_ide/src/syntax_highlighting/tests.rs b/crates/ra_ide/src/syntax_highlighting/tests.rs
index 13894869c8bf..eb43a23da682 100644
--- a/crates/ra_ide/src/syntax_highlighting/tests.rs
+++ b/crates/ra_ide/src/syntax_highlighting/tests.rs
@@ -17,6 +17,16 @@ struct Foo {
pub y: i32,
}
+trait Bar {
+ fn bar(&self) -> i32;
+}
+
+impl Bar for Foo {
+ fn bar(&self) -> i32 {
+ self.x
+ }
+}
+
static mut STATIC_MUT: i32 = 0;
fn foo<'a, T>() -> T {
@@ -47,6 +57,10 @@ fn main() {
STATIC_MUT = 1;
}
+ for e in vec {
+ // Do nothing
+ }
+
let mut x = 42;
let y = &mut x;
let z = &y;
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs
index 4500d49827e3..33c2fd595fbd 100644
--- a/crates/rust-analyzer/src/to_proto.rs
+++ b/crates/rust-analyzer/src/to_proto.rs
@@ -264,7 +264,7 @@ fn semantic_token_type_and_modifiers(
HighlightTag::Trait => lsp_types::SemanticTokenType::INTERFACE,
HighlightTag::BuiltinType => semantic_tokens::BUILTIN_TYPE,
HighlightTag::SelfType => lsp_types::SemanticTokenType::TYPE,
- HighlightTag::Field => lsp_types::SemanticTokenType::MEMBER,
+ HighlightTag::Field => lsp_types::SemanticTokenType::PROPERTY,
HighlightTag::Function => lsp_types::SemanticTokenType::FUNCTION,
HighlightTag::Module => lsp_types::SemanticTokenType::NAMESPACE,
HighlightTag::Constant => {
diff --git a/editors/code/.vscodeignore b/editors/code/.vscodeignore
index ac411f8e2be4..257b744bfeaa 100644
--- a/editors/code/.vscodeignore
+++ b/editors/code/.vscodeignore
@@ -3,5 +3,6 @@
!package.json
!package-lock.json
!ra_syntax_tree.tmGrammar.json
+!rust.tmGrammar.json
!icon.png
!README.md
diff --git a/editors/code/package.json b/editors/code/package.json
index c6fc13519e06..f46684c76570 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -478,6 +478,11 @@
}
],
"grammars": [
+ {
+ "language": "rust",
+ "scopeName": "source.rust",
+ "path": "rust.tmGrammar.json"
+ },
{
"language": "ra_syntax_tree",
"scopeName": "source.ra_syntax_tree",
@@ -596,28 +601,28 @@
"support.type.primitive"
],
"lifetime": [
- "entity.name.lifetime.rust"
+ "storage.modifier.lifetime.rust"
],
"typeAlias": [
- "entity.name.typeAlias"
+ "entity.name.type.typeAlias"
],
"union": [
- "entity.name.union"
+ "entity.name.type.union"
],
"struct": [
"entity.name.type.struct"
],
- "keyword.unsafe": [
- "keyword.other.unsafe"
- ],
"keyword": [
- "keyword"
+ "keyword.other"
],
"keyword.controlFlow": [
"keyword.control"
],
"variable.constant": [
- "entity.name.constant"
+ "variable.other.constant"
+ ],
+ "formatSpecifier": [
+ "punctuation.section.embedded"
]
}
}
diff --git a/editors/code/rust.tmGrammar.json b/editors/code/rust.tmGrammar.json
new file mode 100644
index 000000000000..27982c13a501
--- /dev/null
+++ b/editors/code/rust.tmGrammar.json
@@ -0,0 +1,681 @@
+{
+ "name": "Rust",
+ "scopeName": "source.rust",
+ "patterns": [
+ {
+ "comment": "Implementation",
+ "begin": "\\b(impl)\\b",
+ "end": "\\{",
+ "beginCaptures": {
+ "1": {
+ "name": "storage.type.rust"
+ }
+ },
+ "patterns": [
+ {
+ "include": "#block_comment"
+ },
+ {
+ "include": "#line_comment"
+ },
+ {
+ "include": "#sigils"
+ },
+ {
+ "include": "#mut"
+ },
+ {
+ "include": "#dyn"
+ },
+ {
+ "include": "#ref_lifetime"
+ },
+ {
+ "include": "#core_types"
+ },
+ {
+ "include": "#core_marker"
+ },
+ {
+ "include": "#core_traits"
+ },
+ {
+ "include": "#std_types"
+ },
+ {
+ "include": "#std_traits"
+ },
+ {
+ "include": "#type_params"
+ },
+ {
+ "include": "#where"
+ },
+ {
+ "name": "storage.type.rust",
+ "match": "\\bfor\\b"
+ },
+ {
+ "include": "#type"
+ }
+ ]
+ },
+ {
+ "include": "#block_doc_comment"
+ },
+ {
+ "include": "#block_comment"
+ },
+ {
+ "include": "#line_doc_comment"
+ },
+ {
+ "include": "#line_comment"
+ },
+ {
+ "comment": "Attribute",
+ "name": "meta.attribute.rust",
+ "begin": "#\\!?\\[",
+ "end": "\\]",
+ "patterns": [
+ {
+ "include": "#string_literal"
+ },
+ {
+ "include": "#block_doc_comment"
+ },
+ {
+ "include": "#block_comment"
+ },
+ {
+ "include": "#line_doc_comment"
+ },
+ {
+ "include": "#line_comment"
+ }
+ ]
+ },
+ {
+ "comment": "Single-quote string literal (character)",
+ "name": "string.quoted.single.rust",
+ "match": "b?'([^'\\\\]|\\\\(x[0-9A-Fa-f]{2}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.))'"
+ },
+ {
+ "include": "#string_literal"
+ },
+ {
+ "include": "#raw_string_literal"
+ },
+ {
+ "comment": "Floating point literal (fraction)",
+ "name": "constant.numeric.float.rust",
+ "match": "\\b[0-9][0-9_]*\\.[0-9][0-9_]*([eE][+-]?[0-9_]+)?(f32|f64)?\\b"
+ },
+ {
+ "comment": "Floating point literal (exponent)",
+ "name": "constant.numeric.float.rust",
+ "match": "\\b[0-9][0-9_]*(\\.[0-9][0-9_]*)?[eE][+-]?[0-9_]+(f32|f64)?\\b"
+ },
+ {
+ "comment": "Floating point literal (typed)",
+ "name": "constant.numeric.float.rust",
+ "match": "\\b[0-9][0-9_]*(\\.[0-9][0-9_]*)?([eE][+-]?[0-9_]+)?(f32|f64)\\b"
+ },
+ {
+ "comment": "Integer literal (decimal)",
+ "name": "constant.numeric.integer.decimal.rust",
+ "match": "\\b[0-9][0-9_]*([ui](8|16|32|64|128|s|size))?\\b"
+ },
+ {
+ "comment": "Integer literal (hexadecimal)",
+ "name": "constant.numeric.integer.hexadecimal.rust",
+ "match": "\\b0x[a-fA-F0-9_]+([ui](8|16|32|64|128|s|size))?\\b"
+ },
+ {
+ "comment": "Integer literal (octal)",
+ "name": "constant.numeric.integer.octal.rust",
+ "match": "\\b0o[0-7_]+([ui](8|16|32|64|128|s|size))?\\b"
+ },
+ {
+ "comment": "Integer literal (binary)",
+ "name": "constant.numeric.integer.binary.rust",
+ "match": "\\b0b[01_]+([ui](8|16|32|64|128|s|size))?\\b"
+ },
+ {
+ "comment": "Static storage modifier",
+ "name": "storage.modifier.static.rust",
+ "match": "\\bstatic\\b"
+ },
+ {
+ "comment": "Boolean constant",
+ "name": "constant.language.boolean.rust",
+ "match": "\\b(true|false)\\b"
+ },
+ {
+ "comment": "Control keyword",
+ "name": "keyword.control.rust",
+ "match": "\\b(async|await|break|continue|else|if|in|for|loop|match|return|try|while)\\b"
+ },
+ {
+ "comment": "Keyword",
+ "name": "keyword.other.rust",
+ "match": "\\b(crate|extern|mod|let|ref|use|super|move|as)\\b"
+ },
+ {
+ "comment": "Reserved keyword",
+ "name": "invalid.deprecated.rust",
+ "match": "\\b(abstract|alignof|become|do|final|macro|offsetof|override|priv|proc|pure|sizeof|typeof|virtual|yield)\\b"
+ },
+ {
+ "include": "#unsafe"
+ },
+ {
+ "include": "#sigils"
+ },
+ {
+ "include": "#self"
+ },
+ {
+ "include": "#mut"
+ },
+ {
+ "include": "#dyn"
+ },
+ {
+ "include": "#impl"
+ },
+ {
+ "include": "#box"
+ },
+ {
+ "include": "#lifetime"
+ },
+ {
+ "include": "#ref_lifetime"
+ },
+ {
+ "include": "#const"
+ },
+ {
+ "include": "#pub"
+ },
+ {
+ "comment": "Miscellaneous operator",
+ "name": "keyword.operator.misc.rust",
+ "match": "(=>|::)"
+ },
+ {
+ "comment": "Comparison operator",
+ "name": "keyword.operator.comparison.rust",
+ "match": "(&&|\\|\\||==|!=)"
+ },
+ {
+ "comment": "Assignment operator",
+ "name": "keyword.operator.assignment.rust",
+ "match": "(\\+=|-=|/=|\\*=|%=|\\^=|&=|\\|=|<<=|>>=|=)"
+ },
+ {
+ "comment": "Arithmetic operator",
+ "name": "keyword.operator.arithmetic.rust",
+ "match": "(!|\\+|-|/|\\*|%|\\^|&|\\||<<|>>)"
+ },
+ {
+ "comment": "Comparison operator (second group because of regex precedence)",
+ "name": "keyword.operator.comparison.rust",
+ "match": "(<=|>=|<|>)"
+ },
+ {
+ "include": "#core_types"
+ },
+ {
+ "include": "#core_vars"
+ },
+ {
+ "include": "#core_marker"
+ },
+ {
+ "include": "#core_traits"
+ },
+ {
+ "include": "#std_types"
+ },
+ {
+ "include": "#std_traits"
+ },
+ {
+ "comment": "Built-in macro",
+ "name": "support.function.builtin.rust",
+ "match": "\\b(macro_rules|compile_error|format_args|env|option_env|concat_idents|concat|line|column|file|stringify|include|include_str|include_bytes|module_path|cfg)!"
+ },
+ {
+ "comment": "Core macro",
+ "name": "support.function.core.rust",
+ "match": "\\b(panic|assert|assert_eq|assert_ne|debug_assert|debug_assert_eq|debug_assert_ne|try|write|writeln|unreachable|unimplemented)!"
+ },
+ {
+ "comment": "Standard library macro",
+ "name": "support.function.std.rust",
+ "match": "\\b(format|print|println|eprint|eprintln|select|vec)!"
+ },
+ {
+ "comment": "Logging macro",
+ "name": "support.function.log.rust",
+ "match": "\\b(log|error|warn|info|debug|trace|log_enabled)!"
+ },
+ {
+ "comment": "Invokation of a macro",
+ "match": "\\b([a-zA-Z_][a-zA-Z0-9_]*\\!)\\s*[({\\[]",
+ "captures": {
+ "1": {
+ "name": "entity.name.function.macro.rust"
+ }
+ }
+ },
+ {
+ "comment": "Function call",
+ "match": "\\b([A-Za-z][A-Za-z0-9_]*|_[A-Za-z0-9_]+)\\s*\\(",
+ "captures": {
+ "1": {
+ "name": "entity.name.function.rust"
+ }
+ }
+ },
+ {
+ "comment": "Function call with type parameters",
+ "begin": "\\b([A-Za-z][A-Za-z0-9_]*|_[A-Za-z0-9_]+)\\s*(::)(?=\\s*<.*>\\s*\\()",
+ "end": "\\(",
+ "captures": {
+ "1": {
+ "name": "entity.name.function.rust"
+ },
+ "2": {
+ "name": "keyword.operator.misc.rust"
+ }
+ },
+ "patterns": [
+ {
+ "include": "#type_params"
+ }
+ ]
+ },
+ {
+ "comment": "Function definition",
+ "begin": "\\b(fn)\\s+([A-Za-z][A-Za-z0-9_]*|_[A-Za-z0-9_]+)",
+ "end": "[\\{;]",
+ "beginCaptures": {
+ "1": {
+ "name": "keyword.other.fn.rust"
+ },
+ "2": {
+ "name": "entity.name.function.rust"
+ }
+ },
+ "patterns": [
+ {
+ "include": "#block_comment"
+ },
+ {
+ "include": "#line_comment"
+ },
+ {
+ "include": "#sigils"
+ },
+ {
+ "include": "#self"
+ },
+ {
+ "include": "#mut"
+ },
+ {
+ "include": "#dyn"
+ },
+ {
+ "include": "#impl"
+ },
+ {
+ "include": "#ref_lifetime"
+ },
+ {
+ "include": "#core_types"
+ },
+ {
+ "include": "#core_marker"
+ },
+ {
+ "include": "#core_traits"
+ },
+ {
+ "include": "#std_types"
+ },
+ {
+ "include": "#std_traits"
+ },
+ {
+ "include": "#type_params"
+ },
+ {
+ "include": "#const"
+ },
+ {
+ "include": "#where"
+ },
+ {
+ "include": "#unsafe"
+ },
+ {
+ "comment": "Function arguments",
+ "match": "\bfn\b",
+ "name": "keyword.other.fn.rust"
+ }
+ ]
+ },
+ {
+ "comment": "Type declaration",
+ "begin": "\\b(enum|struct|trait|union)\\s+([a-zA-Z_][a-zA-Z0-9_]*)",
+ "end": "[\\{\\(;]",
+ "beginCaptures": {
+ "1": {
+ "name": "storage.type.rust"
+ },
+ "2": {
+ "name": "entity.name.type.rust"
+ }
+ },
+ "patterns": [
+ {
+ "include": "#block_comment"
+ },
+ {
+ "include": "#line_comment"
+ },
+ {
+ "include": "#core_traits"
+ },
+ {
+ "include": "#std_traits"
+ },
+ {
+ "include": "#type_params"
+ },
+ {
+ "include": "#core_types"
+ },
+ {
+ "include": "#pub"
+ },
+ {
+ "include": "#where"
+ }
+ ]
+ },
+ {
+ "comment": "Type alias",
+ "begin": "\\b(type)\\s+([a-zA-Z_][a-zA-Z0-9_]*)",
+ "end": ";",
+ "beginCaptures": {
+ "1": {
+ "name": "storage.type.rust"
+ },
+ "2": {
+ "name": "entity.name.type.rust"
+ }
+ },
+ "patterns": [
+ {
+ "include": "#block_comment"
+ },
+ {
+ "include": "#line_comment"
+ },
+ {
+ "include": "#sigils"
+ },
+ {
+ "include": "#mut"
+ },
+ {
+ "include": "#dyn"
+ },
+ {
+ "include": "#impl"
+ },
+ {
+ "include": "#lifetime"
+ },
+ {
+ "include": "#ref_lifetime"
+ },
+ {
+ "include": "#core_types"
+ },
+ {
+ "include": "#core_marker"
+ },
+ {
+ "include": "#core_traits"
+ },
+ {
+ "include": "#std_types"
+ },
+ {
+ "include": "#std_traits"
+ },
+ {
+ "include": "#type_params"
+ }
+ ]
+ }
+ ],
+ "repository": {
+ "block_doc_comment": {
+ "comment": "Block documentation comment",
+ "name": "comment.block.documentation.rust",
+ "begin": "/\\*[\\*!](?![\\*/])",
+ "end": "\\*/",
+ "patterns": [
+ {
+ "include": "#block_doc_comment"
+ },
+ {
+ "include": "#block_comment"
+ }
+ ]
+ },
+ "block_comment": {
+ "comment": "Block comment",
+ "name": "comment.block.rust",
+ "begin": "/\\*",
+ "end": "\\*/",
+ "patterns": [
+ {
+ "include": "#block_doc_comment"
+ },
+ {
+ "include": "#block_comment"
+ }
+ ]
+ },
+ "line_doc_comment": {
+ "comment": "Single-line documentation comment",
+ "name": "comment.line.documentation.rust",
+ "begin": "//[!/](?=[^/])",
+ "end": "$"
+ },
+ "line_comment": {
+ "comment": "Single-line comment",
+ "name": "comment.line.double-slash.rust",
+ "begin": "//",
+ "end": "$"
+ },
+ "escaped_character": {
+ "name": "constant.character.escape.rust",
+ "match": "\\\\(x[0-9A-Fa-f]{2}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)"
+ },
+ "string_literal": {
+ "comment": "Double-quote string literal",
+ "name": "string.quoted.double.rust",
+ "begin": "b?\"",
+ "end": "\"",
+ "patterns": [
+ {
+ "include": "#escaped_character"
+ }
+ ]
+ },
+ "raw_string_literal": {
+ "comment": "Raw double-quote string literal",
+ "name": "string.quoted.double.raw.rust",
+ "begin": "b?r(#*)\"",
+ "end": "\"\\1"
+ },
+ "sigils": {
+ "comment": "Sigil",
+ "name": "keyword.operator.sigil.rust",
+ "match": "[&*](?=[a-zA-Z0-9_\\(\\[\\|\\\"]+)"
+ },
+ "self": {
+ "comment": "Self variable",
+ "name": "variable.language.rust",
+ "match": "\\bself\\b"
+ },
+ "mut": {
+ "comment": "Mutable storage modifier",
+ "name": "storage.modifier.mut.rust",
+ "match": "\\bmut\\b"
+ },
+ "dyn": {
+ "comment": "Dynamic modifier",
+ "name": "storage.modifier.dyn.rust",
+ "match": "\\bdyn\\b"
+ },
+ "impl": {
+ "comment": "Existential type modifier",
+ "name": "storage.modifier.impl.rust",
+ "match": "\\bimpl\\b"
+ },
+ "box": {
+ "comment": "Box storage modifier",
+ "name": "storage.modifier.box.rust",
+ "match": "\\bbox\\b"
+ },
+ "const": {
+ "comment": "Const storage modifier",
+ "name": "storage.modifier.const.rust",
+ "match": "\\bconst\\b"
+ },
+ "pub": {
+ "comment": "Visibility modifier",
+ "name": "storage.modifier.visibility.rust",
+ "match": "\\bpub\\b"
+ },
+ "unsafe": {
+ "comment": "Unsafe code keyword",
+ "name": "keyword.other.unsafe.rust",
+ "match": "\\bunsafe\\b"
+ },
+ "where": {
+ "comment": "Generic where clause",
+ "name": "keyword.other.where.rust",
+ "match": "\\bwhere\\b"
+ },
+ "lifetime": {
+ "comment": "Named lifetime",
+ "name": "storage.modifier.lifetime.rust",
+ "match": "'([a-zA-Z_][a-zA-Z0-9_]*)\\b"
+ },
+ "ref_lifetime": {
+ "comment": "Reference with named lifetime",
+ "match": "(&)('[a-zA-Z_][a-zA-Z0-9_]*)\\b",
+ "captures": {
+ "1": {
+ "name": "keyword.operator.sigil.rust"
+ },
+ "2": {
+ "name": "storage.modifier.lifetime.rust"
+ }
+ }
+ },
+ "core_types": {
+ "comment": "Built-in/core type",
+ "name": "support.type.primitive",
+ "match": "\\b(bool|char|usize|isize|u8|u16|u32|u64|u128|i8|i16|i32|i64|i128|f32|f64|str|Self)\\b"
+ },
+ "core_vars": {
+ "comment": "Core type variant",
+ "name": "support.constant.core.rust",
+ "match": "\\b(Some|None|Ok|Err)\\b"
+ },
+ "core_marker": {
+ "comment": "Core trait (marker)",
+ "name": "entity.name.type.marker.rust",
+ "match": "\\b(Copy|Send|Sized|Sync)\\b"
+ },
+ "core_traits": {
+ "comment": "Core trait",
+ "name": "entity.name.type.core.rust",
+ "match": "\\b(Drop|Fn|FnMut|FnOnce|Clone|PartialEq|PartialOrd|Eq|Ord|AsRef|AsMut|Into|From|Default|Iterator|Extend|IntoIterator|DoubleEndedIterator|ExactSizeIterator)\\b"
+ },
+ "std_types": {
+ "comment": "Standard library type",
+ "name": "entity.name.type.class.std.rust",
+ "match": "\\b(Box|String|Vec|Path|PathBuf|Option|Result)\\b"
+ },
+ "std_traits": {
+ "comment": "Standard library trait",
+ "name": "entity.name.type.std.rust",
+ "match": "\\b(ToOwned|ToString)\\b"
+ },
+ "type": {
+ "comment": "A type",
+ "name": "entity.name.type.rust",
+ "match": "\\b([A-Za-z][_A-Za-z0-9]*|_[_A-Za-z0-9]+)\\b"
+ },
+ "type_params": {
+ "comment": "Type parameters",
+ "name": "meta.type_params.rust",
+ "begin": "<(?![=<])",
+ "end": "(?",
+ "patterns": [
+ {
+ "include": "#block_comment"
+ },
+ {
+ "include": "#line_comment"
+ },
+ {
+ "include": "#sigils"
+ },
+ {
+ "include": "#mut"
+ },
+ {
+ "include": "#dyn"
+ },
+ {
+ "include": "#impl"
+ },
+ {
+ "include": "#lifetime"
+ },
+ {
+ "include": "#core_types"
+ },
+ {
+ "include": "#core_marker"
+ },
+ {
+ "include": "#core_traits"
+ },
+ {
+ "include": "#std_types"
+ },
+ {
+ "include": "#std_traits"
+ },
+ {
+ "include": "#type_params"
+ }
+ ]
+ }
+ }
+}
\ No newline at end of file