From 6437295b173a17361fdca1a45d2f9e7547cbc99f Mon Sep 17 00:00:00 2001 From: "Zack M. Davis" Date: Sun, 15 Apr 2018 14:30:23 -0700 Subject: [PATCH 1/2] in which we check for confusable Unicodepoints in float literal exponent The `FatalError.raise()` might seem unmotivated (in most places in the compiler, `err.emit()` suffices), but it's actually used to maintain behavior (viz., stop lexing, don't emit potentially spurious errors looking for the next token after the bad Unicodepoint in the exponent): the previous revision's `self.err_span_` ultimately calls `Handler::emit`, which aborts if the `Handler`'s continue_after_error flag is set, which seems to typically be true during lexing (see `phase_1_parse_input` and and how `CompileController::basic` has `continue_parse_after_error: false` in librustc_driver). Also, let's avoid apostrophes in error messages (the present author would argue that users expect a reassuringly detached, formal, above-it-all tone from a Serious tool like a compiler), and use an RLS-friendly structured suggestion. Resolves #49746. --- src/libsyntax/parse/lexer/mod.rs | 13 ++++++++++--- src/libsyntax/parse/lexer/unicode_chars.rs | 4 ++-- ...746-unicode-confusable-in-float-literal-expt.rs | 14 ++++++++++++++ ...unicode-confusable-in-float-literal-expt.stderr | 12 ++++++++++++ 4 files changed, 38 insertions(+), 5 deletions(-) create mode 100644 src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.rs create mode 100644 src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index a9dd234e1adc8..50a398d8c63ca 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -1075,9 +1075,16 @@ impl<'a> StringReader<'a> { self.bump(); } if self.scan_digits(10, 10) == 0 { - self.err_span_(self.pos, - self.next_pos, - "expected at least one digit in exponent") + let mut err = self.struct_span_fatal( + self.pos, self.next_pos, + "expected at least one digit in exponent" + ); + if let Some(ch) = self.ch { + // check for e.g. Unicode minus '−' (Issue #49746) + unicode_chars::check_for_substitution(self, ch, &mut err); + } + err.emit(); + FatalError.raise(); } } } diff --git a/src/libsyntax/parse/lexer/unicode_chars.rs b/src/libsyntax/parse/lexer/unicode_chars.rs index 35afe8dd56d93..3c0bb82212fd0 100644 --- a/src/libsyntax/parse/lexer/unicode_chars.rs +++ b/src/libsyntax/parse/lexer/unicode_chars.rs @@ -344,9 +344,9 @@ pub fn check_for_substitution<'a>(reader: &StringReader<'a>, match ASCII_ARRAY.iter().find(|&&(c, _)| c == ascii_char) { Some(&(ascii_char, ascii_name)) => { let msg = - format!("unicode character '{}' ({}) looks like '{}' ({}), but it's not", + format!("Unicode character '{}' ({}) looks like '{}' ({}), but it is not", ch, u_name, ascii_char, ascii_name); - err.span_help(span, &msg); + err.span_suggestion(span, &msg, ascii_char.to_string()); }, None => { let msg = format!("substitution character not found for '{}'", ch); diff --git a/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.rs b/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.rs new file mode 100644 index 0000000000000..a588616772c33 --- /dev/null +++ b/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.rs @@ -0,0 +1,14 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +const UNIVERSAL_GRAVITATIONAL_CONSTANT = 6.674e−11; // m³⋅kg⁻¹⋅s⁻² +//~^ ERROR expected at least one digit in exponent + +fn main() {} diff --git a/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr b/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr new file mode 100644 index 0000000000000..78eddd946bb32 --- /dev/null +++ b/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr @@ -0,0 +1,12 @@ +error: expected at least one digit in exponent + --> $DIR/issue-49746-unicode-confusable-in-float-literal-expt.rs:11:48 + | +LL | const UNIVERSAL_GRAVITATIONAL_CONSTANT = 6.674e−11; // m³⋅kg⁻¹⋅s⁻² + | ^ +help: Unicode character '−' (Minus Sign) looks like '-' (Minus/Hyphen), but it is not + | +LL | const UNIVERSAL_GRAVITATIONAL_CONSTANT = 6.674e-11; // m³⋅kg⁻¹⋅s⁻² + | ^ + +error: aborting due to previous error + From 7dec8a4e99ee10696a3b1e61bfa5918683c49437 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 25 May 2018 21:57:02 -0700 Subject: [PATCH 2/2] Fix test --- src/libsyntax/parse/lexer/mod.rs | 6 ++++-- src/libsyntax/parse/lexer/unicode_chars.rs | 6 ++++-- src/test/parse-fail/unicode-chars.rs | 2 +- ...e-49746-unicode-confusable-in-float-literal-expt.rs | 2 +- ...746-unicode-confusable-in-float-literal-expt.stderr | 10 +++++----- 5 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 50a398d8c63ca..c39eb1594b28b 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -1081,10 +1081,12 @@ impl<'a> StringReader<'a> { ); if let Some(ch) = self.ch { // check for e.g. Unicode minus '−' (Issue #49746) - unicode_chars::check_for_substitution(self, ch, &mut err); + if unicode_chars::check_for_substitution(self, ch, &mut err) { + self.bump(); + self.scan_digits(10, 10); + } } err.emit(); - FatalError.raise(); } } } diff --git a/src/libsyntax/parse/lexer/unicode_chars.rs b/src/libsyntax/parse/lexer/unicode_chars.rs index 3c0bb82212fd0..c5c2e02523302 100644 --- a/src/libsyntax/parse/lexer/unicode_chars.rs +++ b/src/libsyntax/parse/lexer/unicode_chars.rs @@ -335,7 +335,7 @@ const ASCII_ARRAY: &'static [(char, &'static str)] = &[ pub fn check_for_substitution<'a>(reader: &StringReader<'a>, ch: char, - err: &mut DiagnosticBuilder<'a>) { + err: &mut DiagnosticBuilder<'a>) -> bool { UNICODE_ARRAY .iter() .find(|&&(c, _, _)| c == ch) @@ -347,11 +347,13 @@ pub fn check_for_substitution<'a>(reader: &StringReader<'a>, format!("Unicode character '{}' ({}) looks like '{}' ({}), but it is not", ch, u_name, ascii_char, ascii_name); err.span_suggestion(span, &msg, ascii_char.to_string()); + true }, None => { let msg = format!("substitution character not found for '{}'", ch); reader.sess.span_diagnostic.span_bug_no_panic(span, &msg); + false } } - }); + }).unwrap_or(false) } diff --git a/src/test/parse-fail/unicode-chars.rs b/src/test/parse-fail/unicode-chars.rs index 1bdeb121a55d5..f590a7f2aa2eb 100644 --- a/src/test/parse-fail/unicode-chars.rs +++ b/src/test/parse-fail/unicode-chars.rs @@ -13,5 +13,5 @@ fn main() { let y = 0; //~^ ERROR unknown start of token: \u{37e} - //~^^ HELP unicode character ';' (Greek Question Mark) looks like ';' (Semicolon), but it's not + //~^^ HELP Unicode character ';' (Greek Question Mark) looks like ';' (Semicolon), but it is not } diff --git a/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.rs b/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.rs index a588616772c33..9daf9df695548 100644 --- a/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.rs +++ b/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -const UNIVERSAL_GRAVITATIONAL_CONSTANT = 6.674e−11; // m³⋅kg⁻¹⋅s⁻² +const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e−11; // m³⋅kg⁻¹⋅s⁻² //~^ ERROR expected at least one digit in exponent fn main() {} diff --git a/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr b/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr index 78eddd946bb32..b387472e0e749 100644 --- a/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr +++ b/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr @@ -1,12 +1,12 @@ error: expected at least one digit in exponent - --> $DIR/issue-49746-unicode-confusable-in-float-literal-expt.rs:11:48 + --> $DIR/issue-49746-unicode-confusable-in-float-literal-expt.rs:11:53 | -LL | const UNIVERSAL_GRAVITATIONAL_CONSTANT = 6.674e−11; // m³⋅kg⁻¹⋅s⁻² - | ^ +LL | const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e−11; // m³⋅kg⁻¹⋅s⁻² + | ^ help: Unicode character '−' (Minus Sign) looks like '-' (Minus/Hyphen), but it is not | -LL | const UNIVERSAL_GRAVITATIONAL_CONSTANT = 6.674e-11; // m³⋅kg⁻¹⋅s⁻² - | ^ +LL | const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e-11; // m³⋅kg⁻¹⋅s⁻² + | ^ error: aborting due to previous error