Skip to content

Commit

Permalink
Rollup merge of rust-lang#90861 - 5225225:nonprinting-char, r=davidtwco
Browse files Browse the repository at this point in the history
Print escaped string if char literal has multiple characters, but only one printable character

Fixes rust-lang#90857

I'm not sure about the error message here, it could get rather long and *maybe* using the names of characters would be better? That wouldn't help the length any, though.
  • Loading branch information
matthiaskrgr committed Nov 16, 2021
2 parents 77f42c2 + eee29b0 commit 501daae
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 1 deletion.
27 changes: 27 additions & 0 deletions compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,33 @@ pub(crate) fn emit_unescape_error(
Applicability::MachineApplicable,
);
}
} else {
let printable: Vec<char> = lit
.chars()
.filter(|&x| {
unicode_width::UnicodeWidthChar::width(x).unwrap_or(0) != 0
&& !x.is_whitespace()
})
.collect();

if let [ch] = printable.as_slice() {
has_help = true;

handler.span_note(
span,
&format!(
"there are non-printing characters, the full sequence is `{}`",
lit.escape_default(),
),
);

handler.span_suggestion(
span,
"consider removing the non-printing characters",
ch.to_string(),
Applicability::MaybeIncorrect,
);
}
}

if !has_help {
Expand Down
10 changes: 10 additions & 0 deletions src/test/ui/parser/char/whitespace-character-literal.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// This tests that the error generated when a character literal has multiple
// characters in it contains a note about non-printing characters.

fn main() {
let _hair_space_around = ' x​';
//~^ ERROR: character literal may only contain one codepoint
//~| NOTE: there are non-printing characters, the full sequence is `\u{200a}x\u{200b}`
//~| HELP: consider removing the non-printing characters
//~| SUGGESTION: x
}
16 changes: 16 additions & 0 deletions src/test/ui/parser/char/whitespace-character-literal.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
error: character literal may only contain one codepoint
--> $DIR/whitespace-character-literal.rs:5:30
|
LL | let _hair_space_around = ' x​';
| ^--^
| |
| help: consider removing the non-printing characters: `x`
|
note: there are non-printing characters, the full sequence is `\u{200a}x\u{200b}`
--> $DIR/whitespace-character-literal.rs:5:31
|
LL | let _hair_space_around = ' x​';
| ^^

error: aborting due to previous error

2 changes: 1 addition & 1 deletion src/tools/tidy/src/ui_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const ENTRY_LIMIT: usize = 1000;
// FIXME: The following limits should be reduced eventually.
const ROOT_ENTRY_LIMIT: usize = 1102;
const ISSUES_ENTRY_LIMIT: usize = 2310;
const PARSER_LIMIT: usize = 1004;
const PARSER_LIMIT: usize = 1005;

fn check_entries(path: &Path, bad: &mut bool) {
let dirs = walkdir::WalkDir::new(&path.join("test/ui"))
Expand Down

0 comments on commit 501daae

Please sign in to comment.