about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_parse/src/lexer/unescape_error_reporting.rs27
-rw-r--r--src/test/ui/parser/char/whitespace-character-literal.rs10
-rw-r--r--src/test/ui/parser/char/whitespace-character-literal.stderr16
-rw-r--r--src/tools/tidy/src/ui_tests.rs2
4 files changed, 54 insertions, 1 deletions
diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
index 569f186a727..7f68112a427 100644
--- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
+++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
@@ -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 {
diff --git a/src/test/ui/parser/char/whitespace-character-literal.rs b/src/test/ui/parser/char/whitespace-character-literal.rs
new file mode 100644
index 00000000000..de5e09204b4
--- /dev/null
+++ b/src/test/ui/parser/char/whitespace-character-literal.rs
@@ -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
+}
diff --git a/src/test/ui/parser/char/whitespace-character-literal.stderr b/src/test/ui/parser/char/whitespace-character-literal.stderr
new file mode 100644
index 00000000000..d73de41a809
--- /dev/null
+++ b/src/test/ui/parser/char/whitespace-character-literal.stderr
@@ -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
+
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index cc058d538f3..681b2486d07 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -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"))