Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
5d59b441
R
Rust
项目概览
int
/
Rust
大约 1 年 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
5d59b441
编写于
7月 30, 2021
作者:
A
Anton Golov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add warning when whitespace is not skipped after an escaped newline.
上级
1195bea5
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
75 addition
and
8 deletion
+75
-8
compiler/rustc_ast/src/util/literal.rs
compiler/rustc_ast/src/util/literal.rs
+20
-4
compiler/rustc_lexer/src/unescape.rs
compiler/rustc_lexer/src/unescape.rs
+30
-4
compiler/rustc_lexer/src/unescape/tests.rs
compiler/rustc_lexer/src/unescape/tests.rs
+19
-0
compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
+6
-0
未找到文件。
compiler/rustc_ast/src/util/literal.rs
浏览文件 @
5d59b441
...
...
@@ -63,7 +63,11 @@ fn from_lit_token(lit: token::Lit) -> Result<LitKind, LitError> {
unescape_literal
(
&
s
,
Mode
::
Str
,
&
mut
|
_
,
unescaped_char
|
{
match
unescaped_char
{
Ok
(
c
)
=>
buf
.push
(
c
),
Err
(
_
)
=>
error
=
Err
(
LitError
::
LexerError
),
Err
(
err
)
=>
{
if
err
.is_fatal
()
{
error
=
Err
(
LitError
::
LexerError
);
}
}
}
});
error
?
;
...
...
@@ -83,7 +87,11 @@ fn from_lit_token(lit: token::Lit) -> Result<LitKind, LitError> {
unescape_literal
(
&
s
,
Mode
::
RawStr
,
&
mut
|
_
,
unescaped_char
|
{
match
unescaped_char
{
Ok
(
c
)
=>
buf
.push
(
c
),
Err
(
_
)
=>
error
=
Err
(
LitError
::
LexerError
),
Err
(
err
)
=>
{
if
err
.is_fatal
()
{
error
=
Err
(
LitError
::
LexerError
);
}
}
}
});
error
?
;
...
...
@@ -100,7 +108,11 @@ fn from_lit_token(lit: token::Lit) -> Result<LitKind, LitError> {
unescape_byte_literal
(
&
s
,
Mode
::
ByteStr
,
&
mut
|
_
,
unescaped_byte
|
{
match
unescaped_byte
{
Ok
(
c
)
=>
buf
.push
(
c
),
Err
(
_
)
=>
error
=
Err
(
LitError
::
LexerError
),
Err
(
err
)
=>
{
if
err
.is_fatal
()
{
error
=
Err
(
LitError
::
LexerError
);
}
}
}
});
error
?
;
...
...
@@ -114,7 +126,11 @@ fn from_lit_token(lit: token::Lit) -> Result<LitKind, LitError> {
unescape_byte_literal
(
&
s
,
Mode
::
RawByteStr
,
&
mut
|
_
,
unescaped_byte
|
{
match
unescaped_byte
{
Ok
(
c
)
=>
buf
.push
(
c
),
Err
(
_
)
=>
error
=
Err
(
LitError
::
LexerError
),
Err
(
err
)
=>
{
if
err
.is_fatal
()
{
error
=
Err
(
LitError
::
LexerError
);
}
}
}
});
error
?
;
...
...
compiler/rustc_lexer/src/unescape.rs
浏览文件 @
5d59b441
...
...
@@ -7,7 +7,7 @@
#[cfg(test)]
mod
tests
;
/// Errors that can occur during string unescaping.
/// Errors
and warnings
that can occur during string unescaping.
#[derive(Debug,
PartialEq,
Eq)]
pub
enum
EscapeError
{
/// Expected 1 char, but 0 were found.
...
...
@@ -56,6 +56,20 @@ pub enum EscapeError {
NonAsciiCharInByte
,
/// Non-ascii character in byte string literal.
NonAsciiCharInByteString
,
/// After a line ending with '\', the next line contains whitespace
/// characters that are not skipped.
UnskippedWhitespaceWarning
,
}
impl
EscapeError
{
/// Returns true for actual errors, as opposed to warnings.
pub
fn
is_fatal
(
&
self
)
->
bool
{
match
self
{
EscapeError
::
UnskippedWhitespaceWarning
=>
false
,
_
=>
true
,
}
}
}
/// Takes a contents of a literal (without quotes) and produces a
...
...
@@ -283,7 +297,7 @@ fn unescape_str_or_byte_str<F>(src: &str, mode: Mode, callback: &mut F)
// if unescaped '\' character is followed by '\n'.
// For details see [Rust language reference]
// (https://doc.rust-lang.org/reference/tokens.html#string-literals).
skip_ascii_whitespace
(
&
mut
chars
);
skip_ascii_whitespace
(
&
mut
chars
,
start
,
callback
);
continue
;
}
_
=>
scan_escape
(
first_char
,
&
mut
chars
,
mode
),
...
...
@@ -297,13 +311,25 @@ fn unescape_str_or_byte_str<F>(src: &str, mode: Mode, callback: &mut F)
callback
(
start
..
end
,
unescaped_char
);
}
fn
skip_ascii_whitespace
(
chars
:
&
mut
Chars
<
'_
>
)
{
fn
skip_ascii_whitespace
<
F
>
(
chars
:
&
mut
Chars
<
'_
>
,
start
:
usize
,
callback
:
&
mut
F
)
where
F
:
FnMut
(
Range
<
usize
>
,
Result
<
char
,
EscapeError
>
),
{
let
str
=
chars
.as_str
();
let
first_non_space
=
str
.bytes
()
.position
(|
b
|
b
!=
b
' '
&&
b
!=
b
'\t'
&&
b
!=
b
'\n'
&&
b
!=
b
'\r'
)
.unwrap_or
(
str
.len
());
*
chars
=
str
[
first_non_space
..
]
.chars
()
let
tail
=
&
str
[
first_non_space
..
];
if
let
Some
(
c
)
=
tail
.chars
()
.nth
(
0
)
{
// For error reporting, we would like the span to contain the character that was not
// skipped. The +1 is necessary to account for the leading \ that started the escape.
let
end
=
start
+
first_non_space
+
c
.len_utf8
()
+
1
;
if
c
.is_whitespace
()
{
callback
(
start
..
end
,
Err
(
EscapeError
::
UnskippedWhitespaceWarning
));
}
}
*
chars
=
tail
.chars
();
}
}
...
...
compiler/rustc_lexer/src/unescape/tests.rs
浏览文件 @
5d59b441
...
...
@@ -98,6 +98,25 @@ fn check(literal_text: &str, expected_char: char) {
check
(
r"\u{1F63b}"
,
'😻'
);
}
#[test]
fn
test_unescape_str_warn
()
{
fn
check
(
literal
:
&
str
,
expected
:
&
[(
Range
<
usize
>
,
Result
<
char
,
EscapeError
>
)])
{
let
mut
unescaped
=
Vec
::
with_capacity
(
literal
.len
());
unescape_literal
(
literal
,
Mode
::
Str
,
&
mut
|
range
,
res
|
unescaped
.push
((
range
,
res
)));
assert_eq!
(
unescaped
,
expected
);
}
check
(
"
\\\n
\
u{a0} x"
,
&
[
(
0
..
5
,
Err
(
EscapeError
::
UnskippedWhitespaceWarning
)),
(
3
..
5
,
Ok
(
'\
u
{
a0
}
'
)),
(
5
..
6
,
Ok
(
' '
)),
(
6
..
7
,
Ok
(
'x'
)),
],
);
}
#[test]
fn
test_unescape_str_good
()
{
fn
check
(
literal_text
:
&
str
,
expected
:
&
str
)
{
...
...
compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
浏览文件 @
5d59b441
...
...
@@ -253,6 +253,12 @@ pub(crate) fn emit_unescape_error(
let
msg
=
"invalid trailing slash in literal"
;
handler
.struct_span_err
(
span
,
msg
)
.span_label
(
span
,
msg
)
.emit
();
}
EscapeError
::
UnskippedWhitespaceWarning
=>
{
let
(
c
,
char_span
)
=
last_char
();
let
msg
=
format!
(
"non-ASCII whitespace symbol '{}' is not skipped"
,
c
.escape_unicode
());
handler
.struct_span_warn
(
span
,
&
msg
)
.span_label
(
char_span
,
&
msg
)
.emit
();
}
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录