]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #90861 - 5225225:nonprinting-char, r=davidtwco
authorMatthias Krüger <matthias.krueger@famsik.de>
Wed, 17 Nov 2021 14:58:02 +0000 (15:58 +0100)
committerGitHub <noreply@github.com>
Wed, 17 Nov 2021 14:58:02 +0000 (15:58 +0100)
Print escaped string if char literal has multiple characters, but only one printable character

Fixes #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.

compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
src/test/ui/parser/char/whitespace-character-literal.rs [new file with mode: 0644]
src/test/ui/parser/char/whitespace-character-literal.stderr [new file with mode: 0644]
src/tools/tidy/src/ui_tests.rs

index 569f186a72766f45aed97f560400a3cc91c5f6e7..7f68112a427ba1be2270c2bf58dfe06b6c09cdc2 100644 (file)
@@ -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 (file)
index 0000000..de5e092
--- /dev/null
@@ -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 (file)
index 0000000..d73de41
--- /dev/null
@@ -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
+
index cc058d538f38886056537c153e0be70e93922001..681b2486d07cc0bc20b54ccf95ac22dc20d7e798 100644 (file)
@@ -9,7 +9,7 @@
 // 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"))