Skip to content

Commit

Permalink
Rollup merge of rust-lang#59421 - estebank:tuple-index-suffix, r=petr…
Browse files Browse the repository at this point in the history
…ochenkov

Reject integer suffix when tuple indexing

Fix rust-lang#59418.

r? @varkor
  • Loading branch information
cuviper authored Mar 28, 2019
2 parents 468c02f + 8d1cc72 commit be34621
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 74 deletions.
102 changes: 52 additions & 50 deletions src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
}
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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::<f64>().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::<f64>().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;
}
Expand Down Expand Up @@ -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)),
Expand Down Expand Up @@ -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))
}
_ => {
Expand Down
16 changes: 8 additions & 8 deletions src/test/ui/parser/bad-lit-suffixes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
32 changes: 16 additions & 16 deletions src/test/ui/parser/bad-lit-suffixes.stderr
Original file line number Diff line number Diff line change
@@ -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
Expand Down
18 changes: 18 additions & 0 deletions src/test/ui/parser/issue-59418.rs
Original file line number Diff line number Diff line change
@@ -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
}
}
26 changes: 26 additions & 0 deletions src/test/ui/parser/issue-59418.stderr
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit be34621

Please sign in to comment.