From 9fb994b5870cc45821af5291f9b275b92619d255 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Thu, 26 Mar 2026 16:50:52 +0100 Subject: [PATCH] Drastically restrict the grammar of tuple indices --- compiler/rustc_parse/src/parser/expr.rs | 127 ++++++++---- compiler/rustc_parse/src/parser/mod.rs | 37 +++- compiler/rustc_parse/src/parser/pat.rs | 10 +- tests/ui/numeric/numeric-fields.rs | 10 - tests/ui/numeric/numeric-fields.stderr | 28 --- tests/ui/offset-of/offset-of-tuple-field.rs | 17 +- .../ui/offset-of/offset-of-tuple-field.stderr | 98 ++++----- tests/ui/parser/float-field.rs | 33 ++- tests/ui/parser/float-field.stderr | 191 +++++++++++------- tests/ui/parser/invalid-tuple-indices.rs | 73 +++++++ tests/ui/parser/invalid-tuple-indices.stderr | 164 +++++++++++++++ tests/ui/parser/recover/recover-pat-exprs.rs | 1 + .../parser/recover/recover-pat-exprs.stderr | 86 ++++---- .../struct-expr-pat-tuple-index-shorthand.rs | 15 ++ ...uct-expr-pat-tuple-index-shorthand.stderr} | 16 +- .../parser/struct-field-numeric-shorthand.rs | 8 - tests/ui/pattern/self-ctor-133272.stderr | 4 +- tests/ui/self/self_type_keyword.rs | 1 - tests/ui/self/self_type_keyword.stderr | 22 +- .../struct-pat-unmentioned-tuple-indices.rs | 11 + ...truct-pat-unmentioned-tuple-indices.stderr | 41 ++++ tests/ui/structs/struct-tuple-field-names.rs | 18 -- .../structs/struct-tuple-field-names.stderr | 47 ----- .../tuple-struct-field-naming-47073.rs | 13 -- .../tuple-struct-field-naming-47073.stderr | 19 -- tests/ui/tuple/index-invalid.rs | 2 - tests/ui/tuple/index-invalid.stderr | 10 +- ...variant-written-as-empty-struct-variant.rs | 7 + ...ant-written-as-empty-struct-variant.stderr | 27 +++ 29 files changed, 740 insertions(+), 396 deletions(-) delete mode 100644 tests/ui/numeric/numeric-fields.rs delete mode 100644 tests/ui/numeric/numeric-fields.stderr create mode 100644 tests/ui/parser/invalid-tuple-indices.rs create mode 100644 tests/ui/parser/invalid-tuple-indices.stderr create mode 100644 tests/ui/parser/struct-expr-pat-tuple-index-shorthand.rs rename tests/ui/parser/{struct-field-numeric-shorthand.stderr => struct-expr-pat-tuple-index-shorthand.stderr} (55%) delete mode 100644 tests/ui/parser/struct-field-numeric-shorthand.rs create mode 100644 tests/ui/structs/struct-pat-unmentioned-tuple-indices.rs create mode 100644 tests/ui/structs/struct-pat-unmentioned-tuple-indices.stderr delete mode 100644 tests/ui/structs/struct-tuple-field-names.rs delete mode 100644 tests/ui/structs/struct-tuple-field-names.stderr delete mode 100644 tests/ui/structs/tuple-struct-field-naming-47073.rs delete mode 100644 tests/ui/structs/tuple-struct-field-naming-47073.stderr create mode 100644 tests/ui/tuple/tuple-variant-written-as-empty-struct-variant.rs create mode 100644 tests/ui/tuple/tuple-variant-written-as-empty-struct-variant.stderr diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index c18e8c631fecc..b296b603df722 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -44,7 +44,7 @@ pub(super) enum DestructuredFloat { /// 1. TrailingDot(Symbol, Span, Span), /// 1.2 | 1.2e3 - MiddleDot(Symbol, Span, Span, Symbol, Span), + MiddleDot(Symbol, Span, Symbol, Span), /// Invalid Error, } @@ -961,6 +961,7 @@ impl<'a> Parser<'a> { token::Ident(..) => self.parse_dot_suffix(base, lo), token::Literal(token::Lit { kind: token::Integer, symbol, suffix }) => { let ident_span = self.token.span; + let symbol = self.validate_tuple_index(symbol, ident_span); self.bump(); Ok(self.mk_expr_tuple_field_access(lo, ident_span, base, symbol, suffix)) } @@ -986,13 +987,9 @@ impl<'a> Parser<'a> { self.mk_expr_tuple_field_access(lo, ident_span, base, sym, None) } // 1.2 | 1.2e3 - DestructuredFloat::MiddleDot( - sym1, - ident1_span, - _dot_span, - sym2, - ident2_span, - ) => { + // FIXME(fmease): (preexisting) For some reason for `x.0.0xyz` (i.e., suffixed) + // highlight `0.0xyz` when we should just highlight `0xyz`. + DestructuredFloat::MiddleDot(sym1, ident1_span, sym2, ident2_span) => { // `foo.1.2` (or `foo.1.2e3`): two complete dot accesses. We end up with // the `sym2` (`2` or `2e3`) token in `self.prev_token` and the following // token in `self.token`. @@ -1055,30 +1052,68 @@ impl<'a> Parser<'a> { // support pushing "future tokens" (would be also helpful to `break_and_eat`), or // we should break everything including floats into more basic proc-macro style // tokens in the lexer (probably preferable). + // FIXME(fmease): De-jank the impl. pub(super) fn break_up_float(&self, float: Symbol, span: Span) -> DestructuredFloat { #[derive(Debug)] enum FloatComponent { - IdentLike(String), + IdentLike(IdentLike), Punct(char), } use FloatComponent::*; + #[derive(Debug, Default)] + struct IdentLike { + str: String, + len: usize, + poisoned: bool, + } + let float_str = float.as_str(); let mut components = Vec::new(); - let mut ident_like = String::new(); + let mut ident_like = IdentLike::default(); + let mut zero = false; + for c in float_str.chars() { - if c == '_' || c.is_ascii_alphanumeric() { - ident_like.push(c); - } else if matches!(c, '.' | '+' | '-') { - if !ident_like.is_empty() { - components.push(IdentLike(mem::take(&mut ident_like))); + match c { + '0'..='9' => { + ident_like.len += 1; + if zero { + ident_like.poisoned = true; + } + zero = c == '0' && ident_like.str.is_empty(); + if !zero { + ident_like.str.push(c); + } } - components.push(Punct(c)); - } else { - panic!("unexpected character in a float token: {c:?}") + '_' | 'b' | 'o' | 'x' => { + ident_like.len += 1; + ident_like.poisoned = true; + } + 'e' | 'E' => { + ident_like.len += 1; + ident_like.poisoned = true; + if mem::take(&mut zero) { + ident_like.str.push('0'); + } + ident_like.str.push(c); + } + '.' | '+' | '-' => { + if mem::take(&mut zero) { + ident_like.str.push('0'); + } + if !ident_like.str.is_empty() { + components.push(IdentLike(mem::take(&mut ident_like))); + } + components.push(Punct(c)); + } + _ => panic!("unexpected character in a float token: {c:?}"), } } - if !ident_like.is_empty() { + + if zero { + ident_like.str.push('0'); + } + if !ident_like.str.is_empty() { components.push(IdentLike(ident_like)); } @@ -1090,44 +1125,58 @@ impl<'a> Parser<'a> { match &*components { // 1e2 - [IdentLike(i)] => { - DestructuredFloat::Single(Symbol::intern(i), span) - } + [IdentLike(ident)] => { + if ident.poisoned { + self.dcx().span_err(span, "invalid tuple index"); + } + + DestructuredFloat::Single(Symbol::intern(&ident.str), span) }, // 1. [IdentLike(left), Punct('.')] => { let (left_span, dot_span) = if can_take_span_apart() { - let left_span = span.with_hi(span.lo() + BytePos::from_usize(left.len())); + let left_span = span.with_hi(span.lo() + BytePos::from_usize(left.len)); let dot_span = span.with_lo(left_span.hi()); (left_span, dot_span) } else { (span, span) }; - let left = Symbol::intern(left); + if left.poisoned { + self.dcx().span_err(left_span, "invalid tuple index"); + } + let left = Symbol::intern(&left.str); DestructuredFloat::TrailingDot(left, left_span, dot_span) } // 1.2 | 1.2e3 [IdentLike(left), Punct('.'), IdentLike(right)] => { - let (left_span, dot_span, right_span) = if can_take_span_apart() { - let left_span = span.with_hi(span.lo() + BytePos::from_usize(left.len())); + let (left_span, right_span) = if can_take_span_apart() { + let left_span = span.with_hi(span.lo() + BytePos::from_usize(left.len)); let dot_span = span.with_lo(left_span.hi()).with_hi(left_span.hi() + BytePos(1)); let right_span = span.with_lo(dot_span.hi()); - (left_span, dot_span, right_span) + (left_span, right_span) } else { - (span, span, span) + (span, span) }; - let left = Symbol::intern(left); - let right = Symbol::intern(right); - DestructuredFloat::MiddleDot(left, left_span, dot_span, right, right_span) + if left.poisoned { + self.dcx().span_err(left_span, "invalid tuple index"); + } + let left = Symbol::intern(&left.str); + if right.poisoned { + self.dcx().span_err(right_span, "invalid tuple index"); + } + let right = Symbol::intern(&right.str); + DestructuredFloat::MiddleDot(left, left_span, right, right_span) } // 1e+ | 1e- (recovered) - [IdentLike(_), Punct('+' | '-')] | + [IdentLike(..), Punct('+' | '-')] | // 1e+2 | 1e-2 - [IdentLike(_), Punct('+' | '-'), IdentLike(_)] | + [IdentLike(..), Punct('+' | '-'), IdentLike(..)] | // 1.2e+ | 1.2e- - [IdentLike(_), Punct('.'), IdentLike(_), Punct('+' | '-')] | + [IdentLike(..), Punct('.'), IdentLike(..), Punct('+' | '-')] | // 1.2e+3 | 1.2e-3 - [IdentLike(_), Punct('.'), IdentLike(_), Punct('+' | '-'), IdentLike(_)] => { + [IdentLike(..), Punct('.'), IdentLike(..), Punct('+' | '-'), IdentLike(..)] => { // See the FIXME about `TokenCursor` above. + // FIXME(fmease): We report 2 errors on `x.0e+1`. + // FIXME(fmease): (preexisting) Too many confusing errs in cases like `x.0x0.0`. self.error_unexpected_after_dot(); DestructuredFloat::Error } @@ -1187,13 +1236,7 @@ impl<'a> Parser<'a> { fields.insert(start_idx, Ident::new(sym, sym_span)); } // 1.2 | 1.2e3 - DestructuredFloat::MiddleDot( - symbol1, - span1, - _dot_span, - symbol2, - span2, - ) => { + DestructuredFloat::MiddleDot(symbol1, span1, symbol2, span2) => { trailing_dot = None; fields.insert(start_idx, Ident::new(symbol2, span2)); fields.insert(start_idx, Ident::new(symbol1, span1)); diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 8c1c3c7025f5e..63baecc6011d2 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -1307,7 +1307,11 @@ impl<'a> Parser<'a> { if self.eat_keyword(exp!(Mut)) { Mutability::Mut } else { Mutability::Not } } - /// Parses reference binding mode (`ref`, `ref mut`, `ref pin const`, `ref pin mut`, or nothing). + /// Parse a reference binding mode. + /// + /// ```ebnf + /// ByRef = ("ref" ("mut" | "pin" ("const" | "mut"))?)? + /// ``` fn parse_byref(&mut self) -> ByRef { if self.eat_keyword(exp!(Ref)) { let (pinnedness, mutability) = self.parse_pin_and_mut(); @@ -1328,22 +1332,49 @@ impl<'a> Parser<'a> { } } + /// Parse a field name. + /// + /// ```enbf + /// FieldName = TupleIndex | Ident + /// TupleIndex = re"0|[1-9][0-9]*" + /// ``` fn parse_field_name(&mut self) -> PResult<'a, Ident> { + // FIXME(fmease): It would be nice if we could emit a custom error when encountering + // float literals. E.g., ideally, we'd emit "invalid tuple index" for `1e1`. + // I'm even thinking about breaking up float lits here, just so we can emit + // unexpected token `.` for `1.2` etc. if let token::Literal(token::Lit { kind: token::Integer, symbol, suffix }) = self.token.kind { + let ident_span = self.token.span; + let symbol = self.validate_tuple_index(symbol, ident_span); if let Some(suffix) = suffix { self.dcx().emit_err(errors::InvalidLiteralSuffixOnTupleIndex { - span: self.token.span, + span: ident_span, suffix, }); } self.bump(); - Ok(Ident::new(symbol, self.prev_token.span)) + Ok(Ident::new(symbol, ident_span)) } else { self.parse_ident_common(true) } } + // FIXME(fmease): De-jank this impl. + fn validate_tuple_index(&mut self, symbol: Symbol, span: Span) -> Symbol { + let str = symbol.as_str(); + + if str.contains(|c: char| !c.is_ascii_digit()) || matches!(str.as_bytes(), [b'0', _, ..]) { + self.dcx().span_err(span, "invalid tuple index"); + let str = str.replace(|c: char| !c.is_ascii_digit(), ""); + let str = str.trim_start_matches('0'); + let str = if str.is_empty() { "0" } else { str }; + return Symbol::intern(str); + } + + symbol + } + fn parse_delim_args(&mut self) -> PResult<'a, Box> { if let Some(args) = self.parse_delim_args_inner() { Ok(Box::new(args)) diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index a21d19b6d3a20..eb05ac44272c0 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -1731,11 +1731,14 @@ impl<'a> Parser<'a> { self.dcx().emit_err(DotDotDotForRemainingFields { span: self.token.span, token_str }); } + /// Parse a field in a struct pattern. + /// + /// ```ebnf + /// PatField = FieldName ":" Pat | "box"? "mut"? ByRef Ident + /// ``` fn parse_pat_field(&mut self, lo: Span, attrs: AttrVec) -> PResult<'a, PatField> { - // Check if a colon exists one ahead. This means we're parsing a fieldname. let hi; let (subpat, fieldname, is_shorthand) = if self.look_ahead(1, |t| t == &token::Colon) { - // Parsing a pattern of the form `fieldname: pat`. let fieldname = self.parse_field_name()?; self.bump(); let pat = self.parse_pat_allow_top_guard( @@ -1747,13 +1750,12 @@ impl<'a> Parser<'a> { hi = pat.span; (pat, fieldname, false) } else { - // Parsing a pattern of the form `(box) (ref) (mut) fieldname`. let is_box = self.eat_keyword(exp!(Box)); let boxed_span = self.token.span; let mutability = self.parse_mutability(); let by_ref = self.parse_byref(); - let fieldname = self.parse_field_name()?; + let fieldname = self.parse_ident_common(false)?; hi = self.prev_token.span; let ann = BindingMode(by_ref, mutability); let fieldpat = self.mk_pat_ident(boxed_span.to(hi), ann, fieldname); diff --git a/tests/ui/numeric/numeric-fields.rs b/tests/ui/numeric/numeric-fields.rs deleted file mode 100644 index 28234bbdff94e..0000000000000 --- a/tests/ui/numeric/numeric-fields.rs +++ /dev/null @@ -1,10 +0,0 @@ -struct S(u8, u16); - -fn main() { - let s = S{0b1: 10, 0: 11}; - //~^ ERROR struct `S` has no field named `0b1` - match s { - S{0: a, 0x1: b, ..} => {} - //~^ ERROR does not have a field named `0x1` - } -} diff --git a/tests/ui/numeric/numeric-fields.stderr b/tests/ui/numeric/numeric-fields.stderr deleted file mode 100644 index 6877bb3bef4e5..0000000000000 --- a/tests/ui/numeric/numeric-fields.stderr +++ /dev/null @@ -1,28 +0,0 @@ -error[E0560]: struct `S` has no field named `0b1` - --> $DIR/numeric-fields.rs:4:15 - | -LL | struct S(u8, u16); - | - `S` defined here -... -LL | let s = S{0b1: 10, 0: 11}; - | ^^^ field does not exist - | -help: `S` is a tuple struct, use the appropriate syntax - | -LL - let s = S{0b1: 10, 0: 11}; -LL + let s = S(/* u8 */, /* u16 */); - | - -error[E0026]: struct `S` does not have a field named `0x1` - --> $DIR/numeric-fields.rs:7:17 - | -LL | S{0: a, 0x1: b, ..} => {} - | ^^^ - | | - | struct `S` does not have this field - | help: `S` has a field named `1` - -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0026, E0560. -For more information about an error, try `rustc --explain E0026`. diff --git a/tests/ui/offset-of/offset-of-tuple-field.rs b/tests/ui/offset-of/offset-of-tuple-field.rs index 02d41f91a2563..2e50d70d72b0c 100644 --- a/tests/ui/offset-of/offset-of-tuple-field.rs +++ b/tests/ui/offset-of/offset-of-tuple-field.rs @@ -4,19 +4,22 @@ use std::mem::offset_of; fn main() { offset_of!((u8, u8), _0); //~ ERROR no field `_0` - offset_of!((u8, u8), 01); //~ ERROR no field `01` - offset_of!((u8, u8), 1e2); //~ ERROR no field `1e2` - offset_of!((u8, u8), 1_u8); //~ ERROR no field `1_` + offset_of!((u8, u8), 01); //~ ERROR invalid tuple index + offset_of!((u8, u8), 1e2); //~ ERROR invalid tuple index + //~^ ERROR no field `1e2` + offset_of!((u8, u8), 1_u8); //~ ERROR invalid tuple index //~| ERROR suffixes on a tuple index - builtin # offset_of((u8, u8), 1e2); //~ ERROR no field `1e2` + builtin # offset_of((u8, u8), 1e2); //~ ERROR invalid tuple index + //~^ ERROR no field `1e2` builtin # offset_of((u8, u8), _0); //~ ERROR no field `_0` - builtin # offset_of((u8, u8), 01); //~ ERROR no field `01` - builtin # offset_of((u8, u8), 1_u8); //~ ERROR no field `1_` + builtin # offset_of((u8, u8), 01); //~ ERROR invalid tuple index + builtin # offset_of((u8, u8), 1_u8); //~ ERROR invalid tuple index //~| ERROR suffixes on a tuple index offset_of!(((u8, u16), (u32, u16, u8)), 0.2); //~ ERROR no field `2` - offset_of!(((u8, u16), (u32, u16, u8)), 0.1e2); //~ ERROR no field `1e2` + offset_of!(((u8, u16), (u32, u16, u8)), 0.1e2); //~ ERROR invalid tuple index + //~^ ERROR no field `1e2` offset_of!(((u8, u16), (u32, u16, u8)), 1.2); offset_of!(((u8, u16), (u32, u16, u8)), 1.2.0); //~ ERROR no field `0` } diff --git a/tests/ui/offset-of/offset-of-tuple-field.stderr b/tests/ui/offset-of/offset-of-tuple-field.stderr index 01622c5fa2da6..4c68aec996c7c 100644 --- a/tests/ui/offset-of/offset-of-tuple-field.stderr +++ b/tests/ui/offset-of/offset-of-tuple-field.stderr @@ -1,15 +1,57 @@ +error: invalid tuple index + --> $DIR/offset-of-tuple-field.rs:13:35 + | +LL | builtin # offset_of((u8, u8), 1e2); + | ^^^ + +error: invalid tuple index + --> $DIR/offset-of-tuple-field.rs:16:35 + | +LL | builtin # offset_of((u8, u8), 01); + | ^^ + error: suffixes on a tuple index are invalid - --> $DIR/offset-of-tuple-field.rs:15:35 + --> $DIR/offset-of-tuple-field.rs:17:35 | LL | builtin # offset_of((u8, u8), 1_u8); | ^^^^ invalid suffix `u8` +error: invalid tuple index + --> $DIR/offset-of-tuple-field.rs:17:35 + | +LL | builtin # offset_of((u8, u8), 1_u8); + | ^^^^ + +error: invalid tuple index + --> $DIR/offset-of-tuple-field.rs:7:26 + | +LL | offset_of!((u8, u8), 01); + | ^^ + +error: invalid tuple index + --> $DIR/offset-of-tuple-field.rs:8:26 + | +LL | offset_of!((u8, u8), 1e2); + | ^^^ + error: suffixes on a tuple index are invalid - --> $DIR/offset-of-tuple-field.rs:9:26 + --> $DIR/offset-of-tuple-field.rs:10:26 | LL | offset_of!((u8, u8), 1_u8); | ^^^^ invalid suffix `u8` +error: invalid tuple index + --> $DIR/offset-of-tuple-field.rs:10:26 + | +LL | offset_of!((u8, u8), 1_u8); + | ^^^^ + +error: invalid tuple index + --> $DIR/offset-of-tuple-field.rs:21:47 + | +LL | offset_of!(((u8, u16), (u32, u16, u8)), 0.1e2); + | ^^^ + error[E0609]: no field `_0` on type `(u8, u8)` --> $DIR/offset-of-tuple-field.rs:6:26 | @@ -22,14 +64,6 @@ LL - offset_of!((u8, u8), _0); LL + offset_of!((u8, u8), 0); | -error[E0609]: no field `01` on type `(u8, u8)` - --> $DIR/offset-of-tuple-field.rs:7:26 - | -LL | offset_of!((u8, u8), 01); - | ^^ - | - = note: available fields are: `0`, `1` - error[E0609]: no field `1e2` on type `(u8, u8)` --> $DIR/offset-of-tuple-field.rs:8:26 | @@ -38,20 +72,8 @@ LL | offset_of!((u8, u8), 1e2); | = note: available fields are: `0`, `1` -error[E0609]: no field `1_` on type `(u8, u8)` - --> $DIR/offset-of-tuple-field.rs:9:26 - | -LL | offset_of!((u8, u8), 1_u8); - | ^^^^ - | -help: a field with a similar name exists - | -LL - offset_of!((u8, u8), 1_u8); -LL + offset_of!((u8, u8), 1); - | - error[E0609]: no field `1e2` on type `(u8, u8)` - --> $DIR/offset-of-tuple-field.rs:12:35 + --> $DIR/offset-of-tuple-field.rs:13:35 | LL | builtin # offset_of((u8, u8), 1e2); | ^^^ @@ -59,7 +81,7 @@ LL | builtin # offset_of((u8, u8), 1e2); = note: available fields are: `0`, `1` error[E0609]: no field `_0` on type `(u8, u8)` - --> $DIR/offset-of-tuple-field.rs:13:35 + --> $DIR/offset-of-tuple-field.rs:15:35 | LL | builtin # offset_of((u8, u8), _0); | ^^ @@ -70,28 +92,8 @@ LL - builtin # offset_of((u8, u8), _0); LL + builtin # offset_of((u8, u8), 0); | -error[E0609]: no field `01` on type `(u8, u8)` - --> $DIR/offset-of-tuple-field.rs:14:35 - | -LL | builtin # offset_of((u8, u8), 01); - | ^^ - | - = note: available fields are: `0`, `1` - -error[E0609]: no field `1_` on type `(u8, u8)` - --> $DIR/offset-of-tuple-field.rs:15:35 - | -LL | builtin # offset_of((u8, u8), 1_u8); - | ^^^^ - | -help: a field with a similar name exists - | -LL - builtin # offset_of((u8, u8), 1_u8); -LL + builtin # offset_of((u8, u8), 1); - | - error[E0609]: no field `2` on type `(u8, u16)` - --> $DIR/offset-of-tuple-field.rs:18:47 + --> $DIR/offset-of-tuple-field.rs:20:47 | LL | offset_of!(((u8, u16), (u32, u16, u8)), 0.2); | ^ @@ -99,7 +101,7 @@ LL | offset_of!(((u8, u16), (u32, u16, u8)), 0.2); = note: available fields are: `0`, `1` error[E0609]: no field `1e2` on type `(u8, u16)` - --> $DIR/offset-of-tuple-field.rs:19:47 + --> $DIR/offset-of-tuple-field.rs:21:47 | LL | offset_of!(((u8, u16), (u32, u16, u8)), 0.1e2); | ^^^ @@ -107,11 +109,11 @@ LL | offset_of!(((u8, u16), (u32, u16, u8)), 0.1e2); = note: available fields are: `0`, `1` error[E0609]: no field `0` on type `u8` - --> $DIR/offset-of-tuple-field.rs:21:49 + --> $DIR/offset-of-tuple-field.rs:24:49 | LL | offset_of!(((u8, u16), (u32, u16, u8)), 1.2.0); | ^ -error: aborting due to 13 previous errors +error: aborting due to 16 previous errors For more information about this error, try `rustc --explain E0609`. diff --git a/tests/ui/parser/float-field.rs b/tests/ui/parser/float-field.rs index 9bf4d90fb46b5..03b0784c3f2dc 100644 --- a/tests/ui/parser/float-field.rs +++ b/tests/ui/parser/float-field.rs @@ -1,15 +1,19 @@ +// FIXME(fmease): Fully or partially consolidate w/ test `tests/ui/parser/invalid-tuple-indices.rs`. + struct S(u8, (u8, u8)); fn main() { let s = S(0, (0, 0)); - { s.1e1; } //~ ERROR no field `1e1` on type `S` + { s.1e1; } //~ ERROR invalid tuple index + //~^ ERROR no field `1e1` on type `S` { s.1.; } //~ ERROR unexpected token: `;` { s.1.1; } - { s.1.1e1; } //~ ERROR no field `1e1` on type `(u8, u8)` + { s.1.1e1; } //~ ERROR invalid tuple index + //~^ ERROR no field `1e1` on type `(u8, u8)` { s.1e+; } //~ ERROR unexpected token: `1e+` //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1e+` @@ -31,7 +35,8 @@ fn main() { { s.1.1e-1; } //~ ERROR unexpected token: `1.1e-1` //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1e-1` - { s.0x1e1; } //~ ERROR no field `0x1e1` on type `S` + { s.0x1e1; } //~ ERROR invalid tuple index + //~^ ERROR no field `11` on type `S` { s.0x1.; } //~ ERROR hexadecimal float literal is not supported //~| ERROR unexpected token: `0x1.` @@ -45,13 +50,17 @@ fn main() { //~| ERROR unexpected token: `0x1.1e1` //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `0x1.1e1` - { s.0x1e+; } //~ ERROR expected expression, found `;` + { s.0x1e+; } //~ ERROR invalid tuple index + //~^ ERROR expected expression, found `;` - { s.0x1e-; } //~ ERROR expected expression, found `;` + { s.0x1e-; } //~ ERROR invalid tuple index + //~^ ERROR expected expression, found `;` - { s.0x1e+1; } //~ ERROR no field `0x1e` on type `S` + { s.0x1e+1; } //~ ERROR invalid tuple index + //~^ ERROR cannot add `{integer}` to `(u8, u8)` - { s.0x1e-1; } //~ ERROR no field `0x1e` on type `S` + { s.0x1e-1; } //~ ERROR invalid tuple index + //~^ ERROR cannot subtract `{integer}` from `(u8, u8)` { s.0x1.1e+1; } //~ ERROR unexpected token: `0x1.1e+1` //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `0x1.1e+1` @@ -61,15 +70,17 @@ fn main() { //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `0x1.1e-1` //~| ERROR hexadecimal float literal is not supported - { s.1e1f32; } //~ ERROR no field `1e1` on type `S` - //~| ERROR suffixes on a tuple index are invalid + { s.1e1f32; } //~ ERROR invalid tuple index + //~^ ERROR no field `1e1` on type `S` + //~| ERROR suffixes on a tuple index are invalid { s.1.f32; } //~ ERROR no field `f32` on type `(u8, u8)` { s.1.1f32; } //~ ERROR suffixes on a tuple index are invalid - { s.1.1e1f32; } //~ ERROR no field `1e1` on type `(u8, u8)` - //~| ERROR suffixes on a tuple index are invalid + { s.1.1e1f32; } //~ ERROR invalid tuple index + //~^ ERROR suffixes on a tuple index are invalid + //~| ERROR no field `1e1` on type `(u8, u8)` { s.1e+f32; } //~ ERROR unexpected token: `1e+f32` //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1e+f32` diff --git a/tests/ui/parser/float-field.stderr b/tests/ui/parser/float-field.stderr index 078d16a411729..b8c8c5f85f3ba 100644 --- a/tests/ui/parser/float-field.stderr +++ b/tests/ui/parser/float-field.stderr @@ -1,299 +1,353 @@ error: expected at least one digit in exponent - --> $DIR/float-field.rs:14:9 + --> $DIR/float-field.rs:18:9 | LL | { s.1e+; } | ^^^ error: expected at least one digit in exponent - --> $DIR/float-field.rs:18:9 + --> $DIR/float-field.rs:22:9 | LL | { s.1e-; } | ^^^ error: hexadecimal float literal is not supported - --> $DIR/float-field.rs:36:9 + --> $DIR/float-field.rs:41:9 | LL | { s.0x1.; } | ^^^^ error: hexadecimal float literal is not supported - --> $DIR/float-field.rs:40:9 + --> $DIR/float-field.rs:45:9 | LL | { s.0x1.1; } | ^^^^^ error: hexadecimal float literal is not supported - --> $DIR/float-field.rs:44:9 + --> $DIR/float-field.rs:49:9 | LL | { s.0x1.1e1; } | ^^^^^^^ error: hexadecimal float literal is not supported - --> $DIR/float-field.rs:56:9 + --> $DIR/float-field.rs:65:9 | LL | { s.0x1.1e+1; } | ^^^^^^^^ error: hexadecimal float literal is not supported - --> $DIR/float-field.rs:60:9 + --> $DIR/float-field.rs:69:9 | LL | { s.0x1.1e-1; } | ^^^^^^^^ error: expected at least one digit in exponent - --> $DIR/float-field.rs:74:9 + --> $DIR/float-field.rs:85:9 | LL | { s.1e+f32; } | ^^^^^^ error: expected at least one digit in exponent - --> $DIR/float-field.rs:78:9 + --> $DIR/float-field.rs:89:9 | LL | { s.1e-f32; } | ^^^^^^ +error: invalid tuple index + --> $DIR/float-field.rs:8:9 + | +LL | { s.1e1; } + | ^^^ + error: unexpected token: `;` - --> $DIR/float-field.rs:8:11 + --> $DIR/float-field.rs:11:11 | LL | { s.1.; } | ^ +error: invalid tuple index + --> $DIR/float-field.rs:15:11 + | +LL | { s.1.1e1; } + | ^^^ + error: unexpected token: `1e+` - --> $DIR/float-field.rs:14:9 + --> $DIR/float-field.rs:18:9 | LL | { s.1e+; } | ^^^ error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1e+` - --> $DIR/float-field.rs:14:9 + --> $DIR/float-field.rs:18:9 | LL | { s.1e+; } | ^^^ expected one of `.`, `;`, `?`, `}`, or an operator error: unexpected token: `1e-` - --> $DIR/float-field.rs:18:9 + --> $DIR/float-field.rs:22:9 | LL | { s.1e-; } | ^^^ error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1e-` - --> $DIR/float-field.rs:18:9 + --> $DIR/float-field.rs:22:9 | LL | { s.1e-; } | ^^^ expected one of `.`, `;`, `?`, `}`, or an operator error: unexpected token: `1e+1` - --> $DIR/float-field.rs:22:9 + --> $DIR/float-field.rs:26:9 | LL | { s.1e+1; } | ^^^^ error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1e+1` - --> $DIR/float-field.rs:22:9 + --> $DIR/float-field.rs:26:9 | LL | { s.1e+1; } | ^^^^ expected one of `.`, `;`, `?`, `}`, or an operator error: unexpected token: `1e-1` - --> $DIR/float-field.rs:25:9 + --> $DIR/float-field.rs:29:9 | LL | { s.1e-1; } | ^^^^ error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1e-1` - --> $DIR/float-field.rs:25:9 + --> $DIR/float-field.rs:29:9 | LL | { s.1e-1; } | ^^^^ expected one of `.`, `;`, `?`, `}`, or an operator error: unexpected token: `1.1e+1` - --> $DIR/float-field.rs:28:9 + --> $DIR/float-field.rs:32:9 | LL | { s.1.1e+1; } | ^^^^^^ error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1e+1` - --> $DIR/float-field.rs:28:9 + --> $DIR/float-field.rs:32:9 | LL | { s.1.1e+1; } | ^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator error: unexpected token: `1.1e-1` - --> $DIR/float-field.rs:31:9 + --> $DIR/float-field.rs:35:9 | LL | { s.1.1e-1; } | ^^^^^^ error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1e-1` - --> $DIR/float-field.rs:31:9 + --> $DIR/float-field.rs:35:9 | LL | { s.1.1e-1; } | ^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator +error: invalid tuple index + --> $DIR/float-field.rs:38:9 + | +LL | { s.0x1e1; } + | ^^^^^ + error: unexpected token: `0x1.` - --> $DIR/float-field.rs:36:9 + --> $DIR/float-field.rs:41:9 | LL | { s.0x1.; } | ^^^^ error: expected one of `.`, `;`, `?`, `}`, or an operator, found `0x1.` - --> $DIR/float-field.rs:36:9 + --> $DIR/float-field.rs:41:9 | LL | { s.0x1.; } | ^^^^ expected one of `.`, `;`, `?`, `}`, or an operator error: unexpected token: `0x1.1` - --> $DIR/float-field.rs:40:9 + --> $DIR/float-field.rs:45:9 | LL | { s.0x1.1; } | ^^^^^ error: expected one of `.`, `;`, `?`, `}`, or an operator, found `0x1.1` - --> $DIR/float-field.rs:40:9 + --> $DIR/float-field.rs:45:9 | LL | { s.0x1.1; } | ^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator error: unexpected token: `0x1.1e1` - --> $DIR/float-field.rs:44:9 + --> $DIR/float-field.rs:49:9 | LL | { s.0x1.1e1; } | ^^^^^^^ error: expected one of `.`, `;`, `?`, `}`, or an operator, found `0x1.1e1` - --> $DIR/float-field.rs:44:9 + --> $DIR/float-field.rs:49:9 | LL | { s.0x1.1e1; } | ^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator +error: invalid tuple index + --> $DIR/float-field.rs:53:9 + | +LL | { s.0x1e+; } + | ^^^^ + error: expected expression, found `;` - --> $DIR/float-field.rs:48:14 + --> $DIR/float-field.rs:53:14 | LL | { s.0x1e+; } | ^ expected expression +error: invalid tuple index + --> $DIR/float-field.rs:56:9 + | +LL | { s.0x1e-; } + | ^^^^ + error: expected expression, found `;` - --> $DIR/float-field.rs:50:14 + --> $DIR/float-field.rs:56:14 | LL | { s.0x1e-; } | ^ expected expression +error: invalid tuple index + --> $DIR/float-field.rs:59:9 + | +LL | { s.0x1e+1; } + | ^^^^ + +error: invalid tuple index + --> $DIR/float-field.rs:62:9 + | +LL | { s.0x1e-1; } + | ^^^^ + error: unexpected token: `0x1.1e+1` - --> $DIR/float-field.rs:56:9 + --> $DIR/float-field.rs:65:9 | LL | { s.0x1.1e+1; } | ^^^^^^^^ error: expected one of `.`, `;`, `?`, `}`, or an operator, found `0x1.1e+1` - --> $DIR/float-field.rs:56:9 + --> $DIR/float-field.rs:65:9 | LL | { s.0x1.1e+1; } | ^^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator error: unexpected token: `0x1.1e-1` - --> $DIR/float-field.rs:60:9 + --> $DIR/float-field.rs:69:9 | LL | { s.0x1.1e-1; } | ^^^^^^^^ error: expected one of `.`, `;`, `?`, `}`, or an operator, found `0x1.1e-1` - --> $DIR/float-field.rs:60:9 + --> $DIR/float-field.rs:69:9 | LL | { s.0x1.1e-1; } | ^^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator +error: invalid tuple index + --> $DIR/float-field.rs:73:9 + | +LL | { s.1e1f32; } + | ^^^^^^ + error: suffixes on a tuple index are invalid - --> $DIR/float-field.rs:64:9 + --> $DIR/float-field.rs:73:9 | LL | { s.1e1f32; } | ^^^^^^ invalid suffix `f32` error: suffixes on a tuple index are invalid - --> $DIR/float-field.rs:69:9 + --> $DIR/float-field.rs:79:9 | LL | { s.1.1f32; } | ^^^^^^ invalid suffix `f32` +error: invalid tuple index + --> $DIR/float-field.rs:81:9 + | +LL | { s.1.1e1f32; } + | ^^^^^^^^ + error: suffixes on a tuple index are invalid - --> $DIR/float-field.rs:71:9 + --> $DIR/float-field.rs:81:9 | LL | { s.1.1e1f32; } | ^^^^^^^^ invalid suffix `f32` error: unexpected token: `1e+f32` - --> $DIR/float-field.rs:74:9 + --> $DIR/float-field.rs:85:9 | LL | { s.1e+f32; } | ^^^^^^ error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1e+f32` - --> $DIR/float-field.rs:74:9 + --> $DIR/float-field.rs:85:9 | LL | { s.1e+f32; } | ^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator error: unexpected token: `1e-f32` - --> $DIR/float-field.rs:78:9 + --> $DIR/float-field.rs:89:9 | LL | { s.1e-f32; } | ^^^^^^ error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1e-f32` - --> $DIR/float-field.rs:78:9 + --> $DIR/float-field.rs:89:9 | LL | { s.1e-f32; } | ^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator error: unexpected token: `1e+1f32` - --> $DIR/float-field.rs:82:9 + --> $DIR/float-field.rs:93:9 | LL | { s.1e+1f32; } | ^^^^^^^ error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1e+1f32` - --> $DIR/float-field.rs:82:9 + --> $DIR/float-field.rs:93:9 | LL | { s.1e+1f32; } | ^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator error: unexpected token: `1e-1f32` - --> $DIR/float-field.rs:85:9 + --> $DIR/float-field.rs:96:9 | LL | { s.1e-1f32; } | ^^^^^^^ error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1e-1f32` - --> $DIR/float-field.rs:85:9 + --> $DIR/float-field.rs:96:9 | LL | { s.1e-1f32; } | ^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator error: unexpected token: `1.1e+1f32` - --> $DIR/float-field.rs:88:9 + --> $DIR/float-field.rs:99:9 | LL | { s.1.1e+1f32; } | ^^^^^^^^^ error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1e+1f32` - --> $DIR/float-field.rs:88:9 + --> $DIR/float-field.rs:99:9 | LL | { s.1.1e+1f32; } | ^^^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator error: unexpected token: `1.1e-1f32` - --> $DIR/float-field.rs:91:9 + --> $DIR/float-field.rs:102:9 | LL | { s.1.1e-1f32; } | ^^^^^^^^^ error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1e-1f32` - --> $DIR/float-field.rs:91:9 + --> $DIR/float-field.rs:102:9 | LL | { s.1.1e-1f32; } | ^^^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator error[E0609]: no field `1e1` on type `S` - --> $DIR/float-field.rs:6:9 + --> $DIR/float-field.rs:8:9 | LL | { s.1e1; } | ^^^ unknown field @@ -301,39 +355,39 @@ LL | { s.1e1; } = note: available fields are: `0`, `1` error[E0609]: no field `1e1` on type `(u8, u8)` - --> $DIR/float-field.rs:12:11 + --> $DIR/float-field.rs:15:11 | LL | { s.1.1e1; } | ^^^ unknown field | = note: available fields are: `0`, `1` -error[E0609]: no field `0x1e1` on type `S` - --> $DIR/float-field.rs:34:9 +error[E0609]: no field `11` on type `S` + --> $DIR/float-field.rs:38:9 | LL | { s.0x1e1; } | ^^^^^ unknown field | = note: available fields are: `0`, `1` -error[E0609]: no field `0x1e` on type `S` - --> $DIR/float-field.rs:52:9 +error[E0369]: cannot add `{integer}` to `(u8, u8)` + --> $DIR/float-field.rs:59:13 | LL | { s.0x1e+1; } - | ^^^^ unknown field - | - = note: available fields are: `0`, `1` + | ------^- {integer} + | | + | (u8, u8) -error[E0609]: no field `0x1e` on type `S` - --> $DIR/float-field.rs:54:9 +error[E0369]: cannot subtract `{integer}` from `(u8, u8)` + --> $DIR/float-field.rs:62:13 | LL | { s.0x1e-1; } - | ^^^^ unknown field - | - = note: available fields are: `0`, `1` + | ------^- {integer} + | | + | (u8, u8) error[E0609]: no field `1e1` on type `S` - --> $DIR/float-field.rs:64:9 + --> $DIR/float-field.rs:73:9 | LL | { s.1e1f32; } | ^^^^^^ unknown field @@ -341,7 +395,7 @@ LL | { s.1e1f32; } = note: available fields are: `0`, `1` error[E0609]: no field `f32` on type `(u8, u8)` - --> $DIR/float-field.rs:67:11 + --> $DIR/float-field.rs:77:11 | LL | { s.1.f32; } | ^^^ unknown field @@ -349,13 +403,14 @@ LL | { s.1.f32; } = note: available fields are: `0`, `1` error[E0609]: no field `1e1` on type `(u8, u8)` - --> $DIR/float-field.rs:71:9 + --> $DIR/float-field.rs:81:9 | LL | { s.1.1e1f32; } | ^^^^^^^^ unknown field | = note: available fields are: `0`, `1` -error: aborting due to 57 previous errors +error: aborting due to 66 previous errors -For more information about this error, try `rustc --explain E0609`. +Some errors have detailed explanations: E0369, E0609. +For more information about an error, try `rustc --explain E0369`. diff --git a/tests/ui/parser/invalid-tuple-indices.rs b/tests/ui/parser/invalid-tuple-indices.rs new file mode 100644 index 0000000000000..3e8bd027a5939 --- /dev/null +++ b/tests/ui/parser/invalid-tuple-indices.rs @@ -0,0 +1,73 @@ +// Syntactically, tuple indices have to be of the form `0|[1-9][0-9]*`. +// What makes this slightly annoying for the parser is the fact that lexically we only have +// int and float literals which adhere to a larger grammar. For that reason, the parser has +// to manully introspect these tokens. + +// See also . + +fn scope() { + // Note that we normalize these faulty indices "as you expected" (i.e., dropping underscores, + // leading zeroes, non-digits[^1]) to suppress bad follow-up errors like "unknown field" and + // to force good ones like "private field". + // + // [^1]: FIXME(fmease): We shouldn't blindly drop alphabetics and instead take into account the + // "requested" base & exponent. + + // Subsequently we interpret `00` as `0`. + let _ = (0,).00; //~ ERROR invalid tuple index + + // Subsequently we interpret `01_00` as `100`. + let _ = ().01_00; //~ ERROR invalid tuple index + //~^ ERROR no field `100` on type `()` + + struct Xyz(f32, f32, f32); + + // Subsequently we interpret `02` as `2`. + let Xyz { 02: _, .. }; //~ ERROR invalid tuple index + + // Subsequently we interpret `3_000` as `3000`. + let Xyz { 3_000: _, .. }; //~ ERROR invalid tuple index + //~^ ERROR struct `Xyz` does not have a field named `3000` + + // Subsequently we interpret `0x0` as `0`, `01` as `1` and `2__` as `2`. + let _ = Xyz { 0x0: 0., 01: 0., 2__: 0. }; + //~^ ERROR invalid tuple index + //~| ERROR invalid tuple index + //~| ERROR invalid tuple index +} + +// This is cfg'ed out to ensure that these checks are syntactic not just semantic. +#[cfg(false)] +fn scope() { + let X { 00: _, 1_0: _, 0xF: _ }; + //~^ ERROR invalid tuple index + //~| ERROR invalid tuple index + //~| ERROR invalid tuple index + + let _ = X { 001: (), 1_000: (), 0o7: () }; + //~^ ERROR invalid tuple index + //~| ERROR invalid tuple index + //~| ERROR invalid tuple index + + // FIXME(fmease): Also emit "invalid tuple index" here: + let X { 1e1: _ } = X { 100e10: () }; + //~^ ERROR expected identifier, found `1e1` + //~| ERROR expected identifier, found `100e10` + + let _ = x.0001; //~ ERROR invalid tuple index + let _ = x.1_000; //~ ERROR invalid tuple index + let _ = x.0b1010; //~ ERROR invalid tuple index + let _ = x.2e3; //~ ERROR invalid tuple index + let _ = x.1.00; //~ ERROR invalid tuple index + let _ = x.1.1_; //~ ERROR invalid tuple index + let _ = x.1.1e1; //~ ERROR invalid tuple index + + // FIXME(fmease): Also emit "invalid tuple index" here and maybe recover from it: + let _ = x.1e+10; + //~^ ERROR unexpected token: `1e+10` + //~| ERROR expected one of + // FIXME(fmease): Maybe recover from above and emit "invalid tuple index" below: + let _ = x.1e-10; +} + +fn main() {} diff --git a/tests/ui/parser/invalid-tuple-indices.stderr b/tests/ui/parser/invalid-tuple-indices.stderr new file mode 100644 index 0000000000000..ef7513badb3ff --- /dev/null +++ b/tests/ui/parser/invalid-tuple-indices.stderr @@ -0,0 +1,164 @@ +error: invalid tuple index + --> $DIR/invalid-tuple-indices.rs:17:18 + | +LL | let _ = (0,).00; + | ^^ + +error: invalid tuple index + --> $DIR/invalid-tuple-indices.rs:20:16 + | +LL | let _ = ().01_00; + | ^^^^^ + +error: invalid tuple index + --> $DIR/invalid-tuple-indices.rs:26:15 + | +LL | let Xyz { 02: _, .. }; + | ^^ + +error: invalid tuple index + --> $DIR/invalid-tuple-indices.rs:29:15 + | +LL | let Xyz { 3_000: _, .. }; + | ^^^^^ + +error: invalid tuple index + --> $DIR/invalid-tuple-indices.rs:33:19 + | +LL | let _ = Xyz { 0x0: 0., 01: 0., 2__: 0. }; + | ^^^ + +error: invalid tuple index + --> $DIR/invalid-tuple-indices.rs:33:28 + | +LL | let _ = Xyz { 0x0: 0., 01: 0., 2__: 0. }; + | ^^ + +error: invalid tuple index + --> $DIR/invalid-tuple-indices.rs:33:36 + | +LL | let _ = Xyz { 0x0: 0., 01: 0., 2__: 0. }; + | ^^^ + +error: invalid tuple index + --> $DIR/invalid-tuple-indices.rs:42:13 + | +LL | let X { 00: _, 1_0: _, 0xF: _ }; + | ^^ + +error: invalid tuple index + --> $DIR/invalid-tuple-indices.rs:42:20 + | +LL | let X { 00: _, 1_0: _, 0xF: _ }; + | ^^^ + +error: invalid tuple index + --> $DIR/invalid-tuple-indices.rs:42:28 + | +LL | let X { 00: _, 1_0: _, 0xF: _ }; + | ^^^ + +error: invalid tuple index + --> $DIR/invalid-tuple-indices.rs:47:17 + | +LL | let _ = X { 001: (), 1_000: (), 0o7: () }; + | ^^^ + +error: invalid tuple index + --> $DIR/invalid-tuple-indices.rs:47:26 + | +LL | let _ = X { 001: (), 1_000: (), 0o7: () }; + | ^^^^^ + +error: invalid tuple index + --> $DIR/invalid-tuple-indices.rs:47:37 + | +LL | let _ = X { 001: (), 1_000: (), 0o7: () }; + | ^^^ + +error: expected identifier, found `1e1` + --> $DIR/invalid-tuple-indices.rs:53:13 + | +LL | let X { 1e1: _ } = X { 100e10: () }; + | - ^^^ expected identifier + | | + | while parsing the fields for this pattern + +error: expected identifier, found `100e10` + --> $DIR/invalid-tuple-indices.rs:53:28 + | +LL | let X { 1e1: _ } = X { 100e10: () }; + | - ^^^^^^ expected identifier + | | + | while parsing this struct + +error: invalid tuple index + --> $DIR/invalid-tuple-indices.rs:57:15 + | +LL | let _ = x.0001; + | ^^^^ + +error: invalid tuple index + --> $DIR/invalid-tuple-indices.rs:58:15 + | +LL | let _ = x.1_000; + | ^^^^^ + +error: invalid tuple index + --> $DIR/invalid-tuple-indices.rs:59:15 + | +LL | let _ = x.0b1010; + | ^^^^^^ + +error: invalid tuple index + --> $DIR/invalid-tuple-indices.rs:60:15 + | +LL | let _ = x.2e3; + | ^^^ + +error: invalid tuple index + --> $DIR/invalid-tuple-indices.rs:61:17 + | +LL | let _ = x.1.00; + | ^^ + +error: invalid tuple index + --> $DIR/invalid-tuple-indices.rs:62:17 + | +LL | let _ = x.1.1_; + | ^^ + +error: invalid tuple index + --> $DIR/invalid-tuple-indices.rs:63:17 + | +LL | let _ = x.1.1e1; + | ^^^ + +error: unexpected token: `1e+10` + --> $DIR/invalid-tuple-indices.rs:66:15 + | +LL | let _ = x.1e+10; + | ^^^^^ + +error: expected one of `.`, `;`, `?`, `else`, or an operator, found `1e+10` + --> $DIR/invalid-tuple-indices.rs:66:15 + | +LL | let _ = x.1e+10; + | ^^^^^ expected one of `.`, `;`, `?`, `else`, or an operator + +error[E0609]: no field `100` on type `()` + --> $DIR/invalid-tuple-indices.rs:20:16 + | +LL | let _ = ().01_00; + | ^^^^^ unknown field + +error[E0026]: struct `Xyz` does not have a field named `3000` + --> $DIR/invalid-tuple-indices.rs:29:15 + | +LL | let Xyz { 3_000: _, .. }; + | ^^^^^ struct `Xyz` does not have this field + +error: aborting due to 26 previous errors + +Some errors have detailed explanations: E0026, E0609. +For more information about an error, try `rustc --explain E0026`. diff --git a/tests/ui/parser/recover/recover-pat-exprs.rs b/tests/ui/parser/recover/recover-pat-exprs.rs index 41b44ec96422c..c22d815ea3ee3 100644 --- a/tests/ui/parser/recover/recover-pat-exprs.rs +++ b/tests/ui/parser/recover/recover-pat-exprs.rs @@ -12,6 +12,7 @@ fn field_access() { } { let x.0e0; } //~ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.` + //~^ error: invalid tuple index { let x.-0.0; } //~ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.` { let x.-0; } //~ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.` diff --git a/tests/ui/parser/recover/recover-pat-exprs.stderr b/tests/ui/parser/recover/recover-pat-exprs.stderr index 60e8386bcba78..02579219d16dc 100644 --- a/tests/ui/parser/recover/recover-pat-exprs.stderr +++ b/tests/ui/parser/recover/recover-pat-exprs.stderr @@ -105,6 +105,12 @@ LL | x.0.1 => (), LL ~ VAL => (), | +error: invalid tuple index + --> $DIR/recover-pat-exprs.rs:14:13 + | +LL | { let x.0e0; } + | ^^^ + error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.` --> $DIR/recover-pat-exprs.rs:14:12 | @@ -112,31 +118,31 @@ LL | { let x.0e0; } | ^ expected one of `:`, `;`, `=`, `@`, or `|` error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.` - --> $DIR/recover-pat-exprs.rs:15:12 + --> $DIR/recover-pat-exprs.rs:16:12 | LL | { let x.-0.0; } | ^ expected one of `:`, `;`, `=`, `@`, or `|` error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.` - --> $DIR/recover-pat-exprs.rs:16:12 + --> $DIR/recover-pat-exprs.rs:17:12 | LL | { let x.-0; } | ^ expected one of `:`, `;`, `=`, `@`, or `|` error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.` - --> $DIR/recover-pat-exprs.rs:18:12 + --> $DIR/recover-pat-exprs.rs:19:12 | LL | { let x.0u32; } | ^ expected one of `:`, `;`, `=`, `@`, or `|` error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.` - --> $DIR/recover-pat-exprs.rs:19:12 + --> $DIR/recover-pat-exprs.rs:20:12 | LL | { let x.0.0_f64; } | ^ expected one of `:`, `;`, `=`, `@`, or `|` error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:25:9 + --> $DIR/recover-pat-exprs.rs:26:9 | LL | x[0] => (), | ^^^^ not a pattern @@ -155,7 +161,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:26:9 + --> $DIR/recover-pat-exprs.rs:27:9 | LL | x[..] => (), | ^^^^^ not a pattern @@ -175,25 +181,25 @@ LL ~ VAL => (), | error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[` - --> $DIR/recover-pat-exprs.rs:29:12 + --> $DIR/recover-pat-exprs.rs:30:12 | LL | { let x[0, 1, 2]; } | ^ expected one of `:`, `;`, `=`, `@`, or `|` error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[` - --> $DIR/recover-pat-exprs.rs:30:12 + --> $DIR/recover-pat-exprs.rs:31:12 | LL | { let x[0; 20]; } | ^ expected one of `:`, `;`, `=`, `@`, or `|` error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[` - --> $DIR/recover-pat-exprs.rs:31:12 + --> $DIR/recover-pat-exprs.rs:32:12 | LL | { let x[]; } | ^ expected one of `:`, `;`, `=`, `@`, or `|` error: expected one of `)`, `,`, `@`, `if`, or `|`, found `[` - --> $DIR/recover-pat-exprs.rs:32:13 + --> $DIR/recover-pat-exprs.rs:33:13 | LL | { let (x[]); } | ^ @@ -202,7 +208,7 @@ LL | { let (x[]); } | help: missing `,` error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:39:9 + --> $DIR/recover-pat-exprs.rs:40:9 | LL | x.f() => (), | ^^^^^ not a pattern @@ -221,7 +227,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:40:9 + --> $DIR/recover-pat-exprs.rs:41:9 | LL | x._f() => (), | ^^^^^^ not a pattern @@ -241,7 +247,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:41:9 + --> $DIR/recover-pat-exprs.rs:42:9 | LL | x? => (), | ^^ not a pattern @@ -262,7 +268,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:42:9 + --> $DIR/recover-pat-exprs.rs:43:9 | LL | ().f() => (), | ^^^^^^ not a pattern @@ -284,7 +290,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:43:9 + --> $DIR/recover-pat-exprs.rs:44:9 | LL | (0, x)?.f() => (), | ^^^^^^^^^^^ not a pattern @@ -306,7 +312,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:44:9 + --> $DIR/recover-pat-exprs.rs:45:9 | LL | x.f().g() => (), | ^^^^^^^^^ not a pattern @@ -328,7 +334,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:45:9 + --> $DIR/recover-pat-exprs.rs:46:9 | LL | 0.f()?.g()?? => (), | ^^^^^^^^^^^^ not a pattern @@ -350,7 +356,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:52:9 + --> $DIR/recover-pat-exprs.rs:53:9 | LL | x as usize => (), | ^^^^^^^^^^ not a pattern @@ -369,7 +375,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:53:9 + --> $DIR/recover-pat-exprs.rs:54:9 | LL | 0 as usize => (), | ^^^^^^^^^^ not a pattern @@ -389,7 +395,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:54:9 + --> $DIR/recover-pat-exprs.rs:55:9 | LL | x.f().0.4 as f32 => (), | ^^^^^^^^^^^^^^^^ not a pattern @@ -410,7 +416,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:61:9 + --> $DIR/recover-pat-exprs.rs:62:9 | LL | 1 + 1 => (), | ^^^^^ not a pattern @@ -429,7 +435,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:62:9 + --> $DIR/recover-pat-exprs.rs:63:9 | LL | (1 + 2) * 3 => (), | ^^^^^^^^^^^ not a pattern @@ -449,7 +455,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:65:9 + --> $DIR/recover-pat-exprs.rs:66:9 | LL | x.0 > 2 => (), | ^^^^^^^ not a pattern @@ -471,7 +477,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:66:9 + --> $DIR/recover-pat-exprs.rs:67:9 | LL | x.0 == 2 => (), | ^^^^^^^^ not a pattern @@ -493,7 +499,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:71:13 + --> $DIR/recover-pat-exprs.rs:72:13 | LL | (x, y.0 > 2) if x != 0 => (), | ^^^^^^^ not a pattern @@ -512,7 +518,7 @@ LL ~ (x, VAL) if x != 0 => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:72:13 + --> $DIR/recover-pat-exprs.rs:73:13 | LL | (x, y.0 > 2) if x != 0 || x != 1 => (), | ^^^^^^^ not a pattern @@ -532,7 +538,7 @@ LL ~ (x, VAL) if x != 0 || x != 1 => (), | error: left-hand side of `@` must be a binding - --> $DIR/recover-pat-exprs.rs:85:9 + --> $DIR/recover-pat-exprs.rs:86:9 | LL | x.sqrt() @ .. => (), | --------^^^-- @@ -543,13 +549,13 @@ LL | x.sqrt() @ .. => (), = note: bindings are `x`, `mut x`, `ref x`, and `ref mut x` error: expected one of `)`, `,`, `if`, or `|`, found `+` - --> $DIR/recover-pat-exprs.rs:99:12 + --> $DIR/recover-pat-exprs.rs:100:12 | LL | (_ + 1) => (), | ^ expected one of `)`, `,`, `if`, or `|` error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:83:9 + --> $DIR/recover-pat-exprs.rs:84:9 | LL | u8::MAX.abs() => (), | ^^^^^^^^^^^^^ not a pattern @@ -568,7 +574,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:88:17 + --> $DIR/recover-pat-exprs.rs:89:17 | LL | z @ w @ v.u() => (), | ^^^^^ not a pattern @@ -590,7 +596,7 @@ LL ~ z @ w @ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:90:9 + --> $DIR/recover-pat-exprs.rs:91:9 | LL | y.ilog(3) => (), | ^^^^^^^^^ not a pattern @@ -612,7 +618,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:92:9 + --> $DIR/recover-pat-exprs.rs:93:9 | LL | n + 1 => (), | ^^^^^ not a pattern @@ -634,7 +640,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:94:10 + --> $DIR/recover-pat-exprs.rs:95:10 | LL | ("".f() + 14 * 8) => (), | ^^^^^^^^^^^^^^^ not a pattern @@ -656,7 +662,7 @@ LL ~ (VAL) => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:97:9 + --> $DIR/recover-pat-exprs.rs:98:9 | LL | f?() => (), | ^^^^ not a pattern @@ -678,7 +684,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:103:9 + --> $DIR/recover-pat-exprs.rs:104:9 | LL | let 1 + 1 = 2; | ^^^^^ not a pattern @@ -686,7 +692,7 @@ LL | let 1 + 1 = 2; = note: arbitrary expressions are not allowed in patterns: error: expected one of `)`, `,`, `@`, `if`, or `|`, found `*` - --> $DIR/recover-pat-exprs.rs:106:28 + --> $DIR/recover-pat-exprs.rs:107:28 | LL | let b = matches!(x, (x * x | x.f()) | x[0]); | ^ expected one of `)`, `,`, `@`, `if`, or `|` @@ -696,7 +702,7 @@ LL | let b = matches!(x, (x * x | x.f()) | x[0]); = note: while parsing argument for this `pat` macro fragment error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:62:10 + --> $DIR/recover-pat-exprs.rs:63:10 | LL | (1 + 2) * 3 => (), | ^^^^^ not a pattern @@ -704,7 +710,7 @@ LL | (1 + 2) * 3 => (), = note: arbitrary expressions are not allowed in patterns: error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:77:5 + --> $DIR/recover-pat-exprs.rs:78:5 | LL | 1 + 2 * PI.cos() => 2, | ^^^^^^^^^^^^^^^^ not a pattern @@ -712,12 +718,12 @@ LL | 1 + 2 * PI.cos() => 2, = note: arbitrary expressions are not allowed in patterns: error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:85:9 + --> $DIR/recover-pat-exprs.rs:86:9 | LL | x.sqrt() @ .. => (), | ^^^^^^^^ not a pattern | = note: arbitrary expressions are not allowed in patterns: -error: aborting due to 45 previous errors +error: aborting due to 46 previous errors diff --git a/tests/ui/parser/struct-expr-pat-tuple-index-shorthand.rs b/tests/ui/parser/struct-expr-pat-tuple-index-shorthand.rs new file mode 100644 index 0000000000000..eb4cdffdd5860 --- /dev/null +++ b/tests/ui/parser/struct-expr-pat-tuple-index-shorthand.rs @@ -0,0 +1,15 @@ +// Check that tuple indices in struct exprs & pats don't have a shorthand. +// If they did it would be possible to bind and reference numeric identifiers which is undesirable. + +struct Rgb(u8, u8, u8); + +fn main() { + // FIXME: Also report a diagnostic for the other two fields. + let Rgb { 0, 1, 2 }; + //~^ ERROR expected identifier, found `0` + + let _ = Rgb { 0, 1, 2 }; + //~^ ERROR expected identifier, found `0` + //~| ERROR expected identifier, found `1` + //~| ERROR expected identifier, found `2` +} diff --git a/tests/ui/parser/struct-field-numeric-shorthand.stderr b/tests/ui/parser/struct-expr-pat-tuple-index-shorthand.stderr similarity index 55% rename from tests/ui/parser/struct-field-numeric-shorthand.stderr rename to tests/ui/parser/struct-expr-pat-tuple-index-shorthand.stderr index 9878cfbbdceb8..11ef6e3f9f8e7 100644 --- a/tests/ui/parser/struct-field-numeric-shorthand.stderr +++ b/tests/ui/parser/struct-expr-pat-tuple-index-shorthand.stderr @@ -1,5 +1,13 @@ error: expected identifier, found `0` - --> $DIR/struct-field-numeric-shorthand.rs:4:19 + --> $DIR/struct-expr-pat-tuple-index-shorthand.rs:8:15 + | +LL | let Rgb { 0, 1, 2 }; + | --- ^ expected identifier + | | + | while parsing the fields for this pattern + +error: expected identifier, found `0` + --> $DIR/struct-expr-pat-tuple-index-shorthand.rs:11:19 | LL | let _ = Rgb { 0, 1, 2 }; | --- ^ expected identifier @@ -7,7 +15,7 @@ LL | let _ = Rgb { 0, 1, 2 }; | while parsing this struct error: expected identifier, found `1` - --> $DIR/struct-field-numeric-shorthand.rs:4:22 + --> $DIR/struct-expr-pat-tuple-index-shorthand.rs:11:22 | LL | let _ = Rgb { 0, 1, 2 }; | --- ^ expected identifier @@ -15,12 +23,12 @@ LL | let _ = Rgb { 0, 1, 2 }; | while parsing this struct error: expected identifier, found `2` - --> $DIR/struct-field-numeric-shorthand.rs:4:25 + --> $DIR/struct-expr-pat-tuple-index-shorthand.rs:11:25 | LL | let _ = Rgb { 0, 1, 2 }; | --- ^ expected identifier | | | while parsing this struct -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors diff --git a/tests/ui/parser/struct-field-numeric-shorthand.rs b/tests/ui/parser/struct-field-numeric-shorthand.rs deleted file mode 100644 index aa342eb02a916..0000000000000 --- a/tests/ui/parser/struct-field-numeric-shorthand.rs +++ /dev/null @@ -1,8 +0,0 @@ -struct Rgb(u8, u8, u8); - -fn main() { - let _ = Rgb { 0, 1, 2 }; - //~^ ERROR expected identifier, found `0` - //~| ERROR expected identifier, found `1` - //~| ERROR expected identifier, found `2` -} diff --git a/tests/ui/pattern/self-ctor-133272.stderr b/tests/ui/pattern/self-ctor-133272.stderr index bca55a43d9c08..f3053a3e7d79a 100644 --- a/tests/ui/pattern/self-ctor-133272.stderr +++ b/tests/ui/pattern/self-ctor-133272.stderr @@ -2,7 +2,9 @@ error: expected identifier, found keyword `Self` --> $DIR/self-ctor-133272.rs:17:21 | LL | let S { ref Self } = todo!(); - | ^^^^ expected identifier, found keyword + | - ^^^^ expected identifier, found keyword + | | + | while parsing the fields for this pattern error[E0422]: cannot find struct, variant or union type `S` in this scope --> $DIR/self-ctor-133272.rs:17:13 diff --git a/tests/ui/self/self_type_keyword.rs b/tests/ui/self/self_type_keyword.rs index 463872585f942..70eb539bb1fd9 100644 --- a/tests/ui/self/self_type_keyword.rs +++ b/tests/ui/self/self_type_keyword.rs @@ -22,7 +22,6 @@ pub fn main() { Foo { Self } => (), //~^ ERROR expected identifier, found keyword `Self` //~| ERROR mismatched types - //~| ERROR `Foo` does not have a field named `Self` } } diff --git a/tests/ui/self/self_type_keyword.stderr b/tests/ui/self/self_type_keyword.stderr index 06761bb40c031..b839bec0b8b7a 100644 --- a/tests/ui/self/self_type_keyword.stderr +++ b/tests/ui/self/self_type_keyword.stderr @@ -39,22 +39,24 @@ error: expected identifier, found keyword `Self` --> $DIR/self_type_keyword.rs:22:15 | LL | Foo { Self } => (), - | ^^^^ expected identifier, found keyword + | --- ^^^^ expected identifier, found keyword + | | + | while parsing the fields for this pattern error: expected identifier, found keyword `Self` - --> $DIR/self_type_keyword.rs:30:26 + --> $DIR/self_type_keyword.rs:29:26 | LL | extern crate core as Self; | ^^^^ expected identifier, found keyword error: expected identifier, found keyword `Self` - --> $DIR/self_type_keyword.rs:35:32 + --> $DIR/self_type_keyword.rs:34:32 | LL | use std::option::Option as Self; | ^^^^ expected identifier, found keyword error: expected identifier, found keyword `Self` - --> $DIR/self_type_keyword.rs:40:11 + --> $DIR/self_type_keyword.rs:39:11 | LL | trait Self {} | ^^^^ expected identifier, found keyword @@ -88,13 +90,7 @@ LL | match 15 { LL | Foo { Self } => (), | ^^^^^^^^^^^^ expected integer, found `Foo` -error[E0026]: struct `Foo` does not have a field named `Self` - --> $DIR/self_type_keyword.rs:22:15 - | -LL | Foo { Self } => (), - | ^^^^ struct `Foo` does not have this field - -error: aborting due to 13 previous errors +error: aborting due to 12 previous errors -Some errors have detailed explanations: E0026, E0308, E0392, E0531. -For more information about an error, try `rustc --explain E0026`. +Some errors have detailed explanations: E0308, E0392, E0531. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/structs/struct-pat-unmentioned-tuple-indices.rs b/tests/ui/structs/struct-pat-unmentioned-tuple-indices.rs new file mode 100644 index 0000000000000..1f637d34c1abc --- /dev/null +++ b/tests/ui/structs/struct-pat-unmentioned-tuple-indices.rs @@ -0,0 +1,11 @@ +// On unmentioned tuple indices in struct patterns, don't suggest turning the pattern into a +// tuple struct pattern and keep the struct pattern in the suggestion. +// issue: + +struct S(i32, f32); +enum E { V(i32, f32) } + +fn main() { + let S { 0: _ } = S(1, 2.2); //~ ERROR: pattern does not mention field `1` + let E::V { 0: _ } = E::V(1, 2.2); //~ ERROR: pattern does not mention field `1` +} diff --git a/tests/ui/structs/struct-pat-unmentioned-tuple-indices.stderr b/tests/ui/structs/struct-pat-unmentioned-tuple-indices.stderr new file mode 100644 index 0000000000000..bc5480c26bbdc --- /dev/null +++ b/tests/ui/structs/struct-pat-unmentioned-tuple-indices.stderr @@ -0,0 +1,41 @@ +error[E0027]: pattern does not mention field `1` + --> $DIR/struct-pat-unmentioned-tuple-indices.rs:9:9 + | +LL | let S { 0: _ } = S(1, 2.2); + | ^^^^^^^^^^ missing field `1` + | +help: include the missing field in the pattern + | +LL | let S { 0: _, 1: _ } = S(1, 2.2); + | ++++++ +help: if you don't care about this missing field, you can explicitly ignore it + | +LL | let S { 0: _, 1: _ } = S(1, 2.2); + | ++++++ +help: or always ignore missing fields here + | +LL | let S { 0: _, .. } = S(1, 2.2); + | ++++ + +error[E0027]: pattern does not mention field `1` + --> $DIR/struct-pat-unmentioned-tuple-indices.rs:10:9 + | +LL | let E::V { 0: _ } = E::V(1, 2.2); + | ^^^^^^^^^^^^^ missing field `1` + | +help: include the missing field in the pattern + | +LL | let E::V { 0: _, 1: _ } = E::V(1, 2.2); + | ++++++ +help: if you don't care about this missing field, you can explicitly ignore it + | +LL | let E::V { 0: _, 1: _ } = E::V(1, 2.2); + | ++++++ +help: or always ignore missing fields here + | +LL | let E::V { 0: _, .. } = E::V(1, 2.2); + | ++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0027`. diff --git a/tests/ui/structs/struct-tuple-field-names.rs b/tests/ui/structs/struct-tuple-field-names.rs deleted file mode 100644 index 33f264aa25091..0000000000000 --- a/tests/ui/structs/struct-tuple-field-names.rs +++ /dev/null @@ -1,18 +0,0 @@ -struct S(i32, f32); -enum E { - S(i32, f32), -} -fn main() { - let x = E::S(1, 2.2); - match x { - E::S { 0, 1 } => {} - //~^ ERROR tuple variant `E::S` written as struct variant [E0769] - } - let y = S(1, 2.2); - match y { - S { } => {} //~ ERROR: tuple variant `S` written as struct variant [E0769] - } - - if let E::S { 0: a } = x { //~ ERROR: pattern does not mention field `1` - } -} diff --git a/tests/ui/structs/struct-tuple-field-names.stderr b/tests/ui/structs/struct-tuple-field-names.stderr deleted file mode 100644 index 953f01e1fb6cc..0000000000000 --- a/tests/ui/structs/struct-tuple-field-names.stderr +++ /dev/null @@ -1,47 +0,0 @@ -error[E0769]: tuple variant `E::S` written as struct variant - --> $DIR/struct-tuple-field-names.rs:8:9 - | -LL | E::S { 0, 1 } => {} - | ^^^^^^^^^^^^^ - | -help: use the tuple variant pattern syntax instead - | -LL - E::S { 0, 1 } => {} -LL + E::S(_, _) => {} - | - -error[E0769]: tuple variant `S` written as struct variant - --> $DIR/struct-tuple-field-names.rs:13:9 - | -LL | S { } => {} - | ^^^^^ - | -help: use the tuple variant pattern syntax instead - | -LL - S { } => {} -LL + S(_, _) => {} - | - -error[E0027]: pattern does not mention field `1` - --> $DIR/struct-tuple-field-names.rs:16:12 - | -LL | if let E::S { 0: a } = x { - | ^^^^^^^^^^^^^ missing field `1` - | -help: include the missing field in the pattern - | -LL | if let E::S { 0: a, 1: _ } = x { - | ++++++ -help: if you don't care about this missing field, you can explicitly ignore it - | -LL | if let E::S { 0: a, 1: _ } = x { - | ++++++ -help: or always ignore missing fields here - | -LL | if let E::S { 0: a, .. } = x { - | ++++ - -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0027, E0769. -For more information about an error, try `rustc --explain E0027`. diff --git a/tests/ui/structs/tuple-struct-field-naming-47073.rs b/tests/ui/structs/tuple-struct-field-naming-47073.rs deleted file mode 100644 index 6cf27e55c4bbb..0000000000000 --- a/tests/ui/structs/tuple-struct-field-naming-47073.rs +++ /dev/null @@ -1,13 +0,0 @@ -// https://github.com/rust-lang/rust/issues/47073 -type Guilty = bool; -type FineDollars = u32; - -struct Verdict(Guilty, Option); - -fn main() { - let justice = Verdict(true, Some(2718)); - let _condemned = justice.00; - //~^ ERROR no field `00` on type `Verdict` - let _punishment = justice.001; - //~^ ERROR no field `001` on type `Verdict` -} diff --git a/tests/ui/structs/tuple-struct-field-naming-47073.stderr b/tests/ui/structs/tuple-struct-field-naming-47073.stderr deleted file mode 100644 index 09ba2fb406a9e..0000000000000 --- a/tests/ui/structs/tuple-struct-field-naming-47073.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0609]: no field `00` on type `Verdict` - --> $DIR/tuple-struct-field-naming-47073.rs:9:30 - | -LL | let _condemned = justice.00; - | ^^ unknown field - | - = note: available fields are: `0`, `1` - -error[E0609]: no field `001` on type `Verdict` - --> $DIR/tuple-struct-field-naming-47073.rs:11:31 - | -LL | let _punishment = justice.001; - | ^^^ unknown field - | - = note: available fields are: `0`, `1` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0609`. diff --git a/tests/ui/tuple/index-invalid.rs b/tests/ui/tuple/index-invalid.rs index d36f6cfe3df7f..bdcd5600366d6 100644 --- a/tests/ui/tuple/index-invalid.rs +++ b/tests/ui/tuple/index-invalid.rs @@ -2,6 +2,4 @@ fn main() { let _ = (((),),).1.0; //~ ERROR no field `1` on type `(((),),)` let _ = (((),),).0.1; //~ ERROR no field `1` on type `((),)` - - let _ = (((),),).000.000; //~ ERROR no field `000` on type `(((),),)` } diff --git a/tests/ui/tuple/index-invalid.stderr b/tests/ui/tuple/index-invalid.stderr index fee09b7947c12..cafd46fe346d5 100644 --- a/tests/ui/tuple/index-invalid.stderr +++ b/tests/ui/tuple/index-invalid.stderr @@ -14,14 +14,6 @@ LL | let _ = (((),),).0.1; | = note: available field is: `0` -error[E0609]: no field `000` on type `(((),),)` - --> $DIR/index-invalid.rs:6:22 - | -LL | let _ = (((),),).000.000; - | ^^^ unknown field - | - = note: available field is: `0` - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0609`. diff --git a/tests/ui/tuple/tuple-variant-written-as-empty-struct-variant.rs b/tests/ui/tuple/tuple-variant-written-as-empty-struct-variant.rs new file mode 100644 index 0000000000000..3382ac9e868a7 --- /dev/null +++ b/tests/ui/tuple/tuple-variant-written-as-empty-struct-variant.rs @@ -0,0 +1,7 @@ +struct S(i32); +enum E { V(i32) } + +fn main() { + let S {} = S(0); //~ ERROR tuple variant `S` written as struct variant + let E::V {} = E::V(0); //~ ERROR tuple variant `E::V` written as struct variant +} diff --git a/tests/ui/tuple/tuple-variant-written-as-empty-struct-variant.stderr b/tests/ui/tuple/tuple-variant-written-as-empty-struct-variant.stderr new file mode 100644 index 0000000000000..ef63238b00406 --- /dev/null +++ b/tests/ui/tuple/tuple-variant-written-as-empty-struct-variant.stderr @@ -0,0 +1,27 @@ +error[E0769]: tuple variant `S` written as struct variant + --> $DIR/tuple-variant-written-as-empty-struct-variant.rs:5:9 + | +LL | let S {} = S(0); + | ^^^^ + | +help: use the tuple variant pattern syntax instead + | +LL - let S {} = S(0); +LL + let S(_) = S(0); + | + +error[E0769]: tuple variant `E::V` written as struct variant + --> $DIR/tuple-variant-written-as-empty-struct-variant.rs:6:9 + | +LL | let E::V {} = E::V(0); + | ^^^^^^^ + | +help: use the tuple variant pattern syntax instead + | +LL - let E::V {} = E::V(0); +LL + let E::V(_) = E::V(0); + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0769`.