Skip to content

Commit e5bea6f

Browse files
authored
fix: not closed generic state in case of left-shift operator (#5572)
1 parent 5f89a33 commit e5bea6f

File tree

3 files changed

+85
-28
lines changed

3 files changed

+85
-28
lines changed

src/mode/_test/text_rust.txt

+5
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,8 @@ fn map<T, U>(vector: &[T], function: &fn(v: &T) -> U) -> ~[U] {
3434

3535
// identifiers ending in constant.numeric
3636
foo1; foo1u32; foo1f32; foo0xF; foo1.0
37+
38+
39+
pub fn g<T>() -> std::mem::MaybeUninit<[T; 1 << 2]> {
40+
std::mem::MaybeUninit::uninit()
41+
}

src/mode/_test/tokens_rust.json

+45
Original file line numberDiff line numberDiff line change
@@ -338,4 +338,49 @@
338338
["constant.numeric.source.rust","0"]
339339
],[
340340
"start"
341+
],[
342+
"start"
343+
],[
344+
"start",
345+
["keyword.source.rust","pub"],
346+
["text"," "],
347+
["keyword.source.rust","fn"],
348+
["text"," "],
349+
["entity.name.function.source.rust","g"],
350+
["punctuation","<"],
351+
["identifier","T"],
352+
["punctuation",">"],
353+
["paren.lparen","("],
354+
["paren.rparen",")"],
355+
["text"," "],
356+
["keyword.operator","->"],
357+
["text"," "],
358+
["support.constant","std::mem::"],
359+
["identifier","MaybeUninit"],
360+
["punctuaction","<"],
361+
["paren.lparen","["],
362+
["identifier","T"],
363+
["punctuation.operator",";"],
364+
["text"," "],
365+
["constant.numeric.source.rust","1"],
366+
["text"," "],
367+
["keyword.operator","<<"],
368+
["text"," "],
369+
["constant.numeric.source.rust","2"],
370+
["paren.rparen","]"],
371+
["punctuation",">"],
372+
["text"," "],
373+
["paren.lparen","{"]
374+
],[
375+
"start",
376+
["text"," "],
377+
["support.constant","std::mem::MaybeUninit::"],
378+
["identifier","uninit"],
379+
["paren.lparen","("],
380+
["paren.rparen",")"]
381+
],[
382+
"start",
383+
["paren.rparen","}"]
384+
],[
385+
"start"
341386
]]

src/mode/rust_highlight_rules.js

+35-28
Original file line numberDiff line numberDiff line change
@@ -85,14 +85,14 @@ var RustHighlightRules = function() {
8585
]
8686
}, {
8787
token: ['keyword.source.rust', 'text', 'entity.name.function.source.rust', 'punctuation'],
88-
regex: '\\b(fn)(\\s+)((?:r#)?' + wordPattern + ')(<)',
88+
regex: '\\b(fn)(\\s+)((?:r#)?' + wordPattern + ')(<)(?!<)',
8989
push: "generics"
9090
}, {
9191
token: ['keyword.source.rust', 'text', 'entity.name.function.source.rust'],
9292
regex: '\\b(fn)(\\s+)((?:r#)?' + wordPattern + ')'
9393
}, {
9494
token: ['support.constant', "punctuation"],
95-
regex: "(" + wordPattern + '::)(<)',
95+
regex: "(" + wordPattern + '::)(<)(?!<)',
9696
push: "generics"
9797
}, {
9898
token: 'support.constant',
@@ -126,12 +126,15 @@ var RustHighlightRules = function() {
126126
]
127127
}, {
128128
token: ["keyword.source.rust", "identifier", "punctuaction"],
129-
regex: "(?:(impl)|(" + wordPattern + "))(<)",
129+
regex: "(?:(impl)|(" + wordPattern + "))(<)(?!<)",
130130
stateName: 'generics',
131131
push: [
132132
{
133+
token: 'keyword.operator',
134+
regex: /<<|=/
135+
}, {
133136
token: "punctuaction",
134-
regex: "<",
137+
regex: "<(?!<)",
135138
push: "generics"
136139
}, {
137140
token: 'variable.other.source.rust', // `(?![\\\'])` to keep a lifetime name highlighting from continuing one character
@@ -141,51 +144,55 @@ var RustHighlightRules = function() {
141144
}, {
142145
token: "storage.type.source.rust",
143146
regex: "\\b(u8|u16|u32|u64|u128|usize|i8|i16|i32|i64|i128|isize|char|bool)\\b"
144-
}, {
145-
token: "punctuation.operator",
146-
regex: "[,:]"
147147
}, {
148148
token: "keyword",
149149
regex: "\\b(?:const|dyn)\\b"
150150
}, {
151151
token: "punctuation",
152152
regex: ">",
153153
next: "pop"
154-
}, {
155-
token: "paren.lparen",
156-
regex: "[(]"
157-
}, {
158-
token: "paren.rparen",
159-
regex: "[)]"
160-
}, {
154+
},
155+
{include: "punctuation"},
156+
{include: "operators"},
157+
{include: "constants"},
158+
{
161159
token: "identifier",
162160
regex: "\\b"+wordPattern+"\\b"
163-
}, {
164-
token: 'keyword.operator',
165-
regex: "="
166161
}
167162
]
168163
}, {
169164
token: keywordMapper,
170165
regex: wordPattern
171166
}, {
172-
token: 'keyword.operator', // `[*/](?![*/])=?` is separated because `//` and `/* */` become comments and must be
173-
// guarded against. This states either `*` or `/` may be matched as long as the match
174-
// it isn't followed by either of the two. An `=` may be on the end.
175-
regex: /\$|[-=]>|[-+%^=!&|<>]=?|[*/](?![*/])=?/
176-
}, {
177-
token: "punctuation.operator",
178-
regex: /[?:,;.]/
179-
}, {
167+
token: 'meta.preprocessor.source.rust',
168+
regex: '\\b\\w\\(\\w\\)*!|#\\[[\\w=\\(\\)_]+\\]\\b'
169+
},
170+
{include: "punctuation"},
171+
{include: "operators"},
172+
{include: "constants"}
173+
],
174+
punctuation: [
175+
{
180176
token: "paren.lparen",
181177
regex: /[\[({]/
182178
}, {
183179
token: "paren.rparen",
184180
regex: /[\])}]/
185181
}, {
186-
token: 'meta.preprocessor.source.rust',
187-
regex: '\\b\\w\\(\\w\\)*!|#\\[[\\w=\\(\\)_]+\\]\\b'
188-
}, {
182+
token: "punctuation.operator",
183+
regex: /[?:,;.]/
184+
}
185+
],
186+
operators: [
187+
{
188+
token: 'keyword.operator', // `[*/](?![*/])=?` is separated because `//` and `/* */` become comments and must be
189+
// guarded against. This states either `*` or `/` may be matched as long as the match
190+
// it isn't followed by either of the two. An `=` may be on the end.
191+
regex: /\$|[-=]>|[-+%^=!&|<>]=?|[*/](?![*/])=?/
192+
}
193+
],
194+
constants: [
195+
{
189196
token: 'constant.numeric.source.rust',
190197
regex: /\b(?:0x[a-fA-F0-9_]+|0o[0-7_]+|0b[01_]+|[0-9][0-9_]*(?!\.))(?:[iu](?:size|8|16|32|64|128))?\b/
191198
}, {

0 commit comments

Comments
 (0)