diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 1e6d3c0d0107c..d3eadfeceb289 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() @@ -2481,7 +2480,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 { @@ -3185,51 +3185,53 @@ 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()); + + self.expect_no_suffix(span, "a tuple index", suffix); + } + 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)); - } + } + _ => { + // 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; } @@ -7827,7 +7829,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)), @@ -8648,7 +8650,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 new file mode 100644 index 0000000000000..0fa191d4a7ef4 --- /dev/null +++ b/src/test/ui/parser/issue-59418.rs @@ -0,0 +1,18 @@ +struct X(i32,i32,i32); + +fn main() { + let a = X(1, 2, 3); + let b = a.1suffix; + //~^ ERROR suffixes on a tuple index are invalid + println!("{}", b); + let c = (1, 2, 3); + 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 new file mode 100644 index 0000000000000..347051e9f921c --- /dev/null +++ b/src/test/ui/parser/issue-59418.stderr @@ -0,0 +1,26 @@ +error: suffixes on a tuple index are invalid + --> $DIR/issue-59418.rs:5:15 + | +LL | let b = a.1suffix; + | ^^^^^^^ invalid suffix `suffix` + +error: suffixes on a tuple index are invalid + --> $DIR/issue-59418.rs:9:15 + | +LL | let d = c.1suffix; + | ^^^^^^^ invalid suffix `suffix` + +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 +