From ea44f12f72888528ddb5b26492c3b72ad4b7bcb4 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Fri, 15 Aug 2025 21:47:39 +0800 Subject: [PATCH 1/4] Rename and move tuple index suffix regression test To make it more obvious what it's testing. This is its own commit to make git blame easier. --- src/tools/tidy/src/issues.txt | 1 - tests/ui/parser/{issues/issue-59418.rs => tuple-index-suffix.rs} | 0 .../{issues/issue-59418.stderr => tuple-index-suffix.stderr} | 0 3 files changed, 1 deletion(-) rename tests/ui/parser/{issues/issue-59418.rs => tuple-index-suffix.rs} (100%) rename tests/ui/parser/{issues/issue-59418.stderr => tuple-index-suffix.stderr} (100%) diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt index ee06707415f59..849dcb9e88fb1 100644 --- a/src/tools/tidy/src/issues.txt +++ b/src/tools/tidy/src/issues.txt @@ -2021,7 +2021,6 @@ ui/parser/issues/issue-5806.rs ui/parser/issues/issue-58094-missing-right-square-bracket.rs ui/parser/issues/issue-58856-1.rs ui/parser/issues/issue-58856-2.rs -ui/parser/issues/issue-59418.rs ui/parser/issues/issue-60075.rs ui/parser/issues/issue-61858.rs ui/parser/issues/issue-62524.rs diff --git a/tests/ui/parser/issues/issue-59418.rs b/tests/ui/parser/tuple-index-suffix.rs similarity index 100% rename from tests/ui/parser/issues/issue-59418.rs rename to tests/ui/parser/tuple-index-suffix.rs diff --git a/tests/ui/parser/issues/issue-59418.stderr b/tests/ui/parser/tuple-index-suffix.stderr similarity index 100% rename from tests/ui/parser/issues/issue-59418.stderr rename to tests/ui/parser/tuple-index-suffix.stderr From d7f7443a9540761c7cc2540c4b7b07b31b6120e5 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Fri, 15 Aug 2025 22:11:10 +0800 Subject: [PATCH 2/4] Expand `tuple-index-suffix` test coverage Actually, the accidentally accepted invalid suffixes also include tuple struct indexing positions, struct numeral field name positions. So before changing anything, first expand test coverage, so we can observe the effect of bumping the non-lint pseudo-FCW warning into a hard error. --- tests/ui/parser/tuple-index-suffix.rs | 75 ++++++++-- tests/ui/parser/tuple-index-suffix.stderr | 166 ++++++++++++++++++++-- 2 files changed, 222 insertions(+), 19 deletions(-) diff --git a/tests/ui/parser/tuple-index-suffix.rs b/tests/ui/parser/tuple-index-suffix.rs index 0fa191d4a7ef4..31c5bc25063dd 100644 --- a/tests/ui/parser/tuple-index-suffix.rs +++ b/tests/ui/parser/tuple-index-suffix.rs @@ -1,18 +1,77 @@ +//! See #60210. +//! +//! Check that we hard error on invalid suffixes in tuple indexing subexpressions and struct numeral +//! field names, modulo carve-outs for `{i,u}{32,usize}` at warning level to mitigate ecosystem +//! impact. + struct X(i32,i32,i32); fn main() { - let a = X(1, 2, 3); - let b = a.1suffix; + let tup_struct = X(1, 2, 3); + let invalid_tup_struct_suffix = tup_struct.0suffix; //~^ ERROR suffixes on a tuple index are invalid - println!("{}", b); - let c = (1, 2, 3); - let d = c.1suffix; + let carve_out_tup_struct_suffix = tup_struct.0i32; + //~^ WARN suffixes on a tuple index are invalid + + let tup = (1, 2, 3); + let invalid_tup_suffix = tup.0suffix; //~^ ERROR suffixes on a tuple index are invalid - println!("{}", d); - let s = X { 0suffix: 0, 1: 1, 2: 2 }; + let carve_out_tup_suffix = tup.0u32; + //~^ WARN suffixes on a tuple index are invalid + + numeral_struct_field_name_suffix_invalid(); + numeral_struct_field_name_suffix_carve_out(); +} + +// Very limited carve outs as a ecosystem impact mitigation implemented in #60186. *Only* +// `{i,u}{32,usize}` suffixes are temporarily accepted. +fn carve_outs() { + // Ok, only pseudo-FCW warnings. + + let carve_out_i32 = (42,).0i32; //~ WARN suffixes on a tuple index are invalid + let carve_out_i32 = (42,).0u32; //~ WARN suffixes on a tuple index are invalid + let carve_out_isize = (42,).0isize; //~ WARN suffixes on a tuple index are invalid + let carve_out_usize = (42,).0usize; //~ WARN suffixes on a tuple index are invalid + + // Not part of the carve outs! + let error_i8 = (42,).0i8; //~ ERROR suffixes on a tuple index are invalid + let error_u8 = (42,).0u8; //~ ERROR suffixes on a tuple index are invalid + let error_i16 = (42,).0i16; //~ ERROR suffixes on a tuple index are invalid + let error_u16 = (42,).0u16; //~ ERROR suffixes on a tuple index are invalid + let error_i64 = (42,).0i64; //~ ERROR suffixes on a tuple index are invalid + let error_u64 = (42,).0u64; //~ ERROR suffixes on a tuple index are invalid + let error_i128 = (42,).0i128; //~ ERROR suffixes on a tuple index are invalid + let error_u128 = (42,).0u128; //~ ERROR suffixes on a tuple index are invalid +} + +fn numeral_struct_field_name_suffix_invalid() { + let invalid_struct_name = X { 0suffix: 0, 1: 1, 2: 2 }; //~^ ERROR suffixes on a tuple index are invalid - match s { + match invalid_struct_name { X { 0suffix: _, .. } => {} //~^ ERROR suffixes on a tuple index are invalid } } + +fn numeral_struct_field_name_suffix_carve_out() { + let carve_out_struct_name = X { 0u32: 0, 1: 1, 2: 2 }; + //~^ WARN suffixes on a tuple index are invalid + match carve_out_struct_name { + X { 0u32: _, .. } => {} + //~^ WARN suffixes on a tuple index are invalid + } +} + +// Unfortunately, it turns out `std::mem::offset_of!` uses the same expect suffix code path. +fn offset_of_suffix() { + #[repr(C)] + pub struct Struct(u8, T); + + // Carve outs + assert_eq!(std::mem::offset_of!(Struct, 0usize), 0); + //~^ WARN suffixes on a tuple index are invalid + + // Not part of carve outs + assert_eq!(std::mem::offset_of!(Struct, 0u8), 0); + //~^ ERROR suffixes on a tuple index are invalid +} diff --git a/tests/ui/parser/tuple-index-suffix.stderr b/tests/ui/parser/tuple-index-suffix.stderr index 347051e9f921c..3a499dd6a8dff 100644 --- a/tests/ui/parser/tuple-index-suffix.stderr +++ b/tests/ui/parser/tuple-index-suffix.stderr @@ -1,26 +1,170 @@ error: suffixes on a tuple index are invalid - --> $DIR/issue-59418.rs:5:15 + --> $DIR/tuple-index-suffix.rs:11:48 | -LL | let b = a.1suffix; - | ^^^^^^^ invalid suffix `suffix` +LL | let invalid_tup_struct_suffix = tup_struct.0suffix; + | ^^^^^^^ invalid suffix `suffix` + +warning: suffixes on a tuple index are invalid + --> $DIR/tuple-index-suffix.rs:13:50 + | +LL | let carve_out_tup_struct_suffix = tup_struct.0i32; + | ^^^^ invalid suffix `i32` + | + = help: `i32` is *temporarily* accepted on tuple index fields as it was incorrectly accepted on stable for a few releases + = help: on proc macros, you'll want to use `syn::Index::from` or `proc_macro::Literal::*_unsuffixed` for code that will desugar to tuple field access + = help: see issue #60210 for more information + +error: suffixes on a tuple index are invalid + --> $DIR/tuple-index-suffix.rs:17:34 + | +LL | let invalid_tup_suffix = tup.0suffix; + | ^^^^^^^ invalid suffix `suffix` + +warning: suffixes on a tuple index are invalid + --> $DIR/tuple-index-suffix.rs:19:36 + | +LL | let carve_out_tup_suffix = tup.0u32; + | ^^^^ invalid suffix `u32` + | + = help: `u32` is *temporarily* accepted on tuple index fields as it was incorrectly accepted on stable for a few releases + = help: on proc macros, you'll want to use `syn::Index::from` or `proc_macro::Literal::*_unsuffixed` for code that will desugar to tuple field access + = help: see issue #60210 for more information + +warning: suffixes on a tuple index are invalid + --> $DIR/tuple-index-suffix.rs:31:31 + | +LL | let carve_out_i32 = (42,).0i32; + | ^^^^ invalid suffix `i32` + | + = help: `i32` is *temporarily* accepted on tuple index fields as it was incorrectly accepted on stable for a few releases + = help: on proc macros, you'll want to use `syn::Index::from` or `proc_macro::Literal::*_unsuffixed` for code that will desugar to tuple field access + = help: see issue #60210 for more information + +warning: suffixes on a tuple index are invalid + --> $DIR/tuple-index-suffix.rs:32:31 + | +LL | let carve_out_i32 = (42,).0u32; + | ^^^^ invalid suffix `u32` + | + = help: `u32` is *temporarily* accepted on tuple index fields as it was incorrectly accepted on stable for a few releases + = help: on proc macros, you'll want to use `syn::Index::from` or `proc_macro::Literal::*_unsuffixed` for code that will desugar to tuple field access + = help: see issue #60210 for more information + +warning: suffixes on a tuple index are invalid + --> $DIR/tuple-index-suffix.rs:33:33 + | +LL | let carve_out_isize = (42,).0isize; + | ^^^^^^ invalid suffix `isize` + | + = help: `isize` is *temporarily* accepted on tuple index fields as it was incorrectly accepted on stable for a few releases + = help: on proc macros, you'll want to use `syn::Index::from` or `proc_macro::Literal::*_unsuffixed` for code that will desugar to tuple field access + = help: see issue #60210 for more information + +warning: suffixes on a tuple index are invalid + --> $DIR/tuple-index-suffix.rs:34:33 + | +LL | let carve_out_usize = (42,).0usize; + | ^^^^^^ invalid suffix `usize` + | + = help: `usize` is *temporarily* accepted on tuple index fields as it was incorrectly accepted on stable for a few releases + = help: on proc macros, you'll want to use `syn::Index::from` or `proc_macro::Literal::*_unsuffixed` for code that will desugar to tuple field access + = help: see issue #60210 for more information + +error: suffixes on a tuple index are invalid + --> $DIR/tuple-index-suffix.rs:37:26 + | +LL | let error_i8 = (42,).0i8; + | ^^^ invalid suffix `i8` + +error: suffixes on a tuple index are invalid + --> $DIR/tuple-index-suffix.rs:38:26 + | +LL | let error_u8 = (42,).0u8; + | ^^^ invalid suffix `u8` error: suffixes on a tuple index are invalid - --> $DIR/issue-59418.rs:9:15 + --> $DIR/tuple-index-suffix.rs:39:27 | -LL | let d = c.1suffix; - | ^^^^^^^ invalid suffix `suffix` +LL | let error_i16 = (42,).0i16; + | ^^^^ invalid suffix `i16` error: suffixes on a tuple index are invalid - --> $DIR/issue-59418.rs:12:17 + --> $DIR/tuple-index-suffix.rs:40:27 | -LL | let s = X { 0suffix: 0, 1: 1, 2: 2 }; - | ^^^^^^^ invalid suffix `suffix` +LL | let error_u16 = (42,).0u16; + | ^^^^ invalid suffix `u16` error: suffixes on a tuple index are invalid - --> $DIR/issue-59418.rs:15:13 + --> $DIR/tuple-index-suffix.rs:41:27 + | +LL | let error_i64 = (42,).0i64; + | ^^^^ invalid suffix `i64` + +error: suffixes on a tuple index are invalid + --> $DIR/tuple-index-suffix.rs:42:27 + | +LL | let error_u64 = (42,).0u64; + | ^^^^ invalid suffix `u64` + +error: suffixes on a tuple index are invalid + --> $DIR/tuple-index-suffix.rs:43:28 + | +LL | let error_i128 = (42,).0i128; + | ^^^^^ invalid suffix `i128` + +error: suffixes on a tuple index are invalid + --> $DIR/tuple-index-suffix.rs:44:28 + | +LL | let error_u128 = (42,).0u128; + | ^^^^^ invalid suffix `u128` + +error: suffixes on a tuple index are invalid + --> $DIR/tuple-index-suffix.rs:48:35 + | +LL | let invalid_struct_name = X { 0suffix: 0, 1: 1, 2: 2 }; + | ^^^^^^^ invalid suffix `suffix` + +error: suffixes on a tuple index are invalid + --> $DIR/tuple-index-suffix.rs:51:13 | LL | X { 0suffix: _, .. } => {} | ^^^^^^^ invalid suffix `suffix` -error: aborting due to 4 previous errors +warning: suffixes on a tuple index are invalid + --> $DIR/tuple-index-suffix.rs:57:37 + | +LL | let carve_out_struct_name = X { 0u32: 0, 1: 1, 2: 2 }; + | ^^^^ invalid suffix `u32` + | + = help: `u32` is *temporarily* accepted on tuple index fields as it was incorrectly accepted on stable for a few releases + = help: on proc macros, you'll want to use `syn::Index::from` or `proc_macro::Literal::*_unsuffixed` for code that will desugar to tuple field access + = help: see issue #60210 for more information + +warning: suffixes on a tuple index are invalid + --> $DIR/tuple-index-suffix.rs:60:13 + | +LL | X { 0u32: _, .. } => {} + | ^^^^ invalid suffix `u32` + | + = help: `u32` is *temporarily* accepted on tuple index fields as it was incorrectly accepted on stable for a few releases + = help: on proc macros, you'll want to use `syn::Index::from` or `proc_macro::Literal::*_unsuffixed` for code that will desugar to tuple field access + = help: see issue #60210 for more information + +warning: suffixes on a tuple index are invalid + --> $DIR/tuple-index-suffix.rs:71:50 + | +LL | assert_eq!(std::mem::offset_of!(Struct, 0usize), 0); + | ^^^^^^ invalid suffix `usize` + | + = help: `usize` is *temporarily* accepted on tuple index fields as it was incorrectly accepted on stable for a few releases + = help: on proc macros, you'll want to use `syn::Index::from` or `proc_macro::Literal::*_unsuffixed` for code that will desugar to tuple field access + = help: see issue #60210 for more information + +error: suffixes on a tuple index are invalid + --> $DIR/tuple-index-suffix.rs:75:50 + | +LL | assert_eq!(std::mem::offset_of!(Struct, 0u8), 0); + | ^^^ invalid suffix `u8` + +error: aborting due to 13 previous errors; 9 warnings emitted From eb3441b25a7acbce8cec0571b3f8ec87cca8c349 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Fri, 15 Aug 2025 22:41:43 +0800 Subject: [PATCH 3/4] Add test coverage for proc-macro invalid tup index suffixes --- .../tuple-index-suffix-proc-macro-aux.rs | 33 ++++++++++++++++++ .../parser/tuple-index-suffix-proc-macro.rs | 31 +++++++++++++++++ .../tuple-index-suffix-proc-macro.stderr | 34 +++++++++++++++++++ 3 files changed, 98 insertions(+) create mode 100644 tests/ui/parser/auxiliary/tuple-index-suffix-proc-macro-aux.rs create mode 100644 tests/ui/parser/tuple-index-suffix-proc-macro.rs create mode 100644 tests/ui/parser/tuple-index-suffix-proc-macro.stderr diff --git a/tests/ui/parser/auxiliary/tuple-index-suffix-proc-macro-aux.rs b/tests/ui/parser/auxiliary/tuple-index-suffix-proc-macro-aux.rs new file mode 100644 index 0000000000000..fa40ed948a623 --- /dev/null +++ b/tests/ui/parser/auxiliary/tuple-index-suffix-proc-macro-aux.rs @@ -0,0 +1,33 @@ +#![feature(proc_macro_quote, proc_macro_span)] + +extern crate proc_macro; + +use proc_macro::{Ident, Literal, Span, TokenStream, TokenTree, quote}; + +#[proc_macro] +pub fn bad_tup_indexing(input: TokenStream) -> TokenStream { + let tt = input.into_iter().next().unwrap(); + let TokenTree::Literal(indexing_expr) = tt else { + unreachable!(); + }; + quote! { (42,).$indexing_expr } +} + +// Expects {IDENT, COMMA, LITERAL} +#[proc_macro] +pub fn bad_tup_struct_indexing(input: TokenStream) -> TokenStream { + let mut input = input.into_iter(); + + let id_tt = input.next().unwrap(); + let _comma = input.next().unwrap(); + let tt = input.next().unwrap(); + + let TokenTree::Ident(ident) = id_tt else { + unreachable!("id"); + }; + let TokenTree::Literal(indexing_expr) = tt else { + unreachable!("lit"); + }; + + quote! { $ident.$indexing_expr } +} diff --git a/tests/ui/parser/tuple-index-suffix-proc-macro.rs b/tests/ui/parser/tuple-index-suffix-proc-macro.rs new file mode 100644 index 0000000000000..feca6f9cdfb06 --- /dev/null +++ b/tests/ui/parser/tuple-index-suffix-proc-macro.rs @@ -0,0 +1,31 @@ +//! See #59418. +//! +//! Like `tuple-index-suffix.rs`, but exercises the proc-macro interaction. + +//@ proc-macro: tuple-index-suffix-proc-macro-aux.rs + +extern crate tuple_index_suffix_proc_macro_aux; +use tuple_index_suffix_proc_macro_aux as aux; + +fn main() { + struct TupStruct(i32); + let tup_struct = TupStruct(42); + + // #60186 carve outs `{i,u}{32,usize}` as non-lint pseudo-FCW warnings. + + aux::bad_tup_indexing!(0usize); + //~^ WARN suffixes on a tuple index are invalid + aux::bad_tup_struct_indexing!(tup_struct, 0isize); + //~^ WARN suffixes on a tuple index are invalid + + // Not part of the #60186 carve outs. + + aux::bad_tup_indexing!(0u8); + //~^ ERROR suffixes on a tuple index are invalid + aux::bad_tup_struct_indexing!(tup_struct, 0u64); + //~^ ERROR suffixes on a tuple index are invalid + + // NOTE: didn't bother with trying to figure out how to generate `struct P { 0u32: u32 }` using + // *only* `proc_macro` without help with `syn`/`quote`, looks like you can't with just + // `proc_macro::quote`? +} diff --git a/tests/ui/parser/tuple-index-suffix-proc-macro.stderr b/tests/ui/parser/tuple-index-suffix-proc-macro.stderr new file mode 100644 index 0000000000000..c8bc3a4576b40 --- /dev/null +++ b/tests/ui/parser/tuple-index-suffix-proc-macro.stderr @@ -0,0 +1,34 @@ +warning: suffixes on a tuple index are invalid + --> $DIR/tuple-index-suffix-proc-macro.rs:16:28 + | +LL | aux::bad_tup_indexing!(0usize); + | ^^^^^^ invalid suffix `usize` + | + = help: `usize` is *temporarily* accepted on tuple index fields as it was incorrectly accepted on stable for a few releases + = help: on proc macros, you'll want to use `syn::Index::from` or `proc_macro::Literal::*_unsuffixed` for code that will desugar to tuple field access + = help: see issue #60210 for more information + +warning: suffixes on a tuple index are invalid + --> $DIR/tuple-index-suffix-proc-macro.rs:18:47 + | +LL | aux::bad_tup_struct_indexing!(tup_struct, 0isize); + | ^^^^^^ invalid suffix `isize` + | + = help: `isize` is *temporarily* accepted on tuple index fields as it was incorrectly accepted on stable for a few releases + = help: on proc macros, you'll want to use `syn::Index::from` or `proc_macro::Literal::*_unsuffixed` for code that will desugar to tuple field access + = help: see issue #60210 for more information + +error: suffixes on a tuple index are invalid + --> $DIR/tuple-index-suffix-proc-macro.rs:23:28 + | +LL | aux::bad_tup_indexing!(0u8); + | ^^^ invalid suffix `u8` + +error: suffixes on a tuple index are invalid + --> $DIR/tuple-index-suffix-proc-macro.rs:25:47 + | +LL | aux::bad_tup_struct_indexing!(tup_struct, 0u64); + | ^^^^ invalid suffix `u64` + +error: aborting due to 2 previous errors; 2 warnings emitted + From ddd99930f34b79f209c61cc25706a1dac1173762 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Fri, 15 Aug 2025 23:39:33 +0800 Subject: [PATCH 4/4] Turn invalid index suffixes into hard errors --- compiler/rustc_parse/messages.ftl | 3 - compiler/rustc_parse/src/errors.rs | 4 - compiler/rustc_parse/src/parser/expr.rs | 26 +--- compiler/rustc_parse/src/parser/mod.rs | 5 +- .../tuple-index-suffix-proc-macro-aux.rs | 8 +- .../parser/tuple-index-suffix-proc-macro.rs | 7 +- .../tuple-index-suffix-proc-macro.stderr | 22 +--- tests/ui/parser/tuple-index-suffix.rs | 44 ++++--- tests/ui/parser/tuple-index-suffix.stderr | 124 +++++++----------- 9 files changed, 92 insertions(+), 151 deletions(-) diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index 9e0075c21b9ed..0d1a3c783890a 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -473,9 +473,6 @@ parse_invalid_label = parse_invalid_literal_suffix_on_tuple_index = suffixes on a tuple index are invalid .label = invalid suffix `{$suffix}` - .tuple_exception_line_1 = `{$suffix}` is *temporarily* accepted on tuple index fields as it was incorrectly accepted on stable for a few releases - .tuple_exception_line_2 = on proc macros, you'll want to use `syn::Index::from` or `proc_macro::Literal::*_unsuffixed` for code that will desugar to tuple field access - .tuple_exception_line_3 = see issue #60210 for more information parse_invalid_logical_operator = `{$incorrect}` is not a logical operator .note = unlike in e.g., Python and PHP, `&&` and `||` are used for logical operators diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index a105dd1909e93..8a10e7d05ebeb 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -1016,10 +1016,6 @@ pub(crate) struct InvalidLiteralSuffixOnTupleIndex { #[label] pub span: Span, pub suffix: Symbol, - #[help(parse_tuple_exception_line_1)] - #[help(parse_tuple_exception_line_2)] - #[help(parse_tuple_exception_line_3)] - pub exception: bool, } #[derive(Diagnostic)] diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index d0604f763171b..7d33f3de15cc4 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1163,7 +1163,10 @@ impl<'a> Parser<'a> { suffix, }) => { if let Some(suffix) = suffix { - self.expect_no_tuple_index_suffix(current.span, suffix); + self.dcx().emit_err(errors::InvalidLiteralSuffixOnTupleIndex { + span: current.span, + suffix, + }); } match self.break_up_float(symbol, current.span) { // 1e2 @@ -1239,7 +1242,8 @@ impl<'a> Parser<'a> { suffix: Option, ) -> Box { if let Some(suffix) = suffix { - self.expect_no_tuple_index_suffix(ident_span, suffix); + self.dcx() + .emit_err(errors::InvalidLiteralSuffixOnTupleIndex { span: ident_span, suffix }); } self.mk_expr(lo.to(ident_span), ExprKind::Field(base, Ident::new(field, ident_span))) } @@ -2225,24 +2229,6 @@ impl<'a> Parser<'a> { }) } - pub(super) fn expect_no_tuple_index_suffix(&self, span: Span, suffix: Symbol) { - if [sym::i32, sym::u32, sym::isize, sym::usize].contains(&suffix) { - // #59553: warn instead of reject out of hand to allow the fix to percolate - // through the ecosystem when people fix their macros - self.dcx().emit_warn(errors::InvalidLiteralSuffixOnTupleIndex { - span, - suffix, - exception: true, - }); - } else { - self.dcx().emit_err(errors::InvalidLiteralSuffixOnTupleIndex { - span, - suffix, - exception: false, - }); - } - } - /// Matches `'-' lit | lit` (cf. `ast_validation::AstValidator::check_expr_within_pat`). /// Keep this in sync with `Token::can_begin_literal_maybe_minus`. pub fn parse_literal_maybe_minus(&mut self) -> PResult<'a, Box> { diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 41ed1f95a010f..db72faf4ec7a7 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -1333,7 +1333,10 @@ impl<'a> Parser<'a> { if let token::Literal(token::Lit { kind: token::Integer, symbol, suffix }) = self.token.kind { if let Some(suffix) = suffix { - self.expect_no_tuple_index_suffix(self.token.span, suffix); + self.dcx().emit_err(errors::InvalidLiteralSuffixOnTupleIndex { + span: self.token.span, + suffix, + }); } self.bump(); Ok(Ident::new(symbol, self.prev_token.span)) diff --git a/tests/ui/parser/auxiliary/tuple-index-suffix-proc-macro-aux.rs b/tests/ui/parser/auxiliary/tuple-index-suffix-proc-macro-aux.rs index fa40ed948a623..a5084b55aac79 100644 --- a/tests/ui/parser/auxiliary/tuple-index-suffix-proc-macro-aux.rs +++ b/tests/ui/parser/auxiliary/tuple-index-suffix-proc-macro-aux.rs @@ -18,14 +18,14 @@ pub fn bad_tup_indexing(input: TokenStream) -> TokenStream { pub fn bad_tup_struct_indexing(input: TokenStream) -> TokenStream { let mut input = input.into_iter(); - let id_tt = input.next().unwrap(); + let ident = input.next().unwrap(); let _comma = input.next().unwrap(); - let tt = input.next().unwrap(); + let lit = input.next().unwrap(); - let TokenTree::Ident(ident) = id_tt else { + let TokenTree::Ident(ident) = ident else { unreachable!("id"); }; - let TokenTree::Literal(indexing_expr) = tt else { + let TokenTree::Literal(indexing_expr) = lit else { unreachable!("lit"); }; diff --git a/tests/ui/parser/tuple-index-suffix-proc-macro.rs b/tests/ui/parser/tuple-index-suffix-proc-macro.rs index feca6f9cdfb06..557c67738d30f 100644 --- a/tests/ui/parser/tuple-index-suffix-proc-macro.rs +++ b/tests/ui/parser/tuple-index-suffix-proc-macro.rs @@ -11,12 +11,13 @@ fn main() { struct TupStruct(i32); let tup_struct = TupStruct(42); - // #60186 carve outs `{i,u}{32,usize}` as non-lint pseudo-FCW warnings. + // Previously, #60186 had carve outs for `{i,u}{32,usize}` as non-lint pseudo-FCW warnings. Now, + // they all hard error. aux::bad_tup_indexing!(0usize); - //~^ WARN suffixes on a tuple index are invalid + //~^ ERROR suffixes on a tuple index are invalid aux::bad_tup_struct_indexing!(tup_struct, 0isize); - //~^ WARN suffixes on a tuple index are invalid + //~^ ERROR suffixes on a tuple index are invalid // Not part of the #60186 carve outs. diff --git a/tests/ui/parser/tuple-index-suffix-proc-macro.stderr b/tests/ui/parser/tuple-index-suffix-proc-macro.stderr index c8bc3a4576b40..47d179d355513 100644 --- a/tests/ui/parser/tuple-index-suffix-proc-macro.stderr +++ b/tests/ui/parser/tuple-index-suffix-proc-macro.stderr @@ -1,34 +1,26 @@ -warning: suffixes on a tuple index are invalid - --> $DIR/tuple-index-suffix-proc-macro.rs:16:28 +error: suffixes on a tuple index are invalid + --> $DIR/tuple-index-suffix-proc-macro.rs:17:28 | LL | aux::bad_tup_indexing!(0usize); | ^^^^^^ invalid suffix `usize` - | - = help: `usize` is *temporarily* accepted on tuple index fields as it was incorrectly accepted on stable for a few releases - = help: on proc macros, you'll want to use `syn::Index::from` or `proc_macro::Literal::*_unsuffixed` for code that will desugar to tuple field access - = help: see issue #60210 for more information -warning: suffixes on a tuple index are invalid - --> $DIR/tuple-index-suffix-proc-macro.rs:18:47 +error: suffixes on a tuple index are invalid + --> $DIR/tuple-index-suffix-proc-macro.rs:19:47 | LL | aux::bad_tup_struct_indexing!(tup_struct, 0isize); | ^^^^^^ invalid suffix `isize` - | - = help: `isize` is *temporarily* accepted on tuple index fields as it was incorrectly accepted on stable for a few releases - = help: on proc macros, you'll want to use `syn::Index::from` or `proc_macro::Literal::*_unsuffixed` for code that will desugar to tuple field access - = help: see issue #60210 for more information error: suffixes on a tuple index are invalid - --> $DIR/tuple-index-suffix-proc-macro.rs:23:28 + --> $DIR/tuple-index-suffix-proc-macro.rs:24:28 | LL | aux::bad_tup_indexing!(0u8); | ^^^ invalid suffix `u8` error: suffixes on a tuple index are invalid - --> $DIR/tuple-index-suffix-proc-macro.rs:25:47 + --> $DIR/tuple-index-suffix-proc-macro.rs:26:47 | LL | aux::bad_tup_struct_indexing!(tup_struct, 0u64); | ^^^^ invalid suffix `u64` -error: aborting due to 2 previous errors; 2 warnings emitted +error: aborting due to 4 previous errors diff --git a/tests/ui/parser/tuple-index-suffix.rs b/tests/ui/parser/tuple-index-suffix.rs index 31c5bc25063dd..c476950000545 100644 --- a/tests/ui/parser/tuple-index-suffix.rs +++ b/tests/ui/parser/tuple-index-suffix.rs @@ -1,8 +1,10 @@ -//! See #60210. +//! Regression test for both the original regression in #59418 where invalid suffixes in indexing +//! positions were accidentally accepted, and also for the removal of the temporary carve out that +//! mitigated ecosystem impact following trying to reject #59418 (this was implemented as a FCW +//! tracked in #60210). //! //! Check that we hard error on invalid suffixes in tuple indexing subexpressions and struct numeral -//! field names, modulo carve-outs for `{i,u}{32,usize}` at warning level to mitigate ecosystem -//! impact. +//! field names. struct X(i32,i32,i32); @@ -10,28 +12,28 @@ fn main() { let tup_struct = X(1, 2, 3); let invalid_tup_struct_suffix = tup_struct.0suffix; //~^ ERROR suffixes on a tuple index are invalid - let carve_out_tup_struct_suffix = tup_struct.0i32; - //~^ WARN suffixes on a tuple index are invalid + let previous_carve_out_tup_struct_suffix = tup_struct.0i32; + //~^ ERROR suffixes on a tuple index are invalid let tup = (1, 2, 3); let invalid_tup_suffix = tup.0suffix; //~^ ERROR suffixes on a tuple index are invalid - let carve_out_tup_suffix = tup.0u32; - //~^ WARN suffixes on a tuple index are invalid + let previous_carve_out_tup_suffix = tup.0u32; + //~^ ERROR suffixes on a tuple index are invalid numeral_struct_field_name_suffix_invalid(); - numeral_struct_field_name_suffix_carve_out(); + numeral_struct_field_name_suffix_previous_carve_out(); } -// Very limited carve outs as a ecosystem impact mitigation implemented in #60186. *Only* -// `{i,u}{32,usize}` suffixes are temporarily accepted. -fn carve_outs() { - // Ok, only pseudo-FCW warnings. +// Previously, there were very limited carve outs as a ecosystem impact mitigation implemented in +// #60186. *Only* `{i,u}{32,usize}` suffixes were temporarily accepted. Now, they all hard error. +fn previous_carve_outs() { + // Previously temporarily accepted by a pseudo-FCW (#60210), now hard error. - let carve_out_i32 = (42,).0i32; //~ WARN suffixes on a tuple index are invalid - let carve_out_i32 = (42,).0u32; //~ WARN suffixes on a tuple index are invalid - let carve_out_isize = (42,).0isize; //~ WARN suffixes on a tuple index are invalid - let carve_out_usize = (42,).0usize; //~ WARN suffixes on a tuple index are invalid + let previous_carve_out_i32 = (42,).0i32; //~ ERROR suffixes on a tuple index are invalid + let previous_carve_out_i32 = (42,).0u32; //~ ERROR suffixes on a tuple index are invalid + let previous_carve_out_isize = (42,).0isize; //~ ERROR suffixes on a tuple index are invalid + let previous_carve_out_usize = (42,).0usize; //~ ERROR suffixes on a tuple index are invalid // Not part of the carve outs! let error_i8 = (42,).0i8; //~ ERROR suffixes on a tuple index are invalid @@ -53,12 +55,12 @@ fn numeral_struct_field_name_suffix_invalid() { } } -fn numeral_struct_field_name_suffix_carve_out() { +fn numeral_struct_field_name_suffix_previous_carve_out() { let carve_out_struct_name = X { 0u32: 0, 1: 1, 2: 2 }; - //~^ WARN suffixes on a tuple index are invalid + //~^ ERROR suffixes on a tuple index are invalid match carve_out_struct_name { X { 0u32: _, .. } => {} - //~^ WARN suffixes on a tuple index are invalid + //~^ ERROR suffixes on a tuple index are invalid } } @@ -67,9 +69,9 @@ fn offset_of_suffix() { #[repr(C)] pub struct Struct(u8, T); - // Carve outs + // Previous pseudo-FCW carve outs assert_eq!(std::mem::offset_of!(Struct, 0usize), 0); - //~^ WARN suffixes on a tuple index are invalid + //~^ ERROR suffixes on a tuple index are invalid // Not part of carve outs assert_eq!(std::mem::offset_of!(Struct, 0u8), 0); diff --git a/tests/ui/parser/tuple-index-suffix.stderr b/tests/ui/parser/tuple-index-suffix.stderr index 3a499dd6a8dff..6d96c6d3cbf88 100644 --- a/tests/ui/parser/tuple-index-suffix.stderr +++ b/tests/ui/parser/tuple-index-suffix.stderr @@ -1,170 +1,134 @@ error: suffixes on a tuple index are invalid - --> $DIR/tuple-index-suffix.rs:11:48 + --> $DIR/tuple-index-suffix.rs:13:48 | LL | let invalid_tup_struct_suffix = tup_struct.0suffix; | ^^^^^^^ invalid suffix `suffix` -warning: suffixes on a tuple index are invalid - --> $DIR/tuple-index-suffix.rs:13:50 - | -LL | let carve_out_tup_struct_suffix = tup_struct.0i32; - | ^^^^ invalid suffix `i32` +error: suffixes on a tuple index are invalid + --> $DIR/tuple-index-suffix.rs:15:59 | - = help: `i32` is *temporarily* accepted on tuple index fields as it was incorrectly accepted on stable for a few releases - = help: on proc macros, you'll want to use `syn::Index::from` or `proc_macro::Literal::*_unsuffixed` for code that will desugar to tuple field access - = help: see issue #60210 for more information +LL | let previous_carve_out_tup_struct_suffix = tup_struct.0i32; + | ^^^^ invalid suffix `i32` error: suffixes on a tuple index are invalid - --> $DIR/tuple-index-suffix.rs:17:34 + --> $DIR/tuple-index-suffix.rs:19:34 | LL | let invalid_tup_suffix = tup.0suffix; | ^^^^^^^ invalid suffix `suffix` -warning: suffixes on a tuple index are invalid - --> $DIR/tuple-index-suffix.rs:19:36 - | -LL | let carve_out_tup_suffix = tup.0u32; - | ^^^^ invalid suffix `u32` +error: suffixes on a tuple index are invalid + --> $DIR/tuple-index-suffix.rs:21:45 | - = help: `u32` is *temporarily* accepted on tuple index fields as it was incorrectly accepted on stable for a few releases - = help: on proc macros, you'll want to use `syn::Index::from` or `proc_macro::Literal::*_unsuffixed` for code that will desugar to tuple field access - = help: see issue #60210 for more information +LL | let previous_carve_out_tup_suffix = tup.0u32; + | ^^^^ invalid suffix `u32` -warning: suffixes on a tuple index are invalid - --> $DIR/tuple-index-suffix.rs:31:31 - | -LL | let carve_out_i32 = (42,).0i32; - | ^^^^ invalid suffix `i32` +error: suffixes on a tuple index are invalid + --> $DIR/tuple-index-suffix.rs:33:40 | - = help: `i32` is *temporarily* accepted on tuple index fields as it was incorrectly accepted on stable for a few releases - = help: on proc macros, you'll want to use `syn::Index::from` or `proc_macro::Literal::*_unsuffixed` for code that will desugar to tuple field access - = help: see issue #60210 for more information +LL | let previous_carve_out_i32 = (42,).0i32; + | ^^^^ invalid suffix `i32` -warning: suffixes on a tuple index are invalid - --> $DIR/tuple-index-suffix.rs:32:31 - | -LL | let carve_out_i32 = (42,).0u32; - | ^^^^ invalid suffix `u32` +error: suffixes on a tuple index are invalid + --> $DIR/tuple-index-suffix.rs:34:40 | - = help: `u32` is *temporarily* accepted on tuple index fields as it was incorrectly accepted on stable for a few releases - = help: on proc macros, you'll want to use `syn::Index::from` or `proc_macro::Literal::*_unsuffixed` for code that will desugar to tuple field access - = help: see issue #60210 for more information +LL | let previous_carve_out_i32 = (42,).0u32; + | ^^^^ invalid suffix `u32` -warning: suffixes on a tuple index are invalid - --> $DIR/tuple-index-suffix.rs:33:33 - | -LL | let carve_out_isize = (42,).0isize; - | ^^^^^^ invalid suffix `isize` +error: suffixes on a tuple index are invalid + --> $DIR/tuple-index-suffix.rs:35:42 | - = help: `isize` is *temporarily* accepted on tuple index fields as it was incorrectly accepted on stable for a few releases - = help: on proc macros, you'll want to use `syn::Index::from` or `proc_macro::Literal::*_unsuffixed` for code that will desugar to tuple field access - = help: see issue #60210 for more information +LL | let previous_carve_out_isize = (42,).0isize; + | ^^^^^^ invalid suffix `isize` -warning: suffixes on a tuple index are invalid - --> $DIR/tuple-index-suffix.rs:34:33 - | -LL | let carve_out_usize = (42,).0usize; - | ^^^^^^ invalid suffix `usize` +error: suffixes on a tuple index are invalid + --> $DIR/tuple-index-suffix.rs:36:42 | - = help: `usize` is *temporarily* accepted on tuple index fields as it was incorrectly accepted on stable for a few releases - = help: on proc macros, you'll want to use `syn::Index::from` or `proc_macro::Literal::*_unsuffixed` for code that will desugar to tuple field access - = help: see issue #60210 for more information +LL | let previous_carve_out_usize = (42,).0usize; + | ^^^^^^ invalid suffix `usize` error: suffixes on a tuple index are invalid - --> $DIR/tuple-index-suffix.rs:37:26 + --> $DIR/tuple-index-suffix.rs:39:26 | LL | let error_i8 = (42,).0i8; | ^^^ invalid suffix `i8` error: suffixes on a tuple index are invalid - --> $DIR/tuple-index-suffix.rs:38:26 + --> $DIR/tuple-index-suffix.rs:40:26 | LL | let error_u8 = (42,).0u8; | ^^^ invalid suffix `u8` error: suffixes on a tuple index are invalid - --> $DIR/tuple-index-suffix.rs:39:27 + --> $DIR/tuple-index-suffix.rs:41:27 | LL | let error_i16 = (42,).0i16; | ^^^^ invalid suffix `i16` error: suffixes on a tuple index are invalid - --> $DIR/tuple-index-suffix.rs:40:27 + --> $DIR/tuple-index-suffix.rs:42:27 | LL | let error_u16 = (42,).0u16; | ^^^^ invalid suffix `u16` error: suffixes on a tuple index are invalid - --> $DIR/tuple-index-suffix.rs:41:27 + --> $DIR/tuple-index-suffix.rs:43:27 | LL | let error_i64 = (42,).0i64; | ^^^^ invalid suffix `i64` error: suffixes on a tuple index are invalid - --> $DIR/tuple-index-suffix.rs:42:27 + --> $DIR/tuple-index-suffix.rs:44:27 | LL | let error_u64 = (42,).0u64; | ^^^^ invalid suffix `u64` error: suffixes on a tuple index are invalid - --> $DIR/tuple-index-suffix.rs:43:28 + --> $DIR/tuple-index-suffix.rs:45:28 | LL | let error_i128 = (42,).0i128; | ^^^^^ invalid suffix `i128` error: suffixes on a tuple index are invalid - --> $DIR/tuple-index-suffix.rs:44:28 + --> $DIR/tuple-index-suffix.rs:46:28 | LL | let error_u128 = (42,).0u128; | ^^^^^ invalid suffix `u128` error: suffixes on a tuple index are invalid - --> $DIR/tuple-index-suffix.rs:48:35 + --> $DIR/tuple-index-suffix.rs:50:35 | LL | let invalid_struct_name = X { 0suffix: 0, 1: 1, 2: 2 }; | ^^^^^^^ invalid suffix `suffix` error: suffixes on a tuple index are invalid - --> $DIR/tuple-index-suffix.rs:51:13 + --> $DIR/tuple-index-suffix.rs:53:13 | LL | X { 0suffix: _, .. } => {} | ^^^^^^^ invalid suffix `suffix` -warning: suffixes on a tuple index are invalid - --> $DIR/tuple-index-suffix.rs:57:37 +error: suffixes on a tuple index are invalid + --> $DIR/tuple-index-suffix.rs:59:37 | LL | let carve_out_struct_name = X { 0u32: 0, 1: 1, 2: 2 }; | ^^^^ invalid suffix `u32` - | - = help: `u32` is *temporarily* accepted on tuple index fields as it was incorrectly accepted on stable for a few releases - = help: on proc macros, you'll want to use `syn::Index::from` or `proc_macro::Literal::*_unsuffixed` for code that will desugar to tuple field access - = help: see issue #60210 for more information -warning: suffixes on a tuple index are invalid - --> $DIR/tuple-index-suffix.rs:60:13 +error: suffixes on a tuple index are invalid + --> $DIR/tuple-index-suffix.rs:62:13 | LL | X { 0u32: _, .. } => {} | ^^^^ invalid suffix `u32` - | - = help: `u32` is *temporarily* accepted on tuple index fields as it was incorrectly accepted on stable for a few releases - = help: on proc macros, you'll want to use `syn::Index::from` or `proc_macro::Literal::*_unsuffixed` for code that will desugar to tuple field access - = help: see issue #60210 for more information -warning: suffixes on a tuple index are invalid - --> $DIR/tuple-index-suffix.rs:71:50 +error: suffixes on a tuple index are invalid + --> $DIR/tuple-index-suffix.rs:73:50 | LL | assert_eq!(std::mem::offset_of!(Struct, 0usize), 0); | ^^^^^^ invalid suffix `usize` - | - = help: `usize` is *temporarily* accepted on tuple index fields as it was incorrectly accepted on stable for a few releases - = help: on proc macros, you'll want to use `syn::Index::from` or `proc_macro::Literal::*_unsuffixed` for code that will desugar to tuple field access - = help: see issue #60210 for more information error: suffixes on a tuple index are invalid - --> $DIR/tuple-index-suffix.rs:75:50 + --> $DIR/tuple-index-suffix.rs:77:50 | LL | assert_eq!(std::mem::offset_of!(Struct, 0u8), 0); | ^^^ invalid suffix `u8` -error: aborting due to 13 previous errors; 9 warnings emitted +error: aborting due to 22 previous errors