From 91b74237605a6715213ae32b5781431ff6e40019 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 25 Mar 2019 16:11:21 -0700 Subject: [PATCH 1/5] Reject integer suffix when tuple indexing --- src/libsyntax/parse/parser.rs | 95 +++++++++++++++------------ src/test/ui/parser/issue-59418.rs | 9 +++ src/test/ui/parser/issue-59418.stderr | 8 +++ 3 files changed, 69 insertions(+), 43 deletions(-) create mode 100644 src/test/ui/parser/issue-59418.rs create mode 100644 src/test/ui/parser/issue-59418.stderr diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index d7a2170342d7f..efeace4f05ecc 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3196,51 +3196,60 @@ impl<'a> Parser<'a> { // expr.f if self.eat(&token::Dot) { match self.token { - token::Ident(..) => { - e = self.parse_dot_suffix(e, lo)?; - } - token::Literal(token::Integer(name), _) => { - let span = self.span; - self.bump(); - let field = ExprKind::Field(e, Ident::new(name, span)); - e = self.mk_expr(lo.to(span), field, ThinVec::new()); - } - token::Literal(token::Float(n), _suf) => { - self.bump(); - let fstr = n.as_str(); - let mut err = self.diagnostic() - .struct_span_err(self.prev_span, &format!("unexpected token: `{}`", n)); - err.span_label(self.prev_span, "unexpected token"); - if fstr.chars().all(|x| "0123456789.".contains(x)) { - let float = match fstr.parse::().ok() { - Some(f) => f, - None => continue, - }; - let sugg = pprust::to_string(|s| { - use crate::print::pprust::PrintState; - s.popen()?; - s.print_expr(&e)?; - s.s.word( ".")?; - s.print_usize(float.trunc() as usize)?; - s.pclose()?; - s.s.word(".")?; - s.s.word(fstr.splitn(2, ".").last().unwrap().to_string()) - }); - err.span_suggestion( - lo.to(self.prev_span), - "try parenthesizing the first index", - sugg, - Applicability::MachineApplicable - ); + token::Ident(..) => { + e = self.parse_dot_suffix(e, lo)?; } - return Err(err); + token::Literal(token::Integer(name), suffix) => { + let span = self.span; + self.bump(); + let field = ExprKind::Field(e, Ident::new(name, span)); + e = self.mk_expr(lo.to(span), field, ThinVec::new()); - } - _ => { - // FIXME Could factor this out into non_fatal_unexpected or something. - let actual = self.this_token_to_string(); - self.span_err(self.span, &format!("unexpected token: `{}`", actual)); - } + if let Some(suffix) = suffix { + let mut err = self.diagnostic().struct_span_err( + span, + "tuple index with a suffix is invalid", + ); + err.span_label(span, format!("invalid suffix `{}`", suffix)); + err.emit(); + } + } + token::Literal(token::Float(n), _suf) => { + self.bump(); + let fstr = n.as_str(); + let mut err = self.diagnostic() + .struct_span_err(self.prev_span, &format!("unexpected token: `{}`", n)); + err.span_label(self.prev_span, "unexpected token"); + if fstr.chars().all(|x| "0123456789.".contains(x)) { + let float = match fstr.parse::().ok() { + Some(f) => f, + None => continue, + }; + let sugg = pprust::to_string(|s| { + use crate::print::pprust::PrintState; + s.popen()?; + s.print_expr(&e)?; + s.s.word( ".")?; + s.print_usize(float.trunc() as usize)?; + s.pclose()?; + s.s.word(".")?; + s.s.word(fstr.splitn(2, ".").last().unwrap().to_string()) + }); + err.span_suggestion( + lo.to(self.prev_span), + "try parenthesizing the first index", + sugg, + Applicability::MachineApplicable + ); + } + return Err(err); + + } + _ => { + // FIXME Could factor this out into non_fatal_unexpected or something. + let actual = self.this_token_to_string(); + self.span_err(self.span, &format!("unexpected token: `{}`", actual)); + } } continue; } diff --git a/src/test/ui/parser/issue-59418.rs b/src/test/ui/parser/issue-59418.rs new file mode 100644 index 0000000000000..33ad11bb0b011 --- /dev/null +++ b/src/test/ui/parser/issue-59418.rs @@ -0,0 +1,9 @@ +struct X(i32,i32,i32); + +fn main() { + let a = X(1, 2, 3); + let b = a.1suffix; + //~^ ERROR tuple index with a suffix is invalid + println!("{}", b); +} + diff --git a/src/test/ui/parser/issue-59418.stderr b/src/test/ui/parser/issue-59418.stderr new file mode 100644 index 0000000000000..c06b950f60119 --- /dev/null +++ b/src/test/ui/parser/issue-59418.stderr @@ -0,0 +1,8 @@ +error: tuple index with a suffix is invalid + --> $DIR/issue-59418.rs:5:15 + | +LL | let b = a.1suffix; + | ^^^^^^^ invalid suffix `suffix` + +error: aborting due to previous error + From 6ad77b09388224c38b65f5c54125b669b886c7f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 25 Mar 2019 21:38:23 -0700 Subject: [PATCH 2/5] review comments --- src/libsyntax/parse/parser.rs | 2 +- src/test/ui/parser/issue-59418.rs | 6 +++++- src/test/ui/parser/issue-59418.stderr | 10 ++++++++-- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index efeace4f05ecc..38647bec982cc 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3208,7 +3208,7 @@ impl<'a> Parser<'a> { if let Some(suffix) = suffix { let mut err = self.diagnostic().struct_span_err( span, - "tuple index with a suffix is invalid", + "suffixes on tuple indexes are invalid", ); err.span_label(span, format!("invalid suffix `{}`", suffix)); err.emit(); diff --git a/src/test/ui/parser/issue-59418.rs b/src/test/ui/parser/issue-59418.rs index 33ad11bb0b011..cab37e0d80920 100644 --- a/src/test/ui/parser/issue-59418.rs +++ b/src/test/ui/parser/issue-59418.rs @@ -3,7 +3,11 @@ struct X(i32,i32,i32); fn main() { let a = X(1, 2, 3); let b = a.1suffix; - //~^ ERROR tuple index with a suffix is invalid + //~^ ERROR suffixes on tuple indexes are invalid println!("{}", b); + let c = (1, 2, 3); + let d = c.1suffix; + //~^ ERROR suffixes on tuple indexes are invalid + println!("{}", d); } diff --git a/src/test/ui/parser/issue-59418.stderr b/src/test/ui/parser/issue-59418.stderr index c06b950f60119..e50780de4f96b 100644 --- a/src/test/ui/parser/issue-59418.stderr +++ b/src/test/ui/parser/issue-59418.stderr @@ -1,8 +1,14 @@ -error: tuple index with a suffix is invalid +error: suffixes on tuple indexes are invalid --> $DIR/issue-59418.rs:5:15 | LL | let b = a.1suffix; | ^^^^^^^ invalid suffix `suffix` -error: aborting due to previous error +error: suffixes on tuple indexes are invalid + --> $DIR/issue-59418.rs:9:15 + | +LL | let d = c.1suffix; + | ^^^^^^^ invalid suffix `suffix` + +error: aborting due to 2 previous errors From c7ddb83980a89118937c8f9c264183f5abf73339 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 26 Mar 2019 10:18:18 -0700 Subject: [PATCH 3/5] Use `expect_no_suffix` for error --- src/libsyntax/parse/parser.rs | 9 +-------- src/test/ui/parser/issue-59418.rs | 5 ++--- src/test/ui/parser/issue-59418.stderr | 8 ++++---- 3 files changed, 7 insertions(+), 15 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 38647bec982cc..8dacb27063793 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3205,14 +3205,7 @@ impl<'a> Parser<'a> { let field = ExprKind::Field(e, Ident::new(name, span)); e = self.mk_expr(lo.to(span), field, ThinVec::new()); - if let Some(suffix) = suffix { - let mut err = self.diagnostic().struct_span_err( - span, - "suffixes on tuple indexes are invalid", - ); - err.span_label(span, format!("invalid suffix `{}`", suffix)); - err.emit(); - } + self.expect_no_suffix(span, "tuple index", suffix); } token::Literal(token::Float(n), _suf) => { self.bump(); diff --git a/src/test/ui/parser/issue-59418.rs b/src/test/ui/parser/issue-59418.rs index cab37e0d80920..d1afa6af320f0 100644 --- a/src/test/ui/parser/issue-59418.rs +++ b/src/test/ui/parser/issue-59418.rs @@ -3,11 +3,10 @@ struct X(i32,i32,i32); fn main() { let a = X(1, 2, 3); let b = a.1suffix; - //~^ ERROR suffixes on tuple indexes are invalid + //~^ ERROR tuple index with a suffix is invalid println!("{}", b); let c = (1, 2, 3); let d = c.1suffix; - //~^ ERROR suffixes on tuple indexes are invalid + //~^ ERROR tuple index with a suffix is invalid println!("{}", d); } - diff --git a/src/test/ui/parser/issue-59418.stderr b/src/test/ui/parser/issue-59418.stderr index e50780de4f96b..4ca4bd73abc1c 100644 --- a/src/test/ui/parser/issue-59418.stderr +++ b/src/test/ui/parser/issue-59418.stderr @@ -1,14 +1,14 @@ -error: suffixes on tuple indexes are invalid +error: tuple index with a suffix is invalid --> $DIR/issue-59418.rs:5:15 | LL | let b = a.1suffix; - | ^^^^^^^ invalid suffix `suffix` + | ^^^^^^^ tuple index with a suffix is invalid -error: suffixes on tuple indexes are invalid +error: tuple index with a suffix is invalid --> $DIR/issue-59418.rs:9:15 | LL | let d = c.1suffix; - | ^^^^^^^ invalid suffix `suffix` + | ^^^^^^^ tuple index with a suffix is invalid error: aborting due to 2 previous errors From 1bb3694b1a6368f456c2e62cf234a332a21df2a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 26 Mar 2019 12:09:13 -0700 Subject: [PATCH 4/5] Reword invalid suffixe errors --- src/libsyntax/parse/parser.rs | 13 ++++----- src/test/ui/parser/bad-lit-suffixes.rs | 16 +++++------ src/test/ui/parser/bad-lit-suffixes.stderr | 32 +++++++++++----------- src/test/ui/parser/issue-59418.rs | 4 +-- src/test/ui/parser/issue-59418.stderr | 8 +++--- 5 files changed, 36 insertions(+), 37 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 8dacb27063793..bb3dc8edfb001 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1119,9 +1119,8 @@ impl<'a> Parser<'a> { if text.is_empty() { self.span_bug(sp, "found empty literal suffix in Some") } - let msg = format!("{} with a suffix is invalid", kind); - self.struct_span_err(sp, &msg) - .span_label(sp, msg) + self.struct_span_err(sp, &format!("suffixes on {} are invalid", kind)) + .span_label(sp, format!("invalid suffix `{}`", text)) .emit(); } } @@ -2150,7 +2149,7 @@ impl<'a> Parser<'a> { if suffix_illegal { let sp = self.span; - self.expect_no_suffix(sp, lit.literal_name(), suf) + self.expect_no_suffix(sp, &format!("a {}", lit.literal_name()), suf) } result.unwrap() @@ -3205,7 +3204,7 @@ impl<'a> Parser<'a> { let field = ExprKind::Field(e, Ident::new(name, span)); e = self.mk_expr(lo.to(span), field, ThinVec::new()); - self.expect_no_suffix(span, "tuple index", suffix); + self.expect_no_suffix(span, "a tuple index", suffix); } token::Literal(token::Float(n), _suf) => { self.bump(); @@ -7791,7 +7790,7 @@ impl<'a> Parser<'a> { match self.token { token::Literal(token::Str_(s), suf) | token::Literal(token::StrRaw(s, _), suf) => { let sp = self.span; - self.expect_no_suffix(sp, "ABI spec", suf); + self.expect_no_suffix(sp, "an ABI spec", suf); self.bump(); match abi::lookup(&s.as_str()) { Some(abi) => Ok(Some(abi)), @@ -8612,7 +8611,7 @@ impl<'a> Parser<'a> { match self.parse_optional_str() { Some((s, style, suf)) => { let sp = self.prev_span; - self.expect_no_suffix(sp, "string literal", suf); + self.expect_no_suffix(sp, "a string literal", suf); Ok((s, style)) } _ => { diff --git a/src/test/ui/parser/bad-lit-suffixes.rs b/src/test/ui/parser/bad-lit-suffixes.rs index 391e7f0acf979..75bed3088587c 100644 --- a/src/test/ui/parser/bad-lit-suffixes.rs +++ b/src/test/ui/parser/bad-lit-suffixes.rs @@ -2,20 +2,20 @@ extern - "C"suffix //~ ERROR ABI spec with a suffix is invalid + "C"suffix //~ ERROR suffixes on an ABI spec are invalid fn foo() {} extern - "C"suffix //~ ERROR ABI spec with a suffix is invalid + "C"suffix //~ ERROR suffixes on an ABI spec are invalid {} fn main() { - ""suffix; //~ ERROR string literal with a suffix is invalid - b""suffix; //~ ERROR byte string literal with a suffix is invalid - r#""#suffix; //~ ERROR string literal with a suffix is invalid - br#""#suffix; //~ ERROR byte string literal with a suffix is invalid - 'a'suffix; //~ ERROR char literal with a suffix is invalid - b'a'suffix; //~ ERROR byte literal with a suffix is invalid + ""suffix; //~ ERROR suffixes on a string literal are invalid + b""suffix; //~ ERROR suffixes on a byte string literal are invalid + r#""#suffix; //~ ERROR suffixes on a string literal are invalid + br#""#suffix; //~ ERROR suffixes on a byte string literal are invalid + 'a'suffix; //~ ERROR suffixes on a char literal are invalid + b'a'suffix; //~ ERROR suffixes on a byte literal are invalid 1234u1024; //~ ERROR invalid width `1024` for integer literal 1234i1024; //~ ERROR invalid width `1024` for integer literal diff --git a/src/test/ui/parser/bad-lit-suffixes.stderr b/src/test/ui/parser/bad-lit-suffixes.stderr index 3d4d7b4a78b43..de194f4820de0 100644 --- a/src/test/ui/parser/bad-lit-suffixes.stderr +++ b/src/test/ui/parser/bad-lit-suffixes.stderr @@ -1,50 +1,50 @@ -error: ABI spec with a suffix is invalid +error: suffixes on an ABI spec are invalid --> $DIR/bad-lit-suffixes.rs:5:5 | LL | "C"suffix - | ^^^^^^^^^ ABI spec with a suffix is invalid + | ^^^^^^^^^ invalid suffix `suffix` -error: ABI spec with a suffix is invalid +error: suffixes on an ABI spec are invalid --> $DIR/bad-lit-suffixes.rs:9:5 | LL | "C"suffix - | ^^^^^^^^^ ABI spec with a suffix is invalid + | ^^^^^^^^^ invalid suffix `suffix` -error: string literal with a suffix is invalid +error: suffixes on a string literal are invalid --> $DIR/bad-lit-suffixes.rs:13:5 | LL | ""suffix; - | ^^^^^^^^ string literal with a suffix is invalid + | ^^^^^^^^ invalid suffix `suffix` -error: byte string literal with a suffix is invalid +error: suffixes on a byte string literal are invalid --> $DIR/bad-lit-suffixes.rs:14:5 | LL | b""suffix; - | ^^^^^^^^^ byte string literal with a suffix is invalid + | ^^^^^^^^^ invalid suffix `suffix` -error: string literal with a suffix is invalid +error: suffixes on a string literal are invalid --> $DIR/bad-lit-suffixes.rs:15:5 | LL | r#""#suffix; - | ^^^^^^^^^^^ string literal with a suffix is invalid + | ^^^^^^^^^^^ invalid suffix `suffix` -error: byte string literal with a suffix is invalid +error: suffixes on a byte string literal are invalid --> $DIR/bad-lit-suffixes.rs:16:5 | LL | br#""#suffix; - | ^^^^^^^^^^^^ byte string literal with a suffix is invalid + | ^^^^^^^^^^^^ invalid suffix `suffix` -error: char literal with a suffix is invalid +error: suffixes on a char literal are invalid --> $DIR/bad-lit-suffixes.rs:17:5 | LL | 'a'suffix; - | ^^^^^^^^^ char literal with a suffix is invalid + | ^^^^^^^^^ invalid suffix `suffix` -error: byte literal with a suffix is invalid +error: suffixes on a byte literal are invalid --> $DIR/bad-lit-suffixes.rs:18:5 | LL | b'a'suffix; - | ^^^^^^^^^^ byte literal with a suffix is invalid + | ^^^^^^^^^^ invalid suffix `suffix` error: invalid width `1024` for integer literal --> $DIR/bad-lit-suffixes.rs:20:5 diff --git a/src/test/ui/parser/issue-59418.rs b/src/test/ui/parser/issue-59418.rs index d1afa6af320f0..a37af2180bf1b 100644 --- a/src/test/ui/parser/issue-59418.rs +++ b/src/test/ui/parser/issue-59418.rs @@ -3,10 +3,10 @@ struct X(i32,i32,i32); fn main() { let a = X(1, 2, 3); let b = a.1suffix; - //~^ ERROR tuple index with a suffix is invalid + //~^ ERROR suffixes on a tuple index are invalid println!("{}", b); let c = (1, 2, 3); let d = c.1suffix; - //~^ ERROR tuple index with a suffix is invalid + //~^ ERROR suffixes on a tuple index are invalid println!("{}", d); } diff --git a/src/test/ui/parser/issue-59418.stderr b/src/test/ui/parser/issue-59418.stderr index 4ca4bd73abc1c..ca7d4cfda7294 100644 --- a/src/test/ui/parser/issue-59418.stderr +++ b/src/test/ui/parser/issue-59418.stderr @@ -1,14 +1,14 @@ -error: tuple index with a suffix is invalid +error: suffixes on a tuple index are invalid --> $DIR/issue-59418.rs:5:15 | LL | let b = a.1suffix; - | ^^^^^^^ tuple index with a suffix is invalid + | ^^^^^^^ invalid suffix `suffix` -error: tuple index with a suffix is invalid +error: suffixes on a tuple index are invalid --> $DIR/issue-59418.rs:9:15 | LL | let d = c.1suffix; - | ^^^^^^^ tuple index with a suffix is invalid + | ^^^^^^^ invalid suffix `suffix` error: aborting due to 2 previous errors From 8d1cc72cf9fca507f4e14fad88f7269594305846 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 26 Mar 2019 12:32:32 -0700 Subject: [PATCH 5/5] Add specific message for tuple struct invoked with suffixed numeric field name --- src/libsyntax/parse/parser.rs | 3 ++- src/test/ui/parser/issue-59418.rs | 6 ++++++ src/test/ui/parser/issue-59418.stderr | 14 +++++++++++++- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index bb3dc8edfb001..71dde91e65455 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2491,7 +2491,8 @@ impl<'a> Parser<'a> { } fn parse_field_name(&mut self) -> PResult<'a, Ident> { - if let token::Literal(token::Integer(name), None) = self.token { + if let token::Literal(token::Integer(name), suffix) = self.token { + self.expect_no_suffix(self.span, "a tuple index", suffix); self.bump(); Ok(Ident::new(name, self.prev_span)) } else { diff --git a/src/test/ui/parser/issue-59418.rs b/src/test/ui/parser/issue-59418.rs index a37af2180bf1b..0fa191d4a7ef4 100644 --- a/src/test/ui/parser/issue-59418.rs +++ b/src/test/ui/parser/issue-59418.rs @@ -9,4 +9,10 @@ fn main() { let d = c.1suffix; //~^ ERROR suffixes on a tuple index are invalid println!("{}", d); + let s = X { 0suffix: 0, 1: 1, 2: 2 }; + //~^ ERROR suffixes on a tuple index are invalid + match s { + X { 0suffix: _, .. } => {} + //~^ ERROR suffixes on a tuple index are invalid + } } diff --git a/src/test/ui/parser/issue-59418.stderr b/src/test/ui/parser/issue-59418.stderr index ca7d4cfda7294..347051e9f921c 100644 --- a/src/test/ui/parser/issue-59418.stderr +++ b/src/test/ui/parser/issue-59418.stderr @@ -10,5 +10,17 @@ error: suffixes on a tuple index are invalid LL | let d = c.1suffix; | ^^^^^^^ invalid suffix `suffix` -error: aborting due to 2 previous errors +error: suffixes on a tuple index are invalid + --> $DIR/issue-59418.rs:12:17 + | +LL | let s = X { 0suffix: 0, 1: 1, 2: 2 }; + | ^^^^^^^ invalid suffix `suffix` + +error: suffixes on a tuple index are invalid + --> $DIR/issue-59418.rs:15:13 + | +LL | X { 0suffix: _, .. } => {} + | ^^^^^^^ invalid suffix `suffix` + +error: aborting due to 4 previous errors