Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit d7f039e

Browse files
authoredMay 30, 2025··
Unrolled build for #141004
Rollup merge of #141004 - matthewjasper:unicode-before-expansion, r=davidtwco Report text_direction_codepoint_in_literal when parsing The lint is now reported in code that gets removed/modified/duplicated by macro expansion, and spans are more accurate so we don't get ICEs from trying to split a span in the middle of a character. This removes support for lint level attributes for `text_direction_codepoint_in_literal` except at the crate level, I don't think that there's an easy way around this when the lint can be reported on code that's removed by `cfg` or that is only in the input of a macro. Fixes #140281
2 parents 1c0849d + f652067 commit d7f039e

File tree

15 files changed

+311
-180
lines changed

15 files changed

+311
-180
lines changed
 

‎Cargo.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2171,6 +2171,7 @@ dependencies = [
21712171
name = "lint-docs"
21722172
version = "0.1.0"
21732173
dependencies = [
2174+
"rustc-literal-escaper",
21742175
"serde_json",
21752176
"tempfile",
21762177
"walkdir",

‎compiler/rustc_lint/src/early/diagnostics.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,27 @@ pub fn decorate_builtin_lint(
187187
lints::ReservedMultihash { suggestion }.decorate_lint(diag);
188188
}
189189
}
190+
BuiltinLintDiag::HiddenUnicodeCodepoints {
191+
label,
192+
count,
193+
span_label,
194+
labels,
195+
escape,
196+
spans,
197+
} => {
198+
lints::HiddenUnicodeCodepointsDiag {
199+
label: &label,
200+
count,
201+
span_label,
202+
labels: labels.map(|spans| lints::HiddenUnicodeCodepointsDiagLabels { spans }),
203+
sub: if escape {
204+
lints::HiddenUnicodeCodepointsDiagSub::Escape { spans }
205+
} else {
206+
lints::HiddenUnicodeCodepointsDiagSub::NoEscape { spans }
207+
},
208+
}
209+
.decorate_lint(diag);
210+
}
190211
BuiltinLintDiag::UnusedBuiltinAttribute { attr_name, macro_name, invoc_span } => {
191212
lints::UnusedBuiltinAttribute { invoc_span, attr_name, macro_name }.decorate_lint(diag);
192213
}

‎compiler/rustc_lint/src/hidden_unicode_codepoints.rs

Lines changed: 0 additions & 136 deletions
This file was deleted.

‎compiler/rustc_lint/src/lib.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ mod errors;
4848
mod expect;
4949
mod for_loops_over_fallibles;
5050
mod foreign_modules;
51-
pub mod hidden_unicode_codepoints;
5251
mod if_let_rescope;
5352
mod impl_trait_overcaptures;
5453
mod internal;
@@ -92,7 +91,6 @@ use deref_into_dyn_supertrait::*;
9291
use drop_forget_useless::*;
9392
use enum_intrinsics_non_enums::EnumIntrinsicsNonEnums;
9493
use for_loops_over_fallibles::*;
95-
use hidden_unicode_codepoints::*;
9694
use if_let_rescope::IfLetRescope;
9795
use impl_trait_overcaptures::ImplTraitOvercaptures;
9896
use internal::*;
@@ -177,7 +175,6 @@ early_lint_methods!(
177175
DeprecatedAttr: DeprecatedAttr::default(),
178176
WhileTrue: WhileTrue,
179177
NonAsciiIdents: NonAsciiIdents,
180-
HiddenUnicodeCodepoints: HiddenUnicodeCodepoints,
181178
IncompleteInternalFeatures: IncompleteInternalFeatures,
182179
RedundantSemicolons: RedundantSemicolons,
183180
UnusedDocComment: UnusedDocComment,

‎compiler/rustc_lint_defs/src/builtin.rs

Lines changed: 39 additions & 3 deletions
This file contains bidirectional or hidden Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ declare_lint_pass! {
103103
TAIL_EXPR_DROP_ORDER,
104104
TEST_UNSTABLE_LINT,
105105
TEXT_DIRECTION_CODEPOINT_IN_COMMENT,
106+
TEXT_DIRECTION_CODEPOINT_IN_LITERAL,
106107
TRIVIAL_CASTS,
107108
TRIVIAL_NUMERIC_CASTS,
108109
TYVAR_BEHIND_RAW_POINTER,
@@ -3782,7 +3783,6 @@ declare_lint! {
37823783
}
37833784

37843785
declare_lint! {
3785-
#[allow(text_direction_codepoint_in_literal)]
37863786
/// The `text_direction_codepoint_in_comment` lint detects Unicode codepoints in comments that
37873787
/// change the visual representation of text on screen in a way that does not correspond to
37883788
/// their on memory representation.
@@ -3792,7 +3792,7 @@ declare_lint! {
37923792
/// ```rust,compile_fail
37933793
/// #![deny(text_direction_codepoint_in_comment)]
37943794
/// fn main() {
3795-
/// println!("{:?}"); // '');
3795+
#[doc = " println!(\"{:?}\"); // '\u{202E}');"]
37963796
/// }
37973797
/// ```
37983798
///
@@ -3807,7 +3807,43 @@ declare_lint! {
38073807
/// their use.
38083808
pub TEXT_DIRECTION_CODEPOINT_IN_COMMENT,
38093809
Deny,
3810-
"invisible directionality-changing codepoints in comment"
3810+
"invisible directionality-changing codepoints in comment",
3811+
crate_level_only
3812+
}
3813+
3814+
declare_lint! {
3815+
/// The `text_direction_codepoint_in_literal` lint detects Unicode codepoints that change the
3816+
/// visual representation of text on screen in a way that does not correspond to their on
3817+
/// memory representation.
3818+
///
3819+
/// ### Explanation
3820+
///
3821+
/// The unicode characters `\u{202A}`, `\u{202B}`, `\u{202D}`, `\u{202E}`, `\u{2066}`,
3822+
/// `\u{2067}`, `\u{2068}`, `\u{202C}` and `\u{2069}` make the flow of text on screen change
3823+
/// its direction on software that supports these codepoints. This makes the text "abc" display
3824+
/// as "cba" on screen. By leveraging software that supports these, people can write specially
3825+
/// crafted literals that make the surrounding code seem like it's performing one action, when
3826+
/// in reality it is performing another. Because of this, we proactively lint against their
3827+
/// presence to avoid surprises.
3828+
///
3829+
/// ### Example
3830+
///
3831+
/// ```rust,compile_fail
3832+
/// #![deny(text_direction_codepoint_in_literal)]
3833+
/// fn main() {
3834+
// ` - convince tidy that backticks match
3835+
#[doc = " println!(\"{:?}\", '\u{202E}');"]
3836+
// `
3837+
/// }
3838+
/// ```
3839+
///
3840+
/// {{produces}}
3841+
///
3842+
pub TEXT_DIRECTION_CODEPOINT_IN_LITERAL,
3843+
Deny,
3844+
"detect special Unicode codepoints that affect the visual representation of text on screen, \
3845+
changing the direction in which text flows",
3846+
crate_level_only
38113847
}
38123848

38133849
declare_lint! {

‎compiler/rustc_lint_defs/src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,14 @@ pub enum BuiltinLintDiag {
698698
is_string: bool,
699699
suggestion: Span,
700700
},
701+
HiddenUnicodeCodepoints {
702+
label: String,
703+
count: usize,
704+
span_label: Span,
705+
labels: Option<Vec<(char, Span)>>,
706+
escape: bool,
707+
spans: Vec<(char, Span)>,
708+
},
701709
TrailingMacro(bool, Ident),
702710
BreakWithLabelAndLoop(Span),
703711
UnicodeTextFlow(Span, String),

‎compiler/rustc_parse/src/lexer/mod.rs

Lines changed: 87 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use diagnostics::make_unclosed_delims_error;
44
use rustc_ast::ast::{self, AttrStyle};
55
use rustc_ast::token::{self, CommentKind, Delimiter, IdentIsRaw, Token, TokenKind};
66
use rustc_ast::tokenstream::TokenStream;
7-
use rustc_ast::util::unicode::contains_text_flow_control_chars;
7+
use rustc_ast::util::unicode::{TEXT_FLOW_CONTROL_CHARS, contains_text_flow_control_chars};
88
use rustc_errors::codes::*;
99
use rustc_errors::{Applicability, Diag, DiagCtxtHandle, StashKey};
1010
use rustc_lexer::{
@@ -14,7 +14,7 @@ use rustc_literal_escaper::{EscapeError, Mode, unescape_mixed, unescape_unicode}
1414
use rustc_session::lint::BuiltinLintDiag;
1515
use rustc_session::lint::builtin::{
1616
RUST_2021_PREFIXES_INCOMPATIBLE_SYNTAX, RUST_2024_GUARDED_STRING_INCOMPATIBLE_SYNTAX,
17-
TEXT_DIRECTION_CODEPOINT_IN_COMMENT,
17+
TEXT_DIRECTION_CODEPOINT_IN_COMMENT, TEXT_DIRECTION_CODEPOINT_IN_LITERAL,
1818
};
1919
use rustc_session::parse::ParseSess;
2020
use rustc_span::{BytePos, Pos, Span, Symbol, sym};
@@ -174,6 +174,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
174174
// Opening delimiter of the length 3 is not included into the symbol.
175175
let content_start = start + BytePos(3);
176176
let content = self.str_from(content_start);
177+
self.lint_doc_comment_unicode_text_flow(start, content);
177178
self.cook_doc_comment(content_start, content, CommentKind::Line, doc_style)
178179
}
179180
rustc_lexer::TokenKind::BlockComment { doc_style, terminated } => {
@@ -193,6 +194,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
193194
let content_start = start + BytePos(3);
194195
let content_end = self.pos - BytePos(if terminated { 2 } else { 0 });
195196
let content = self.str_from_to(content_start, content_end);
197+
self.lint_doc_comment_unicode_text_flow(start, content);
196198
self.cook_doc_comment(content_start, content, CommentKind::Block, doc_style)
197199
}
198200
rustc_lexer::TokenKind::Frontmatter { has_invalid_preceding_whitespace, invalid_infostring } => {
@@ -287,6 +289,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
287289
} else {
288290
None
289291
};
292+
self.lint_literal_unicode_text_flow(symbol, kind, self.mk_sp(start, self.pos), "literal");
290293
token::Literal(token::Lit { kind, symbol, suffix })
291294
}
292295
rustc_lexer::TokenKind::Lifetime { starts_with_number } => {
@@ -481,6 +484,88 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
481484
}
482485
}
483486

487+
fn lint_doc_comment_unicode_text_flow(&mut self, start: BytePos, content: &str) {
488+
if contains_text_flow_control_chars(content) {
489+
self.report_text_direction_codepoint(
490+
content,
491+
self.mk_sp(start, self.pos),
492+
0,
493+
false,
494+
"doc comment",
495+
);
496+
}
497+
}
498+
499+
fn lint_literal_unicode_text_flow(
500+
&mut self,
501+
text: Symbol,
502+
lit_kind: token::LitKind,
503+
span: Span,
504+
label: &'static str,
505+
) {
506+
if !contains_text_flow_control_chars(text.as_str()) {
507+
return;
508+
}
509+
let (padding, point_at_inner_spans) = match lit_kind {
510+
// account for `"` or `'`
511+
token::LitKind::Str | token::LitKind::Char => (1, true),
512+
// account for `c"`
513+
token::LitKind::CStr => (2, true),
514+
// account for `r###"`
515+
token::LitKind::StrRaw(n) => (n as u32 + 2, true),
516+
// account for `cr###"`
517+
token::LitKind::CStrRaw(n) => (n as u32 + 3, true),
518+
// suppress bad literals.
519+
token::LitKind::Err(_) => return,
520+
// Be conservative just in case new literals do support these.
521+
_ => (0, false),
522+
};
523+
self.report_text_direction_codepoint(
524+
text.as_str(),
525+
span,
526+
padding,
527+
point_at_inner_spans,
528+
label,
529+
);
530+
}
531+
532+
fn report_text_direction_codepoint(
533+
&self,
534+
text: &str,
535+
span: Span,
536+
padding: u32,
537+
point_at_inner_spans: bool,
538+
label: &str,
539+
) {
540+
// Obtain the `Span`s for each of the forbidden chars.
541+
let spans: Vec<_> = text
542+
.char_indices()
543+
.filter_map(|(i, c)| {
544+
TEXT_FLOW_CONTROL_CHARS.contains(&c).then(|| {
545+
let lo = span.lo() + BytePos(i as u32 + padding);
546+
(c, span.with_lo(lo).with_hi(lo + BytePos(c.len_utf8() as u32)))
547+
})
548+
})
549+
.collect();
550+
551+
let count = spans.len();
552+
let labels = point_at_inner_spans.then_some(spans.clone());
553+
554+
self.psess.buffer_lint(
555+
TEXT_DIRECTION_CODEPOINT_IN_LITERAL,
556+
span,
557+
ast::CRATE_NODE_ID,
558+
BuiltinLintDiag::HiddenUnicodeCodepoints {
559+
label: label.to_string(),
560+
count,
561+
span_label: span,
562+
labels,
563+
escape: point_at_inner_spans && !spans.is_empty(),
564+
spans,
565+
},
566+
);
567+
}
568+
484569
fn validate_frontmatter(
485570
&self,
486571
start: BytePos,

‎src/tools/lint-docs/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ description = "A script to extract the lint documentation for the rustc book."
77
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
88

99
[dependencies]
10+
rustc-literal-escaper = "0.0.2"
1011
serde_json = "1.0.57"
1112
tempfile = "3.1.0"
1213
walkdir = "2.3.1"

‎src/tools/lint-docs/src/lib.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::fs;
44
use std::path::{Path, PathBuf};
55
use std::process::Command;
66

7+
use rustc_literal_escaper::{Mode, unescape_unicode};
78
use walkdir::WalkDir;
89

910
mod groups;
@@ -214,6 +215,16 @@ impl<'a> LintExtractor<'a> {
214215
let line = line.trim();
215216
if let Some(text) = line.strip_prefix("/// ") {
216217
doc_lines.push(text.to_string());
218+
} else if let Some(text) = line.strip_prefix("#[doc = \"") {
219+
let escaped = text.strip_suffix("\"]").unwrap();
220+
let mut buf = String::new();
221+
unescape_unicode(escaped, Mode::Str, &mut |_, c| match c {
222+
Ok(c) => buf.push(c),
223+
Err(err) => {
224+
assert!(!err.is_fatal(), "failed to unescape string literal")
225+
}
226+
});
227+
doc_lines.push(buf);
217228
} else if line == "///" {
218229
doc_lines.push("".to_string());
219230
} else if line.starts_with("// ") {

‎tests/crashes/140281.rs

Lines changed: 0 additions & 18 deletions
This file was deleted.
Lines changed: 19 additions & 0 deletions
This file contains bidirectional or hidden Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#![allow(text_direction_codepoint_in_literal)]
2+
3+
extern crate proc_macro;
4+
use proc_macro::*;
5+
6+
#[proc_macro]
7+
pub fn create_rtl_in_string(_: TokenStream) -> TokenStream {
8+
r#""‮test⁦ RTL in string literal""#.parse().unwrap()
9+
}
10+
11+
#[proc_macro]
12+
pub fn forward_stream(s: TokenStream) -> TokenStream {
13+
s
14+
}
15+
16+
#[proc_macro]
17+
pub fn recollect_stream(s: TokenStream) -> TokenStream {
18+
s.into_iter().collect()
19+
}
Lines changed: 49 additions & 0 deletions
This file contains bidirectional or hidden Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Regression test for #140281
2+
//@ edition: 2021
3+
//@ proc-macro: unicode-control.rs
4+
5+
extern crate unicode_control;
6+
use unicode_control::*;
7+
8+
macro_rules! foo {
9+
($x:expr) => {
10+
$x
11+
};
12+
}
13+
14+
macro_rules! empty {
15+
($x:expr) => {};
16+
}
17+
18+
fn main() {
19+
let t = vec![
20+
/// ‮test⁦ RTL in doc in vec
21+
//~^ ERROR unicode codepoint changing visible direction of text present in doc comment
22+
1
23+
];
24+
foo!(
25+
/**
26+
* ‮test⁦ RTL in doc in macro
27+
*/
28+
//~^^^ ERROR unicode codepoint changing visible direction of text present in doc comment
29+
1
30+
);
31+
empty!(
32+
/**
33+
* ‮test⁦ RTL in doc in macro
34+
*/
35+
//~^^^ ERROR unicode codepoint changing visible direction of text present in doc comment
36+
1
37+
);
38+
let x = create_rtl_in_string!(); // OK
39+
forward_stream!(
40+
/// ‮test⁦ RTL in doc in proc macro
41+
//~^ ERROR unicode codepoint changing visible direction of text present in doc comment
42+
mod a {}
43+
);
44+
recollect_stream!(
45+
/// ‮test⁦ RTL in doc in proc macro
46+
//~^ ERROR unicode codepoint changing visible direction of text present in doc comment
47+
mod b {}
48+
);
49+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
error: unicode codepoint changing visible direction of text present in doc comment
2+
--> $DIR/unicode-control-codepoints-macros.rs:20:9
3+
|
4+
LL | /// �test� RTL in doc in vec
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this doc comment contains invisible unicode text flow control codepoints
6+
|
7+
= note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen
8+
= note: if their presence wasn't intentional, you can remove them
9+
= note: if you want to keep them but make them visible in your source code, you can escape them: '\u{202e}', '\u{2066}'
10+
= note: `#[deny(text_direction_codepoint_in_literal)]` on by default
11+
12+
error: unicode codepoint changing visible direction of text present in doc comment
13+
--> $DIR/unicode-control-codepoints-macros.rs:25:9
14+
|
15+
LL | / /**
16+
LL | | * �test� RTL in doc in macro
17+
LL | | */
18+
| |___________^ this doc comment contains invisible unicode text flow control codepoints
19+
|
20+
= note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen
21+
= note: if their presence wasn't intentional, you can remove them
22+
= note: if you want to keep them but make them visible in your source code, you can escape them: '\u{202e}', '\u{2066}'
23+
24+
error: unicode codepoint changing visible direction of text present in doc comment
25+
--> $DIR/unicode-control-codepoints-macros.rs:32:9
26+
|
27+
LL | / /**
28+
LL | | * �test� RTL in doc in macro
29+
LL | | */
30+
| |___________^ this doc comment contains invisible unicode text flow control codepoints
31+
|
32+
= note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen
33+
= note: if their presence wasn't intentional, you can remove them
34+
= note: if you want to keep them but make them visible in your source code, you can escape them: '\u{202e}', '\u{2066}'
35+
36+
error: unicode codepoint changing visible direction of text present in doc comment
37+
--> $DIR/unicode-control-codepoints-macros.rs:40:9
38+
|
39+
LL | /// �test� RTL in doc in proc macro
40+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this doc comment contains invisible unicode text flow control codepoints
41+
|
42+
= note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen
43+
= note: if their presence wasn't intentional, you can remove them
44+
= note: if you want to keep them but make them visible in your source code, you can escape them: '\u{202e}', '\u{2066}'
45+
46+
error: unicode codepoint changing visible direction of text present in doc comment
47+
--> $DIR/unicode-control-codepoints-macros.rs:45:9
48+
|
49+
LL | /// �test� RTL in doc in proc macro
50+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this doc comment contains invisible unicode text flow control codepoints
51+
|
52+
= note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen
53+
= note: if their presence wasn't intentional, you can remove them
54+
= note: if you want to keep them but make them visible in your source code, you can escape them: '\u{202e}', '\u{2066}'
55+
56+
error: aborting due to 5 previous errors
57+

‎tests/ui/parser/unicode-control-codepoints.rs

Lines changed: 1 addition & 1 deletion
This file contains bidirectional or hidden Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ fn main() {
3434
//~^ ERROR unicode codepoint changing visible direction of text present in literal
3535

3636
println!("{{‮}}");
37-
//~^ ERROR unicode codepoint changing visible direction of text present in format string
37+
//~^ ERROR unicode codepoint changing visible direction of text present in literal
3838
}
3939

4040
//"/*‮ } ⁦if isAdmin⁩ ⁦ begin admins only */"

‎tests/ui/parser/unicode-control-codepoints.stderr

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -100,21 +100,6 @@ LL | // if access_level != "us�e�r" { // Check if admin
100100
= note: `#[deny(text_direction_codepoint_in_comment)]` on by default
101101
= help: if their presence wasn't intentional, you can remove them
102102

103-
error: unicode codepoint changing visible direction of text present in comment
104-
--> $DIR/unicode-control-codepoints.rs:40:1
105-
|
106-
LL | //"/*� } �if isAdmin� � begin admins only */"
107-
| ^^^^^-^^^-^^^^^^^^^^-^-^^^^^^^^^^^^^^^^^^^^^^
108-
| | | | | |
109-
| | | | | '\u{2066}'
110-
| | | | '\u{2069}'
111-
| | | '\u{2066}'
112-
| | '\u{202e}'
113-
| this comment contains invisible unicode text flow control codepoints
114-
|
115-
= note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen
116-
= help: if their presence wasn't intentional, you can remove them
117-
118103
error: unicode codepoint changing visible direction of text present in literal
119104
--> $DIR/unicode-control-codepoints.rs:13:22
120105
|
@@ -207,14 +192,14 @@ LL - let _ = cr#"�"#;
207192
LL + let _ = cr#"\u{202e}"#;
208193
|
209194

210-
error: unicode codepoint changing visible direction of text present in format string
195+
error: unicode codepoint changing visible direction of text present in literal
211196
--> $DIR/unicode-control-codepoints.rs:36:14
212197
|
213198
LL | println!("{{�}}");
214199
| ^^^-^^^
215200
| | |
216201
| | '\u{202e}'
217-
| this format string contains an invisible unicode text flow control codepoint
202+
| this literal contains an invisible unicode text flow control codepoint
218203
|
219204
= note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen
220205
= help: if their presence wasn't intentional, you can remove them
@@ -224,6 +209,21 @@ LL - println!("{{�}}");
224209
LL + println!("{{\u{202e}}}");
225210
|
226211

212+
error: unicode codepoint changing visible direction of text present in comment
213+
--> $DIR/unicode-control-codepoints.rs:40:1
214+
|
215+
LL | //"/*� } �if isAdmin� � begin admins only */"
216+
| ^^^^^-^^^-^^^^^^^^^^-^-^^^^^^^^^^^^^^^^^^^^^^
217+
| | | | | |
218+
| | | | | '\u{2066}'
219+
| | | | '\u{2069}'
220+
| | | '\u{2066}'
221+
| | '\u{202e}'
222+
| this comment contains invisible unicode text flow control codepoints
223+
|
224+
= note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen
225+
= help: if their presence wasn't intentional, you can remove them
226+
227227
error: unicode codepoint changing visible direction of text present in doc comment
228228
--> $DIR/unicode-control-codepoints.rs:43:1
229229
|

0 commit comments

Comments
 (0)
Please sign in to comment.