Skip to content

Commit 99718d0

Browse files
committed
Auto merge of #15303 - oxalica:fix/byte-escape-highlight, r=lowr
Fix highlighting of byte escape sequences Currently non-UTF8 escape sequences in byte strings and any escape sequences in byte literals are ignored.
2 parents c99bb3c + 51b35cc commit 99718d0

29 files changed

+143
-47
lines changed

crates/hir-def/src/body/pretty.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,7 @@ impl Printer<'_> {
634634
match literal {
635635
Literal::String(it) => w!(self, "{:?}", it),
636636
Literal::ByteString(it) => w!(self, "\"{}\"", it.escape_ascii()),
637-
Literal::CString(it) => w!(self, "\"{}\\0\"", it),
637+
Literal::CString(it) => w!(self, "\"{}\\0\"", it.escape_ascii()),
638638
Literal::Char(it) => w!(self, "'{}'", it.escape_debug()),
639639
Literal::Bool(it) => w!(self, "{}", it),
640640
Literal::Int(i, suffix) => {

crates/hir-def/src/hir.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ impl fmt::Display for FloatTypeWrapper {
8585
pub enum Literal {
8686
String(Box<str>),
8787
ByteString(Box<[u8]>),
88-
CString(Box<str>),
88+
CString(Box<[u8]>),
8989
Char(char),
9090
Bool(bool),
9191
Int(i128, Option<BuiltinInt>),

crates/hir-ty/src/mir/lower.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1355,7 +1355,6 @@ impl<'ctx> MirLowerCtx<'ctx> {
13551355
return Ok(Operand::from_concrete_const(data, mm, ty));
13561356
}
13571357
hir_def::hir::Literal::CString(b) => {
1358-
let b = b.as_bytes();
13591358
let bytes = b.iter().copied().chain(iter::once(0)).collect::<Vec<_>>();
13601359

13611360
let mut data = Vec::with_capacity(mem::size_of::<usize>() * 2);

crates/ide/src/syntax_highlighting.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use syntax::{
2424

2525
use crate::{
2626
syntax_highlighting::{
27-
escape::{highlight_escape_char, highlight_escape_string},
27+
escape::{highlight_escape_byte, highlight_escape_char, highlight_escape_string},
2828
format::highlight_format_string,
2929
highlights::Highlights,
3030
macro_::MacroHighlighter,
@@ -471,6 +471,14 @@ fn traverse(
471471
};
472472

473473
highlight_escape_char(hl, &char, range.start())
474+
} else if ast::Byte::can_cast(token.kind())
475+
&& ast::Byte::can_cast(descended_token.kind())
476+
{
477+
let Some(byte) = ast::Byte::cast(token) else {
478+
continue;
479+
};
480+
481+
highlight_escape_byte(hl, &byte, range.start())
474482
}
475483
}
476484

crates/ide/src/syntax_highlighting/escape.rs

+30-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Syntax highlighting for escape sequences
22
use crate::syntax_highlighting::highlights::Highlights;
33
use crate::{HlRange, HlTag};
4-
use syntax::ast::{Char, IsString};
4+
use syntax::ast::{Byte, Char, IsString};
55
use syntax::{AstToken, TextRange, TextSize};
66

77
pub(super) fn highlight_escape_string<T: IsString>(
@@ -10,14 +10,14 @@ pub(super) fn highlight_escape_string<T: IsString>(
1010
start: TextSize,
1111
) {
1212
string.escaped_char_ranges(&mut |piece_range, char| {
13-
if char.is_err() {
14-
return;
15-
}
16-
1713
if string.text()[piece_range.start().into()..].starts_with('\\') {
14+
let highlight = match char {
15+
Ok(_) => HlTag::EscapeSequence,
16+
Err(_) => HlTag::InvalidEscapeSequence,
17+
};
1818
stack.add(HlRange {
1919
range: piece_range + start,
20-
highlight: HlTag::EscapeSequence.into(),
20+
highlight: highlight.into(),
2121
binding_hash: None,
2222
});
2323
}
@@ -26,6 +26,9 @@ pub(super) fn highlight_escape_string<T: IsString>(
2626

2727
pub(super) fn highlight_escape_char(stack: &mut Highlights, char: &Char, start: TextSize) {
2828
if char.value().is_none() {
29+
// We do not emit invalid escapes highlighting here. The lexer would likely be in a bad
30+
// state and this token contains junks, since `'` is not a reliable delimiter (consider
31+
// lifetimes). Nonetheless, parser errors should already be emitted.
2932
return;
3033
}
3134

@@ -43,3 +46,24 @@ pub(super) fn highlight_escape_char(stack: &mut Highlights, char: &Char, start:
4346
TextRange::new(start + TextSize::from(1), start + TextSize::from(text.len() as u32 + 1));
4447
stack.add(HlRange { range, highlight: HlTag::EscapeSequence.into(), binding_hash: None })
4548
}
49+
50+
pub(super) fn highlight_escape_byte(stack: &mut Highlights, byte: &Byte, start: TextSize) {
51+
if byte.value().is_none() {
52+
// See `highlight_escape_char` for why no error highlighting here.
53+
return;
54+
}
55+
56+
let text = byte.text();
57+
if !text.starts_with("b'") || !text.ends_with('\'') {
58+
return;
59+
}
60+
61+
let text = &text[2..text.len() - 1];
62+
if !text.starts_with('\\') {
63+
return;
64+
}
65+
66+
let range =
67+
TextRange::new(start + TextSize::from(2), start + TextSize::from(text.len() as u32 + 2));
68+
stack.add(HlRange { range, highlight: HlTag::EscapeSequence.into(), binding_hash: None })
69+
}

crates/ide/src/syntax_highlighting/html.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
109109
.control { font-style: italic; }
110110
.reference { font-style: italic; font-weight: bold; }
111111
112-
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
112+
.invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
113+
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
113114
</style>
114115
";

crates/ide/src/syntax_highlighting/tags.rs

+2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ pub enum HlTag {
2929
Comment,
3030
EscapeSequence,
3131
FormatSpecifier,
32+
InvalidEscapeSequence,
3233
Keyword,
3334
NumericLiteral,
3435
Operator(HlOperator),
@@ -166,6 +167,7 @@ impl HlTag {
166167
HlTag::CharLiteral => "char_literal",
167168
HlTag::Comment => "comment",
168169
HlTag::EscapeSequence => "escape_sequence",
170+
HlTag::InvalidEscapeSequence => "invalid_escape_sequence",
169171
HlTag::FormatSpecifier => "format_specifier",
170172
HlTag::Keyword => "keyword",
171173
HlTag::Punctuation(punct) => match punct {

crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html

+2-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@
4040
.control { font-style: italic; }
4141
.reference { font-style: italic; font-weight: bold; }
4242

43-
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
43+
.invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
44+
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
4445
</style>
4546
<pre><code><span class="keyword">fn</span> <span class="function declaration">not_static</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
4647

crates/ide/src/syntax_highlighting/test_data/highlight_attributes.html

+2-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@
4040
.control { font-style: italic; }
4141
.reference { font-style: italic; font-weight: bold; }
4242

43-
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
43+
.invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
44+
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
4445
</style>
4546
<pre><code><span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute library">allow</span><span class="parenthesis attribute">(</span><span class="none attribute">dead_code</span><span class="parenthesis attribute">)</span><span class="attribute_bracket attribute">]</span>
4647
<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="tool_module attribute library">rustfmt</span><span class="operator attribute">::</span><span class="tool_module attribute library">skip</span><span class="attribute_bracket attribute">]</span>

crates/ide/src/syntax_highlighting/test_data/highlight_crate_root.html

+2-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@
4040
.control { font-style: italic; }
4141
.reference { font-style: italic; font-weight: bold; }
4242

43-
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
43+
.invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
44+
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
4445
</style>
4546
<pre><code><span class="keyword">extern</span> <span class="keyword">crate</span> <span class="module crate_root library">foo</span><span class="semicolon">;</span>
4647
<span class="keyword">use</span> <span class="module crate_root default_library library">core</span><span class="operator">::</span><span class="module default_library library">iter</span><span class="semicolon">;</span>

crates/ide/src/syntax_highlighting/test_data/highlight_default_library.html

+2-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@
4040
.control { font-style: italic; }
4141
.reference { font-style: italic; font-weight: bold; }
4242

43-
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
43+
.invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
44+
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
4445
</style>
4546
<pre><code><span class="keyword">use</span> <span class="module crate_root default_library library">core</span><span class="operator">::</span><span class="module default_library library">iter</span><span class="semicolon">;</span>
4647

crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html

+2-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@
4040
.control { font-style: italic; }
4141
.reference { font-style: italic; font-weight: bold; }
4242

43-
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
43+
.invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
44+
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
4445
</style>
4546
<pre><code><span class="comment documentation">//! This is a module to test doc injection.</span>
4647
<span class="comment documentation">//! ```</span>

crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html

+2-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@
4040
.control { font-style: italic; }
4141
.reference { font-style: italic; font-weight: bold; }
4242

43-
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
43+
.invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
44+
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
4445
</style>
4546
<pre><code><span class="keyword">extern</span> <span class="keyword">crate</span> <span class="module crate_root default_library library">std</span><span class="semicolon">;</span>
4647
<span class="keyword">extern</span> <span class="keyword">crate</span> <span class="module crate_root default_library library">alloc</span> <span class="keyword">as</span> <span class="module crate_root default_library declaration library">abc</span><span class="semicolon">;</span>

crates/ide/src/syntax_highlighting/test_data/highlight_general.html

+2-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@
4040
.control { font-style: italic; }
4141
.reference { font-style: italic; font-weight: bold; }
4242

43-
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
43+
.invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
44+
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
4445
</style>
4546
<pre><code><span class="keyword">use</span> <span class="module">inner</span><span class="operator">::</span><span class="brace">{</span><span class="self_keyword">self</span> <span class="keyword">as</span> <span class="module declaration">inner_mod</span><span class="brace">}</span><span class="semicolon">;</span>
4647
<span class="keyword">mod</span> <span class="module declaration">inner</span> <span class="brace">{</span><span class="brace">}</span>

crates/ide/src/syntax_highlighting/test_data/highlight_injection.html

+2-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@
4040
.control { font-style: italic; }
4141
.reference { font-style: italic; font-weight: bold; }
4242

43-
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
43+
.invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
44+
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
4445
</style>
4546
<pre><code><span class="keyword">fn</span> <span class="function declaration">fixture</span><span class="parenthesis">(</span><span class="value_param declaration reference">ra_fixture</span><span class="colon">:</span> <span class="punctuation">&</span><span class="builtin_type">str</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
4647

crates/ide/src/syntax_highlighting/test_data/highlight_keywords.html

+2-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@
4040
.control { font-style: italic; }
4141
.reference { font-style: italic; font-weight: bold; }
4242

43-
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
43+
.invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
44+
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
4445
</style>
4546
<pre><code><span class="keyword">extern</span> <span class="keyword">crate</span> <span class="self_keyword crate_root public">self</span><span class="semicolon">;</span>
4647

crates/ide/src/syntax_highlighting/test_data/highlight_lifetimes.html

+2-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@
4040
.control { font-style: italic; }
4141
.reference { font-style: italic; font-weight: bold; }
4242

43-
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
43+
.invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
44+
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
4445
</style>
4546
<pre><code>
4647
<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="attribute attribute default_library library">derive</span><span class="parenthesis attribute">(</span><span class="parenthesis attribute">)</span><span class="attribute_bracket attribute">]</span>

crates/ide/src/syntax_highlighting/test_data/highlight_macros.html

+2-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@
4040
.control { font-style: italic; }
4141
.reference { font-style: italic; font-weight: bold; }
4242

43-
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
43+
.invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
44+
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
4445
</style>
4546
<pre><code><span class="module crate_root library">proc_macros</span><span class="operator">::</span><span class="macro library">mirror</span><span class="macro_bang">!</span> <span class="brace macro">{</span>
4647
<span class="brace macro">{</span>

crates/ide/src/syntax_highlighting/test_data/highlight_module_docs_inline.html

+2-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@
4040
.control { font-style: italic; }
4141
.reference { font-style: italic; font-weight: bold; }
4242

43-
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
43+
.invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
44+
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
4445
</style>
4546
<pre><code><span class="comment documentation">//! </span><span class="struct documentation injected intra_doc_link">[Struct]</span>
4647
<span class="comment documentation">//! This is an intra doc injection test for modules</span>

crates/ide/src/syntax_highlighting/test_data/highlight_module_docs_outline.html

+2-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@
4040
.control { font-style: italic; }
4141
.reference { font-style: italic; font-weight: bold; }
4242

43-
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
43+
.invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
44+
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
4445
</style>
4546
<pre><code><span class="comment documentation">/// </span><span class="struct documentation injected intra_doc_link">[crate::foo::Struct]</span>
4647
<span class="comment documentation">/// This is an intra doc injection test for modules</span>

crates/ide/src/syntax_highlighting/test_data/highlight_operators.html

+2-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@
4040
.control { font-style: italic; }
4141
.reference { font-style: italic; font-weight: bold; }
4242

43-
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
43+
.invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
44+
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
4445
</style>
4546
<pre><code><span class="keyword">fn</span> <span class="function declaration">main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
4647
<span class="numeric_literal">1</span> <span class="arithmetic">+</span> <span class="numeric_literal">1</span> <span class="arithmetic">-</span> <span class="numeric_literal">1</span> <span class="arithmetic">*</span> <span class="numeric_literal">1</span> <span class="arithmetic">/</span> <span class="numeric_literal">1</span> <span class="arithmetic">%</span> <span class="numeric_literal">1</span> <span class="bitwise">|</span> <span class="numeric_literal">1</span> <span class="bitwise">&</span> <span class="numeric_literal">1</span> <span class="logical">!</span> <span class="numeric_literal">1</span> <span class="bitwise">^</span> <span class="numeric_literal">1</span> <span class="bitwise">&gt;&gt;</span> <span class="numeric_literal">1</span> <span class="bitwise">&lt;&lt;</span> <span class="numeric_literal">1</span><span class="semicolon">;</span>

crates/ide/src/syntax_highlighting/test_data/highlight_rainbow.html

+2-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@
4040
.control { font-style: italic; }
4141
.reference { font-style: italic; font-weight: bold; }
4242

43-
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
43+
.invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
44+
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
4445
</style>
4546
<pre><code><span class="keyword">fn</span> <span class="function declaration">main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
4647
<span class="keyword">let</span> <span class="variable declaration reference" data-binding-hash="8121853618659664005" style="color: hsl(273,88%,88%);">hello</span> <span class="operator">=</span> <span class="string_literal">"hello"</span><span class="semicolon">;</span>

0 commit comments

Comments
 (0)