diff --git a/Rust/Rust.sublime-syntax b/Rust/Rust.sublime-syntax index 1aebebb071..dafe3bece6 100644 --- a/Rust/Rust.sublime-syntax +++ b/Rust/Rust.sublime-syntax @@ -13,11 +13,18 @@ first_line_match: |- ) variables: - identifier: '(?:(?:[[:alpha:]][_[:alnum:]]*|_[_[:alnum:]]+)\b)' # include a word boundary at the end to ensure all possible characters are consumed, to prevent catastrophic backtracking - escaped_byte: '\\(x\h{2}|n|r|t|0|"|''|\\)' - escaped_char: '\\(x\h{2}|n|r|t|0|"|''|\\|u\{\h{1,6}\})' - int_suffixes: 'i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize' - support_type: \b(Copy|Send|Sized|Sync|Drop|Fn|FnMut|FnOnce|Box|ToOwned|Clone|PartialEq|PartialOrd|Eq|Ord|AsRef|AsMut|Into|From|Default|Iterator|Extend|IntoIterator|DoubleEndedIterator|ExactSizeIterator|Option|Some|None|Result|Ok|Err|SliceConcatExt|String|ToString|Vec)\b + non_raw_ident: '[[:alpha:]][_[:alnum:]]*|_[_[:alnum:]]+' + # include a word boundary at the end to ensure all possible characters are + # consumed, to prevent catastrophic backtracking + identifier: '(?:(?:(?:r\#)?{{non_raw_ident}})\b)' + camel_ident: '\b_*[A-Z][a-zA-Z0-9_]*[a-z][a-zA-Z0-9_]*\b' + lifetime: '''(?:_|{{non_raw_ident}})(?!\'')\b' + escaped_byte: '\\([nrt0\"''\\]|x\h{2})' + escaped_char: '\\([nrt0\"''\\]|x[0-7]\h|u\{(?:\h_*){1,6}\})' + int_suffixes: '[iu](?:8|16|32|64|128|size)' + float_suffixes: 'f(32|64)' + dec_literal: '[0-9](?:[0-9_])*' + float_exponent: '[eE][+-]?[0-9_]*[0-9][0-9_]*' contexts: main: - include: statements @@ -30,151 +37,124 @@ contexts: - match: '\${{identifier}}' scope: variable.other.rust - else-pop: - - match: (?=\S) - pop: true + statements: + # This isn't really just "statements", it also includes all types, + # expressions, items, etc. - pop-immediately: - - match: '' - pop: true + - include: visibility - statements: + - match: ';' + scope: punctuation.terminator.rust - - match: '(''{{identifier}})\s*(:)' + - match: '(''(?:{{non_raw_ident}}))\s*(:)' captures: 1: entity.name.label.rust 2: punctuation.separator.rust - - match: '''{{identifier}}(?!\'')\b' - scope: storage.modifier.lifetime.rust - - match: '\b(?:(pub)\s+)?\b(mod)\s+({{identifier}})\b' + - include: lifetime + + - match: '\b(mod)\s+({{identifier}})\b' captures: - 1: storage.modifier.rust - 2: storage.type.module.rust - 3: entity.name.module.rust + 1: storage.type.module.rust + 2: entity.name.module.rust push: - meta_scope: meta.module.rust - match: ';' scope: punctuation.terminator.rust - set: after-operator + pop: true - include: statements-block - match: '\b({{identifier}})\s*(=)\s*(?=\|)' captures: 1: entity.name.function.rust - 2: keyword.operator.rust + 2: keyword.operator.assignment.rust push: closure - - match: '\b(?:(pub)\s+)?\b(fn)\s+(?={{identifier}})' - scope: meta.function.rust + - match: '\b(fn)\s+(?={{identifier}})' captures: - 1: storage.modifier.rust - 2: storage.type.function.rust + 1: storage.type.function.rust push: fn-definition - - match: '\b(?:(pub)\s+)?(struct)\s+' - scope: meta.struct.rust - captures: - 1: storage.modifier.rust - 2: storage.type.struct.rust + - match: '\bstruct\b' + scope: storage.type.struct.rust push: struct-identifier - - match: '\b(?:(pub)\s+)?(type)\s+({{identifier}})\b' + - match: '\bunion\b' + scope: storage.type.union.rust + push: union-identifier + + - match: '\b(type)\s+({{identifier}})\b' captures: - 1: storage.modifier.rust - 2: storage.type.type.rust - 3: entity.name.type.rust + 1: storage.type.type.rust + 2: entity.name.type.rust + push: + - match: '=(?!=)' + scope: keyword.operator.assignment.rust + push: after-operator + - match: '(?=\S)' + pop: true - - match: '\b(?:(pub)\s+)?(trait)\s+({{identifier}})\b' + - match: '\b(trait)\s+({{identifier}})\b' captures: - 1: storage.modifier.rust - 2: storage.type.trait.rust - 3: entity.name.trait.rust + 1: storage.type.trait.rust + 2: entity.name.trait.rust push: - meta_scope: meta.trait.rust + - match: '(?=:)' + push: impl-where + - match: '(?=\bwhere\b)' + push: impl-where + - match: '(?=<)' + push: generic-angles - include: statements-block - match: '\bimpl\b' scope: storage.type.impl.rust push: impl-definition - - match: '\b(?:(pub)\s+)?(enum)\s+({{identifier}})\b' - captures: - 1: storage.modifier.rust - 2: storage.type.enum.rust - 3: entity.name.enum.rust - push: - - meta_scope: meta.enum.rust - - include: statements-block - - - match: \b(let|const|static)\b - scope: storage.type.rust - - - match: \*const\b - scope: storage.type.rust - - - match: \bfn\b - scope: storage.type.function.rust - - - match: \bmod\b - scope: storage.type.module.rust - - - match: \bstruct\b - scope: storage.type.struct.rust - - - match: \bimpl\b - scope: storage.type.impl.rust - - - match: \benum\b + - match: '\benum\b' scope: storage.type.enum.rust + push: enum-identifier - - match: \btype\b - scope: storage.type.type.rust - - - match: \btrait\b - scope: storage.type.trait.rust - - - match: \b(mut|pub|unsafe|move|ref)\b - scope: storage.modifier.rust - - - match: \*mut\b - scope: storage.modifier.rust - - - match: \b(crate|extern|use|where)\b - scope: keyword.other.rust + - include: raw-pointer - - match: \b(break|else|for|if|loop|match|while|continue)\b - scope: keyword.control.rust - - - match: \breturn\b - scope: keyword.control.rust - push: after-operator + # `const` in a function header has a different scope from `const` values. + - match: '\b(const)\s+(?=unsafe|extern|fn)' + captures: + 1: storage.modifier.rust - - match: \b(as|in|box)\b - scope: keyword.operator.rust + - match: '\b(const)\s+({{identifier}})' + captures: + 1: storage.type.rust + 2: entity.name.constant.rust - - match: \b(virtual|proc|alignof|become|offsetof|priv|pure|sizeof|typeof|unsized|yield|do|abstract|final|override|macro)\b - scope: invalid.illegal.rust + - match: '\b(static)\s+(?:(mut)\s+)?({{identifier}})' + captures: + 1: storage.type.rust + 2: storage.modifier.rust + 3: entity.name.constant.rust - - match: \b(true|false)\b - scope: constant.language.rust + - match: '\b(break|continue)\b(?:\s+(''{{non_raw_ident}}))?' + captures: + 1: keyword.control.rust + 2: entity.name.label.rust + - include: support-type - include: type - - match: '\b(macro_rules!)\s+([[:alpha:]_][[:alnum:]_]*)\b' + - match: '\b(macro_rules!)\s+({{identifier}})\b' captures: 1: support.function.rust 2: entity.name.macro.rust push: macro-block - include: comments + - include: attribute - include: strings - include: chars - - match: '\b[[:lower:]_][[:lower:][:digit:]_]*(?=\()' - scope: support.function.rust - - - match: '\b((?:format|print|println|eprint|eprintln)!)\s*(\()' + # macros which take format specs as the only parameter + - match: '\b((?:format(?:_args)?|e?print(?:ln)?|panic|unreachable|unimplemented)!)\s*(\()' captures: 1: support.macro.rust 2: meta.group.rust punctuation.section.group.begin.rust @@ -186,12 +166,13 @@ contexts: - match: '(?=\S)' set: group-tail - - match: '\b((?:write|writeln)!)\s*(\()' + # macros which take format specs as the second parameter + - match: '\b((?:write(?:ln)?|(?:debug_)?assert)!)\s*(\()' captures: 1: support.macro.rust 2: meta.group.rust punctuation.section.group.begin.rust push: - - meta_content_scope: meta.group.rust + - meta_scope: meta.group.rust - include: comments - match: ',' set: @@ -200,17 +181,19 @@ contexts: - include: format-raw-string - match: '(?=\S)' set: group-tail + - include: group-tail + + # macros which take format specs as the third parameter + # - match: '\b((?:assert_eq|assert_ne|debug_assert_eq|debug_assert_ne)!)\s*(\()' + # is more performant as the below + # - match: '\b((?:debug_)?assert_(?:eq|ne)!)\s*(\()' - - match: '\b[[:lower:]_][[:lower:][:digit:]_]*!(?=\s*(\(|\{|\[))' + - match: '\b{{identifier}}!(?=\s*(\(|\{|\[))' scope: support.macro.rust - - match: '{{support_type}}' - scope: support.type.rust + - include: support-type - include: basic-identifiers - - - include: attributes - - include: numbers - match: '(?=\{)' @@ -231,80 +214,83 @@ contexts: - include: statements - include: return-type + - include: symbols + - include: keywords - # Making this an operator helps visually break up large - # match blocks containing just enums - - match: '=>' - scope: keyword.operator.rust + - match: ',' + scope: punctuation.separator.rust push: after-operator - - include: operators - - - match: ';' - scope: punctuation.terminator.rust - push: after-operator + - match: '\b[[:lower:]_][[:lower:][:digit:]_]*(?=\()' + scope: variable.function.rust - - match: '[:,]' - scope: punctuation.separator.rust - push: after-operator + - match: '{{identifier}}' - match: '\.' scope: punctuation.accessor.dot.rust - operators: - - match: \.{2,3} - scope: keyword.operator.range.rust - - match: '(?:[-+%/*^&|]|<<|>>)=' - scope: keyword.operator.assignment.rust - - match: '[!<>=]=|[<>]' - scope: keyword.operator.comparison.rust - - match: '=' - scope: keyword.operator.assignment.rust - push: after-operator - - match: '&&|\|\||!' - scope: keyword.operator.logical.rust - - match: '[-+%/*]' - scope: keyword.operator.arithmetic.rust - - match: '[&|^]|<<|>>' - scope: keyword.operator.bitwise.rust - - match: '[@~?$#'']' - scope: keyword.operator.rust - - match: '\b_\b' - scope: keyword.operator.rust - + visibility: + - match: '\b(pub)\s*(\()' + captures: + 1: storage.modifier.rust + 2: punctuation.section.group.begin.rust + push: + - include: comments + - match: '\)' + scope: punctuation.section.group.end.rust + pop: true + - match: '(crate|in|self|super)' + scope: keyword.other.rust + - match: '::' + scope: meta.path.rust + - match: '{{identifier}}' + scope: meta.path.rust + - match: '\bpub\b' + scope: storage.modifier.rust - attributes: - - match: '(#!?)(\[)' + attribute: + - match: '(#)\s*(!?)\s*(\[)' captures: 1: punctuation.definition.annotation.rust - 2: punctuation.section.group.begin.rust + 2: punctuation.definition.annotation.rust + 3: punctuation.section.group.begin.rust push: + # https://github.com/sublimehq/Packages/issues/709#issuecomment-266835130 - meta_scope: meta.annotation.rust - - match: '({{identifier}})(\()' + - match: '(?:{{identifier}}\s*::\s*)*({{identifier}})' + scope: meta.path.rust captures: 1: variable.annotation.rust - 2: meta.annotation.parameters.rust meta.group.rust punctuation.section.group.begin.rust + - match: '\(' + scope: meta.annotation.parameters.rust meta.group.rust punctuation.section.group.begin.rust push: - meta_content_scope: meta.annotation.parameters.rust meta.group.rust - match: \) scope: meta.annotation.parameters.rust meta.group.rust punctuation.section.group.end.rust pop: true - include: attribute-call - - match: '({{identifier}})' - scope: variable.annotation.rust - match: '=' - scope: keyword.operator.rust + scope: keyword.operator.assignment.rust + set: + - meta_content_scope: meta.annotation.rust + - include: strings + - include: chars + - include: numbers + - include: comments + - match: '\]' + scope: meta.annotation.rust punctuation.section.group.end.rust + pop: true + - match: '\]' scope: punctuation.section.group.end.rust pop: true - - match: '[ \t]+' - - include: strings + - include: comments attribute-call: - match: \) scope: meta.function-call.rust meta.group.rust punctuation.section.group.end.rust pop: true - - match: '({{identifier}})(\()' + - match: '({{identifier}})\s*(\()' scope: meta.function-call.rust captures: 1: variable.function.rust @@ -315,8 +301,14 @@ contexts: - match: ',' scope: punctuation.separator.rust - match: '=' - scope: keyword.operator.rust + scope: keyword.operator.assignment.rust - include: strings + - include: chars + - include: numbers + - include: comments + - include: lifetime + - include: keywords + - include: symbols block: - match: '\}' @@ -331,6 +323,7 @@ contexts: - match: '(?=\})' pop: true - include: statements + - include: attribute group: - match: '\)' @@ -354,6 +347,8 @@ contexts: - include: statements after-operator: + # after-operator tries to handle ambiguous < and | symbols which can be + # either binary operators, or the start of a generic or closure. - match: '(?=<)' set: generic-angles - include: try-closure @@ -365,7 +360,25 @@ contexts: - match: '(?=\S)' pop: true + support-type: + - match: '(Vec|Option|Result|BTreeMap|HashMap|Box|Rc|Arc|AsRef|AsMut|Into|From)\s*(?=<)' + scope: support.type.rust + push: generic-angles + - match: '[?]?(?=\bSized\b)' + scope: keyword.operator.rust + - match: '[!]?(?=\bSync|Send\b)' + scope: keyword.operator.rust + - match: \b(Copy|Send|Sized|Sync|Drop|Fn|FnMut|FnOnce|Box|ToOwned|Clone|PartialEq|PartialOrd|Eq|Ord|AsRef|AsMut|Into|From|Default|Iterator|Extend|IntoIterator|DoubleEndedIterator|ExactSizeIterator|Option|Some|None|Result|Ok|Err|SliceConcatExt|String|ToString|Vec)\b + scope: support.type.rust + return-type: + - match: '\bimpl\b' + scope: storage.type.impl.rust + push: + - include: comments + - include: impl-generic + - match: '(?=\S)' + pop: true - match: '->' scope: punctuation.separator.rust push: @@ -380,6 +393,79 @@ contexts: - match: '(?=\S)' pop: true + pattern-param: + # A pattern used in a function or closure parameter. + - include: comments + - match: '&' + scope: keyword.operator.rust + - match: \b(mut|ref)\b + scope: storage.modifier.rust + - match: '@' + scope: keyword.operator.rust + - include: lifetime + - match: '\b{{identifier}}\b(?!\s*(?:::|\{|\[|\())' + scope: variable.parameter.rust + + - match: '\{' + # Struct pattern. + scope: punctuation.section.block.begin.rust + push: + - meta_scope: meta.block.rust + - match: '\}' + scope: punctuation.section.block.end.rust + pop: true + - match: '(\d+)\s*(:)' + # Tuple struct field specifier. + captures: + 1: constant.numeric.integer.decimal.rust + 2: punctuation.separator.rust + - match: '{{identifier}}\s*(:)' + # Struct field specifier. + captures: + 1: punctuation.separator.rust + - match: '\.\.' + scope: keyword.operator.rust + - include: pattern-param + + - match: '\(' + # Tuple or tuple struct pattern. + scope: punctuation.section.group.begin.rust + push: + - meta_scope: meta.group.rust + - match: '\)' + scope: punctuation.section.group.end.rust + pop: true + - match: '\.\.' + scope: keyword.operator.rust + - include: pattern-param + + - match: '\[' + # Slice pattern. + scope: punctuation.section.brackets.begin.rust + push: + - meta_scope: meta.brackets.rust + - match: '\]' + scope: punctuation.section.brackets.end.rust + pop: true + - include: pattern-param + + # Path for struct patterns. + - match: '\bself\b|\bsuper\b' + scope: keyword.other.rust + - match: '\b{{identifier}}\b' + - match: '::' + + - match: ':(?!:)' + # Type + scope: punctuation.separator.rust + push: + - match: '(?=,|\)|\]|\}|\|)' + pop: true + - include: type-any-identifier + + - match: ',' + scope: punctuation.separator.rust + closure: - meta_content_scope: meta.function.closure.rust - match: '\|' @@ -388,56 +474,16 @@ contexts: closure-parameters: - meta_scope: meta.function.parameters.rust + - match: '\|' + scope: punctuation.section.parameters.end.rust + pop: true + - include: pattern-param # If the user has just typed a |, exit the params # scope as soon as we hit something that it not a # valid part so the whole rest of the document isn't # highlighted using the params scope - - match: '(?=[};)\]\n])' + - match: '(?=[=};)\]])' pop: true - - match: ',' - scope: punctuation.separator.rust - - match: '\(' - scope: meta.group.rust punctuation.section.group.begin.rust - push: - - meta_content_scope: meta.group.rust - - match: '\)' - scope: meta.group.rust punctuation.section.group.end.rust - pop: true - - match: ',' - scope: punctuation.separator.rust - - match: '({{identifier}})' - scope: variable.parameter.rust - - match: '(:)\s*(\()' - captures: - 1: punctuation.separator.rust - 2: meta.group.rust punctuation.section.group.begin.rust - push: - - meta_content_scope: meta.group.rust - - match: '\)' - scope: meta.group.rust punctuation.section.group.end.rust - pop: true - - match: ',' - scope: punctuation.separator.rust - - include: type-any-identifier - - match: '\|' - scope: punctuation.section.parameters.end.rust - pop: true - - match: \bself\b - scope: variable.parameter.rust - - match: '({{identifier}})\s*(?:(:(?!:))|(?=\||,))' - captures: - 1: variable.parameter.rust - 2: punctuation.separator.rust - push: - - match: (?=,|\|) - pop: true - - include: type-any-identifier - - match: '&' - scope: keyword.operator.rust - - match: \b(mut|ref)\b - scope: storage.modifier.rust - - match: '''{{identifier}}(?!\'')\b' - scope: storage.modifier.lifetime.rust closure-return: - meta_content_scope: meta.function.closure.rust @@ -460,73 +506,68 @@ contexts: - include: block type: - - match: (?:{{support_type}}|{{identifier}})(?=<) - captures: - 1: support.type.rust + # A low-level type. Typically you want type-any-identifier for the full + # type grammar. + - match: '{{identifier}}(?=<)' push: generic-angles - - match: \b(Self|i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize|f32|f64|bool|char|str)\b + - match: \b(Self|{{int_suffixes}}|{{float_suffixes}}|bool|char|str)\b + scope: storage.type.rust + # stdsimd types + - match: |- + (?x) + \b(?: + [ium]8x(?:2|4|8|16|32) | [iu]8x64 | + [ium]16x(?:2|4|8|16) | [iu]16x32 | # f16xN types might come later + [iumf]32x(?:2|4|8) | [iuf]32x16 | + [iumf]64x(?:2|4) | [iuf]64x8 | + m1x(?:64|32|16|8) | # 512-bit masks + __m(?:64|128|256)[di]? # __m512 should come later + )\b scope: storage.type.rust + - match: '\bdyn\b(?!\s*::)(?=\s*(?:\(|{{lifetime}}|{{identifier}}))' + scope: storage.type.trait.rust generic-angles: - meta_scope: meta.generic.rust - - include: comments - - match: '->' - scope: punctuation.separator.generic.rust - push: generic-angles-contents - match: '>' scope: punctuation.definition.generic.end.rust pop: true - match: '<' scope: punctuation.definition.generic.begin.rust push: generic-angles-contents - # Alert the user of a broken generic construct - - match: '\S' - scope: invalid.illegal.rust + - match: '(?=\S)' pop: true generic-angles-contents: - include: comments - - match: \bextern\b - scope: keyword.other.rust - push: - - include: strings - - match: '(?=\S)' - pop: true - - match: '(?=>|[^ \t\n\$=<_+''(),&:\[\]*[:alnum:]])' + - include: attribute + - match: '(?=>)' pop: true - match: '<' scope: punctuation.definition.generic.begin.rust push: - match: '>' - scope: punctuation.definition.generic.begin.rust + scope: punctuation.definition.generic.end.rust pop: true - include: generic-angles-contents - - match: '\[' - scope: punctuation.section.group.begin.rust - push: - - meta_scope: meta.group.rust - - match: '\]' - scope: punctuation.section.group.end.rust - pop: true - - match: ';' - scope: punctuation.separator.rust - set: - - match: '\]' - scope: punctuation.section.group.end.rust - pop: true - - include: constant-integer-expression - - match: '(?=\S)' - pop: true - - include: generic-angles-contents + - include: bool + # byte must be before type-any-identifier since it doesn't know about byte tokens + - include: byte - include: type-any-identifier - - match: '{{support_type}}' - scope: support.type.rust - - match: ':' + # char must be after type-any-identifier to deal with conflict with lifetimes + - include: char + # Handle negative integers (technically unary negative expression with a literal expression) + - match: '-' + scope: keyword.operator.arithmetic.rust + - include: integers + - include: block + - match: '{{identifier}}' + - match: ':|,' scope: punctuation.separator.rust - - match: '\+' - scope: keyword.operator.rust - - match: '\bas\b' + - match: '\+|=' scope: keyword.operator.rust + - match: '(?=\S)' + pop: true constant-integer-expression: - include: integers @@ -546,13 +587,18 @@ contexts: scope: keyword.operator.arithmetic.rust type-any-identifier: + - include: comments + - include: support-type + - include: return-type - match: '&' scope: keyword.operator.rust - - match: \bref\b - scope: storage.modifier.rust - - match: (?:\b|\*)(?:mut|const)\b + - include: raw-pointer + - match: \b(mut|ref|const|unsafe)\b scope: storage.modifier.rust - - match: \b(fn)\b(\() + - match: '\bas\b' + # This is for qualified type paths + scope: keyword.operator.rust + - match: \b(fn)\b\s*(\() captures: 1: storage.type.function.rust 2: meta.group.rust punctuation.section.group.begin.rust @@ -565,8 +611,7 @@ contexts: - match: '(?=\S)' pop: true - include: type-any-identifier - - match: '''{{identifier}}(?!\'')\b' - scope: storage.modifier.lifetime.rust + - include: lifetime - match: '\b([[:upper:]]|_*[[:upper:]][[:alnum:]_]*[[:lower:]][[:alnum:]_]*)\b(::)' scope: meta.path.rust storage.type.rust captures: @@ -583,15 +628,66 @@ contexts: - match: '\(' scope: punctuation.section.group.begin.rust push: + - meta_scope: meta.group.rust - match: '\)' scope: punctuation.section.group.end.rust pop: true + - match: ',' + scope: punctuation.separator.rust - include: type-any-identifier + - match: '\+' + scope: keyword.operator.rust + - match: \bextern\b + scope: keyword.other.rust + push: + - include: strings + - match: '(?=\S)' + pop: true + - include: hrtb - include: type + - include: type-slice-or-array - match: '\b_\b' scope: keyword.operator.rust + - match: '!' + scope: keyword.operator.rust + - match: '{{identifier}}' + + raw-pointer: + - match: '\*\s*(?:const|mut)\b' + scope: storage.modifier.rust + + hrtb: + - match: \bfor\b + scope: keyword.other.rust + push: + - match: '(?=<)' + push: generic-angles + - include: type-any-identifier + - match: '&' + scope: keyword.operator.rust + - include: lifetime + - match: '(?=\S)' + pop: true + + type-slice-or-array: + - match: '\[' + scope: punctuation.section.group.begin.rust + push: + - match: '\]' + scope: punctuation.section.group.end.rust + pop: true + - match: ';' + scope: punctuation.separator.rust + set: + - match: '\]' + scope: punctuation.section.group.end.rust + pop: true + - include: constant-integer-expression + - include: type-any-identifier struct-identifier: + - meta_scope: meta.struct.rust + - include: comments - match: '{{identifier}}(?=<)' scope: entity.name.struct.rust set: @@ -603,15 +699,21 @@ contexts: - match: '{{identifier}}' scope: entity.name.struct.rust set: struct-body + - match: '(?=\S)' + # Abort on invalid character. + pop: true struct-body: - meta_scope: meta.struct.rust - include: comments + - match: '(?=\bwhere\b)' + push: impl-where - match: '(?=\()' - set: struct-tuple + push: struct-tuple - match: '(?=\{)' set: struct-classic - - match: '(?=;)' + - match: '(?=\S)' + # Semicolon is valid here, others should just abort. pop: true struct-tuple: @@ -621,15 +723,15 @@ contexts: pop: true - match: '\(' scope: punctuation.section.group.begin.rust - # Ensure that we end the tuple at the next ) to - # prevent odd highlighting as the user is typing - with_prototype: + push: - match: '(?=\))' pop: true - push: - meta_scope: meta.group.rust - include: comments + - include: visibility - include: type-any-identifier + - match: ',' + scope: punctuation.separator.rust struct-classic: - meta_scope: meta.struct.rust @@ -638,134 +740,310 @@ contexts: pop: true - match: '\{' scope: punctuation.section.block.begin.rust + push: struct-classic-body + - match: '(?=\S)' + # Abort for an invalid match. + pop: true + + struct-classic-body: + - meta_scope: meta.block.rust + - match: '(?=\})' + pop: true + - include: comments + - include: attribute + - include: visibility + - match: '{{identifier}}(?=\s*:)' + scope: variable.other.member.rust push: - - meta_scope: meta.block.rust + - match: ',' + scope: punctuation.separator.rust + pop: true - match: '(?=\})' pop: true - include: comments - - include: attributes - - match: \b(pub)\b(?:(\()(crate)(\)))? - captures: - 1: storage.modifier.rust - 2: punctuation.definition.modifier-scope.begin.rust - 3: storage.modifier.rust - 4: punctuation.definition.modifier-scope.end.rust - - match: '{{identifier}}(?=\s*:)' - scope: variable.other.member.rust - push: - - match: ',|(?=\})' - pop: true - - include: comments - - match: ':' - scope: punctuation.separator.type.rust - - include: type-any-identifier + - match: ':' + scope: punctuation.separator.rust + - include: type-any-identifier + - match: '(?=\S)' + # Abort for an invalid match. + pop: true + + union-identifier: + - meta_scope: meta.union.rust + - include: comments + - match: '{{identifier}}(?=<)' + scope: entity.name.union.rust + set: + - meta_scope: meta.union.rust meta.generic.rust + - match: '(?=<)' + push: generic-angles + - match: '' + set: union-body + - match: '{{identifier}}' + scope: entity.name.union.rust + set: union-body + + union-body: + - meta_scope: meta.union.rust + - include: comments + - match: '(?=\bwhere\b)' + push: impl-where + - match: '\{' + scope: punctuation.section.block.begin.rust + push: struct-classic-body + - match: '\}' + scope: meta.block.rust punctuation.section.block.end.rust + pop: true + - match: '(?=;)' + pop: true + + enum-identifier: + - meta_scope: meta.enum.rust + - include: comments + - match: '{{identifier}}(?=<)' + scope: entity.name.enum.rust + set: + - meta_scope: meta.enum.rust meta.generic.rust + - match: '(?=<)' + push: generic-angles + - match: '' + set: enum-maybe-where + - match: '{{identifier}}' + scope: entity.name.enum.rust + set: enum-maybe-where + - match: '(?=\S)' + # Abort on invalid character. + pop: true + + enum-maybe-where: + - meta_scope: meta.enum.rust + - include: comments + - match: '(?=\bwhere\b)' + push: impl-where + - match: '\{' + scope: punctuation.section.block.begin.rust + set: enum-body + - match: '(?=\S)' + # Abort on invalid character. + pop: true + + enum-body: + - meta_scope: meta.block.rust meta.enum.rust + - include: comments + - include: attribute + - match: '\}' + scope: punctuation.section.block.end.rust + pop: true + - match: '\b[[:upper:]_][[:upper:][:digit:]_]*\b' + scope: constant.other.rust + push: enum-variant-type + - match: '{{camel_ident}}' + scope: storage.type.source.rust + push: enum-variant-type + - match: '{{identifier}}' + push: enum-variant-type + + enum-variant-type: + - include: comments + - match: '(?=\})' + pop: true + - match: ',' + scope: punctuation.separator.rust + pop: true + - match: '=' + set: enum-discriminant + - match: '(?=\()' + push: struct-tuple + - match: '(?=\{)' + push: struct-classic + + enum-discriminant: + - match: ',' + pop: true + - match: '(?=\})' + pop: true + # This is just constant-expression, but we don't have that defined. + - include: statements macro-block: - # This meta scope requires some juggling - meta_scope: meta.macro.rust - - match: \{ - scope: meta.block.rust punctuation.section.block.begin.rust + - include: comments + - match: '\{' + scope: punctuation.section.block.begin.rust set: - - meta_content_scope: meta.macro.rust meta.block.rust - - match: \} - scope: meta.macro.rust meta.block.rust punctuation.section.block.end.rust + - meta_scope: meta.macro.rust + - match: '\}' + scope: punctuation.section.block.end.rust pop: true - include: macro-block-contents - - match: \[ - scope: meta.group.rust punctuation.section.group.begin.rust + + # Note: ) and ] require a trailing semicolon, but this + # does not check for that. + - match: '\(' + scope: punctuation.section.block.begin.rust set: - - meta_content_scope: meta.macro.rust meta.group.rust - - match: \] - scope: meta.macro.rust meta.group.rust punctuation.section.group.end.rust + - meta_scope: meta.macro.rust + - match: '\)' + scope: punctuation.section.block.end.rust pop: true - include: macro-block-contents - - match: \( - scope: meta.group.rust punctuation.section.group.begin.rust + + - match: '\[' + scope: punctuation.section.block.begin.rust set: - - meta_content_scope: meta.macro.rust meta.group.rust - - match: \) - scope: meta.macro.rust meta.group.rust punctuation.section.group.end.rust + - meta_scope: meta.macro.rust + - match: '\]' + scope: punctuation.section.block.end.rust pop: true - include: macro-block-contents - - include: else-pop macro-block-contents: + # Macro block consists of a series of rules separated by semicolon + # (trailing semicolon is optional). + # + # A rule is: BRACKET matchers BRACKET => BRACKET transcribers BRACKET + # where BRACKET needs to be matched () or [] or {} - include: comments - - match: (?=\() + - match: '\{' + scope: punctuation.section.block.begin.rust + push: + - meta_include_prototype: false + - meta_scope: meta.macro.matchers.rust + - match: '\}' + scope: punctuation.section.block.end.rust + set: macro-rule-sep + - include: macro-matchers + + - match: '\(' + scope: punctuation.section.block.begin.rust push: - - macro-terminator - - macro-body - - macro-match-operator - - macro-matcher + - meta_include_prototype: false + - meta_scope: meta.macro.matchers.rust + - match: '\)' + scope: punctuation.section.block.end.rust + set: macro-rule-sep + - include: macro-matchers - macro-matcher: - - match: \( - scope: punctuation.section.group.begin.rust - set: + - match: '\[' + scope: punctuation.section.block.begin.rust + push: - meta_include_prototype: false - - meta_scope: meta.group.macro-matcher.rust - - match: \) - scope: punctuation.section.group.end.rust + - meta_scope: meta.macro.matchers.rust + - match: '\]' + scope: punctuation.section.block.end.rust + set: macro-rule-sep + - include: macro-matchers + + macro-matchers: + - include: comments + - match: '\(' + scope: punctuation.section.block.begin.rust + push: + - meta_include_prototype: false + - match: '\)' + scope: punctuation.section.block.end.rust + pop: true + - include: macro-matchers + + - match: '\[' + scope: punctuation.section.block.begin.rust + push: + - meta_include_prototype: false + - match: '\]' + scope: punctuation.section.block.end.rust + pop: true + - include: macro-matchers + + - match: '\{' + scope: punctuation.section.block.begin.rust + push: + - meta_include_prototype: false + - match: '\}' + scope: punctuation.section.block.end.rust pop: true - - match: ((\$)\() + - include: macro-matchers + + - match: '(\$\s*{{identifier}})\s*(:)\s*(ident|path|expr|ty|pat_param|pat|stmt|block|item|meta|tt|lifetime|vis|literal)' + captures: + 1: variable.parameter.rust + 2: punctuation.separator.rust + 3: storage.type.rust + + - match: '(\$)\s*(\()' + # Kleene operator. + captures: + 1: keyword.operator.rust + 2: punctuation.section.group.begin.rust + push: + - meta_include_prototype: false + - match: '(\))\s*[^?*+]*\s*([?*+])' captures: - 1: punctuation.section.group.begin.rust + 1: punctuation.section.group.end.rust 2: keyword.operator.rust - push: - - meta_scope: meta.group.rust - - meta_include_prototype: false - - match: (\))(?:\s*[^*+]?\s*([*+]))? - captures: - 1: punctuation.section.group.end.rust - 2: keyword.operator.rust - pop: true - - include: macro-metavariable - - include: macro-metavariable + pop: true + - include: macro-matchers + + # All other tokens except $ and delimiters are allowed here. + - include: numbers + - include: strings + - include: keywords + - include: lifetime + - include: chars + - include: symbols - macro-match-operator: - - match: => + macro-rule-sep: + - include: comments + - match: '=>' scope: keyword.operator.rust + set: macro-transcriber-block + - match: '(?=\S)' + # Abort on unexpected character. pop: true - - include: else-pop - macro-body: - - match: \{ + macro-transcriber-block: + - include: comments + + - match: '\{' scope: punctuation.section.block.begin.rust set: - - meta_scope: meta.block.macro-body.rust - - match: \} + - meta_scope: meta.macro.transcribers.rust + - match: '\}' scope: punctuation.section.block.end.rust - pop: true + set: macro-semi-sep - include: statements - - match: \( - scope: punctuation.section.group.begin.rust + + - match: '\(' + scope: punctuation.section.block.begin.rust set: - - meta_scope: meta.group.macro-body.rust - - match: \) - scope: punctuation.section.group.end.rust - pop: true + - meta_scope: meta.macro.transcribers.rust + - match: '\)' + scope: punctuation.section.block.end.rust + set: macro-semi-sep - include: statements - - match: \[ - scope: punctuation.section.group.begin.rust + + - match: '\[' + scope: punctuation.section.block.begin.rust set: - - meta_scope: meta.group.macro-body.rust - - match: \] - scope: punctuation.section.group.end.rust - pop: true + - meta_scope: meta.macro.transcribers.rust + - match: '\]' + scope: punctuation.section.block.end.rust + set: macro-semi-sep - include: statements - - include: else-pop - macro-metavariable: - - match: '(\${{identifier}})(:)(ident|path|expr|ty|pat|stmt|block|item|meta|tt)' - captures: - 1: variable.parameter.macro.rust - 2: punctuation.separator.rust - 3: storage.type.rust + - match: '(?=\S)' + # Abort on unexpected character. + pop: true - macro-terminator: - - match: ;|, - scope: punctuation.terminator.macro-matcher.rust - - include: else-pop + macro-semi-sep: + - include: comments + - match: ';' + scope: punctuation.terminator.rust + pop: true + - match: '(?=[})\]])' + pop: true + - match: '\S' + # This is intended to help make it evident when you forget a semicolon. + scope: invalid.illegal.rust impl-definition: - meta_scope: meta.impl.rust @@ -783,10 +1061,13 @@ contexts: pop: true impl-for: - - match: '(?=\s*(?:::|{{identifier}}|\$|<)+(<.*?>)?\s+for\s+)' + # `!?` here matches opt-out trait impls + - match: '(?=\s*(?:::|!?{{identifier}}|\$|<)+(<.*?>)?\s+for\s+)' set: - meta_scope: meta.impl.rust - include: comments + - match: '!?(?=\s*{{identifier}})' + scope: keyword.operator.rust meta.impl.opt-out.rust - match: \bfor\b scope: keyword.other.rust set: impl-identifier @@ -800,25 +1081,26 @@ contexts: - match: '(?=\{)' set: impl-body - match: '(?=\bwhere\b)' - set: impl-where - - match: '{{identifier}}' + push: impl-where + - match: \b(mut|ref)\b + scope: storage.modifier.rust + - match: '{{identifier}}(?=<)' scope: entity.name.impl.rust - - match: '(?=<)' push: generic-angles + - match: '{{identifier}}' + scope: entity.name.impl.rust - match: '&' scope: keyword.operator.rust - - match: \b(mut|ref)\b - scope: storage.modifier.rust - - match: '''{{identifier}}(?!\'')\b' - scope: storage.modifier.lifetime.rust + - include: lifetime + - match: '(?=\S)' + # Abort on unexpected character. + pop: true impl-where: - - meta_scope: meta.impl.rust + - meta_scope: meta.where.rust - include: comments - - match: '(?=\{)' - set: impl-body - - match: \bfor\b - scope: keyword.other.rust + - match: '(?=(\{|;))' + pop: true - match: \bwhere\b scope: keyword.other.rust - include: type-any-identifier @@ -842,13 +1124,14 @@ contexts: push: generic-angles - match: '(?=\()' set: fn-parameters + - match: \bwhere\b + set: fn-where # Escape for incomplete expression - - match: '(?=\S)' + - match: '(?=;)' pop: true fn-parameters: - meta_scope: meta.function.rust - - include: comments - match: '\)' scope: meta.function.parameters.rust punctuation.section.parameters.end.rust set: fn-return @@ -859,36 +1142,7 @@ contexts: - include: comments - match: '(?=\))' pop: true - - match: '\(' - scope: meta.group.rust punctuation.section.group.begin.rust - push: - - meta_content_scope: meta.group.rust - - match: '\)' - scope: meta.group.rust punctuation.section.group.end.rust - pop: true - - match: ',' - scope: punctuation.separator.rust - - match: '{{identifier}}' - scope: variable.parameter.rust - - match: '(:)\s*(\()' - captures: - 1: punctuation.separator.rust - 2: meta.group.rust punctuation.section.group.begin.rust - push: - - meta_content_scope: meta.group.rust - - match: '\)' - scope: meta.group.rust punctuation.section.group.end.rust - pop: true - - match: ',' - scope: punctuation.separator.rust - - include: type-any-identifier - - match: \bself\b - scope: variable.parameter.rust - - match: '({{identifier}})\s*(:(?!:))' - captures: - 1: variable.parameter.rust - 2: punctuation.separator.rust - - include: type-any-identifier + - include: pattern-param fn-return: - meta_scope: meta.function.rust @@ -898,22 +1152,23 @@ contexts: - match: '(?=\bwhere\b)' set: fn-where - include: return-type - # Escape for incomplete expression + # Escape for incomplete expression, or ';' - match: '(?=\S)' pop: true fn-where: - - meta_scope: meta.function.rust + - meta_scope: meta.function.rust meta.where.rust - include: comments - match: '(?=\{)' set: fn-body - - match: \bfor\b - scope: keyword.other.rust - match: \bwhere\b scope: keyword.other.rust - include: type-any-identifier - - match: ':' + - match: '[:,]' scope: punctuation.separator.rust + # Escape for incomplete expression, or ';' + - match: '(?=\S)' + pop: true fn-body: - meta_scope: meta.function.rust @@ -960,6 +1215,7 @@ contexts: - match: \*/ scope: punctuation.definition.comment.rust pop: true + # Javadoc style comment with leading * on each line. Helps with word-wrapping. - match: ^\s*(\*)(?!/) captures: 1: punctuation.definition.comment.rust @@ -983,22 +1239,35 @@ contexts: - include: char - include: byte - escaped-byte: - - match: '{{escaped_byte}}' - scope: constant.character.escape.rust - byte: - - match: "(b)(')(?=([^'\\\\]|{{escaped_byte}})')" + - match: "(b)(')" captures: 1: storage.type.string.rust 2: punctuation.definition.string.begin.rust push: - meta_include_prototype: false - meta_scope: string.quoted.single.rust - - match: \' - scope: punctuation.definition.string.end.rust + # ASCII except ', \, \n, \r or \t + - match: '[\x00-\x08\x0b-\x0c\x0e-\x26\x28-\x5b\x5d-\x7f]' + set: byte-tail + # Don't mark entire file invalid while writing, even though this is + # not valid syntax. + - match: '\n' pop: true - - include: escaped-byte + - match: '{{escaped_byte}}' + scope: constant.character.escape.rust + set: byte-tail + - match: '' + set: byte-tail + + byte-tail: + - match: "'" + scope: string.quoted.single.rust punctuation.definition.string.end.rust + pop: true + - match: '\n' + pop: true + - match: '.' + scope: invalid.illegal.byte.rust byte-string: - match: '(b)(")' @@ -1011,7 +1280,12 @@ contexts: - match: '"' scope: punctuation.definition.string.end.rust pop: true - - include: escaped-byte + - match: '{{escaped_byte}}' + scope: constant.character.escape.rust + - match: '(\\)$' + scope: punctuation.separator.continuation.line.rust + - match: '\\.' + scope: invalid.illegal.character.escape.rust raw-byte-string: - match: (br)(#*)" @@ -1028,16 +1302,36 @@ contexts: escaped-char: - match: '{{escaped_char}}' scope: constant.character.escape.rust + - match: '\\u\{[^}]*\}' + scope: invalid.illegal.character.escape.rust + - match: '\\.' + scope: invalid.illegal.character.escape.rust char: - - match: "'(?=([^'\\\\]|{{escaped_char}})')" + - match: "'" scope: punctuation.definition.string.begin.rust push: - meta_scope: string.quoted.single.rust - - match: \' - scope: punctuation.definition.string.end.rust + - match: "[^'\\\\\n\r\t]" + set: char-tail + # Don't mark entire file invalid while writing, even though this is + # not valid syntax. + - match: '\n' pop: true - - include: escaped-char + - match: '{{escaped_char}}' + scope: constant.character.escape.rust + set: char-tail + - match: '' + set: char-tail + + char-tail: + - match: "'" + scope: string.quoted.single.rust punctuation.definition.string.end.rust + pop: true + - match: '\n' + pop: true + - match: '.' + scope: invalid.illegal.char.rust string: - match: '"' @@ -1104,8 +1398,8 @@ contexts: [+-]? # [sign] \#? # ['#'] 0? # [0] - (\d\$?)? # [width] - (\.(\d\$?|\*)?)? # ['.' precision] + (\d+\$?)? # [width] + (\.(\d+\$?|\*)?)? # ['.' precision] (\?|{{identifier}})? # [type] )? \} @@ -1116,41 +1410,46 @@ contexts: - include: integers floats: - - match: '\b((?:\d[\d_]*)?\d\.)(\d[\d_]*(?:[eE][+-]?[\d_]*\d[\d_]*)?)(f32|f64)?' - captures: - 1: constant.numeric.float.rust - 2: constant.numeric.float.rust - 3: storage.type.numeric.rust - - match: '\b((?:\d[\d_]*)?\d\.)(?!\.)' - scope: constant.numeric.float.rust - - match: '\b(\d[\d_]*)(f32|f64)\b' + - match: '\b({{dec_literal}}(?:\.{{dec_literal}})?(?:{{float_exponent}})?)({{float_suffixes}})' captures: 1: constant.numeric.float.rust 2: storage.type.numeric.rust + - match: '\b{{dec_literal}}\.{{dec_literal}}(?:{{float_exponent}})?' + scope: constant.numeric.float.rust + - match: '\b{{dec_literal}}{{float_exponent}}' + scope: constant.numeric.float.rust + - match: '\b{{dec_literal}}\.(?![A-Za-z._''])' + scope: constant.numeric.float.rust integers: - - match: '\b(\d[\d_]*)({{int_suffixes}})?\b' + - match: '\b({{dec_literal}})({{int_suffixes}})?\b' captures: 1: constant.numeric.integer.decimal.rust 2: storage.type.numeric.rust - - match: '\b(0x[\h_]*\h[\h_]*)({{int_suffixes}})?\b' + - match: '\b(0x[\h_]+)({{int_suffixes}})?\b' captures: 1: constant.numeric.integer.hexadecimal.rust 2: storage.type.numeric.rust - - match: '\b(0o[0-7_]*[0-7][0-7_]*)({{int_suffixes}})?\b' + - match: '\b(0o[0-7_]+)({{int_suffixes}})?\b' captures: 1: constant.numeric.integer.octal.rust 2: storage.type.numeric.rust - - match: '\b(0b[0-1_]*[0-1][0-1_]*)({{int_suffixes}})?\b' + - match: '\b(0b[0-1_]+)({{int_suffixes}})?\b' captures: 1: constant.numeric.integer.binary.rust 2: storage.type.numeric.rust + lifetime: + - match: '{{lifetime}}' + scope: storage.modifier.lifetime.rust + basic-identifiers: - - match: '\b([[:upper:]_][[:upper:][:digit:]_]+)\b' + - match: '\b(?:(?:r#)?[[:upper:]_][[:upper:][:digit:]_]+)\b' scope: constant.other.rust - match: '\b(c_[[:lower:][:digit:]_]+|[[:lower:]_][[:lower:][:digit:]_]*_t)\b' scope: storage.type.rust + - match: '\b(?:r#)?_*[A-Z][a-zA-Z0-9_]*[a-z][a-zA-Z0-9_]*\b' + scope: storage.type.source.rust - match: '(?={{identifier}}::)' push: - meta_scope: meta.path.rust @@ -1158,14 +1457,11 @@ contexts: - match: '::' scope: punctuation.accessor.rust set: no-type-names - - match: '{{identifier}}(::)' + - match: '(::)(?={{identifier}})' scope: meta.path.rust captures: 1: punctuation.accessor.rust push: no-type-names - - match: '(::)(?={{identifier}})' - scope: meta.path.rust punctuation.accessor.rust - push: no-type-names - include: no-path-identifiers no-path-identifiers: @@ -1184,3 +1480,96 @@ contexts: push: generic-angles - match: '' pop: true + + symbols: + - match: '=>' + # Making this an operator helps visually break up large + # match blocks containing just enums + scope: keyword.operator.rust + + - match: '<-|->' + scope: keyword.operator.rust + + - match: '\.\.\.|\.\.=|\.\.' + scope: keyword.operator.range.rust + + - match: '[!<>=]=' + scope: keyword.operator.comparison.rust + + - match: '(?:[-+%/*^&|]|<<|>>)?=' + scope: keyword.operator.assignment.rust + + - match: '&&|\|\||!' + scope: keyword.operator.logical.rust + + - match: '[&|^]|<<|>>' + scope: keyword.operator.bitwise.rust + + - match: '[<>]' + scope: keyword.operator.comparison.rust + + - match: '[-+%/*]' + scope: keyword.operator.arithmetic.rust + + - match: '[@~?$#'']' + scope: keyword.operator.rust + + - match: '[:;,]' + scope: punctuation.separator.rust + + bool: + - match: \b(true|false)\b + scope: constant.language.rust + + keywords: + # All keywords. Note in `statements` some of these are superseded by more + # specific rules. + - include: bool + + - match: \b(let|const|static)\b + scope: storage.type.rust + + - match: \bfn\b + scope: storage.type.function.rust + + - match: \bmod\b + scope: storage.type.module.rust + + - match: \bstruct\b + scope: storage.type.struct.rust + + - match: \bimpl\b + scope: storage.type.impl.rust + + - match: \benum\b + scope: storage.type.enum.rust + + - match: \btype\b + scope: storage.type.type.rust + + - match: \btrait\b + scope: storage.type.trait.rust + + - match: \b(mut|pub|unsafe|move|ref)\b + scope: storage.modifier.rust + + - match: \b(crate|extern|use|where)\b + scope: keyword.other.rust + + - match: \b(async|await|else|for|if|loop|match|try|while|yield)\b + scope: keyword.control.rust + + - match: \b(break|continue)\b + scope: keyword.control.rust + + - match: \breturn\b + scope: keyword.control.rust + + - match: \b(as|in|box)\b + scope: keyword.operator.rust + + - match: \b(virtual|become|priv|typeof|unsized|do|abstract|final|override|macro)\b + scope: invalid.illegal.rust + + - match: \b(super|self|Self)\b + scope: keyword.other.rust diff --git a/Rust/syntax_test_rust.rs b/Rust/syntax_test_rust.rs deleted file mode 100644 index 978893a157..0000000000 --- a/Rust/syntax_test_rust.rs +++ /dev/null @@ -1,1151 +0,0 @@ -// SYNTAX TEST "Packages/Rust/Rust.sublime-syntax" - -// Line comments -// <- comment.line.double-slash punctuation.definition.comment -// ^^^^^^^^^^^^^^ comment.line.double-slash - -// <- - comment -/// Line doc comments -// <- comment.line.documentation -// ^^^^^^^^^^^^^ comment.line.documentation - -/*! -// <- comment.block.documentation punctuation.definition.comment - // <- comment.block.documentation -//^ comment.block.documentation -Block doc comments -// ^^^^^^^^^^^^^^^^ comment.block.documentation -/* Nested comments */ -// ^^^^^^^^^^^^^^^^^^ comment.block.documentation comment.block -*/ - -/** - * -// ^ comment.block.documentation.rust punctuation.definition.comment.rust -*/ - -let c = 'c'; -// <- storage.type -// ^ keyword.operator.assignment -// ^^^ string.quoted.single -let b = b'c'; -// <- storage.type -// ^ keyword.operator.assignment -// ^ storage.type -// ^^^ string.quoted.single - -let s = "This is a string \x01_\u{007F}_\"_\'_\\_\r_\n_\t_\0"; -// <- storage.type -// ^ keyword.operator.assignment -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double -// ^^^^ constant.character.escape -// ^^^^^^^^ constant.character.escape -// ^^ constant.character.escape -// ^^ constant.character.escape -// ^^ constant.character.escape -// ^^ constant.character.escape -// ^^ constant.character.escape -// ^^ constant.character.escape -// ^^ constant.character.escape -let r = r##"This is a raw string, no escapes! \x00 \0 \n"###; -// <- storage.type -// ^ keyword.operator.assignment -// ^ storage.type -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double.raw - constant.character.escape -// ^^^ punctuation.definition.string.begin.rust -// ^^^ punctuation.definition.string.end.rust -// ^ - string - -let bytes = b"This won't escape unicode \u{0123}, but will do \x01_\"_\'_\\_\r_\n_\t_\0"; -// <- storage.type -// ^ keyword.operator -// ^ storage.type -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double -// ^^^^ constant.character.escape -// ^^ constant.character.escape -// ^^ constant.character.escape -// ^^ constant.character.escape -// ^^ constant.character.escape -// ^^ constant.character.escape -// ^^ constant.character.escape -// ^^ constant.character.escape - -let raw_bytes = br#"This won't escape anything either \x01 \""#; -// <- storage.type -// ^ keyword.operator -// ^^ storage.type -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double - constant.character.escape - -0; -// <- constant.numeric.integer.decimal -1_000u32; -// <- constant.numeric.integer.decimal - // <- constant.numeric.integer.decimal -//^^^ constant.numeric.integer.decimal -// ^^^ storage.type - constant.numeric.integer.decimal -1i64; -// <- constant.numeric.integer.decimal - // <- storage.type - constant.numeric.integer.decimal -//^^ storage.type - constant.numeric.integer.decimal - -0.2; -// <- constant.numeric.float - // <- constant.numeric.float -//^ constant.numeric.float -1_000.0_; -// <- constant.numeric.float - // <- constant.numeric.float -//^^^^^^ constant.numeric.float -1.0f32; -// <- constant.numeric.float - // <- constant.numeric.float -//^ constant.numeric.float -// ^^^ storage.type - constant.numeric.float -0.; -// <- constant.numeric.float - // <- constant.numeric.float -0f64; -// <- constant.numeric.float - // <- storage.type - constant.numeric.float -//^^ storage.type - constant.numeric.float - -0x0; -// <- constant.numeric.integer.hexadecimal - // <- constant.numeric.integer.hexadecimal -//^ constant.numeric.integer.hexadecimal -0xfa; -// <- constant.numeric.integer.hexadecimal - // <- constant.numeric.integer.hexadecimal -//^^ constant.numeric.integer.hexadecimal -0xFA_01i32; -// <- constant.numeric.integer.hexadecimal - // <- constant.numeric.integer.hexadecimal -//^^^^^ constant.numeric.integer.hexadecimal -// ^^^ storage.type - constant.numeric.integer.hexadecimal - -0b1; -// <- constant.numeric.integer.binary - // <- constant.numeric.integer.binary -//^ constant.numeric.integer.binary -0b0_1u8; -// <- constant.numeric.integer.binary - // <- constant.numeric.integer.binary -//^^^ constant.numeric.integer.binary -// ^^ storage.type - constant.numeric.integer.binary - -0o0; -// <- constant.numeric.integer.octal - // <- constant.numeric.integer.octal -//^ constant.numeric.integer.octal -0o0000_0010u64; -// <- constant.numeric.integer.octal - // <- constant.numeric.integer.octal -//^^^^^^^^^ constant.numeric.integer.octal -// ^^^ storage.type - constant.numeric.integer.octal - -extern crate foo; -// <- keyword.other -//^^^^ keyword.other -// ^ - keyword.other -// ^^^^^ keyword.other - -mod trafile; -// <- storage.type.module -mod comment; -// <- storage.type.module -mod location; - -pub use self::trafile::*; -// <- storage.modifier -// ^ keyword.other -// ^^^^^^^^^^^^^^^ meta.path -// ^^ punctuation.accessor - -use std::fmt; -// <- keyword.other -// ^^^^^ meta.path -// ^^ punctuation.accessor -// ^^^ - meta.path -use foo::i32; -// ^^^^^ meta.path -// ^^ punctuation.accessor -// ^^^ - meta.path storage.type -use foo::Bar; -// ^^^^^ meta.path -// ^^ punctuation.accessor -use foo::{Baz, QUX, quux}; -// ^^^^^ meta.path -// ^^ punctuation.accessor -// ^^^^^^^^^^^^^^^^ meta.block -// ^^^ constant.other - -String my_var = format!("Hello {0}", "World"); -// ^^^ support.type -// ^ keyword.operator.assignment -// ^^^^^^^ support.macro -// ^ punctuation.section.group.begin -// ^^^^^^^^^^^^^^^^^^^^^^ meta.group -// ^^^^^^^^^^^ string.quoted.double -// ^^^ constant.other.placeholder -// ^ punctuation.section.group.end - -my_var = format!("Hello {name}, how are you?", -// ^ keyword.operator.assignment -// ^^^^^^^ support.macro -// ^ punctuation.section.group.begin -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.group -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double -// ^^^^^^ constant.other.placeholder - name="John"); -// ^^^^^^^^^^^^^ meta.group -// ^ keyword.operator.assignment -// ^^^^^^ string.quoted.double -// ^ punctuation.section.group.end - -struct BasicStruct(i32); -// ^^^^^^^^^^^^^^^^^^^^ meta.struct -// <- storage.type.struct -//^^^^ storage.type.struct -// ^^^^^^^^^^^ entity.name.struct -// ^ punctuation.section.group.begin -// ^^^ storage.type -// ^ punctuation.section.group.end - -#[derive(Debug)] -// <- meta.annotation punctuation.definition.annotation -//^^^^^^^^^^^^^^ meta.annotation -//^^^^^^ variable.annotation -// ^^^^^^^ meta.annotation.parameters -struct PrintableStruct(Box); -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.struct -// <- storage.type.struct -//^^^^ storage.type.struct -// ^^^^^^^^^^^^^^^ entity.name.struct -// ^ punctuation.section.group.begin -// ^^^ support.type -// ^^^^^^^^ meta.generic -// ^ punctuation.definition.generic.begin -// ^^^ storage.type -// ^ punctuation.definition.generic.end -// ^ punctuation.section.group.end - -impl fmt::Display for PrintableStruct { -// <- meta.impl -//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.impl -// <- storage.type.impl -//^^ storage.type.impl -// ^^^^^ meta.path -// ^^ punctuation.accessor -// ^^^ keyword.other -// ^^^^^^^^^^^^^^^ entity.name.impl -// ^ meta.block punctuation.section.block.begin - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.impl -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function -// ^^ storage.type.function -// ^^^ entity.name.function -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.parameters -// ^ punctuation.section.parameters.begin -// ^ keyword.operator -// ^^^^ variable.parameter -// ^ variable.parameter -// ^ punctuation.separator -// ^ keyword.operator -// ^^^ storage.modifier -// ^^^^^ meta.path -// ^ punctuation.section.parameters.end -// ^^ punctuation.separator -// ^^^^^ meta.path -// ^^ punctuation.accessor -// ^ meta.block punctuation.section.block.begin - write!(f, "{}", self.0) -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function -// ^^^^^^ support.macro -// ^^^^^^^^^^^^^^^^^ meta.group -// ^ punctuation.section.group.begin -// ^^^^ string.quoted.double -// ^^ constant.other.placeholder -// ^^^^ variable.language -// ^ punctuation.accessor.dot -// ^ punctuation.section.group.end - } -// ^^ meta.function meta.block -// ^ punctuation.section.block.end -} -// <- meta.block punctuation.section.block.end - -let logical: bool = true; -// ^ punctuation.separator -// ^^^^ storage.type -// ^ keyword.operator.assignment -// ^^^^ constant.language -// ^ punctuation.terminator -let mut mutable = 12; -// ^^^ storage.modifier -// ^ punctuation.terminator - -let ch = '∞'; -// ^^^ string.quoted.single -// ^ punctuation.terminator - -let tuple = (1.0, 0i32, "Hello"); -// ^^^^^^^^^^^^^^^^^^^^ meta.group -// ^ punctuation.section.group.begin -// ^^^ constant.numeric.float -// ^ constant.numeric.integer.decimal -// ^^^ storage.type -// ^^^^^^^ string.quoted.double -// ^ punctuation.section.group.end -// ^ punctuation.terminator - -let xs: [i32; 5] = [1, 2, 3, 4, 5]; -// ^ punctuation.separator -// ^^^^^^^^ meta.group -// ^ punctuation.section.group.begin -// ^^^ storage.type -// ^ punctuation.separator -// ^ constant.numeric.integer.decimal -// ^ punctuation.section.group.end -// ^^^^^^^^^^^^^^^ meta.group -// ^ punctuation.section.group.begin -// ^ punctuation.separator -// ^ punctuation.separator -// ^ punctuation.separator -// ^ punctuation.separator -// ^ punctuation.section.group.end -// ^ punctuation.terminator - -let xsl = &xs; -// ^ keyword.operator - -type FnPointer = fn(i32) -> i32; -// ^^^^^^^^^ entity.name.type -// ^^ storage.type.function -// ^^^^^ meta.group -// ^^^ storage.type -// ^^ punctuation.separator -// ^^^ storage.type - -type GenFnPointer = Bar i32>; -// ^^^^^^^^^^^^ entity.name.type -// ^^^^^^^^^^^^^^^^^^^ meta.generic -// ^^ storage.type.function -// ^^^^^ meta.group -// ^^^ storage.type -// ^^ punctuation.separator -// ^^^ storage.type -// ^ - meta.generic - -type GenFnPointer2 = Bar; -// ^^^^^^^^^^^^^ entity.name.type -// ^^^^^^^^^^^^^^^^^^^^ meta.generic -// ^^^^^^ keyword.other -// ^^^ string.quoted.double -// ^^ storage.type.function -// ^ - meta.generic - -struct Nil; -// ^^^^^^^ meta.struct -// ^ - meta.struct -struct Pair(i32, i32); -// ^^^^^^^^^^^^^^^^^^ meta.struct -// ^^^ storage.type -// ^^^ storage.type -// ^ - meta.struct - -enum OperatingSystem -// <- storage.type.enum -// ^^^^^^^^^^^^^^^^^ meta.enum -// ^^^^^^^^^^^^^^^ entity.name.enum -{ -// <- meta.enum meta.block punctuation.section.block.begin - Osx, - Windows, - Linux, - Bsd(String), - // ^^^^^^ support.type - Info { field: i32, value: str } - // ^ meta.block meta.block punctuation.section.block.begin - // ^^^ storage.type - // ^^^ storage.type - // ^ meta.block meta.block punctuation.section.block.end -} -// <- meta.enum meta.block punctuation.section.block.end - -const ZERO: u64 = 0; -// <- storage.type -// ^^^^ constant.other -// ^ punctuation.separator -// ^^^ storage.type -// ^ keyword.operator.assignment -// ^ constant.numeric.integer.decimal -static NAME: &'static str = "John"; -// <- storage.type -// ^ keyword.operator -// ^^^^^^^ storage.modifier.lifetime -// ^^^ storage.type -// ^ keyword.operator.assignment -// ^^^^^^ string.quoted.double - - -let z = { -// ^ meta.block punctuation.section.block.begin - 2 * 5 -// ^ constant.numeric.integer.decimal -// ^ keyword.operator.arithmetic -// ^ constant.numeric.integer.decimal -}; -// <- meta.block punctuation.section.block.end - -fn my_func(x: i32) -// <- storage.type.function -// ^^^^^^^ entity.name.function -// ^^^^^^^^ meta.function.parameters -// ^ punctuation.section.parameters.begin -// ^ variable.parameter -// ^ punctuation.separator -// ^ punctuation.section.parameters.end -{ -// <- meta.function meta.block punctuation.section.block.begin - -} -// <- meta.function meta.block punctuation.section.block.end - -let n = 5; - -if n < 0 { -// ^ keyword.operator.comparison -// ^ meta.block punctuation.section.block.begin -// <- keyword.control - print!("{} is negative", n); -// ^ punctuation.terminator -} else if n > 0 { -// <- meta.block punctuation.section.block.end -// ^^^ keyword.control -// ^ meta.block punctuation.section.block.begin -// ^^ keyword.control - print!("{0} is positive", n); -} else { -// <- meta.block punctuation.section.block.end -// ^^^ keyword.control -// ^ meta.block punctuation.section.block.begin - print!("{} is zero", n); -// ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.block -} -// <- meta.block punctuation.section.block.end - -let big_n = -// ^ keyword.operator.assignment - if n < 10 && n > -10 { -// ^ meta.block punctuation.section.block.begin - 10 * n - } else { -// ^ meta.block punctuation.section.block.end -// ^ meta.block punctuation.section.block.begin - n / 2 - }; -// ^ meta.block punctuation.section.block.end - -'label_name: loop { -// ^^^^^^^^ entity.name.label -// ^ punctuation.separator -// ^^^^ keyword.control -// ^ meta.block punctuation.section.block.begin - n += 1; -// ^^ keyword.operator.assignment - if n / 2 == 5 { -// ^ keyword.operator.arithmetic -// ^^ keyword.operator.comparison - continue; -// ^^^^^^^^ keyword.control - } - if n > 9 { - break; -// ^^^^^ keyword.control - } -} - -while n < 50 { -//^^^ keyword.control - n = n * 2; -} - -for i in 1..10 { -// <- keyword.control -// ^^ keyword.operator -// ^ constant.numeric.integer.decimal -// ^^ keyword.operator.range -// ^^ constant.numeric.integer.decimal - println!("I: {}", i); -// ^^^^^^^^^^^^^^^^^^^^^^ meta.block -} -// <- meta.block punctuation.section.block.end - -let o = match n { -// ^^^^^ keyword.control - 1 => "one", -// ^ constant.numeric.integer.decimal -// ^^ keyword.operator -// ^^^^^ string.quoted.double - 2 => "two", -// ^ constant.numeric.integer.decimal -// ^^ keyword.operator -// ^^^^^ string.quoted.double - 3...5 => "a few", -// ^ constant.numeric.integer.decimal -// ^^^ keyword.operator.range -// ^ constant.numeric.integer.decimal -// ^^ keyword.operator -// ^^^^^^^ string.quoted.double - _ => "lots", -// ^ keyword.operator -// ^^ keyword.operator -}; - -let mut j = BasicStruct(10); -// ^^^ storage.modifier -// ^^ constant.numeric.integer.decimal - -if let BasicStruct(i) = j { -// ^^^ storage.type -// ^ keyword.operator.assignment -// ^ meta.block punctuation.section.block.begin - println!("Basic value: {}", i); -} -// <- meta.block punctuation.section.block.end - -while let BasicStruct(k) = j { -//^^^ keyword.control -// ^^^ storage.type -// ^ keyword.operator.assignment -// ^ meta.block punctuation.section.block.begin - println!("Constructed example: {}", j) - j = BasicStruct(j + 1); - if k > 20 { - break; - //^^^ meta.block meta.block keyword.control - } -} -// <- meta.block punctuation.section.block.end - -fn foo(i: u32, b: i64) -> u32 { -// <- storage.type.function -// ^^^ entity.name.function -// ^ punctuation.definition.generic.begin -// ^ punctuation.definition.generic.end -// ^^^^^^^^^^^^^^^^ meta.function.parameters -// ^^^ storage.type -// ^ meta.block punctuation.section.block.begin - -} -// <- meta.block punctuation.section.block.end - -// Guards -match n { -// <- keyword.control - a if n > 5 => println!("Big: {}", a), -// ^^ keyword.control -// ^ keyword.operator.comparison -// ^^ keyword.operator -// ^^^^^^^^ support.macro - b if n <= 5 => println!("Small: {}", b), -// ^^ keyword.control -// ^^ keyword.operator.comparison -// ^^ keyword.operator -// ^^^^^^^^ support.macro -// ^^ constant.other.placeholder -} - -// Binding -match my_func() { -// ^^ keyword.control -// ^^^^^^^ support.function -// ^ meta.block punctuation.section.block.begin - 0 => println!("None"), -// ^ constant.numeric.integer.decimal -// ^^ keyword.operator -// ^^^^^^^^ support.macro - res @ 1...9 => println!("Digit: {}", res), -// ^ keyword.operator -// ^^^ keyword.operator -// ^^ constant.other.placeholder - _ => println!("Full number"), -// ^ keyword.operator -// ^^ keyword.operator -} -// <- meta.block punctuation.section.block.end - -fn my_other_func(e: OperatingSystem) -> u32 { -// ^^^^^^^^^^^^^ entity.name.function -// ^ variable.parameter -// ^ punctuation.separator -} - -struct Point -// ^^^^^^^^^ meta.struct -{ -// <- meta.struct meta.block punctuation.section.block.begin - x: i32, -// ^ variable.other.member -// ^ punctuation.separator.type -// ^^^ storage.type - #[serde(default)] -// ^ punctuation.definition.annotation -// ^ punctuation.section.group.begin -// ^^^^^ variable.annotation -// ^ punctuation.section.group.end -// ^^^^^^^^^^^^^^^^^ meta.annotation - pub(crate) y: i32 -// ^^^ storage.modifier -// ^ punctuation.definition.modifier-scope.begin -// ^^^^^ storage.modifier -// ^ punctuation.definition.modifier-scope.end -// ^ variable.other.member -// ^ punctuation.separator.type -// ^^^ storage.type -} -// <- meta.block punctuation.section.block.end - -impl Point -//^^^^^^^^ meta.impl -{ -// <- meta.impl meta.block punctuation.section.block.begin - fn new(x: i32, y: i32) -> Point - // <- storage.type.function - // ^^^ entity.name.function - { - // <- meta.function meta.block - Point {x: x, y: y} - } - - fn double(&mut self) { - // ^^^^^^ entity.name.function - self.x *= 2; - // ^^^^ variable.language - // ^ punctuation.accessor.dot - // ^^ keyword.operator.assignment - self.y >>= 2; - // ^^^ keyword.operator.assignment.rust - } - - fn sum((x, y): (i32, i32)) -> i32 { -// ^^^^^^ meta.group -// ^ punctuation.section.group.begin -// ^ punctuation.separator -// ^ punctuation.section.group.end -// ^ punctuation.separator -// ^^^^^^^^^^ meta.group -// ^ punctuation.section.group.begin -// ^^^ storage.type -// ^ punctuation.separator -// ^^^ storage.type -// ^ punctuation.section.group.end -// ^^ punctuation.separator - } -} - -pub fn pub_function() -> bool -// <- storage.modifier -// ^^ storage.type.function -// ^^^^^^^^^^^^ entity.name.function -{ -// <- meta.function - return true -} - -fn factory() -> Box i32> { -// <- storage.type.function -// ^^^^^^^ entity.name.function -// ^^^^^^^^^^^^^^ meta.generic -// ^^ storage.type -// ^^ storage.type -// ^^ punctuation.separator - Box::new(|x| x + 1) -// ^^ punctuation.accessor -} - -let inferred_closure = |i, j: u32| i + 1; -// ^^^^^^^^^^^^^^^^ entity.name.function -// ^^^^^^^^^^^^^^^^^ meta.function.closure -// ^^^^^^^^^^^ meta.function.parameters -// ^ punctuation.section.parameters.begin -// ^ variable.parameter -// ^ punctuation.separator -// ^ variable.parameter -// ^ punctuation.separator -// ^^^ storage.type -// ^ punctuation.section.parameters.end -let closure = || -> i32 { | | 1 + 2 }; -// ^^^^^^^ entity.name.function -// ^^^^^^^^^^^^^^^^^^^^^^^ meta.function.closure -// ^^ meta.function.parameters -// ^ punctuation.section.parameters.begin -// ^ punctuation.section.parameters.end -// ^^^ storage.type -// ^^^^^^^^^^^^^ meta.block -// ^ meta.block punctuation.section.block.begin -// ^ constant.numeric.integer.decimal -// ^ constant.numeric.integer.decimal -// ^ meta.block punctuation.section.block.end - -let f = |(x, y): (u32, &mut u32)| { x + y }; -// ^ punctuation.section.parameters.begin -// ^ variable.parameter -// ^ punctuation.separator -// ^ variable.parameter -// ^^^^^^^^^^^^^^^ meta.group -// ^ punctuation.section.group.begin -// ^^^ storage.type -// ^ punctuation.separator -// ^ keyword.operator -// ^^^ storage.modifier -// ^^^ storage.type -// ^ punctuation.section.group.end -// ^ punctuation.section.parameters.end - - -let c = a | b; -// ^ keyword.operator.bitwise - -call_func(|c| 1 + 2 + c); -// ^^^^^^^^^^^^^ meta.function.closure -// ^^^ meta.function.parameters - -macro_rules! print_result { - ($expr:expr) => ( - println!("{:?} = {:?}", stringify!($expr), $expr) - ) -} - - -pub fn from_buf_reader(s: io::BufReader) -> Result -// ^ keyword.operator - where T: io::Read -// ^ keyword.other -{ - macro_rules! eat_numbers { - ($count:expr, $msg:expr) => {{ - // ^ meta.function meta.block meta.macro meta.block meta.block punctuation.section.block.begin - // ^ meta.function meta.block meta.macro meta.block meta.block meta.block punctuation.section.block.begin - let parse_err = concat!("Err parsing value in ", $msg); - try!{ eat_numbers(&mut lines, $count, parse_err, missing_err, too_many) } - // ^^^^ support.macro - // ^ meta.function meta.block meta.macro meta.block meta.block meta.block meta.block punctuation.section.block.begin - }} - }; - // <- meta.function meta.block - meta.macro - - let mut starts_stops = eat_numbers!(relief_count_total * 2, "starts and stops"); - - let starts = starts_stops.split_off(relief_count_total); -// ^ punctuation.accessor.dot -// ^^^^^^^^^ support.function - let stops = starts_stops; - - unimplemented!(); -} - -pub mod my_mod { -//^^^^^^^^^^^^^^ meta.module -// <- storage.modifier -// ^^^ storage.type.module -// ^^^^^^ entity.name.module -// ^ meta.block punctuation.section.block.begin -} -// <- meta.module meta.block punctuation.section.block.end - -struct Val (f64,); -struct GenVal(T,); -// ^^^^^^^^^ meta.generic -// ^^^^^^ entity.name.struct -// ^ punctuation.definition.generic.begin - entity.name.struct -// ^ punctuation.definition.generic.end - -// impl of Val -impl Val { - fn value(&self) -> &'a f64 { &self.0 } - // ^ keyword.operator - // ^^ storage.modifier.lifetime -} - -// impl of GenVal for a generic type `T` -impl <'a, T> GenVal { -// ^ punctuation.definition.generic.begin -// ^^ storage.modifier.lifetime -// ^ punctuation.definition.generic.end -// ^^^^^^ entity.name.impl -// ^^^ - entity.name.impl -// ^ punctuation.definition.generic.begin -// ^ punctuation.definition.generic.end - fn value(&self) -> &T { &self.0 } - // ^ keyword.operator - // ^ keyword.operator -} - -fn print_debug (t: &T) { -// ^^^^^^^^^^^ entity.name.function -// ^ punctuation.definition.generic.begin - entity.name.function -// ^ punctuation.separator -// ^ punctuation.definition.generic.end -// ^ variable.parameter -// ^ keyword.operator - println!("{:?}", t); -// ^^^^ constant.other.placeholder -} - -impl<'a, T: MyTrait + OtherTrait> PrintInOption for T where -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.impl -// ^^ storage.modifier.lifetime -// ^ punctuation.separator -// ^ keyword.operator -// ^^^ keyword.other -// ^ entity.name.impl -// ^^^^^ keyword.other - Option: Debug { -//^^^^^^^^^^^^^^^^^^^^ meta.impl - fn print_in_option(self) { -// ^^^^^^^^^^^^^^^ entity.name.function - println!("{:?}", Some(self)); - } -} - -pub trait Animal { -// <- storage.modifier -//^^^^^^^^^^^^^^^^ meta.trait -// ^ meta.block punctuation.section.block.begin - fn noise(quiet: bool) { - // Comment - } -} -// <- meta.trait meta.block punctuation.section.block.end - -fn collect_vec() { - let _: Vec<(usize, usize)> = (0..10).enumerate().collect::>(); -// ^^^ support.type -// ^^^^^^^^^^^^^^^^^^^ meta.generic -// ^ punctuation.section.group.begin -// ^^^^^ storage.type -// ^^^^^ storage.type -// ^ punctuation.section.group.end -// ^ keyword.operator.assignment -// ^ punctuation.section.group.begin -// ^ constant.numeric.integer.decimal -// ^^ keyword.operator.range -// ^^ constant.numeric.integer.decimal -// ^ punctuation.section.group.end -// ^ punctuation.accessor.dot -// ^^^^^^^^^ support.function -// ^^ punctuation.section.group -// ^ punctuation.accessor.dot -// ^^ punctuation.accessor -// ^^^^^^^^ meta.generic -// ^^^ support.type -// ^^^^^^ meta.generic meta.generic -// ^ keyword.operator - let _: Vec<(usize, usize)> = vec!(); -// ^^^^ support.macro - let _: Vec<(usize, usize)> = vec!{}; -// ^^^^ support.macro - let _: Vec<(usize, usize)> = vec![]; -// ^^^^ support.macro - let _: Vec = vec![]; -// ^^^^^^ meta.generic support.type -} - -macro_rules! forward_ref_binop [ -// ^ meta.macro meta.group punctuation.section.group.begin - (impl $imp:ident, $method:ident for $t:ty, $u:ty) => { -// ^^^^ variable.parameter -// ^^^^^ storage.type -// ^^^^^^^ variable.parameter -// ^^^^^ storage.type -// ^^ variable.parameter -// ^^ storage.type -// ^^ variable.parameter -// ^^ storage.type -// ^^ keyword.operator -// ^ meta.macro meta.group meta.block punctuation.section.block.begin - impl<'a, 'b> $imp<&'a $u> for &'b $t { -// ^^^^ storage.type.impl -// ^^^^^^^^ meta.generic -// ^^ storage.modifier.lifetime -// ^^ storage.modifier.lifetime -// ^^^^ variable.other -// ^^^^^^^^ meta.generic -// ^ keyword.operator -// ^^ storage.modifier.lifetime -// ^^ variable.other -// ^^^ keyword.other -// ^ keyword.operator -// ^^ storage.modifier.lifetime -// ^^ variable.other -// ^ meta.macro meta.group meta.block meta.impl meta.block punctuation.section.block.begin - type Output = <$t as $imp<$u>>::Output; -// ^^^^^^^^^^^^^^^^ meta.generic -// ^^ keyword.operator -// ^^ meta.path punctuation.accessor - - #[inline] -// ^^^^^^^^^ meta.annotation -// ^ punctuation.definition.annotation -// ^ punctuation.section.group.begin -// ^ punctuation.section.group.end - fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output { -// ^^ storage.type.function -// ^^^^^^^ variable.other -// ^^^^ variable.language -// ^ keyword.operator -// ^^ storage.modifier.lifetime -// ^^ variable.other -// ^^ punctuation.separator -// ^^^^^^^^^^^^^^^^ meta.generic -// ^^ keyword.operator -// ^^ meta.path punctuation.accessor -// ^ meta.macro meta.group meta.block meta.impl meta.block meta.block punctuation.section.block.begin - #![cfg(all(unix, target_pointer_width = "32"))] -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.annotation -// ^^^ variable.annotation -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.annotation.parameters -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call -// ^^^ variable.function -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.group -// ^ punctuation.section.group.begin -// ^ punctuation.separator -// ^ keyword.operator -// ^^^^ string.quoted -// ^ punctuation.section.group.end - $imp::$method(*self, *other) -// ^^^^ variable.other -// ^^^^^^^ variable.other -// ^ keyword.operator -// ^^^^ variable.language -// ^ keyword.operator - } - } - } -] - -macro_rules! alternate_group ( -// ^ meta.macro meta.group punctuation.section.group.begin - ($a:expr) => ( -// ^^ variable.parameter -// ^^^^ storage.type - println!("Test {}!", $a) - ) -) - -macro_rules! kleene_star { -// ^^^^^^^^^^^^^^^^^^^^^^^^ meta.macro.rust - meta.macro.rust meta.macro.rust -// ^ meta.block.rust punctuation.section.block.begin.rust - ($($arg:tt)+) => ( -// ^^^^^^^^^^^^^^^^^^ meta.macro meta.block -// ^^^^^^^^^^^^^ meta.group.macro-matcher -// ^^^^^^^^^^ meta.group.macro-matcher meta.group -// ^^ punctuation.section.group.begin -// ^ keyword.operator -// ^^^^ variable.parameter.macro.rust -// ^^ storage.type.rust -// ^ keyword.operator.rust -// ^ meta.group punctuation.section.group.end -// ^^ keyword.operator -// ^ meta.group.macro-body.rust punctuation.section.group.begin.rust - println!($($arg)); - ), - ($($arg:tt)*) => ( -// ^^^^^^^^^^^^^ meta.macro meta.block meta.group.macro-matcher -// ^^^^ variable.parameter.macro.rust -// ^^ meta.macro meta.block keyword.operator - println!($($arg)*); -// ^^^^ variable.other.rust -// ^^^^^^^^^ meta.macro.rust meta.block.rust meta.group.macro-body.rust meta.group.rust - ), - ($($arg:tt) ; +) => ( -// ^^^^^^^^^^^^^^^^ meta.macro meta.block meta.group.macro-matcher -// ^^^^ variable.parameter.macro.rust -// ^^ meta.macro meta.block keyword.operator - println!($($arg)); - ), - ($($arg:tt),*) => ( -// ^^^^^^^^^^^^^^ meta.macro meta.block meta.group.macro-matcher -// ^^^^ variable.parameter.macro.rust -// ^^ meta.macro meta.block keyword.operator - println!($($arg)*); - ), - -// incomplete blocks - ($($arg:tt),*) , -// ^ meta.macro.rust meta.block.rust punctuation.terminator.macro-matcher.rust - ($($x:tt),*) => ($x) , - println!($($arg)*); - ) -} - -pub fn next_lex(/* block */data: &mut [T] // line { -// ^^^^^^^^^^^ source.rust meta.function.rust meta.function.parameters.rust comment.block.rust -// ^^^^^^^^^ source.rust meta.function.rust meta.function.parameters.rust comment.line.double-slash.rust - /* block2 */ data2: &mut [T] // line -// ^^^^^^^^^^^^ source.rust meta.function.rust meta.function.parameters.rust comment.block.rust -// ^^^^^^^ source.rust meta.function.rust meta.function.parameters.rust comment.line.double-slash.rust - ) -> bool { - unimplemented!(); -} - -pub fn next_lex2 ( - /* block2 */ data2: &mut [T] // line -// ^^^^^^^^^^^^ source.rust meta.function.rust meta.function.parameters.rust comment.block.rust -// ^^^^^^^ source.rust meta.function.rust meta.function.parameters.rust comment.line.double-slash.rust - ) -> bool { - unimplemented!(); -} - -pub fn new() -> Fibonacci - where T: One + Zero, -// ^^^^^ keyword.other.rust - for <'a> &'a T: Add, -// ^^^ keyword.other.rust -// ^ punctuation.definition.generic.begin.rust -// ^^ storage.modifier.lifetime.rust -// ^ punctuation.definition.generic.end.rust -// ^ keyword.operator.rust -// ^^ storage.modifier.lifetime.rust -{ - unimplemented!(); -} - -pub fn new() -> Fibonacci - where for <'a> &'a T: Add, -// ^^^^^ keyword.other.rust -// ^^^ keyword.other.rust -// ^ punctuation.definition.generic.begin.rust -// ^^ storage.modifier.lifetime.rust -// ^ punctuation.definition.generic.end.rust -// ^ keyword.operator.rust -// ^^ storage.modifier.lifetime.rust -{ - unimplemented!(); -} - -impl Fibonacci - where for <'a> &'a T: Add, -// ^^^^^ keyword.other.rust -// ^^^ keyword.other.rust -// ^ punctuation.definition.generic.begin.rust -// ^^ storage.modifier.lifetime.rust -// ^ punctuation.definition.generic.end.rust -// ^ keyword.operator.rust -// ^^ storage.modifier.lifetime.rust -{ - unimplemented!(); -} - -impl Iterator for Fibonacci - where T: Clone, -// ^^^^^ keyword.other.rust - for <'a> &'a T: Add, -// ^^^ keyword.other.rust -// ^ punctuation.definition.generic.begin.rust -// ^^ storage.modifier.lifetime.rust -// ^ punctuation.definition.generic.end.rust -// ^ keyword.operator.rust -// ^^ storage.modifier.lifetime.rust -{ - unimplemented!(); -} - -pub const FOO: Option<[i32; 1]> = Some([1]); -// ^ punctuation.section.group.begin.rust -// ^ punctuation.separator -// ^ constant.numeric -// ^ punctuation.section.group.end.rust - -fn abc() { - println!("{}hello\ -// ^ punctuation.separator.continuation.line.rust - world, there is no whitespace between hello and world in the output", 0o202u64); -} - -impl ApplicationPreferenceseeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee { -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ entity.name.impl.rust -} - -#[test = "foo ] bar"] -// <- meta.annotation punctuation.definition.annotation -//^^^^^^^^^^^^^^^^^^^ meta.annotation -//^^^^ variable.annotation -// ^ keyword.operator -// ^^^^^^^^^^^ string.quoted.double -pub trait Foo { -} - -const FOO: usize = 5; -let _: Box<[[bool; (FOO + 1) / 2]; FOO * 3 % 12 - 1]>; -// ^ keyword.operator -// ^ punctuation.separator -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.generic -// ^ punctuation.definition.generic.begin -// ^^ punctuation.section.group.begin -// ^^^^ storage.type -// ^ punctuation.separator -// ^ punctuation.section.group.begin -// ^^^ variable.other.constant -// ^ keyword.operator.arithmetic -// ^ constant.numeric.integer.decimal -// ^ punctuation.section.group.end -// ^ keyword.operator.arithmetic -// ^ constant.numeric.integer.decimal -// ^ punctuation.section.group.end -// ^ punctuation.separator -// ^^^ variable.other.constant -// ^ keyword.operator.arithmetic -// ^ constant.numeric.integer.decimal -// ^ keyword.operator.arithmetic -// ^^ constant.numeric.integer.decimal -// ^ keyword.operator.arithmetic -// ^ constant.numeric.integer.decimal -// ^ punctuation.section.group.end -// ^ punctuation.definition.generic.end -// ^ punctuation.terminator - -let _: Box<[[u8; aa::COUNT - 1]; 5]>; -// ^ punctuation.definition.generic.begin -// ^ punctuation.section.group.begin -// ^ punctuation.section.group.begin -// ^^ storage.type -// ^ punctuation.separator -// ^^ variable.other.constant -// ^^ punctuation.accessor.double-colon -// ^^^^^ variable.other.constant -// ^ keyword.operator.arithmetic -// ^ constant.numeric.integer.decimal -// ^ punctuation.section.group.end -// ^ punctuation.separator -// ^ constant.numeric.integer.decimal -// ^ punctuation.section.group.end -// ^ punctuation.definition.generic.end -// ^ punctuation.terminator - -let x = 5; -let raw = &x as *const i32; -// ^^^^^^ storage.type - -let mut y = 10; -let raw_mut = &mut y as *mut i32; -// ^^^^ storage.modifier - -let i: u32 = 1; -let p_imm: *const u32 = &i as *const u32; -// ^^^^^^ storage.type -// ^^^^^^ storage.type - -type ExampleRawPointer = HashMap<*const i32, Option, BuildHasherDefault>; -// ^^^^^^ storage.modifier - invalid -// ^^^ storage.type diff --git a/Rust/tests/syntax_test_attributes.rs b/Rust/tests/syntax_test_attributes.rs new file mode 100644 index 0000000000..6215a67d01 --- /dev/null +++ b/Rust/tests/syntax_test_attributes.rs @@ -0,0 +1,142 @@ +// SYNTAX TEST "Packages/Rust/Rust.sublime-syntax" + +#![warn(unused)] +// <- meta.annotation punctuation.definition.annotation +//^^^^^^^^^^^^^^ meta.annotation +//^ punctuation.section.group.begin +// ^^^^ variable.annotation +// ^^^^^^^^ meta.annotation.parameters meta.group +// ^ punctuation.section.group.begin +// ^ punctuation.section.group.end +// ^ punctuation.section.group.end + + # [ macro_use ] +//^^^^^^^^^^^^^^^ meta.annotation +//^ punctuation.definition.annotation +// ^ punctuation.section.group.begin +// ^^^^^^^^^ variable.annotation +// ^ punctuation.section.group.end + +#[cfg(all(unix, not(target_os = "haiku")))] +// <- meta.annotation punctuation.definition.annotation +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.annotation +//^^^ variable.annotation +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.annotation.parameters meta.group +// ^ punctuation.section.group.begin +// ^^^ meta.function-call variable.function +// ^ meta.annotation.parameters meta.group meta.function-call meta.group punctuation.section.group.begin +// ^ punctuation.separator +// ^^^ meta.function-call meta.function-call variable.function +// ^ punctuation.section.group.begin +// ^ keyword.operator.assignment +// ^^^^^^^ string.quoted.double +// ^ punctuation.section.group.end +// ^ punctuation.section.group.end +// ^ punctuation.section.group.end +// ^ punctuation.section.group.end + +// Test highlighting/scope with struct field attributes +// https://github.com/rust-lang/sublime-rust/issues/120 +pub struct Claim { +// ^^^^^^^^ meta.struct + pub claim_id: String, +// ^^^ storage.modifier + pub patient_id: String, + #[serde(skip_serializing_if="Option::is_none")] +// ^^^^^^^^^^^^^^^ string.quoted.double +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.annotation + pub referring: Option, + #[serde(skip_serializing_if="Option::is_none")] +// ^^^^^ variable.annotation +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.annotation + pub drug: Option>, + #[serde(skip_serializing_if="Option::is_none")] +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.annotation + pub ndc: Option>, + #[serde(skip_serializing_if="Option::is_none")] +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.annotation + pub rendering: Option, + pub date: String, +} + +enum E { + #[allow(dead_code)] +// ^^^^^^^^^^^^^^^^^^^ meta.enum meta.annotation +// ^^^^^ variable.annotation + A(i32), +// ^^^ meta.enum meta.struct meta.group storage.type +} + +// Generic parameters. +unsafe impl<#[may_dangle] T: ?Sized> Drop for Box { } +// ^^^^^^^^^^^^^ meta.annotation +// ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.impl meta.generic + + #[test = "foo ] bar"] +//^^^^^^^^^^^^^^^^^^^^^ meta.annotation +//^ punctuation.definition.annotation +// ^ punctuation.section.group.begin +// ^^^^ variable.annotation +// ^ keyword.operator.assignment +// ^^^^^^^^^^^ string.quoted.double +// ^ punctuation.section.group.end + +// All the things. + # ! [ +//^^^^^^ meta.annotation +//^ punctuation.definition.annotation +// ^ punctuation.definition.annotation +// ^ punctuation.section.group.begin + // comment +// ^^^^^^^^^^^ comment.line.double-slash + attr_name ( +// ^^^^^^^^^ variable.annotation +// ^ meta.annotation.parameters meta.group punctuation.section.group.begin + // comment +// ^^^^^^^^^^^ comment.line.double-slash + "string", +// ^^^^^^^^ string.quoted.double +// ^ punctuation.separator + r##"raw"##, +// ^^^^^^^^^^ string.quoted.double.raw + b"bytes", +// ^ storage.type.string +// ^^^^^^^^ string.quoted.double + br"raw byte", +// ^^^^^^^^^^^^ string.quoted.double.raw + 'c', +// ^^^ string.quoted.single + b'c', +// ^^^^ string.quoted.single + 1_000, +// ^^^^^ constant.numeric.integer.decimal + 1.618, +// ^^^^^ constant.numeric.float + true, +// ^^^^ constant.language + struct, +// ^^^^^^ storage.type.struct + 1 + 1, +// ^ constant.numeric.integer.decimal +// ^ keyword.operator.arithmetic +// ^ constant.numeric.integer.decimal + ) +// ^ punctuation.section.group.end + ] +//^ punctuation.section.group.end + +// quote! uses #var syntax +#[doc=#foo] +//^^^^^^^^^ meta.annotation +// ^ keyword.operator.assignment + +// Macros often use replacement. +#[doc = $doc] +//^^^^^^^^^^^ meta.annotation +// ^ punctuation.section.group.end +// ^ keyword.operator.assignment + +#[rustfmt::skip] +//^^^^^^^^^^^^^^ meta.annotation +//^^^^^^^^^^^^^ meta.path +// ^^^^ variable.annotation diff --git a/Rust/tests/syntax_test_closures.rs b/Rust/tests/syntax_test_closures.rs new file mode 100644 index 0000000000..a8e7ee0682 --- /dev/null +++ b/Rust/tests/syntax_test_closures.rs @@ -0,0 +1,199 @@ +// SYNTAX TEST "Packages/Rust/Rust.sublime-syntax" + +let inferred_closure = |i, j: u32| i + 1; +// ^^^^^^^^^^^^^^^^ entity.name.function +// ^^^^^^^^^^^^^^^^^ meta.function.closure +// ^^^^^^^^^^^ meta.function.parameters +// ^ punctuation.section.parameters.begin +// ^ variable.parameter +// ^ punctuation.separator +// ^ variable.parameter +// ^ punctuation.separator +// ^^^ storage.type +// ^ punctuation.section.parameters.end +let closure = || -> i32 { | | 1 + 2 }; +// ^^^^^^^ entity.name.function +// ^^^^^^^^^^^^^^^^^^^^^^^ meta.function.closure +// ^^ meta.function.parameters +// ^ punctuation.section.parameters.begin +// ^ punctuation.section.parameters.end +// ^^^ storage.type +// ^^^^^^^^^^^^^ meta.block +// ^ meta.block punctuation.section.block.begin +// ^ constant.numeric.integer.decimal +// ^ constant.numeric.integer.decimal +// ^ meta.block punctuation.section.block.end + +// Make sure "or" is not confused with closure. +let c = a | b; +// ^ keyword.operator.bitwise + +call_func(|c| 1 + 2 + c); +// ^^^^^^^^^^^^^ meta.function.closure +// ^^^ meta.function.parameters + +fn lambdas() { + let c = |foo, +// ^ meta.function.closure meta.function.parameters punctuation.section.parameters.begin +// ^^^ meta.function.parameters variable.parameter + bar| {}; +// ^^^ meta.function.parameters variable.parameter +// ^ meta.function.closure meta.function.parameters punctuation.section.parameters.end + let c = |foo, // weird, but should work +// ^ meta.function.closure meta.function.parameters punctuation.section.parameters.begin +// ^^^ meta.function.parameters variable.parameter +// ^^^^^^^^^^^^^^^^^^^^^^^^^ comment.line + bar| {}; +// ^^^ meta.function.parameters variable.parameter +// ^ meta.function.closure meta.function.parameters punctuation.section.parameters.end +} + + +let x = |self, _, _foo, foo: 'static str| {}; +// ^^^^^^^^^^^^^^^^^^^^ meta.function.closure meta.function.parameters +// ^^^^ variable.parameter +// ^^^^ variable.parameter +// ^^^ variable.parameter +// ^ punctuation.separator +// ^^^^^^^ storage.modifier.lifetime +// ^^^ storage.type +let x = |&a, &mut b, ref c, mut d, ref mut e| {}; +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.closure meta.function.parameters +// ^ keyword.operator +// ^ variable.parameter +// ^ keyword.operator +// ^^^ storage.modifier +// ^ variable.parameter +// ^^^ storage.modifier +// ^ variable.parameter +// ^^^ storage.modifier +// ^ variable.parameter +// ^^^ storage.modifier +// ^^^ storage.modifier +// ^ variable.parameter +let x = |foo @ Some{}| {}; +// ^^^^^^^^^^^^^^ meta.function.closure meta.function.parameters +// ^^^ variable.parameter +// ^ keyword.operator +// ^ meta.block punctuation.section.block.begin +// ^ meta.block punctuation.section.block.end +let x = |path :: to :: Struct{a, b, ..}, +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.closure meta.function.parameters +// ^^^^^^^^^^ meta.block +// ^ punctuation.section.block.begin +// ^ variable.parameter +// ^ variable.parameter +// ^^ keyword.operator +// ^ punctuation.section.block.end + self::Struct{c}, super::Struct{d}| {}; +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.closure meta.function.parameters +// ^^^^ keyword.other +// ^^^ meta.block +// ^ variable.parameter +// ^^^^^ keyword.other +// ^^^ meta.block +// ^ variable.parameter +let x = |Struct{ref mut a}| {}; +// ^^^^^^^^^^^^^^^^^^^ meta.function.closure meta.function.parameters +// ^^^^^^^^^^^ meta.block +// ^^^ storage.modifier +// ^^^ storage.modifier +// ^ variable.parameter +let x = |Struct{0: (x, y), 1: z}| {}; +// ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.closure meta.function.parameters +// ^^^^^^^^^^^^^^^^^ meta.block +// ^ constant.numeric.integer.decimal +// ^ punctuation.separator +// ^^^^^^ meta.group +// ^ punctuation.section.group.begin +// ^ variable.parameter +// ^ variable.parameter +// ^ punctuation.section.group.end +// ^ constant.numeric.integer.decimal +// ^ punctuation.separator +// ^ variable.parameter +let x = |Struct{field: (x, y), field2: z}| {}; +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.closure meta.function.parameters +// ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.block +// ^^^^^^ meta.group +// ^ variable.parameter +// ^ variable.parameter +// ^ variable.parameter +let x = |path::to::TupleStruct(x, (y, z), ..)| {}; +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.closure meta.function.parameters +// ^^^^^^^^^^^^^^^ meta.group +// ^ variable.parameter +// ^^^^^^ meta.group meta.group +// ^ variable.parameter +// ^ variable.parameter +// ^^ keyword.operator +let x = |(x, (y, z)), (Foo{&mut i, ..}, foo @ Some{})| {}; +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.closure meta.function.parameters +// ^^^^^^^^^^^ meta.group +// ^ variable.parameter +// ^^^^^^ meta.group meta.group +// ^ variable.parameter +// ^ meta.group variable.parameter +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.group +// ^^^^^^^^^^^^ meta.block +// ^ keyword.operator +// ^^^ storage.modifier +// ^ variable.parameter +// ^^ keyword.operator +// ^^^ variable.parameter +// ^ keyword.operator +let x = |[ref mut a, (x, y)]| {}; +// ^^^^^^^^^^^^^^^^^^^^^ meta.function.closure meta.function.parameters +// ^^^^^^^^^^^^^^^^^^^ meta.brackets +// ^ punctuation.section.brackets.begin +// ^^^ storage.modifier +// ^^^ storage.modifier +// ^ variable.parameter +// ^^^^^^ meta.group +// ^ variable.parameter +// ^ variable.parameter +let x = |a: i32, b: Foo, c: Option, d: extern "C" fn (), e: *const u8| {}; +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.closure meta.function.parameters +// ^ variable.parameter +// ^^^ storage.type +// ^ variable.parameter +// ^ variable.parameter +// ^^^^^^ meta.generic support.type +// ^^^ meta.generic storage.type +// ^ variable.parameter +// ^^^^^^ keyword.other +// ^^^ string.quoted.double +// ^^ storage.type.function +// ^^ meta.group +// ^ variable.parameter +// ^^^^^^ storage.modifier +// ^^ storage.type +let x = |/*comment*/(/*c*/a, [b/*c*/], S{/*c*/f: c})| {}; +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.closure meta.function.parameters +// ^^^^^^^^^^^ comment.block +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.group +// ^^^^^ comment.block +// ^ variable.parameter +// ^^^^^^^^ meta.brackets +// ^ variable.parameter +// ^^^^^ comment.block +// ^^^^^^^^^^^ meta.block +// ^^^^^ comment.block +// ^ variable.parameter + + let f = |(x, y): (u32, &mut u32)| { x + y }; + // ^ punctuation.section.parameters.begin + // ^^^^^^ meta.group + // ^ variable.parameter + // ^ punctuation.separator + // ^ variable.parameter + // ^ punctuation.section.group.end + // ^ punctuation.separator + // ^ punctuation.section.group.begin + // ^^^ storage.type + // ^ punctuation.separator + // ^ keyword.operator + // ^^^ storage.modifier + // ^^^ storage.type + // ^ punctuation.section.group.end + // ^ punctuation.section.parameters.end diff --git a/Rust/tests/syntax_test_comments.rs b/Rust/tests/syntax_test_comments.rs new file mode 100644 index 0000000000..fa41111656 --- /dev/null +++ b/Rust/tests/syntax_test_comments.rs @@ -0,0 +1,37 @@ +// SYNTAX TEST "Packages/Rust/Rust.sublime-syntax" + +// Line comments +// <- comment.line.double-slash punctuation.definition.comment +// ^^^^^^^^^^^^^^ comment.line.double-slash + +// <- -comment + +/// Line doc comments +// <- comment.line.documentation +// ^^^^^^^^^^^^^ comment.line.documentation + +/*! +// <- comment.block.documentation punctuation.definition.comment + // <- comment.block.documentation +//^ comment.block.documentation +Block doc comments +// ^^^^^^^^^^^^^^^^ comment.block.documentation +/* Nested comments */ +// ^^^^^^^^^^^^^^^^^^ comment.block.documentation comment.block +*/ + +/** + * +// ^ comment.block.documentation punctuation.definition.comment +*/ + +// Verify comment is cleared. +mod a {} +// ^^^^^ -comment + +fn foo i32>(f: F) { +// ^^^^^^^ meta.generic comment + let lam = |time: i32 /* comment */, other: i32| { +// ^^^^^^^^^^^^^ meta.function.parameters comment + }; +} diff --git a/Rust/tests/syntax_test_control_flow.rs b/Rust/tests/syntax_test_control_flow.rs new file mode 100644 index 0000000000..393ea5921a --- /dev/null +++ b/Rust/tests/syntax_test_control_flow.rs @@ -0,0 +1,98 @@ +// SYNTAX TEST "Packages/Rust/Rust.sublime-syntax" + +while n < 50 { +//^^^ keyword.control + n = n * 2; +} + +for i in 1..10 { +// <- keyword.control +// ^^ keyword.operator +// ^ constant.numeric.integer.decimal +// ^^ keyword.operator.range +// ^^ constant.numeric.integer.decimal + println!("I: {}", i); +// ^^^^^^^^^^^^^^^^^^^^^^ meta.block +} +// <- meta.block punctuation.section.block.end + +'label_name: loop { +// ^^^^^^^^ entity.name.label +// ^ punctuation.separator +// ^^^^ keyword.control +// ^ meta.block punctuation.section.block.begin + n += 1; + if n / 2 == 5 { +// ^ keyword.operator.arithmetic + continue; +// ^^^^^^^^ keyword.control + } + if n > 9 { + break; +// ^^^^^ keyword.control + } +} + +'label1: for _ in 0..100 { + 'label2 : loop { +// ^^^^^^^ entity.name.label +// ^ punctuation.separator + 'label3: while true { +// ^^^^^^^ entity.name.label +// ^ punctuation.separator + break 'label2; +// ^^^^^^^ entity.name.label +// ^ punctuation.terminator + } + continue 'label1; +// ^^^^^^^ entity.name.label +// ^ punctuation.terminator + } +} + +if n < 0 { +// ^ meta.block punctuation.section.block.begin +// <- keyword.control + print!("{} is negative", n); +// ^ punctuation.terminator +} else if n > 0 { +// <- meta.block punctuation.section.block.end +// ^^^ keyword.control +// ^ meta.block punctuation.section.block.begin +// ^^ keyword.control + print!("{0} is positive", n); +} else { +// <- meta.block punctuation.section.block.end +// ^^^ keyword.control +// ^ meta.block punctuation.section.block.begin + print!("{} is zero", n); +// ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.block +} +// <- meta.block punctuation.section.block.end + +if let BasicStruct(i) = j { +// ^^^ storage.type +// ^ keyword.operator.assignment +// ^ meta.block punctuation.section.block.begin + println!("Basic value: {}", i); +} +// <- meta.block punctuation.section.block.end + +while let BasicStruct(k) = j { +//^^^ keyword.control +// ^^^ storage.type +// ^ keyword.operator.assignment +// ^ meta.block punctuation.section.block.begin + println!("Constructed example: {}", j) + j = BasicStruct(j + 1); + if k > 20 { + break; + //^^^ meta.block meta.block keyword.control + } +} +// <- meta.block punctuation.section.block.end + +continue_running(); +//^^^^^^^^^^^^^^ variable.function +break_things(); +//^^^^^^^^^^ variable.function diff --git a/Rust/tests/syntax_test_dyn.rs b/Rust/tests/syntax_test_dyn.rs new file mode 100644 index 0000000000..b1a7147c51 --- /dev/null +++ b/Rust/tests/syntax_test_dyn.rs @@ -0,0 +1,45 @@ +// SYNTAX TEST "Packages/Rust/Rust.sublime-syntax" + +// dyn trait +fn f(x: dyn T, y: Box, z: &dyn T, +// ^^^ meta.function.parameters storage.type.trait +// ^^^ meta.function.parameters meta.generic storage.type.trait +// ^^^ meta.function.parameters storage.type.trait + f: &dyn Fn(CrateNum) -> bool) -> dyn T { +// ^^^ meta.function.parameters storage.type.trait +// ^^^ meta.function.return-type storage.type.trait + let x: &(dyn 'static + Display) = &BYTE; +// ^^^ meta.group storage.type.trait + let y: Box = Box::new(BYTE); +// ^^^ meta.generic storage.type.trait + let _: &dyn (Display) = &BYTE; +// ^^^ storage.type.trait + let _: &dyn (::std::fmt::Display) = &BYTE; +// ^^^ storage.type.trait + const DT: &'static dyn C = &V; +// ^^^ storage.type.trait + struct S { + f: dyn T +// ^^^ meta.struct storage.type.trait + } + type D4 = dyn (::module::Trait); +// ^^^ storage.type.trait +} + +// dyn is not a keyword in all situations (a "weak" keyword). +type A0 = dyn; +// ^^^ -storage.type.trait +type A1 = dyn::dyn; +// ^^^^^ meta.path -storage.type.trait +// ^^^ -storage.type.trait +type A2 = dyn; +// ^^^ meta.generic -storage.type.trait +// ^^^ meta.generic -storage.type.trait +// ^^^ meta.generic -storage.type.trait +// This is incorrect. `identifier` should not match on the keyword `as`. +// However, avoiding keywords is a little complicated and slow. +type A3 = dyn<::dyn>; +// ^^^ meta.generic -storage.type.trait +// ^^^ meta.generic storage.type.trait +// ^^^ meta.generic -storage.type.trait +// ^^^ meta.generic -storage.type.trait diff --git a/Rust/tests/syntax_test_enum.rs b/Rust/tests/syntax_test_enum.rs new file mode 100644 index 0000000000..257c7b83d1 --- /dev/null +++ b/Rust/tests/syntax_test_enum.rs @@ -0,0 +1,68 @@ +// SYNTAX TEST "Packages/Rust/Rust.sublime-syntax" + +enum OperatingSystem +// <- storage.type.enum +// ^^^^^^^^^^^^^^^^^ meta.enum +// ^^^^^^^^^^^^^^^ entity.name.enum +{ +// <- meta.block meta.enum punctuation.section.block.begin + Osx, +// ^^^ meta.enum storage.type.source + Windows, + Linux, + Bsd(String), + // ^^^^^^ support.type + Info { field: i32, value: str } + // ^ punctuation.section.block.begin + // ^^^ storage.type + // ^^^ storage.type + // ^ meta.block punctuation.section.block.end +} +// <- meta.block meta.enum punctuation.section.block.end + +let q = Message::Quit; +// ^^^^^^^ storage.type.source +// ^^ meta.path +// ^^^^ storage.type.source +// ^ punctuation.terminator +let w = Message::WriteString("Some string".to_string()); +// ^^^^^^^^^^^ storage.type.source +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.group +// ^^^^^^^^^^^^^ string.quoted.double +// ^^^^^^^^^ variable.function +let m = Message::Move { x: 50, y: 200 }; +// ^^^^^^^^^^^^^^^^^ meta.block +// ^^ constant.numeric.integer.decimal +// ^^^ constant.numeric.integer.decimal + +enum Discriminant { + A = 1, +// ^ meta.enum constant.other +// ^ meta.enum constant.numeric.integer.decimal + V1 = 0xABC, +// ^^ meta.enum constant.other +// ^^^^^ meta.enum constant.numeric.integer.hexadecimal + V2, +// ^^ meta.enum constant.other + SomeValue = 123, +// ^^^^^^^^^ meta.enum storage.type.source +// ^^^ meta.enum constant.numeric.integer.decimal + V3 = (1<<4), +// ^^ meta.enum constant.other +// ^^^^^^ meta.enum meta.group +// ^ constant.numeric.integer.decimal +// ^^ keyword.operator.bitwise +// ^ constant.numeric.integer.decimal + lowercase, +// ^^^^^^^^^^^ meta.enum +} + +// Enum type parameters. +enum E<'asdf> {} +// ^^^^^^^ meta.enum meta.generic +// ^^^^^storage.modifier.lifetime +enum C where T: Copy {} +// ^^^ meta.enum meta.generic +// ^^^^^^^^^^^^^ meta.enum meta.where +// ^^^^^ keyword.other +// ^^^^ support.type diff --git a/Rust/tests/syntax_test_expr.rs b/Rust/tests/syntax_test_expr.rs new file mode 100644 index 0000000000..342f1785b6 --- /dev/null +++ b/Rust/tests/syntax_test_expr.rs @@ -0,0 +1,169 @@ +// SYNTAX TEST "Packages/Rust/Rust.sublime-syntax" +// This file is for various expressions that don't fit into other more +// specific categories. + +let big_n = +// ^ keyword.operator.assignment + if n < 10 && n > -10 { +// ^ keyword.operator.comparison +// ^^ keyword.operator.logical +// ^ keyword.operator.comparison +// ^ keyword.operator.arithmetic +// ^^ constant.numeric.integer.decimal +// ^ meta.block punctuation.section.block.begin + 10 * n +// ^ meta.block keyword.operator.arithmetic + } else { +// ^ meta.block punctuation.section.block.end +// ^ meta.block punctuation.section.block.begin + n / 2 +// ^ meta.block keyword.operator.arithmetic + }; +// ^ meta.block punctuation.section.block.end + +let tuple = (1.0, 0i32, "Hello"); +// ^^^^^^^^^^^^^^^^^^^^ meta.group +// ^ punctuation.section.group.begin +// ^^^ constant.numeric.float +// ^ constant.numeric.integer.decimal +// ^^^ storage.type +// ^^^^^^^ string.quoted.double +// ^ punctuation.section.group.end + +// Tuple access. +let x = tuple.1; +// ^ constant.numeric.integer.decimal + +// Array access. +let x = arr[1]; +// ^^^ meta.group +// ^ punctuation.section.group.begin +// ^ constant.numeric.integer.decimal +// ^ punctuation.section.group.end + +// Array expression. +let x = [1; 2]; +// ^^^^^^ meta.group +// ^ punctuation.section.group.begin +// ^ punctuation.separator +// ^ constant.numeric.integer.decimal +// ^ punctuation.terminator +let x = [1; SOME_CONST]; +// ^^^^^^^^^^ constant.other +let _: Box<[[bool; (FOO + 1) / 2]; FOO * 3 % 12 - 1]>; +// ^ punctuation.separator +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.generic +// ^ punctuation.definition.generic.begin +// ^^ punctuation.section.group.begin +// ^^^^ storage.type +// ^ punctuation.separator +// ^ meta.group punctuation.section.group.begin +// ^^^ variable.other.constant +// ^ keyword.operator.arithmetic +// ^ constant.numeric.integer.decimal +// ^ punctuation.section.group.end +// ^ keyword.operator.arithmetic +// ^ constant.numeric.integer.decimal +// ^ punctuation.section.group.end +// ^ punctuation.separator +// ^^^ variable.other.constant +// ^ keyword.operator.arithmetic +// ^ constant.numeric.integer.decimal +// ^ keyword.operator.arithmetic +// ^^ constant.numeric.integer.decimal +// ^ keyword.operator.arithmetic +// ^ constant.numeric.integer.decimal +// ^ punctuation.section.group.end +// ^ punctuation.definition.generic.end +// ^ punctuation.terminator +let _: Box<[[u8; aa::COUNT - 1]; 5]>; +// ^ punctuation.definition.generic.begin +// ^ punctuation.section.group.begin +// ^ punctuation.section.group.begin +// ^^ storage.type +// ^ punctuation.separator +// ^^ variable.other.constant +// ^^ punctuation.accessor.double-colon +// ^^^^^ variable.other.constant +// ^ keyword.operator.arithmetic +// ^ constant.numeric.integer.decimal +// ^ punctuation.section.group.end +// ^ punctuation.separator +// ^ constant.numeric.integer.decimal +// ^ punctuation.section.group.end +// ^ punctuation.definition.generic.end +// ^ punctuation.terminator + +// Borrow expression. +let xsl = &xs; +// ^ keyword.operator +let a = && 10; +// ^^ keyword.operator.logical +let a = & & 10; +// ^ keyword.operator.bitwise +// ^ keyword.operator.bitwise +let y = &mut 9; +// ^ keyword.operator +// ^^^ storage.modifier + +// Dereference. +assert_eq!(*x, 7); +// ^ meta.group keyword.operator.arithmetic + *y = 11; +// ^ keyword.operator.arithmetic + +// Block expression. +let z = { +// ^ meta.block punctuation.section.block.begin + 2 * 5 +// ^ constant.numeric.integer.decimal +// ^ keyword.operator.arithmetic +// ^ constant.numeric.integer.decimal +}; +// <- meta.block punctuation.section.block.end + +// Various operators. +let x = !6; +// ^ keyword.operator.logical +// ^ constant.numeric.integer.decimal +let a = 1 + 2 - 3 * 4 / 6 % 7 & 8 | 9 ^ a << b >> c; +// ^ keyword.operator.arithmetic +// ^ keyword.operator.arithmetic +// ^ keyword.operator.arithmetic +// ^ keyword.operator.arithmetic +// ^ keyword.operator.arithmetic +// ^ keyword.operator.bitwise +// ^ keyword.operator.bitwise +// ^ keyword.operator.bitwise +// ^^ keyword.operator.bitwise +// ^^ keyword.operator.bitwise + a == b != c > d < e >= f <= g +// ^^ keyword.operator.comparison +// ^^ keyword.operator.comparison +// ^ keyword.operator.comparison +// ^ keyword.operator.comparison +// ^^ keyword.operator.comparison +// ^^ keyword.operator.comparison + a || b && c +// ^^ keyword.operator.logical +// ^^ keyword.operator.logical +a += b; +//^^ keyword.operator.assignment +a -= b; +//^^ keyword.operator.assignment +a *= b; +//^^ keyword.operator.assignment +a /= b; +//^^ keyword.operator.assignment +a %= b; +//^^ keyword.operator.assignment +a &= b; +//^^ keyword.operator.assignment +a |= b; +//^^ keyword.operator.assignment +a ^= b; +//^^ keyword.operator.assignment +a <<= b; +//^^^ keyword.operator.assignment +a >>= b; +//^^^ keyword.operator.assignment diff --git a/Rust/tests/syntax_test_functions.rs b/Rust/tests/syntax_test_functions.rs new file mode 100644 index 0000000000..3674699d37 --- /dev/null +++ b/Rust/tests/syntax_test_functions.rs @@ -0,0 +1,146 @@ +// SYNTAX TEST "Packages/Rust/Rust.sublime-syntax" + +fn my_func(x: i32) +// <- storage.type.function +// ^^^^^^^ entity.name.function +// ^^^^^^^^ meta.function.parameters +// ^ punctuation.section.parameters.begin +// ^ variable.parameter +// ^ punctuation.separator +// ^ punctuation.section.parameters.end +{ +// <- meta.function meta.block punctuation.section.block.begin + +} +// <- meta.function meta.block punctuation.section.block.end + +fn foo(i: u32, b: i64) -> u32 { +// <- storage.type.function +// ^^^ entity.name.function +// ^ punctuation.definition.generic.begin +// ^ punctuation.definition.generic.end +// ^^^^^^^^^^^^^^^^ meta.function.parameters +// ^^^ storage.type +// ^ meta.block punctuation.section.block.begin + +} +// <- meta.block punctuation.section.block.end + + +fn my_other_func(e: OperatingSystem) -> &'a f64 { +// ^^^^^^^^^^^^^ entity.name.function +// ^ variable.parameter +// ^ punctuation.separator +// ^ meta.function meta.function.return-type keyword.operator +// ^^ meta.function meta.function.return-type storage.modifier.lifetime +// ^^^ meta.function meta.function.return-type storage.type +} + + +pub fn pub_function() -> bool +// <- storage.modifier +// ^^ storage.type.function +// ^^^^^^^^^^^^ entity.name.function +{ +// <- meta.function + return true +// ^^^^^^ meta.function meta.block keyword.control +} + +pub unsafe extern "C" fn __sync_synchronize() { } +// <- storage.modifier +// ^^^^^^ storage.modifier +// ^^^^^^ keyword.other +// ^^^ string.quoted.double +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function +// ^^ storage.type.function +// ^^^^^^^^^^^^^^^^^^ entity.name.function +// ^ meta.function.parameters punctuation.section.parameters.begin +// ^ meta.function.parameters punctuation.section.parameters.end + +let f: extern "C" fn () = mem::transmute(0xffff0fa0u32); +// ^^^^^^ keyword.other +// ^^^ string.quoted.double +// ^^ storage.type.function +// ^^ meta.group +// ^ keyword.operator.assignment +// ^^^^^^^^^^ meta.group constant.numeric.integer.hexadecimal +// ^^^ meta.group storage.type.numeric + +// Raw pointer in a parameter. +fn f(a: *const u8, b: *mut i8) {} +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function +// ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.parameters +// ^^^^^ storage.modifier +// ^^^ storage.modifier + +// Test irrefutable patterns in params. Most of these tests are in `syntax_test_closure.rs`. +fn f(self, +// ^^^^^^^ meta.function meta.function.parameters +// ^^^^ variable.parameter + (a, b): Tuple, +// ^^^^^^ meta.group +// ^ punctuation.section.group.begin +// ^ variable.parameter +// ^ variable.parameter +// ^ punctuation.section.group.end +// ^ punctuation.separator + Struct{field: c}: Struct, +// ^^^^^^^^^^ meta.block +// ^ punctuation.section.block.begin +// ^ variable.parameter +// ^ punctuation.section.block.end +// ^ punctuation.separator + TupleStruct{0: d}: TupleStruct, +// ^^^^^^ meta.block +// ^ punctuation.section.block.begin +// ^ constant.numeric.integer.decimal +// ^ variable.parameter +// ^ punctuation.section.block.end +// ^ punctuation.separator + [e, f]: Slice) +// ^^^^^^ meta.brackets +// ^ punctuation.section.brackets.begin +// ^ variable.parameter +// ^ variable.parameter +// ^ punctuation.section.brackets.end +// ^ punctuation.separator +{} + +const fn f() {} +// <- storage.modifier +// ^^ meta.function storage.type.function +// ^ meta.function entity.name.function + +const unsafe fn f() {} +// <- storage.modifier +// ^^^^^^ storage.modifier +// ^^ meta.function storage.type.function +// ^ meta.function entity.name.function + +const extern "C" fn f() {} +// <- storage.modifier +// ^^^^^^ keyword.other +// ^^^ string.quoted.double +// ^^ meta.function storage.type.function +// ^ meta.function entity.name.function + +fn foo(&'a self) {} +// ^^^^^^^^ meta.function meta.function.parameters +// ^ keyword.operator +// ^^ storage.modifier.lifetime +// ^^^^ variable.parameter + +fn sum((x, y): (i32, i32)) -> i32 { +// ^^^^^^ meta.group +// ^ punctuation.section.group.begin +// ^ variable.parameter +// ^ punctuation.separator +// ^ variable.parameter +// ^ punctuation.section.group.end +// ^ punctuation.separator +// ^ punctuation.section.group.begin +// ^^^ storage.type +// ^ punctuation.separator +// ^^^ storage.type +// ^ punctuation.section.group.end diff --git a/Rust/tests/syntax_test_generics.rs b/Rust/tests/syntax_test_generics.rs new file mode 100644 index 0000000000..5431c1f040 --- /dev/null +++ b/Rust/tests/syntax_test_generics.rs @@ -0,0 +1,446 @@ +// SYNTAX TEST "Packages/Rust/Rust.sublime-syntax" + +struct GenVal(T,); +// ^^^^^^^^^ meta.generic +// ^^^^^^ entity.name.struct +// ^ punctuation.definition.generic.begin - entity.name.struct +// ^ punctuation.definition.generic.end + +// Ensure that `mut` is a storage modifier. +impl Thing for &'a mut A {} +// ^^^ meta.impl keyword.other +// ^ meta.impl keyword.operator +// ^^ meta.impl storage.modifier.lifetime +// ^^^ meta.impl storage.modifier +// ^ meta.impl entity.name.impl + +// Various tests on `where`. +fn f<'b: 'a>(self) -> &'b mut [i32] where 'a: 'b { } +// ^^^^^^^^^^^^^^ meta.function meta.function.return-type +// ^ meta.function meta.function.return-type punctuation.section.group.begin +// ^^^ meta.function meta.function.return-type storage.type +// ^ meta.function meta.function.return-type punctuation.section.group.end +// ^^^^^ meta.function meta.where keyword.other +// ^^ meta.function meta.where storage.modifier.lifetime +// ^ meta.function meta.where punctuation.separator +// ^^ meta.function meta.where storage.modifier.lifetime +// ^ meta.function meta.block punctuation.section.block.begin +// ^ meta.function meta.block punctuation.section.block.end + +fn f(func: F) -> usize +// ^^ meta.function meta.function.return-type punctuation.separator +// ^^^^^ meta.function meta.function.return-type storage.type + where F: Fn(usize) -> usize {} +// ^^^^^ meta.function meta.where keyword.other +// ^^^^^^^^^^^^^^^^^^^^^ meta.function meta.where +// ^ punctuation.separator +// ^^ support.type +// ^ punctuation.section.group.begin +// ^^^^^ storage.type +// ^ punctuation.section.group.end +// ^^ meta.function.return-type punctuation.separator +// ^^^^^ meta.function.return-type storage.type +// ^ meta.function meta.block punctuation.section.block.begin +// ^ meta.function meta.block punctuation.section.block.end + +fn f(lhs: L, rhs: R) + where L: IntoIterator, +// ^^^^^ meta.function meta.where keyword.other +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function meta.where +// ^^^^^^^^^^^^ support.type +// ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.generic +// ^ punctuation.definition.generic.begin +// ^ punctuation.section.group.begin +// ^ keyword.operator +// ^^ storage.modifier.lifetime +// ^^^ storage.type +// ^ keyword.operator +// ^^ storage.modifier.lifetime +// ^^^ storage.type +// ^ punctuation.section.group.end +// ^ punctuation.definition.generic.end + R: IntoIterator, {} +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function meta.where +// ^ meta.function meta.block punctuation.section.block.begin +// ^ meta.function meta.block punctuation.section.block.end +fn f usize>(func: f) {} +// ^^^^^^^^^^^^^^^^^^^^^^^ meta.generic +// ^ meta.generic punctuation.definition.generic.begin +// ^ meta.generic punctuation.separator +// ^^ meta.generic support.type +// ^ meta.generic punctuation.section.group.begin +// ^^^^^ meta.generic storage.type +// ^ meta.generic punctuation.section.group.end +// ^^^^^ meta.generic meta.function.return-type storage.type +// ^ meta.generic punctuation.definition.generic.end +// ^ meta.function meta.function.parameters punctuation.section.parameters.begin +// ^^^^ meta.function meta.function.parameters variable.parameter +fn f>(lhs: L) {} +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.generic +// ^ punctuation.definition.generic.begin +// ^ punctuation.definition.generic.begin +// ^ keyword.operator +// ^^^^^^^^^^^^^^^^^^ meta.group +// ^ punctuation.section.group.begin +// ^^ storage.modifier.lifetime +// ^^^ storage.type +// ^ punctuation.separator +// ^ punctuation.section.group.end +// ^ punctuation.definition.generic.end +// ^ punctuation.definition.generic.end +// ^ meta.function meta.function.parameters punctuation.section.parameters.begin + +struct A(T) where T: AsRef; +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.struct +// ^^^ meta.struct meta.where storage.type +// ^ punctuation.terminator +// ^^^^^ meta.struct meta.where keyword.other +pub struct A(T) +// ^^^^^^^^^^ meta.struct +// ^^^^^^ meta.struct storage.type +where +//^^^ meta.struct meta.where keyword.other + T: AsRef; +//^^^^^^^^^^^^^^^ meta.struct +// ^^^ meta.struct meta.where storage.type +// ^ punctuation.terminator + +pub struct IterHolder where A: Number { +// ^^^ meta.struct meta.generic +// ^^^^^ meta.struct meta.where keyword.other +// ^^^^^^ meta.struct meta.where +// ^ meta.struct punctuation.section.block.begin + num: A +} + +pub struct IterHolder +// ^^^ meta.struct meta.generic +where +// <- meta.struct meta.where keyword.other + A: Number { +// ^^^^^^ meta.struct meta.where + num: A +} + +pub fn new() -> Fibonacci + where T: One + Zero, +// ^^^^^ keyword.other + for <'a> &'a T: Add, +// ^^^ keyword.other +// ^ punctuation.definition.generic.begin +// ^^ storage.modifier.lifetime +// ^ punctuation.definition.generic.end +// ^ keyword.operator +// ^^ storage.modifier.lifetime +{ + unimplemented!(); +} + +pub fn new() -> Fibonacci + where for <'a> &'a T: Add, +// ^^^^^ meta.where keyword.other +// ^^^ keyword.other +// ^ punctuation.definition.generic.begin +// ^^ storage.modifier.lifetime +// ^ punctuation.definition.generic.end +// ^ keyword.operator +// ^^ storage.modifier.lifetime +{ + unimplemented!(); +} + +impl Fibonacci + where for <'a> &'a T: Add, +// ^^^^^ keyword.other +// ^^^ keyword.other +// ^ punctuation.definition.generic.begin +// ^^ storage.modifier.lifetime +// ^ punctuation.definition.generic.end +// ^ keyword.operator +// ^^ storage.modifier.lifetime +{ + unimplemented!(); +} + +impl Iterator for Fibonacci + where T: Clone, +// ^^^^^ keyword.other + for <'a> &'a T: Add, +// ^^^ keyword.other +// ^ punctuation.definition.generic.begin +// ^^ storage.modifier.lifetime +// ^ punctuation.definition.generic.end +// ^ keyword.operator +// ^^ storage.modifier.lifetime +{ + unimplemented!(); +} + +pub const FOO: Option<[i32; 1]> = Some([1]); +// ^ punctuation.section.group.begin +// ^ punctuation.section.group.end + +#[derive(Clone)] +pub struct GobletMiddleware { +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.generic +// ^^^^^^^ storage.modifier.lifetime + pub derp: Arc>, +} + +impl GobletMiddleware { +// <- meta.impl +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.impl +// ^^^^^^^ storage.modifier.lifetime +// ^^^^^^^^^^^^^^^^^^^ meta.generic + pub fn new(api: Arc>) -> GobletMiddleware { + GobletMiddleware { derp: api } + } +} + +impl Key for GobletMiddleware { +// <- meta.impl +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.impl +// ^^^^^^^ storage.modifier.lifetime +// ^^^ keyword.other +// ^^^^^^^^^^^^^^^^ entity.name.impl +// ^^^ meta.generic + type Value = Arc>; +} + +impl From> for CliError { } +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.impl +// ^^^^^^^^ entity.name.impl +// ^^^ meta.generic + +fn legal_dates_iter() -> Box>> { +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.return-type meta.generic +// ^ keyword.operator + unimplemented!() +} + +fn numbers() -> impl Iterator { +// ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.return-type +// ^^^^ meta.function.return-type storage.type.impl +// ^^^^^^^^ meta.function.return-type support.type +// ^^^^^^^^^^^^ meta.function.return-type meta.generic + Generator(move || for a in (0..10) { yield a; } }) +// ^^^^^ keyword.control +} + +fn collect_vec() { + let _: Vec<(usize, usize)> = (0..10).enumerate().collect::>(); +// ^^^^^^^^^^^^^^^^^^^ meta.generic +// ^^^ support.type +// ^ punctuation.section.group.begin +// ^^^^^ storage.type +// ^^^^^ storage.type +// ^ punctuation.section.group.end +// ^ keyword.operator +// ^ punctuation.section.group.begin +// ^ constant.numeric.integer.decimal +// ^^ keyword.operator +// ^^ constant.numeric.integer.decimal +// ^ punctuation.section.group.end +// ^ punctuation.accessor.dot +// ^^^^^^^^^ variable.function +// ^^ punctuation.section.group +// ^ punctuation.accessor.dot +// ^^ punctuation.accessor +// ^^^ support.type +// ^^^^^^^^ meta.generic +// ^^^^^^ meta.generic meta.generic +// ^ keyword.operator + let _: Vec<(usize, usize)> = vec!(); +// ^^^^ support.macro + let _: Vec<(usize, usize)> = vec!{}; +// ^^^^ support.macro + let _: Vec<(usize, usize)> = vec![]; +// ^^^^ support.macro + let _: Vec = vec![]; +// ^^^^^^ meta.generic support.type +} + + +pub fn next_lex(/* block */data: &mut [T] // line { +// ^^^^^^^^^^^ source meta.function meta.function.parameters comment.block +// ^^^^^^^^^ source meta.function meta.function.parameters comment.line.double-slash + /* block2 */ data2: &mut [T] // line +// ^^^^^^^^^^^^ source meta.function meta.function.parameters comment.block +// ^^^^^^^ source meta.function meta.function.parameters comment.line.double-slash + ) -> bool { + unimplemented!(); +} + +pub fn next_lex2 ( + /* block2 */ data2: &mut [T] // line +// ^^^^^^^^^^^^ source meta.function meta.function.parameters comment.block +// ^^^^^^^ source meta.function meta.function.parameters comment.line.double-slash + ) -> bool { + unimplemented!(); +} + +// impl of GenVal for a generic type `T` +impl <'a, T> GenVal { +// ^ punctuation.definition.generic.begin +// ^^ storage.modifier.lifetime +// ^ punctuation.definition.generic.end +// ^^^^^^ entity.name.impl +// ^^^ - entity.name.impl +// ^ punctuation.definition.generic.begin +// ^ punctuation.definition.generic.end + fn value(&self) -> &T { &self.0 } + // ^ keyword.operator + // ^ keyword.operator +} + +fn print_debug (t: &T) { +// ^^^^^^^^^^^ entity.name.function +// ^ punctuation.definition.generic.begin - entity.name.function +// ^ punctuation.separator +// ^ punctuation.definition.generic.end +// ^ variable.parameter +// ^ keyword.operator + println!("{:?}", t); +// ^^^^ constant.other.placeholder +} + +pub fn from_buf_reader(s: io::BufReader) -> Result +// ^ keyword.operator +// ^^^^^^^ meta.function meta.function.return-type meta.generic storage.modifier.lifetime + where T: io::Read +// ^^^^^ keyword.other +{} + +// HRTB in various positions. +fn f Fn(&'c mut Self)>() {} +// ^^^ meta.generic keyword.other +// ^ meta.generic meta.generic punctuation.definition.generic.begin +// ^^ meta.generic meta.generic storage.modifier.lifetime +// ^ meta.generic meta.generic punctuation.definition.generic.end +// ^^ meta.generic support.type +fn f(a: for<'a, 'b> fn() -> String) {} +// ^ variable.parameter +// ^^^^^^^^^^^^^^ meta.function meta.function.parameters +// ^^^ keyword.other +// ^ meta.generic punctuation.definition.generic.begin +// ^^ meta.generic storage.modifier.lifetime +// ^ meta.generic punctuation.separator +// ^^ meta.generic storage.modifier.lifetime +// ^ meta.function meta.function.parameters meta.generic punctuation.definition.generic.end + +// Function in type path with return type. +fn factory() -> Box i32> { +// <- storage.type.function +// ^^^^^^^ entity.name.function +// ^^^^^^^^^^^^^^^^ meta.generic +// ^^ support.type +// ^ punctuation.section.group.begin +// ^^^ storage.type +// ^ punctuation.section.group.end +// ^^ punctuation.separator +// ^^^ storage.type + Box::new(|x| x + 1) +} + +// Const generics. +trait Foo { +// ^^^^^^^^^^^^^^^^ meta.trait meta.generic +// ^ punctuation.definition.generic.begin +// ^^^^^ storage.modifier +// ^ meta.trait meta.generic punctuation.separator +// ^^^^^ storage.type +// ^ punctuation.definition.generic.end + fn method(&mut self, arr: [[u8; M]; N]); +// ^^^^^^^^^^^^^^^^ meta.generic +// ^ punctuation.definition.generic.begin +// ^^^^^ storage.modifier +// ^ punctuation.separator +// ^^^^^ storage.type +// ^ punctuation.definition.generic.end +} + +struct Bar { +// ^^^^^^^^^^^^^^^^^^^ meta.struct meta.generic +// ^ punctuation.definition.generic.begin +// ^ punctuation.separator +// ^^^^^ storage.modifier +// ^ punctuation.separator +// ^^^^^ storage.type +// ^ punctuation.definition.generic.end + inner: [T; N], +} + +impl Foo for Bar { +// ^^^^^^^^^^^^^^^^ meta.impl meta.generic +// ^ punctuation.definition.generic.begin +// ^^^^^ storage.modifier +// ^ punctuation.separator +// ^^^^^ storage.type +// ^ punctuation.definition.generic.end + fn method(&mut self, arr: [[u8; M]; N]) {} +} + +struct Bool; +// ^^^^^^^^^^^^^^^ meta.struct meta.generic +// ^ punctuation.definition.generic.begin +// ^^^^^ storage.modifier +// ^ punctuation.separator +// ^^^^ storage.type +// ^ punctuation.definition.generic.end +struct Char; +struct Int; +struct Byte; + +fn function() { + const fn foo(x: bool) -> usize { 2 } + let x: Bar = Bar { inner: [1; 1] }; +// ^^^^^^^^ meta.function meta.block meta.generic +// ^ meta.function meta.block meta.generic punctuation.definition.generic.begin +// ^^^ meta.function meta.block meta.generic storage.type +// ^ meta.function meta.block meta.generic punctuation.separator +// ^ meta.function meta.block meta.generic constant.numeric.integer.decimal +// ^ meta.function meta.block meta.generic punctuation.definition.generic.end + let y: Bar 2) / 2 }> = Bar { inner: [1; 1] }; +// ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function meta.block meta.generic +// ^ punctuation.definition.generic.begin +// ^^^^^^^^^^^^^^^^^^ meta.block +// ^^^ variable.function +// ^ meta.group punctuation.section.group.begin +// ^ keyword.operator.comparison +// ^ punctuation.section.group.end +// ^ keyword.operator.arithmetic +// ^ constant.numeric.integer.decimal +// ^ punctuation.section.block.end +// ^ punctuation.definition.generic.end + let b: Bool; +// ^^^^ meta.function meta.block meta.generic constant.language + let c: Char<'∂'>; +// ^^^ meta.function meta.block meta.generic string.quoted.single +// ^ punctuation.definition.string.begin +// ^ punctuation.definition.string.end + let i: Int<-1>; +// ^^^^ meta.function meta.block meta.generic +// ^ keyword.operator.arithmetic +// ^ constant.numeric.integer.decimal + let i: Int<0b1011>; +// ^^^^^^ meta.function meta.block meta.generic constant.numeric.integer.binary + let i: Int<4i32>; +// ^^^^^^ meta.function meta.block meta.generic +// ^ constant.numeric.integer.decimal +// ^^^ storage.type.numeric + let b: Byte; +// ^^^^^^ meta.function meta.block meta.generic +// ^^^^ string.quoted.single.rust +// ^ storage.type.string +// ^ punctuation.definition.string.begin +// ^ punctuation.definition.string.end +} diff --git a/Rust/tests/syntax_test_literals.rs b/Rust/tests/syntax_test_literals.rs new file mode 100644 index 0000000000..fa19c787fd --- /dev/null +++ b/Rust/tests/syntax_test_literals.rs @@ -0,0 +1,255 @@ +// SYNTAX TEST "Packages/Rust/Rust.sublime-syntax" + +let c = 'c'; +// <- storage.type +// ^ keyword.operator.assignment +// ^^^ string.quoted.single +let b = b'c'; +// <- storage.type +// ^ keyword.operator.assignment +// ^ storage.type +// ^^^ string.quoted.single +let ch = '∞'; +// ^^^ string.quoted.single + +let s = "This is a string \x01_\u{007F}_\"_\'_\\_\r_\n_\t_\0"; +// <- storage.type +// ^ keyword.operator.assignment +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double +// ^^^^ constant.character.escape +// ^^^^^^^^ constant.character.escape +// ^^ constant.character.escape +// ^^ constant.character.escape +// ^^ constant.character.escape +// ^^ constant.character.escape +// ^^ constant.character.escape +// ^^ constant.character.escape +// ^^ constant.character.escape +let r = r##"This is a raw string, no escapes! \x00 \0 \n"##; +// <- storage.type +// ^ keyword.operator.assignment +// ^ storage.type +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double.raw - constant.character.escape +// ^^^ punctuation.definition.string.begin.rust +// ^^^ punctuation.definition.string.end.rust +// ^ - string +let s = "\ +// ^ string.quoted.double punctuation.separator.continuation.line +continued \ +// ^ string.quoted.double punctuation.separator.continuation.line +line"; +let b = b"\ +// ^ punctuation.separator.continuation.line +"; +println!("Continuation in format \ +// ^ punctuation.separator.continuation.line +"); + +let bytes = b"This won't escape unicode \u{0123}, but will do \x01_\"_\'_\\_\r_\n_\t_\0"; +// <- storage.type +// ^ keyword.operator.assignment +// ^ storage.type +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double +// ^^^^ constant.character.escape +// ^^ constant.character.escape +// ^^ constant.character.escape +// ^^ constant.character.escape +// ^^ constant.character.escape +// ^^ constant.character.escape +// ^^ constant.character.escape +// ^^ constant.character.escape + +let raw_bytes = br#"This won't escape anything either \x01 \""#; +// <- storage.type +// ^ keyword.operator.assignment +// ^^ storage.type +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double - constant.character.escape + +let b_simple = b'a'; +// ^^^^ string.quoted.single +// ^ storage.type.string +// ^ punctuation.definition.string.begin +// ^ punctuation.definition.string.end +// ^ punctuation.terminator +let b_newline = b'\n'; +// ^^^^^ string.quoted.single +// ^^ string.quoted.single constant.character.escape +let b_nul = b'\0'; +// ^^ string.quoted.single constant.character.escape +let b_back = b'\\'; +// ^^ string.quoted.single constant.character.escape +let b_quote = b'\''; +// ^^ string.quoted.single constant.character.escape +let b_esc_nul = b'\x00'; +// ^^^^ string.quoted.single constant.character.escape +let b_esc_255 = b'\xff'; +// ^^^^ string.quoted.single constant.character.escape +let b_esc_inv = b'\a'; +// ^^ invalid.illegal.byte +// ^ string.quoted.single punctuation.definition.string.end +let b_inv_len = b'abc'; +// ^ string.quoted.single +// ^^ invalid.illegal.byte +// ^ string.quoted.single punctuation.definition.string.end +let b_inv_uni = b'♥'; +// ^ invalid.illegal.byte +// ^ string.quoted.single punctuation.definition.string.end +let b_inv_empty = b''; +// ^^^ string.quoted.single +// ^ punctuation.definition.string.begin +// ^ punctuation.definition.string.end +let b_unclosed1 = b' +// Avoid error on entire file. +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.line.double-slash - invalid - string + +let bs_newline = b"abc\n"; +// ^^^^^^^^ string.quoted.double +// ^ punctuation.definition.string.begin +// ^^ constant.character.escape +// ^ punctuation.definition.string.end +// ^ punctuation.terminator +let bs_nul = b"abc\0"; +// ^^ string.quoted.double constant.character.escape +let bs_esc_nul = b"abc\x00"; +// ^^^^ string.quoted.double constant.character.escape +let bs_esc_255 = b"abc\xff"; +// ^^^^ string.quoted.double constant.character.escape +let bs_esc_inv = b"abc\a"; +// ^^ string.quoted.double invalid.illegal.character.escape +// ^ string.quoted.double punctuation.definition.string.end - invalid + +let char_newline = '\n'; +// ^^^^ string.quoted.single +// ^ punctuation.definition.string.begin +// ^^ constant.character.escape +// ^ punctuation.definition.string.end +// ^ punctuation.terminator +let char_nul = '\0'; +// ^^ string.quoted.single constant.character.escape +let char_extra_inv = 'ab'; +// ^ string.quoted.single +// ^ invalid.illegal.char +// ^ string.quoted.single punctuation.definition.string.end +let char_ascii_esc_nul = '\x00'; +// ^^^^ string.quoted.single constant.character.escape +let char_ascii_esc_127 = '\x7f'; +// ^^^^ string.quoted.single constant.character.escape +let char_ascii_inv_255 = '\xff'; +// ^^^^ invalid.illegal.char +let char_uni_esc = '\u{3b1}'; +// ^^^^^^^ string.quoted.single constant.character.escape +let char_uni_esc_empty = '\u{}'; +// ^^^^ invalid.illegal.char +let char_uni_esc_under_start = '\u{_1_}'; +// ^^^^^^^ invalid.illegal.char +let char_uni_esc_under1 = '\u{1_}'; +// ^^^^^^ string.quoted.single constant.character.escape +let char_uni_esc_under2 = '\u{1_2__3___}'; +// ^^^^^^^^^^^^^ string.quoted.single constant.character.escape +let char_uni_esc_under3 = '\u{10__FFFF}'; +// ^^^^^^^^^^^^ string.quoted.single constant.character.escape +let char_uni_esc_extra = '\u{1234567}'; +// ^^^^^^^^^^^ invalid.illegal.char + +let s_ascii_inv_255 = "\xff"; +// ^^ string.quoted.double invalid.illegal.character.escape +let s_uni_esc_empty = "\u{}"; +// ^^^^ string.quoted.double invalid.illegal.character.escape +let s_uni_esc_under_start = "\u{_1_}"; +// ^^^^^^^ string.quoted.double invalid.illegal.character.escape +let s_uni_esc_under1 = "\u{1_}"; +// ^^^^^^ string.quoted.double constant.character.escape +let s_uni_esc_under2 = "\u{1_2__3___}"; +// ^^^^^^^^^^^^^ string.quoted.double constant.character.escape +let s_uni_esc_under3 = "\u{10__FFFF}"; +// ^^^^^^^^^^^^ string.quoted.double constant.character.escape +let s_uni_esc_extra = "\u{1234567}"; +// ^^^^^^^^^^^ string.quoted.double invalid.illegal.character.escape + +0; +// <- constant.numeric.integer.decimal +1_000u32; +// <- constant.numeric.integer.decimal + // <- constant.numeric.integer.decimal +//^^^ constant.numeric.integer.decimal +// ^^^ storage.type - constant.numeric.integer.decimal +1i64; +// <- constant.numeric.integer.decimal + // <- storage.type - constant.numeric.integer.decimal +//^^ storage.type - constant.numeric.integer.decimal + +0.2; +// <- constant.numeric.float + // <- constant.numeric.float +//^ constant.numeric.float +1_000.0_; +// <- constant.numeric.float + // <- constant.numeric.float +//^^^^^^ constant.numeric.float +1.0f32; +// <- constant.numeric.float + // <- constant.numeric.float +//^ constant.numeric.float +// ^^^ storage.type - constant.numeric.float +0.; +// <- constant.numeric.float + // <- constant.numeric.float +0f64; +// <- constant.numeric.float + // <- storage.type - constant.numeric.float +//^^ storage.type - constant.numeric.float +1e+8; +// <- constant.numeric.float + // <- constant.numeric.float +//^^ constant.numeric.float +1.0E-8234987_f64; +// <- constant.numeric.float + // <- constant.numeric.float +//^^^^^^^^^^^ constant.numeric.float +// ^^^ storage.type - constant.numeric.float + +0x0; +// <- constant.numeric.integer.hexadecimal + // <- constant.numeric.integer.hexadecimal +//^ constant.numeric.integer.hexadecimal +0xfa; +// <- constant.numeric.integer.hexadecimal + // <- constant.numeric.integer.hexadecimal +//^^ constant.numeric.integer.hexadecimal +0xFA_01i32; +// <- constant.numeric.integer.hexadecimal + // <- constant.numeric.integer.hexadecimal +//^^^^^ constant.numeric.integer.hexadecimal +// ^^^ storage.type - constant.numeric.integer.hexadecimal + +0b1; +// <- constant.numeric.integer.binary + // <- constant.numeric.integer.binary +//^ constant.numeric.integer.binary +0b0_1u8; +// <- constant.numeric.integer.binary + // <- constant.numeric.integer.binary +//^^^ constant.numeric.integer.binary +// ^^ storage.type - constant.numeric.integer.binary + +0o0; +// <- constant.numeric.integer.octal + // <- constant.numeric.integer.octal +//^ constant.numeric.integer.octal +0o0000_0010u64; +// <- constant.numeric.integer.octal + // <- constant.numeric.integer.octal +//^^^^^^^^^ constant.numeric.integer.octal +// ^^^ storage.type - constant.numeric.integer.octal + +0x12e15e35b500f16e2e714eb2b37916a5_u128; +// <- constant.numeric.integer.hexadecimal + // <- constant.numeric.integer.hexadecimal +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant.numeric.integer.hexadecimal +// ^^^^ storage.type - constant.numeric.integer.hexadecimal + +let logical: bool = true; +// ^ punctuation.separator +// ^^^^ storage.type +// ^ keyword.operator.assignment +// ^^^^ constant.language diff --git a/Rust/tests/syntax_test_macros.rs b/Rust/tests/syntax_test_macros.rs new file mode 100644 index 0000000000..5f9d539d48 --- /dev/null +++ b/Rust/tests/syntax_test_macros.rs @@ -0,0 +1,385 @@ +// SYNTAX TEST "Packages/Rust/Rust.sublime-syntax" + +String my_var = format!("Hello {0}", "World"); +// ^^^ support.type +// ^ keyword.operator.assignment +// ^^^^^^^ support.macro +// ^ punctuation.section.group.begin +// ^^^^^^^^^^^^^^^^^^^^^^ meta.group +// ^^^^^^^^^^^ string.quoted.double +// ^^^ constant.other.placeholder +// ^ punctuation.section.group.end + +pub fn macro_tests() { + println!(); +// ^^^^^^^^ support.macro + println!("Example"); +// ^^^^^^^^ support.macro +// ^ punctuation.section.group.begin +// ^^^^^^^^^ string.quoted.double +// ^ punctuation.section.group.end + println!("Example {} {message}", "test", message="hi"); +// ^^ constant.other.placeholder +// ^^^^^^^^^ constant.other.placeholder + panic!(); +// ^^^^^^ support.macro + panic!("Example"); +// ^^^^^^ support.macro +// ^ punctuation.section.group.begin +// ^^^^^^^^^ string.quoted.double +// ^ punctuation.section.group.end + panic!("Example {} {message}", "test", message="hi"); +// ^^ constant.other.placeholder +// ^^^^^^^^^ constant.other.placeholder + format_args!("invalid type: {}, expected {}", unexp, exp); +// ^^^^^^^^^^^^ support.macro +// ^^ constant.other.placeholder +// ^^ constant.other.placeholder + unreachable!("{:?}", e); +// ^^^^^^^^^^^^ support.macro +// ^^^^ constant.other.placeholder + unimplemented!("{:?}", e); +// ^^^^^^^^^^^^^^ support.macro +// ^^^^ constant.other.placeholder +} + +my_var = format!("Hello {name}, how are you?", +// ^ keyword.operator.assignment +// ^^^^^^^ support.macro +// ^ punctuation.section.group.begin +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.group +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double +// ^^^^^^ constant.other.placeholder + name="John"); +// ^^^^^^^^^^^^^ meta.group +// ^ keyword.operator.assignment +// ^^^^^^ string.quoted.double +// ^ punctuation.section.group.end + + write!(f, "{}", self.0) +// ^^^^^^ support.macro +// ^^^^^^^^^^^^^^^^^ meta.group +// ^ punctuation.section.group.begin +// ^^^^ string.quoted.double +// ^^ constant.other.placeholder +// ^^^^ variable.language +// ^ punctuation.accessor.dot +// ^ punctuation.section.group.end + write!(f, "{:10}", self.0) +// ^^^^^ constant.other.placeholder + eprint!("{:^10}", self.0) +// ^^^^^^^ support.macro +// ^^^^^^ constant.other.placeholder + eprintln!("{:+046.89?}", self.0) +// ^^^^^^^^^ support.macro +// ^^^^^^^^^^^ constant.other.placeholder + assert!(true, "{:-^#10x}", self.0) +// ^^^^^^^ support.macro +// ^^^^^^^^^ constant.other.placeholder + debug_assert!(true, "{4j:#xf10}", self.0) +// ^^^^^^^^^^^^^ support.macro +// ^^^^^^^^^^ string.quoted.double + write!(f, "{{}}", self.0) +// ^^^^ constant.character.escape + write!(get_writer(), "{}", "{}") +// ^^^^^^ support.macro +// ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.group +// ^^^^^^^^^^ variable.function +// ^^^^ string.quoted.double +// ^^ constant.other.placeholder +// ^^^^ string.quoted.double +// ^ punctuation.section.group.begin +// ^ punctuation.section.group.end + writeln!(w) +// ^^^^^^^^ support.macro +// ^^^ meta.group +// ^ punctuation.section.group.begin +// ^ punctuation.section.group.end + println!() +// ^^^^^^^^ support.macro +// ^^ meta.group +// ^ punctuation.section.group.begin +// ^ punctuation.section.group.end + +/*******************************************************************/ +// The outer brackets can be any type. +macro_rules! brackets_curly { +// ^ meta.macro punctuation.section.block.begin + ($i:ident) => ($i) +// ^^^^^^^^^^ meta.macro meta.macro.matchers +// ^^ meta.macro keyword.operator +// ^^^^ meta.macro meta.macro.transcribers +} +// <- meta.macro punctuation.section.block.end +macro_rules! brackets_paren ( +// ^ meta.macro punctuation.section.block.begin + ($i:ident) => ($i) +// ^^^^^^^^^^ meta.macro meta.macro.matchers +// ^^ meta.macro keyword.operator +// ^^^^ meta.macro meta.macro.transcribers + ); +//^ meta.macro punctuation.section.block.end +// ^ punctuation.terminator +macro_rules! brackets_square [ +// ^ meta.macro punctuation.section.block.begin + ($i:ident) => ($i) +// ^^^^^^^^^^ meta.macro meta.macro.matchers +// ^^ meta.macro keyword.operator +// ^^^^ meta.macro meta.macro.transcribers + ]; +//^ meta.macro punctuation.section.block.end +// ^ punctuation.terminator + +/*******************************************************************/ +// Matchers and transcribers can use any bracket type. +macro_rules! brackets { +//^^^^^^^^^^ meta.macro support.function +// ^^^^^^^^ meta.macro entity.name.macro +// ^ meta.macro punctuation.section.block.begin + ($i:ident) => ($i); +// ^^^^^^^^^^ meta.macro meta.macro.matchers +// ^^^^ meta.macro meta.macro.transcribers +// ^ punctuation.section.block.begin +// ^^ variable.parameter +// ^ punctuation.separator +// ^^^^^ storage.type +// ^ punctuation.section.block.end +// ^^ meta.macro keyword.operator +// ^ punctuation.section.block.begin +// ^^ variable.other +// ^ punctuation.section.block.end +// ^ meta.macro punctuation.terminator + {$i:ident} => {$i}; +// ^^^^^^^^^^ meta.macro meta.macro.matchers +// ^^^^ meta.macro meta.macro.transcribers +// ^ punctuation.section.block.begin +// ^^ variable.parameter +// ^^^^^ storage.type +// ^ punctuation.section.block.end +// ^ punctuation.section.block.begin +// ^ punctuation.section.block.end +// ^ meta.macro punctuation.terminator + [$i:ident] => [$i]; +// ^^^^^^^^^^ meta.macro meta.macro.matchers +// ^^^^ meta.macro meta.macro.transcribers +// ^ punctuation.section.block.begin +// ^^ variable.parameter +// ^^^^^ storage.type +// ^ punctuation.section.block.end +// ^ punctuation.section.block.begin +// ^ punctuation.section.block.end + // And they don't have to match. + ($i:ident) => [$i]; +// ^^^^^^^^^^ meta.macro meta.macro.matchers +// ^^^^ meta.macro meta.macro.transcribers + // Support nested brackets within matcher. + ((hello) ($i:ident) [foo] {bar}) => {$i}; +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.macro meta.macro.matchers +// ^^ variable.parameter +// ^^^^^ storage.type +// ^^ meta.macro keyword.operator +// ^^^^ meta.macro meta.macro.transcribers +// ^^ meta.macro meta.macro.transcribers variable.other +} + +/*******************************************************************/ +// Typical example with embedded rust code. +macro_rules! forward_ref_binop [ +// ^ meta.macro punctuation.section.block.begin + (impl $imp:ident, $method:ident for $t:ty, $u:ty) => { +// ^^^^ variable.parameter +// ^^^^^ storage.type +// ^^^^^^^ variable.parameter +// ^^^^^ storage.type +// ^^ variable.parameter +// ^^ storage.type +// ^^ variable.parameter +// ^^ storage.type +// ^^ keyword.operator +// ^ meta.macro meta.macro.transcribers punctuation.section.block.begin + impl<'a, 'b> $imp<&'a $u> for &'b $t { +// ^^^^ storage.type.impl +// ^^^^^^^^ meta.generic +// ^^ storage.modifier.lifetime +// ^^ storage.modifier.lifetime +// ^^^^ variable.other +// ^^^^^^^^ meta.generic +// ^ keyword.operator +// ^^ storage.modifier.lifetime +// ^^ variable.other +// ^^^ keyword.other +// ^ keyword.operator +// ^^ storage.modifier.lifetime +// ^^ variable.other +// ^ meta.macro meta.macro.transcribers meta.impl meta.block punctuation.section.block.begin + type Output = <$t as $imp<$u>>::Output; +// ^^^^^^^^^^^^^^^^ meta.generic +// ^^ keyword.operator +// ^^ meta.path + + #[inline] +// ^^^^^^^^^ meta.annotation + fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output { +// ^^ storage.type.function +// ^^^^^^^ variable.other +// ^^^^ variable.language +// ^ keyword.operator +// ^^ storage.modifier.lifetime +// ^^ variable.other +// ^^ punctuation.separator +// ^^^^^^^^^^^^^^^^ meta.generic +// ^^ keyword.operator +// ^^ meta.path +// ^ meta.macro meta.macro.transcribers meta.impl meta.block meta.block punctuation.section.block.begin + $imp::$method(*self, *other) +// ^^^^ variable.other +// ^^^^^^^ variable.other +// ^ keyword.operator +// ^^^^ variable.language +// ^ keyword.operator + } + } + } +] + +/*******************************************************************/ +// Kleene operators. +macro_rules! kleene_star { + ($($arg:tt)+) => ( +// ^^^^^^^^^^^^^ meta.macro meta.macro.matchers +// ^ keyword.operator +// ^ punctuation.section.group.begin +// ^^^^ variable.parameter +// ^ punctuation.separator +// ^^ storage.type +// ^ punctuation.section.group.end +// ^ keyword.operator +// ^ punctuation.section.block.end +// ^^ meta.macro keyword.operator +// ^ meta.macro meta.macro.transcribers punctuation.section.block.begin + println!($($arg)); + ); + ($($arg:tt)*) => ( +// ^^^^^^^^^^^^^ meta.macro meta.macro.matchers +// ^^^^ variable.parameter +// ^ keyword.operator +// ^ punctuation.section.block.end +// ^^ meta.macro keyword.operator + println!($($arg)*); + ); + ($($arg:tt);+) => ( +// ^^^^^^^^^^^^^^ meta.macro meta.macro.matchers +// ^^^^ variable.parameter +// ^^ storage.type +// ^ meta.macro meta.macro.matchers +// ^ keyword.operator +// ^ punctuation.section.block.end +// ^^ meta.macro keyword.operator + println!($($arg)); + ); + ($($arg:tt),*) => ( +// ^^^^^^^^^^^^^^ meta.macro meta.macro.matchers +// ^^^^ variable.parameter +// ^^ storage.type +// ^ +// ^ keyword.operator +// ^ meta.macro meta.macro.matchers punctuation.section.block.end +// ^^ meta.macro keyword.operator + println!($($arg)*); + ); + // Spacing should be ignored. + ( $ ( $ arg : tt ) , * ) => (); +// ^^^^^^^^^^^^^^^^^^^^^^^^ meta.macro meta.macro.matchers +// ^ punctuation.section.block.begin +// ^ keyword.operator +// ^ punctuation.section.group.begin +// ^^^^^ variable.parameter +// ^ punctuation.separator +// ^^ storage.type +// ^ punctuation.section.group.end +// ^ keyword.operator +// ^ punctuation.section.block.end +// ^^ meta.macro keyword.operator + // Separators can be any token. + ($($foo:tt) else *) => (); +// ^^^^^^^^^^^^^^^^^^^ meta.macro meta.macro.matchers +// ^ keyword.operator +// ^^ meta.macro keyword.operator +// ^^ meta.macro meta.macro.transcribers + + // At-most-once is new in 2018. + // Note: This is in flux, but looks like they've landed on a final form. + // https://github.com/rust-lang/rust/issues/51934 + ($($a:ident)? ; $num:expr) => {}; +// ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.macro meta.macro.matchers +// ^ keyword.operator +// ^^^^ variable.parameter +// ^^ meta.macro meta.macro.transcribers + +} +// <- meta.macro punctuation.section.block.end + +/*******************************************************************/ +// Different matcher types. +macro_rules! designators { + ($i:item, +// ^^ variable.parameter +// ^^^^ storage.type + $b:block, +// ^^ variable.parameter +// ^^^^^ storage.type + $s:stmt, +// ^^ variable.parameter +// ^^^^ storage.type + $p:pat, +// ^^ variable.parameter +// ^^^ storage.type + $pp:pat_param, +// ^^^ variable.parameter +// ^^^^^^^^^ storage.type + $e:expr, +// ^^ variable.parameter +// ^^^^ storage.type + $t:ty, +// ^^ variable.parameter +// ^^ storage.type + $i:ident, +// ^^ variable.parameter +// ^^^^^ storage.type + $p:path, +// ^^ variable.parameter +// ^^^^ storage.type + $t:tt, +// ^^ variable.parameter +// ^^ storage.type + $m:meta, +// ^^ variable.parameter +// ^^^^ storage.type + $l:lifetime, +// ^^ variable.parameter +// ^^^^^^^^ storage.type + $v:vis, +// ^^ variable.parameter +// ^^^ storage.type + $l:literal, +// ^^ variable.parameter +// ^^^^^^^ storage.type + ) => (); + // And various tokens + ("Any token" /*comment*/ true => 3.14 'life 'c' @ struct self) => (); +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.macro meta.macro.matchers +// ^^^^^^^^^^^ string.quoted.double +// ^^^^^^^^^^^ comment.block +// ^^^^ constant.language +// ^^ keyword.operator +// ^^^^ constant.numeric.float +// ^^^^^ storage.modifier.lifetime +// ^^^ string.quoted.single +// ^ keyword.operator +// ^^^^^^ storage.type.struct +// ^^^^ keyword.other +// ^ punctuation.section.block.end +// ^^ meta.macro keyword.operator +// ^^ meta.macro meta.macro.transcribers +} +//<- meta.macro punctuation.section.block.end diff --git a/Rust/tests/syntax_test_match.rs b/Rust/tests/syntax_test_match.rs new file mode 100644 index 0000000000..2bbcf70886 --- /dev/null +++ b/Rust/tests/syntax_test_match.rs @@ -0,0 +1,57 @@ +// SYNTAX TEST "Packages/Rust/Rust.sublime-syntax" + +let o = match n { +// ^^^^^ keyword.control + 1 => "one", +// ^ constant.numeric.integer.decimal +// ^^ keyword.operator +// ^^^^^ string.quoted.double + 2 => "two", +// ^ constant.numeric.integer.decimal +// ^^ keyword.operator +// ^^^^^ string.quoted.double + 3...5 => "a few", +// ^ constant.numeric.integer.decimal +// ^^^ keyword.operator.range +// ^ constant.numeric.integer.decimal +// ^^ keyword.operator +// ^^^^^^^ string.quoted.double + _ => "lots", +// ^ source +// ^^ keyword.operator +}; + +// Guards +match n { +// <- keyword.control + a if n > 5 => println!("Big: {}", a), +// ^^ keyword.control +// ^ keyword.operator.comparison +// ^^ keyword.operator +// ^^^^^^^^ support.macro + b if n <= 5 => println!("Small: {}", b), +// ^^ keyword.control +// ^^ keyword.operator.comparison +// ^^ keyword.operator +// ^^^^^^^^ support.macro +// ^^ constant.other.placeholder +} + +// Binding +match my_func() { +// ^^ keyword.control +// ^^^^^^^ variable.function +// ^ meta.block punctuation.section.block.begin + 0 => println!("None"), +// ^ constant.numeric.integer.decimal +// ^^ keyword.operator +// ^^^^^^^^ support.macro + res @ 1...9 => println!("Digit: {}", res), +// ^ keyword.operator +// ^^^ keyword.operator.range +// ^^ constant.other.placeholder + _ => println!("Full number"), +// ^ source +// ^^ keyword.operator +} +// <- meta.block punctuation.section.block.end diff --git a/Rust/tests/syntax_test_misc.rs b/Rust/tests/syntax_test_misc.rs new file mode 100644 index 0000000000..1267aa5ba7 --- /dev/null +++ b/Rust/tests/syntax_test_misc.rs @@ -0,0 +1,63 @@ +// SYNTAX TEST "Packages/Rust/Rust.sublime-syntax" +// Random things that don't deserve a file on their own. + +// Unsafe +let x = unsafe { } +// ^^^^^^ storage.modifier +unsafe impl Send for Interned {} +// <- storage.modifier +//^^^^ storage.modifier +pub unsafe trait Alloc { } +// ^^^^^^ storage.modifier +fn f(a: unsafe fn() -> String) {} +// ^^^^^^ meta.function meta.function.parameters storage.modifier +// ^^ meta.function meta.function.parameters storage.type.function + +// Previously reserved keywords now unreserved. +let pure = 1; +// ^^^^ -invalid.illegal.rust +let sizeof = 1; +// ^^^^^^ -invalid.illegal.rust +let alignof = 1; +// ^^^^^^^ -invalid.illegal.rust +let offsetof = 1; +// ^^^^^^^^ -invalid.illegal.rust +let proc = 1; +// ^^^^ -invalid.illegal.rust + +// Reserved keywords. +let virtual = 1; +// ^^^^^^^ invalid.illegal.rust +let become = 1; +// ^^^^^^ invalid.illegal.rust +let priv = 1; +// ^^^^ invalid.illegal.rust +let typeof = 1; +// ^^^^^^ invalid.illegal.rust +let unsized = 1; +// ^^^^^^^ invalid.illegal.rust +let do = 1; +// ^^ invalid.illegal.rust +let abstract = 1; +// ^^^^^^^^ invalid.illegal.rust +let final = 1; +// ^^^^^ invalid.illegal.rust +let override = 1; +// ^^^^^^^^ invalid.illegal.rust +let macro = 1; +// ^^^^^ invalid.illegal.rust + +// async/await +let x = async {} +// ^^^^^ keyword.control.rust +let y = future.await; +// ^^^^^ keyword.control.rust + +// try keyword in 2018 edition +let x = try {} +// ^^^ keyword.control.rust + +// Performance test for catastrophic backtracking. +impl ApplicationPreferenceseeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee { +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ entity.name.impl +} diff --git a/Rust/tests/syntax_test_modules.rs b/Rust/tests/syntax_test_modules.rs new file mode 100644 index 0000000000..3bd4edf9cc --- /dev/null +++ b/Rust/tests/syntax_test_modules.rs @@ -0,0 +1,98 @@ +// SYNTAX TEST "Packages/Rust/Rust.sublime-syntax" + +extern crate foo; +//<- keyword.other +//^^^^ keyword.other +// ^^^^^ keyword.other +// ^^^ source +// ^ punctuation.terminator + +extern crate std as ruststd; +//^^^^ keyword.other +// ^^^^^ keyword.other +// ^^^^ source +// ^^ keyword.operator +// ^^^^^^^ source +// ^ punctuation.terminator + +mod bar; +// <- meta.module storage.type.module +//^^^^^^ meta.module +// ^^^ entity.name.module +// ^ punctuation.terminator + +pub mod my_mod { +// ^^^^^^^^^^^^ meta.module +// <- storage.modifier +// ^^^ storage.type.module +// ^^^^^^ entity.name.module +// ^ meta.block punctuation.section.block.begin +} +// <- meta.module meta.block punctuation.section.block.end + +pub use self::trafile::*; +// <- storage.modifier +// ^^^ keyword.other +// ^^^^ variable.language +// ^^^^^^^^^^^^^^^ meta.path +// ^^ punctuation.accessor +// ^ keyword.operator +// ^ punctuation.terminator + +use std::fmt; +// <- keyword.other +// ^^^^^ meta.path +// ^^ punctuation.accessor +// ^^^ - meta.path +// ^ punctuation.terminator +use foo::i32; +// ^^^^^ meta.path +// ^^ punctuation.accessor +// ^^^ - meta.path storage.type +use foo::Bar; +// ^^^^^ meta.path +// ^^ punctuation.accessor +// ^^^ storage.type.source + +use foo::{Baz, QUX, quux}; +// ^^^^^ meta.path +// ^^ punctuation.accessor.rust +// ^^^^^^^^^^^^^^^^ meta.block +// ^ punctuation.section.block.begin +// ^^^ storage.type.source +// ^^^ constant.other +// ^^^^ meta.block +// ^ punctuation.section.block.end +// ^ punctuation.terminator + +use std::{ +// <- keyword.other +// ^^^^^ meta.path +// ^ meta.block punctuation.section.block.begin + fs::{self, read_dir}, +// ^^^^ meta.block meta.path +// ^ meta.block meta.block punctuation.section.block.begin +// ^^^^ meta.block meta.block variable.language +// ^^^^^^^^ meta.block meta.block +// ^ meta.block meta.block punctuation.section.block.end + path::{Path, PathBuf}, +// ^^^^^^ meta.block meta.path +// ^ meta.block meta.block punctuation.section.block.begin +// ^^^^ meta.block meta.block storage.type.source +// ^^^^^^^ meta.block meta.block storage.type.source +// ^ meta.block meta.block punctuation.section.block.end + }; +// ^ meta.block punctuation.section.block.end +// ^ punctuation.terminator + +extern { +// <- keyword.other +//^^^^ keyword.other +// ^ meta.block punctuation.section.block.begin + fn foo(x: i32, ...); +} +// <- meta.block punctuation.section.block.end + +extern "stdcall" { } +// <- keyword.other +// ^^^^^^^^^ string.quoted.double diff --git a/Rust/tests/syntax_test_punct.rs b/Rust/tests/syntax_test_punct.rs new file mode 100644 index 0000000000..909c40a2a1 --- /dev/null +++ b/Rust/tests/syntax_test_punct.rs @@ -0,0 +1,182 @@ +// SYNTAX TEST "Packages/Rust/Rust.sublime-syntax" +// Various usages of punctuation. + +/************* semicolon *************/ +; +// <- punctuation.terminator +let x = 1; +// ^ punctuation.terminator +[12; 34] +// ^ punctuation.separator +type T = [i32; 3]; +// ^ punctuation.separator +const X: i32 = 1; +// ^ punctuation.terminator +static Y: i32 = 1; +// ^ punctuation.terminator +extern "C" { + fn f(); +// ^ punctuation.terminator + static S: i32 = 1; +// ^ punctuation.terminator +} +trait T { + fn f(); +// ^ punctuation.terminator + const C: i32; +// ^ punctuation.terminator + type T; +// ^ punctuation.terminator +} +extern crate name; +// ^ punctuation.terminator +mod m; +// ^ punctuation.terminator +struct S; +// ^ punctuation.terminator +type T = i32; +// ^ punctuation.terminator +use foo; +// ^ punctuation.terminator + + +/************* colon *************/ +match v { + Point{x: 10, y: 20} => {} +// ^ punctuation.separator +// ^ punctuation.separator +} +let x: i32 = 1; +// ^ punctuation.separator +let c = |a: i32| {} +// ^ punctuation.separator +let s = Foo{x: 50}; +// ^ punctuation.separator +struct S { + f1: 1, +// ^ punctuation.separator +} +enum E { + Foo{x: i32}, +// ^ punctuation.separator +} +'label: +// ^ punctuation.separator +fn f<'a: 'b>(x: i32) where T: Bound {} +// ^ punctuation.separator +// ^ punctuation.separator +// ^ punctuation.separator +// See syntax_test_generics for more generics tests (all separator). +trait T: Bound { +// ^ punctuation.separator + type T: Bound; +// ^ punctuation.separator + const C: i32; +// ^ punctuation.separator + fn f(x: i32); +// ^ punctuation.separator +} +static S: i32 = 1; +// ^ punctuation.separator +const C: i32 = 1; +// ^ punctuation.separator +type T = fn(a: i32); +// ^ punctuation.separator + + +/************* comma *************/ +#[cfg(a, b)] +// ^ punctuation.separator +fn f() where A: B, C: D {} +// ^ punctuation.separator +// ^ punctuation.separator +X +// ^ punctuation.separator +type T = Box; +// ^ punctuation.separator +type T = fn(i32, i32); +// ^ punctuation.separator +type T = (i32, i32); +// ^ punctuation.separator +let S{f1, f2} = a; +// ^ punctuation.separator +let (a, b) = c; +// ^ punctuation.separator +let [a, b] = c; +// ^ punctuation.separator +let a = [1, 2]; +// ^ punctuation.separator +let x = (a, b); +// ^ punctuation.separator +foo(1, 2); +// ^ punctuation.separator +let a = |a, b| {}; +// ^ punctuation.separator +fn f(a: i32, b: i32) {} +// ^ punctuation.separator +struct S { + f1: i32, +// ^ punctuation.separator +} +struct S(i32, i32); +// ^ punctuation.separator +enum E { + Variant1, +// ^ punctuation.separator + Variant2{f1: i32,}, +// ^ punctuation.separator +// ^ punctuation.separator + Variant3(i32, i32), +// ^ punctuation.separator +// ^ punctuation.separator +} +Foo{f1: a,}; +// ^ punctuation.separator +Foo(a, b); +// ^ punctuation.separator +match a { + x => 1, +// ^ punctuation.separator +} +use a::{a,b}; +// ^ punctuation.separator + + +/************* ligatures *************/ +// This is mostly for visual inspection. +foo!{<- -> =>} // emplacement token (unused in language) +// ^^ keyword.operator +// ^^ punctuation.separator +// ^^ keyword.operator +fn f() -> i32 {1} +// ^^ punctuation.separator + a && b || c; +// ^^ keyword.operator.logical +// ^^ keyword.operator.logical + 1 << 2 >> 3; +// ^^ keyword.operator.bitwise +// ^^ keyword.operator.bitwise + a += 1; b -= 1; c *= 1; d /= 1; e %= 1; f ^= 1; g &= 1; h |= 1; +// ^^ keyword.operator.assignment +// ^^ keyword.operator.assignment +// ^^ keyword.operator.assignment +// ^^ keyword.operator.assignment +// ^^ keyword.operator.assignment +// ^^ keyword.operator.assignment +// ^^ keyword.operator.assignment +// ^^ keyword.operator.assignment + a <<= 1; b >>= 2; +// ^^^ keyword.operator.assignment +// ^^^ keyword.operator.assignment + x == y; x != y; +// ^^ keyword.operator.comparison +// ^^ keyword.operator.comparison + a >= b; a <= b; +// ^^ keyword.operator.comparison +// ^^ keyword.operator.comparison + 1..2; 1...2; 1..=2; +//^^ keyword.operator.range +// ^^^ keyword.operator.range +// ^^^ keyword.operator.range +match x { a => {}} +// ^^ meta.block keyword.operator diff --git a/Rust/tests/syntax_test_raw.rs b/Rust/tests/syntax_test_raw.rs new file mode 100644 index 0000000000..b63f42620c --- /dev/null +++ b/Rust/tests/syntax_test_raw.rs @@ -0,0 +1,106 @@ +// SYNTAX TEST "Packages/Rust/Rust.sublime-syntax" +// Raw identifiers in various positions. + +use r#foo::bar as r#alias_foo; +// ^^^^^^^ meta.path +// ^^^^^^^^^^^ source -keyword + +fn main() { + #[r#attr] +// ^^^^^^^^^ meta.annotation -keyword + r#foo::r#bar(); +// ^^^^^^^ meta.path -keyword +// ^^^^^ -keyword + + let r#local = r#Struct { r#struct: () }; +// ^^^^^^^^ -keyword +// ^^^^^^^^ storage.type.source -keyword +// ^^^^^^^^ -keyword + let r#async = r#foo(r#local); +// ^^^^^^^^ -keyword +// ^^^^^ -keyword +// ^^^^^^^ -keyword + r#macro!(); +// ^^^^^^^^ support.macro -keyword -invalid + somecall(r#foo); +// ^^^^^ meta.function meta.block meta.group + + if let r#sub_pat @ Foo(_) = r#Foo(3) {} +// ^^^^^^^^^^ -keyword +// ^^^^^ storage.type.source + + match r#async { +// ^^^^^^^^ -keyword + r#Foo | r#Bar => r#foo(), +// ^^^^^ storage.type.source -keyword +// ^^^^^ storage.type.source -keyword +// ^^^^^ -keyword + } +} + +fn r#bar<'a, r#T>(r#x: &'a r#T) {} +// ^^^^^ meta.function entity.name.function -keyword +// ^^^ meta.generic -keyword +// ^^^ meta.function meta.function.parameters variable.parameter -keyword +// ^^^ meta.function meta.function.parameters -keyword + +struct Generic(T); +// ^^^ meta.struct meta.generic meta.generic -keyword + +mod r#foo { +// ^^^^^ meta.module entity.name.module -keyword + pub fn r#bar() {} +// ^^^^^ meta.module meta.block meta.function entity.name.function -keyword +} + +enum r#Foo { +// ^^^^^ meta.enum meta.enum entity.name.enum + r#Bar {}, +// ^^^^^^ meta.enum -keyword +} + +struct r#Struct { +// ^^^^^^^^ meta.struct entity.name.struct -keyword + r#field: r#FieldType, +// ^^^^^^^ meta.struct meta.block variable.other.member -keyword +// ^^^^^^^^^^^^^ meta.struct meta.block -keyword +} + +trait r#Trait { +// ^^^^^^^ meta.trait entity.name.trait -keyword + type r#Type; +// ^^^^^^ meta.trait meta.block entity.name.type -keyword +} + +impl r#Trait for r#Impl { +// ^^^^^^^^ meta.impl -keyword +// ^^^^^^ meta.impl entity.name.impl -keyword + type r#Type = r#u32; +// ^^^^^^ meta.impl meta.block entity.name.type +// ^^^^^ meta.impl meta.block -keyword -storage + fn r#xxx(r#fjio: r#u32) {} +// ^^^^^ meta.impl meta.block meta.function entity.name.function -keyword +// ^^^^^^ meta.impl meta.block meta.function meta.function.parameters variable.parameter -keyword +// ^^^^^ meta.impl meta.block meta.function meta.function.parameters -keyword -storage +} + +extern "C" { + type r#ccc; +// ^^^^^ meta.block entity.name.type -keyword + static r#static_val: u32; +// ^^^^^^^^^^^^ meta.block -keyword +} + +macro_rules! r#macro { +// ^^^^^^^ meta.macro entity.name.macro -keyword -invalid + () => {}; +} + +macro_rules! foo { + ($x:expr) => { + let r#catch = $x + 1; +// ^^^^^^^^ meta.macro meta.macro.transcribers -keyword + r#println!("{}", r#catch); +// ^^^^^^^ meta.macro meta.macro.transcribers meta.group -keyword + }; +} diff --git a/Rust/tests/syntax_test_struct.rs b/Rust/tests/syntax_test_struct.rs new file mode 100644 index 0000000000..3e5b2a71ad --- /dev/null +++ b/Rust/tests/syntax_test_struct.rs @@ -0,0 +1,124 @@ +// SYNTAX TEST "Packages/Rust/Rust.sublime-syntax" + +struct BasicStruct(i32); +// ^^^^^^^^^^^^^^^^^^^^ meta.struct +// <- storage.type.struct +//^^^^ storage.type.struct +// ^^^^^^^^^^^ entity.name.struct +// ^ punctuation.section.group.begin +// ^^^ storage.type +// ^ punctuation.section.group.end + +struct PrintableStruct(Box); +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.struct +// <- storage.type.struct +//^^^^ storage.type.struct +// ^^^^^^^^^^^^^^^ entity.name.struct +// ^ punctuation.section.group.begin +// ^^^^^^^^ meta.generic +// ^^^ support.type +// ^ punctuation.definition.generic.begin +// ^^^ storage.type +// ^ punctuation.definition.generic.end +// ^ punctuation.section.group.end + +struct Nil; +// ^^^^^^^ meta.struct +// ^ - meta.struct + +struct Pair(i32, i32); +// ^^^^^^^^^^^^^^^^^^ meta.struct +// ^^^ storage.type +// ^^^ storage.type +// ^ - meta.struct + +struct /*comment*/ Comments {} +// ^^^^^^^^^^^ meta.struct comment.block + +struct Point +// ^^^^^^^^^ meta.struct +{ +// <- meta.struct meta.block punctuation.section.block.begin + x: i32, +// ^ variable.other.member +// ^ punctuation.separator +// ^^^ storage.type + y: i32 +// ^ variable.other.member +// ^ punctuation.separator +// ^^^ storage.type +} +// <- meta.block punctuation.section.block.end + +impl Point +//^^^^^^^^ meta.impl +{ +// <- meta.impl meta.block punctuation.section.block.begin + fn new(x: i32, y: i32) -> Point + // <- storage.type.function + // ^^^ entity.name.function + { + // <- meta.function meta.block + Point {x: x, y: y} + } + + fn double(&mut self) { + // ^^^^^^ entity.name.function + self.x *= 2; + // ^^^^ variable.language + // ^ punctuation.accessor.dot + // ^^ keyword.operator.assignment + self.y *= 2; + } +} + +// TODO: `meta.group` should cover the closing parenthesis. +struct Val (f64,); +//^^^^^^^^^^^^^^^ meta.struct +// ^^^ entity.name.struct +// ^^^^^ meta.group +// ^ punctuation.section.group.begin +// ^^^ storage.type +// ^ punctuation.section.group.end +// ^ punctuation.terminator + +struct F { + f: extern "C" fn(x: u8, ... /* comment */), +// ^^^^^^ meta.struct meta.block keyword.other +// ^^^ meta.struct meta.block string.quoted.double +// ^^ meta.struct meta.block storage.type.function +// ^^^^^^^^^^^^^ meta.struct meta.block meta.group comment.block + g: extern "C" fn(x: u8, /* comment */ ...), +// ^^^^^^^^^^^^^ meta.struct meta.block meta.group comment.block + h: extern "C" fn(x: u8, ...), + i: extern "C" fn( + x: u8, +// ^^ meta.struct meta.block meta.group storage.type + // comment 4 +// ^^^^^^^^^^^^^ meta.struct meta.block meta.group comment.line.double-slash + y: String, // comment 3 +// ^^^^^^^^^^^^^ meta.struct meta.block meta.group comment.line.double-slash + z: Foo, + ), +} + +let mut j = BasicStruct(10); +// ^^^ storage.modifier +// ^^ constant.numeric.integer.decimal + +let p = Point {x: 10.0, y: 20.0}; +// ^^^^^ storage.type.source +// ^^^^^^^^^^^^^^^^^^ meta.block +// ^ punctuation.section.block.begin +// ^ punctuation.separator +// ^^^^ constant.numeric.float +// ^ punctuation.section.block.end +let n = NothingInMe {}; +// ^^^^^^^^^^^ storage.type.source +// ^^ meta.block +let tp = TuplePoint { 0: 10.0, 1: 20.0 }; +// ^constant.numeric.integer.decimal +// ^ constant.numeric.integer.decimal +let p = Point { x, y }; +// ^^^^^ storage.type.source +// ^^^^^^^^ meta.block diff --git a/Rust/tests/syntax_test_traits.rs b/Rust/tests/syntax_test_traits.rs new file mode 100644 index 0000000000..a388070e67 --- /dev/null +++ b/Rust/tests/syntax_test_traits.rs @@ -0,0 +1,125 @@ +// SYNTAX TEST "Packages/Rust/Rust.sublime-syntax" + +pub trait Animal { +// <- storage.modifier +// ^^^^^^^^^^^^^^ meta.trait +// ^ meta.block punctuation.section.block.begin + fn noise(quiet: bool) { + // Comment + } + + // Some tests for no-body functions. + fn bare_semi(); +// ^^^^^^^^^^^^^^ meta.function +// ^ punctuation.terminator + fn where_semi() where X: Ord + PartialOrd; +// ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function meta.where +// ^ keyword.operator.rust +// ^ punctuation.terminator + fn return_semi() -> bool; +// ^^^^^^^ meta.function meta.function.return-type +// ^ punctuation.terminator +} +// <- meta.trait meta.block punctuation.section.block.end + +impl<'a, T: MyTrait + OtherTrait> PrintInOption for T where +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.impl +// ^^ storage.modifier.lifetime +// ^ punctuation.separator +// ^ keyword.operator +// ^^^ keyword.other +// ^ entity.name.impl +// ^^^^^ meta.where keyword.other + Option: Debug { +//^^^^^^^^^^^^^^^^^^^^ meta.impl + fn print_in_option(self) { +// ^^^^^^^^^^^^^^^ entity.name.function + println!("{:?}", Some(self)); + } +} + +impl fmt::Display for PrintableStruct { +// <- meta.impl +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.impl +// <- storage.type.impl +//^^ storage.type.impl +// ^^^^^ meta.path +// ^^ punctuation.accessor +// ^^^ keyword.other +// ^^^^^^^^^^^^^^^ entity.name.impl +// ^ meta.block punctuation.section.block.begin + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.impl +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function +// ^^ storage.type.function +// ^^^ entity.name.function +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.parameters +// ^ punctuation.section.parameters.begin +// ^ keyword.operator +// ^^^^ variable.parameter +// ^ variable.parameter +// ^ punctuation.separator +// ^ keyword.operator +// ^^^ storage.modifier +// ^^^^^ meta.path +// ^ punctuation.section.parameters.end +// ^^ punctuation.separator +// ^^^^^ meta.path +// ^ meta.block punctuation.section.block.begin + } +// ^^ meta.function meta.block +// ^ punctuation.section.block.end +} +// <- meta.block punctuation.section.block.end + +impl !Send for Point {} +//^^^^^^^^^^^^^^^^^^^^^ meta.impl +// ^ meta.impl keyword.operator meta.impl.opt-out + +// Trait bounds and type parameters. +trait Foo: 'static {} +//^^^^^^^^^^^^^^^^^^^ meta.trait +// ^ meta.where punctuation.separator +// ^^^^^^^ meta.where storage.modifier.lifetime +// ^^ meta.block +trait Foo<'a>: Sized {} +//^^^^^^^^^^^^^^^^^^^^^ meta.trait +// ^^ meta.generic storage.modifier.lifetime +// ^^^^^ meta.where support.type +trait Executor: Send + Sync + 'static {} +// ^^^^ meta.trait meta.where support.type +// ^^^^ meta.trait meta.where support.type +// ^^^^^^^ meta.trait meta.where storage.modifier.lifetime +trait RcBoxPtr {} +// ^^^^^^^^^^^ meta.trait meta.generic +// ^ keyword.operator +// ^^^^^ support.type +trait Circle where Self: Shape {} +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.trait +// ^^^^^^^^^^^^^^^^^^ meta.trait meta.where +// ^^^^^ keyword.other +// ^^^^ storage.type +trait BorrowMut : Borrow {} +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.trait +// ^^^^^^^^^^^^^^^^^^ meta.generic +// ^ meta.trait meta.where punctuation.separator +trait Add {} +// ^^^^^^^^^^ meta.trait meta.generic +// ^ keyword.operator +// ^^^^ storage.type +trait Wedding<'t>: 't {} +// ^^ meta.trait meta.generic storage.modifier.lifetime +// ^^ meta.trait meta.where storage.modifier.lifetime +trait IntoCow<'a, B: ?Sized> where B: ToOwned {} +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.trait +// ^^ meta.generic storage.modifier.lifetime +// ^ meta.generic keyword.operator +// ^^^^^ meta.generic support.type +// ^^^^^ meta.where keyword.other +// ^^^^^^^ meta.where support.type +trait Bar: for<'a> Foo<&'a ()> {} +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.trait +// ^^^ meta.where keyword.other +// ^^ meta.where meta.generic storage.modifier.lifetime +// ^ meta.where meta.generic keyword.operator +// ^^ meta.where meta.generic storage.modifier.lifetime diff --git a/Rust/tests/syntax_test_types.rs b/Rust/tests/syntax_test_types.rs new file mode 100644 index 0000000000..7e9bceb33e --- /dev/null +++ b/Rust/tests/syntax_test_types.rs @@ -0,0 +1,176 @@ +// SYNTAX TEST "Packages/Rust/Rust.sublime-syntax" +// This file is for misc type definitions that don't fit in other more +// specific categories. + +type FnPointer = fn(i32) -> i32; +// <- storage.type.type +// ^^^^^^^^^ entity.name.type +// ^^ storage.type.function +// ^^^^^ meta.group +// ^^^ storage.type +// ^^ punctuation.separator +// ^^^ storage.type + +type GenFnPointer = Bar i32>; +// <- storage.type.type +// ^^^^^^^^^^^^ entity.name.type +// ^^^^^^^^^^^^^^^^^^^ meta.generic +// ^^ storage.type.function +// ^^^^^ meta.group +// ^^^ storage.type +// ^^ punctuation.separator +// ^^^ storage.type +// ^ - meta.generic + +type GenFnPointer2 = Bar; +// <- storage.type.type +// ^^^^^^^^^^^^^ entity.name.type +// ^^^^^^^^^^^^^^^^^^^^ meta.generic +// ^^^^^^ keyword.other +// ^^^ string.quoted.double +// ^^ storage.type.function +// ^ - meta.generic + +const ZERO: u64 = 0; +// <- storage.type +// ^^^^ entity.name.constant +// ^ punctuation.separator +// ^^^ storage.type +// ^ keyword.operator.assignment +// ^ constant.numeric.integer.decimal +static NAME: &'static str = "John"; +// <- storage.type +// ^^^^ entity.name.constant +// ^ keyword.operator +// ^^^^^^^ storage.modifier.lifetime +// ^^^ storage.type +// ^ keyword.operator.assignment +// ^^^^^^ string.quoted.double +static mut BRAVO: u32 = 0; +// <- storage.type +// ^^^ storage.modifier +// ^^^^^ entity.name.constant + +// Function type in a box return type. +// fixes https://github.com/rust-lang/sublime-rust/issues/144 +fn factory() -> Box i32> { +// <- storage.type.function +// ^^^^^^^ entity.name.function +// ^^^^^^^^^^^^^^ meta.generic +// ^^ storage.type +// ^^ storage.type +// ^^ source meta.function meta.function.return-type +} + +let x: __m128i = __m128i::from_bits(f32x4::from_bits(m32x4::new(true, true, true, true))); +// ^^^^^^^ storage.type +// ^^^^^^^ storage.type +// ^^^^^ meta.group storage.type +// ^^^^^ meta.group meta.group storage.type +// ^^^^ meta.group meta.group meta.group constant.language + +let mut mutable = 12; +// ^^^ storage.modifier + +// Tuple types. +type Pair<'a> = (i32, &'a str); +// <- storage.type.type +// ^^^^ entity.name.type +// ^ keyword.operator +// ^^ storage.modifier.lifetime +// ^ keyword.operator +// ^ keyword.operator.assignment +// ^^^^^^^^^^^^^^ meta.group +// ^ punctuation.section.group.begin +// ^^^ storage.type +// ^ keyword.operator +// ^^ storage.modifier.lifetime +// ^^^ storage.type +// ^ punctuation.section.group.end +// ^ punctuation.terminator +let p: Pair<'static> = (10, "ten"); +// <- storage.type +// ^ punctuation.separator +// ^^^^^^^^^^^^^ meta.generic +// ^ punctuation.definition.generic.begin +// ^^^^^^^ storage.modifier.lifetime +// ^ punctuation.definition.generic.end +// ^ keyword.operator.assignment +// ^^^^^^^^^^^ meta.group +// ^ punctuation.section.group.begin +// ^^ constant.numeric.integer.decimal +// ^^^^^ string.quoted.double +// ^ punctuation.section.group.end +// ^ punctuation.terminator +fn tuple(x: (u32, u32)) {} +// ^^^^^^^^^^ meta.group +// ^ meta.group punctuation.section.group.begin +// ^^^ storage.type +// ^ punctuation.separator +// ^^^ storage.type +// ^ meta.group punctuation.section.group.end + +// Array types. +let xs: [i32; 5] = [1, 2, 3, 4, 5]; +// ^ punctuation.separator +// ^^^^^^^^ meta.group +// ^ punctuation.section.group.begin +// ^^^ storage.type +// ^ punctuation.separator +// ^ constant.numeric.integer.decimal +// ^ punctuation.section.group.end +// ^^^^^^^^^^^^^^^ meta.group +// ^ punctuation.section.group.begin +// ^ punctuation.section.group.end + +// Slice types. +let slice: &[i32]; +// ^ keyword.operator +// ^^^^^ meta.group +// ^ punctuation.section.group.begin +// ^ punctuation.section.group.end +// ^^^ storage.type + + +// Pointer types. +let p: *const Foo; +// ^^^^^^ storage.modifier +// ^^^ storage.type.source +let p: *mut u8; +// ^^^^ storage.modifier +// ^^ storage.type +let raw = &x as *const i32; +// ^^^^^^ storage.modifier +// ^^^ storage.type +let raw_mut = &mut y as *mut i32; +// ^^^^ storage.modifier +// ^^^ storage.type +let p_imm: *const u32 = &i as *const u32; +// ^^^^^^ storage.modifier +// ^^^^^^ storage.modifier +// ^^^ storage.type +type ExampleRawPointer = HashMap<*const i32, Option, BuildHasherDefault>; +// ^^^^^^ meta.generic storage.modifier +// ^^^ meta.generic storage.type + + +// Anonymous lifetimes. +impl Foo<'_, '_> { } +// ^^ meta.impl meta.generic storage.modifier.lifetime +// ^^ meta.impl meta.generic storage.modifier.lifetime +fn f(string: &str) -> StrWrap<'_> { } +// ^^ meta.function meta.function.return-type meta.generic storage.modifier.lifetime + + +// Never type. +fn from_str() -> Result {} +// ^ meta.function meta.function.return-type meta.generic keyword.operator + +// Qualified path with type. +// Note: This isn't actually a generics, but that gets reused for this purpose. +type Item = ::Item; +// ^^^^^^^^^^^^^^^ meta.generic +// ^^ keyword.operator +// ^^^^^^^^ support.type +// ^^ punctuation.accessor +// ^^^^ storage.type.source diff --git a/Rust/tests/syntax_test_union.rs b/Rust/tests/syntax_test_union.rs new file mode 100644 index 0000000000..6ceab3ed91 --- /dev/null +++ b/Rust/tests/syntax_test_union.rs @@ -0,0 +1,40 @@ +// SYNTAX TEST "Packages/Rust/Rust.sublime-syntax" + +union Union { +//^^^ meta.union storage.type.union +//^^^^^^^^^^^ meta.union +// ^^^^^ entity.name.union +// ^ meta.block punctuation.section.block.begin + f: u32, +// ^ meta.union meta.block variable.other.member +// ^ meta.union meta.block punctuation.separator +// ^^^ meta.union meta.block storage.type +} +// <- meta.union meta.block punctuation.section.block.end + +pub union Foo<'a, Y: Baz> +// <- storage.modifier +// ^^^^^^^^^^^^^^^^^^^^^ meta.union +// ^^^^^ meta.union storage.type.union +// ^^^ meta.union meta.generic entity.name.union +// ^ meta.union meta.generic meta.generic punctuation.definition.generic.begin +// ^^ meta.union meta.generic meta.generic storage.modifier.lifetime + where X: Whatever, +// ^^^^^ meta.union meta.where keyword.other +// ^ meta.union meta.where +// ^ meta.union meta.where punctuation.separator +// ^^^^^^^^^^ meta.union meta.where +{ +// <- meta.union meta.block punctuation.section.block.begin + f: SomeType, // Comment beside a field +// ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.union meta.block comment.line.double-slash +} +// <- meta.union meta.block punctuation.section.block.end + +// Union was implemented in such a way that `union` is not a keyword. Verify +// that we don't accidentally interpret it as a keyword. +fn union() {} +// ^^^^^ meta.function entity.name.function + +union /*comment*/ U {} +// ^^^^^^^^^^^ meta.union comment.block diff --git a/Rust/tests/syntax_test_visibility.rs b/Rust/tests/syntax_test_visibility.rs new file mode 100644 index 0000000000..6b0b97331a --- /dev/null +++ b/Rust/tests/syntax_test_visibility.rs @@ -0,0 +1,84 @@ +// SYNTAX TEST "Packages/Rust/Rust.sublime-syntax" + +pub ( crate ) struct S {} +// <- storage.modifier +// ^ punctuation.section.group.begin +// ^^^^^ keyword.other +// ^ punctuation.section.group.end +// ^^^^^^^^^^^ meta.struct +pub ( in foo::bar ) union U {} +// ^ punctuation.section.group.begin +// ^^ keyword.other +// ^^^^^^^^ meta.path +// ^ punctuation.section.group.end +// ^^^^^^^^^^ meta.union +pub ( in foo :: bar ) type T = i32; +// ^ punctuation.section.group.begin +// ^^ keyword.other +// ^^^ meta.path +// ^^ meta.path +// ^^^ meta.path +// ^ punctuation.section.group.end +// ^^^^ storage.type.type +pub ( in ::foo ) fn f() {} +// ^^^^^ meta.path +// ^^^^^^^^^ meta.function +pub ( self ) mod m {} +// ^^^^ keyword.other +// ^^^^^^^^ meta.module +pub ( super ) use a::b; +// ^^^^^ keyword.other +// ^^^ keyword.other +pub ( in self ) enum E {A,B} +// ^^ keyword.other +// ^^^^ keyword.other +// ^^^^^^^^^^^^ meta.enum +pub ( in super ) const CONST: i32 = 1; +// ^^ keyword.other +// ^^^^^ keyword.other +// ^^^^^ storage.type +pub ( in super::super ) static STATIC: i32 = 1; +// ^^ keyword.other +// ^^^^^ keyword.other +// ^^ meta.path +// ^^^^^ keyword.other +// ^^^^^^ storage.type + +struct S { + pub f1: i32, +// ^^^ meta.struct storage.modifier +// ^^ meta.struct variable.other.member + pub(crate) f2: i32, +// ^^^ meta.struct storage.modifier +// ^ meta.struct punctuation.section.group.begin +// ^^^^^ meta.struct keyword.other +// ^ meta.struct punctuation.section.group.end +// ^^ meta.struct variable.other.member + pub(in super::foo) f3: i32, +// ^^^ meta.struct storage.modifier +// ^ meta.struct punctuation.section.group.begin +// ^^ meta.struct keyword.other +// ^^^^^ meta.struct keyword.other +// ^^^^^ meta.struct meta.path +// ^ meta.struct punctuation.section.group.end +// ^^ meta.struct variable.other.member +} + +struct S ( + pub i32, +// ^^^ meta.struct storage.modifier +// ^^^ meta.struct storage.type + pub(crate) i32, +// ^^^ meta.struct storage.modifier +// ^ meta.struct punctuation.section.group.begin +// ^^^^^ meta.struct keyword.other +// ^ meta.struct punctuation.section.group.end +// ^^^ meta.struct storage.type + pub(in super) i32, +// ^^^ meta.struct storage.modifier +// ^ meta.struct punctuation.section.group.begin +// ^^ meta.struct keyword.other +// ^^^^^ meta.struct keyword.other +// ^ meta.struct punctuation.section.group.end +// ^^^ meta.struct storage.type +);