From 848b0da34fa20d0ff5d12d1d4f506affc765534b Mon Sep 17 00:00:00 2001 From: León Orell Valerian Liehr Date: Sun, 23 Mar 2025 22:00:39 +0100 Subject: Remove fields that are dead since the removal of type ascription syntax Since `{ ident: ident }` is a parse error, these fields are dead. --- compiler/rustc_parse/src/parser/diagnostics.rs | 25 ++++++++++--------------- compiler/rustc_parse/src/parser/stmt.rs | 9 +-------- 2 files changed, 11 insertions(+), 23 deletions(-) (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index c1cca1186af..daa27b14669 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -971,18 +971,8 @@ impl<'a> Parser<'a> { // fn foo() -> Foo { // field: value, // } - // Suggest: - // fn foo() -> Foo { Path { - // field: value, - // } } let guar = err.delay_as_bug(); self.restore_snapshot(snapshot); - let mut tail = self.mk_block( - thin_vec![self.mk_stmt_err(expr.span, guar)], - s, - lo.to(self.prev_token.span), - ); - tail.could_be_bare_literal = true; if maybe_struct_name.is_ident() && can_be_struct_literal { // Account for `if Example { a: one(), }.is_pos() {}`. // expand `before` so that we take care of module path such as: @@ -1004,6 +994,10 @@ impl<'a> Parser<'a> { return None; } } else { + // Suggest: + // fn foo() -> Foo { Path { + // field: value, + // } } self.dcx().emit_err(StructLiteralBodyWithoutPath { span: expr.span, sugg: StructLiteralBodyWithoutPathSugg { @@ -1011,7 +1005,11 @@ impl<'a> Parser<'a> { after: expr.span.shrink_to_hi(), }, }); - Ok(tail) + Ok(self.mk_block( + thin_vec![self.mk_stmt_err(expr.span, guar)], + s, + lo.to(self.prev_token.span), + )) } } (Err(err), Ok(tail)) => { @@ -1025,10 +1023,7 @@ impl<'a> Parser<'a> { self.consume_block(exp!(OpenBrace), exp!(CloseBrace), ConsumeClosingDelim::Yes); Err(err) } - (Ok(_), Ok(mut tail)) => { - tail.could_be_bare_literal = true; - Ok(tail) - } + (Ok(_), Ok(tail)) => Ok(tail), }); } None diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 0fe247078d5..368366c60d6 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -1043,14 +1043,7 @@ impl<'a> Parser<'a> { rules: BlockCheckMode, span: Span, ) -> P { - P(Block { - stmts, - id: DUMMY_NODE_ID, - rules, - span, - tokens: None, - could_be_bare_literal: false, - }) + P(Block { stmts, id: DUMMY_NODE_ID, rules, span, tokens: None }) } pub(super) fn mk_stmt(&self, span: Span, kind: StmtKind) -> Stmt { -- cgit 1.4.1-3-g733a5 From 82796dd8585c0c160fe2a50b12f77455a7e0f8d7 Mon Sep 17 00:00:00 2001 From: León Orell Valerian Liehr Date: Mon, 24 Mar 2025 00:01:30 +0100 Subject: Brace-ident-colon can certainly no longer start a block thanks to the removal of type ascription. --- compiler/rustc_parse/src/parser/expr.rs | 14 +--- tests/ui/parser/issues/issue-111692.rs | 10 +-- tests/ui/parser/issues/issue-111692.stderr | 30 ++++---- ...ethod-call-on-struct-literal-in-if-condition.rs | 2 +- ...d-call-on-struct-literal-in-if-condition.stderr | 4 +- tests/ui/parser/type-ascription-in-pattern.rs | 9 ++- tests/ui/parser/type-ascription-in-pattern.stderr | 80 ++++++++++++++++------ 7 files changed, 88 insertions(+), 61 deletions(-) (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index c48f91643e8..79d12ed4bbe 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -3474,19 +3474,9 @@ impl<'a> Parser<'a> { } fn is_certainly_not_a_block(&self) -> bool { + // `{ ident, ` and `{ ident: ` cannot start a block. self.look_ahead(1, |t| t.is_ident()) - && ( - // `{ ident, ` cannot start a block. - self.look_ahead(2, |t| t == &token::Comma) - || self.look_ahead(2, |t| t == &token::Colon) - && ( - // `{ ident: token, ` cannot start a block. - self.look_ahead(4, |t| t == &token::Comma) - // `{ ident: ` cannot start a block unless it's a type ascription - // `ident: Type`. - || self.look_ahead(3, |t| !t.can_begin_type()) - ) - ) + && self.look_ahead(2, |t| t == &token::Comma || t == &token::Colon) } fn maybe_parse_struct_expr( diff --git a/tests/ui/parser/issues/issue-111692.rs b/tests/ui/parser/issues/issue-111692.rs index 56096f706a8..de6de222754 100644 --- a/tests/ui/parser/issues/issue-111692.rs +++ b/tests/ui/parser/issues/issue-111692.rs @@ -9,23 +9,25 @@ mod module { } fn test(x: module::Type) { - if x == module::Type { x: module::C, y: 1 } { //~ ERROR invalid struct literal + if x == module::Type { x: module::C, y: 1 } { //~ ERROR struct literals are not allowed here } } fn test2(x: module::Type) { - if x ==module::Type { x: module::C, y: 1 } { //~ ERROR invalid struct literal + if x ==module::Type { x: module::C, y: 1 } { //~ ERROR struct literals are not allowed here } } fn test3(x: module::Type) { - if x == Type { x: module::C, y: 1 } { //~ ERROR invalid struct literal + use module::Type; + if x == Type { x: module::C, y: 1 } { //~ ERROR struct literals are not allowed here } } fn test4(x: module::Type) { - if x == demo_module::Type { x: module::C, y: 1 } { //~ ERROR invalid struct literal + use module as demo_module; + if x == demo_module::Type { x: module::C, y: 1 } { //~ ERROR struct literals are not allowed here } } diff --git a/tests/ui/parser/issues/issue-111692.stderr b/tests/ui/parser/issues/issue-111692.stderr index 068b0483b0f..979dfade1ba 100644 --- a/tests/ui/parser/issues/issue-111692.stderr +++ b/tests/ui/parser/issues/issue-111692.stderr @@ -1,43 +1,43 @@ -error: invalid struct literal - --> $DIR/issue-111692.rs:12:21 +error: struct literals are not allowed here + --> $DIR/issue-111692.rs:12:13 | LL | if x == module::Type { x: module::C, y: 1 } { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: you might need to surround the struct literal with parentheses +help: surround the struct literal with parentheses | LL | if x == (module::Type { x: module::C, y: 1 }) { | + + -error: invalid struct literal - --> $DIR/issue-111692.rs:17:20 +error: struct literals are not allowed here + --> $DIR/issue-111692.rs:17:12 | LL | if x ==module::Type { x: module::C, y: 1 } { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: you might need to surround the struct literal with parentheses +help: surround the struct literal with parentheses | LL | if x ==(module::Type { x: module::C, y: 1 }) { | + + -error: invalid struct literal - --> $DIR/issue-111692.rs:23:13 +error: struct literals are not allowed here + --> $DIR/issue-111692.rs:24:13 | LL | if x == Type { x: module::C, y: 1 } { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: you might need to surround the struct literal with parentheses +help: surround the struct literal with parentheses | LL | if x == (Type { x: module::C, y: 1 }) { | + + -error: invalid struct literal - --> $DIR/issue-111692.rs:28:26 +error: struct literals are not allowed here + --> $DIR/issue-111692.rs:30:13 | LL | if x == demo_module::Type { x: module::C, y: 1 } { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: you might need to surround the struct literal with parentheses +help: surround the struct literal with parentheses | LL | if x == (demo_module::Type { x: module::C, y: 1 }) { | + + diff --git a/tests/ui/parser/method-call-on-struct-literal-in-if-condition.rs b/tests/ui/parser/method-call-on-struct-literal-in-if-condition.rs index 8be7c9ee8ac..3211b6c7bb9 100644 --- a/tests/ui/parser/method-call-on-struct-literal-in-if-condition.rs +++ b/tests/ui/parser/method-call-on-struct-literal-in-if-condition.rs @@ -7,7 +7,7 @@ impl Example { fn one() -> i32 { 1 } fn main() { - if Example { a: one(), }.is_pos() { //~ ERROR invalid struct literal + if Example { a: one(), }.is_pos() { //~ ERROR struct literals are not allowed here println!("Positive!"); } } diff --git a/tests/ui/parser/method-call-on-struct-literal-in-if-condition.stderr b/tests/ui/parser/method-call-on-struct-literal-in-if-condition.stderr index f7822ba1124..8eba2230f8f 100644 --- a/tests/ui/parser/method-call-on-struct-literal-in-if-condition.stderr +++ b/tests/ui/parser/method-call-on-struct-literal-in-if-condition.stderr @@ -1,10 +1,10 @@ -error: invalid struct literal +error: struct literals are not allowed here --> $DIR/method-call-on-struct-literal-in-if-condition.rs:10:8 | LL | if Example { a: one(), }.is_pos() { | ^^^^^^^^^^^^^^^^^^^^^ | -help: you might need to surround the struct literal with parentheses +help: surround the struct literal with parentheses | LL | if (Example { a: one(), }).is_pos() { | + + diff --git a/tests/ui/parser/type-ascription-in-pattern.rs b/tests/ui/parser/type-ascription-in-pattern.rs index fec168afba1..18d7061d69c 100644 --- a/tests/ui/parser/type-ascription-in-pattern.rs +++ b/tests/ui/parser/type-ascription-in-pattern.rs @@ -1,11 +1,10 @@ fn foo(x: bool) -> i32 { - match x { + match x { //~ ERROR struct literals are not allowed here x: i32 => x, //~ ERROR expected - //~^ ERROR mismatched types - true => 42., - false => 0.333, + true => 42., //~ ERROR expected identifier + false => 0.333, //~ ERROR expected identifier } -} +} //~ ERROR expected one of fn main() { match foo(true) { diff --git a/tests/ui/parser/type-ascription-in-pattern.stderr b/tests/ui/parser/type-ascription-in-pattern.stderr index 09190754993..135879f208b 100644 --- a/tests/ui/parser/type-ascription-in-pattern.stderr +++ b/tests/ui/parser/type-ascription-in-pattern.stderr @@ -1,18 +1,64 @@ -error: expected one of `@` or `|`, found `:` - --> $DIR/type-ascription-in-pattern.rs:3:10 +error: expected one of `!`, `,`, `.`, `::`, `?`, `{`, `}`, or an operator, found `=>` + --> $DIR/type-ascription-in-pattern.rs:3:16 | +LL | match x { + | - while parsing this struct LL | x: i32 => x, - | ^ --- specifying the type of a pattern isn't supported - | | - | expected one of `@` or `|` + | -^^ expected one of 8 possible tokens + | | + | help: try adding a comma: `,` + +error: expected identifier, found keyword `true` + --> $DIR/type-ascription-in-pattern.rs:4:9 | -help: maybe write a path separator here +LL | match x { + | - while parsing this struct +LL | x: i32 => x, +LL | true => 42., + | ^^^^ expected identifier, found keyword + +error: expected identifier, found keyword `false` + --> $DIR/type-ascription-in-pattern.rs:5:9 | -LL | x::i32 => x, - | ~~ +LL | match x { + | - while parsing this struct +... +LL | false => 0.333, + | ^^^^^ expected identifier, found keyword + +error: struct literals are not allowed here + --> $DIR/type-ascription-in-pattern.rs:2:11 + | +LL | match x { + | ___________^ +LL | | x: i32 => x, +LL | | true => 42., +LL | | false => 0.333, +LL | | } + | |_____^ + | +help: surround the struct literal with parentheses + | +LL ~ match (x { +LL | x: i32 => x, +LL | true => 42., +LL | false => 0.333, +LL ~ }) + | + +error: expected one of `.`, `?`, `{`, or an operator, found `}` + --> $DIR/type-ascription-in-pattern.rs:7:1 + | +LL | match x { + | ----- while parsing this `match` expression +... +LL | } + | - expected one of `.`, `?`, `{`, or an operator +LL | } + | ^ unexpected token error: expected one of `...`, `..=`, `..`, or `|`, found `:` - --> $DIR/type-ascription-in-pattern.rs:12:11 + --> $DIR/type-ascription-in-pattern.rs:11:11 | LL | 42: i32 => (), | ^ --- specifying the type of a pattern isn't supported @@ -20,7 +66,7 @@ LL | 42: i32 => (), | expected one of `...`, `..=`, `..`, or `|` error: expected `|`, found `:` - --> $DIR/type-ascription-in-pattern.rs:13:10 + --> $DIR/type-ascription-in-pattern.rs:12:10 | LL | _: f64 => (), | ^ --- specifying the type of a pattern isn't supported @@ -28,7 +74,7 @@ LL | _: f64 => (), | expected `|` error: expected one of `@` or `|`, found `:` - --> $DIR/type-ascription-in-pattern.rs:14:10 + --> $DIR/type-ascription-in-pattern.rs:13:10 | LL | x: i32 => (), | ^ --- specifying the type of a pattern isn't supported @@ -40,15 +86,5 @@ help: maybe write a path separator here LL | x::i32 => (), | ~~ -error[E0308]: mismatched types - --> $DIR/type-ascription-in-pattern.rs:3:19 - | -LL | fn foo(x: bool) -> i32 { - | --- expected `i32` because of return type -LL | match x { -LL | x: i32 => x, - | ^ expected `i32`, found `bool` - -error: aborting due to 5 previous errors +error: aborting due to 8 previous errors -For more information about this error, try `rustc --explain E0308`. -- cgit 1.4.1-3-g733a5 From 9f336ce2eb0ba04de7f1ddd2e1b0958e7df15c42 Mon Sep 17 00:00:00 2001 From: León Orell Valerian Liehr Date: Mon, 24 Mar 2025 00:12:53 +0100 Subject: Remove now unreachable parse recovery code StructLiteralNeedingParens is no longer reachable always giving precedence to StructLiteralNotAllowedHere. As an aside: The former error struct shouldn't've existed in the first place. We should've just used the latter in this branch. --- compiler/rustc_parse/messages.ftl | 4 -- compiler/rustc_parse/src/errors.rs | 18 -------- compiler/rustc_parse/src/parser/diagnostics.rs | 64 ++++++++------------------ compiler/rustc_parse/src/parser/expr.rs | 2 +- compiler/rustc_parse/src/parser/item.rs | 2 +- compiler/rustc_parse/src/parser/stmt.rs | 10 +--- 6 files changed, 24 insertions(+), 76 deletions(-) (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index 6d4308cda1a..3253222b8f2 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -757,10 +757,6 @@ parse_struct_literal_body_without_path = struct literal body without path .suggestion = you might have forgotten to add the struct literal inside the block -parse_struct_literal_needing_parens = - invalid struct literal - .suggestion = you might need to surround the struct literal with parentheses - parse_struct_literal_not_allowed_here = struct literals are not allowed here .suggestion = surround the struct literal with parentheses diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index e090d9cf760..f813c3380fc 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -1272,24 +1272,6 @@ pub(crate) struct StructLiteralBodyWithoutPathSugg { pub after: Span, } -#[derive(Diagnostic)] -#[diag(parse_struct_literal_needing_parens)] -pub(crate) struct StructLiteralNeedingParens { - #[primary_span] - pub span: Span, - #[subdiagnostic] - pub sugg: StructLiteralNeedingParensSugg, -} - -#[derive(Subdiagnostic)] -#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")] -pub(crate) struct StructLiteralNeedingParensSugg { - #[suggestion_part(code = "(")] - pub before: Span, - #[suggestion_part(code = ")")] - pub after: Span, -} - #[derive(Diagnostic)] #[diag(parse_unmatched_angle_brackets)] pub(crate) struct UnmatchedAngleBrackets { diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index daa27b14669..ef044fe9d63 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -40,9 +40,8 @@ use crate::errors::{ HelpIdentifierStartsWithNumber, HelpUseLatestEdition, InInTypo, IncorrectAwait, IncorrectSemicolon, IncorrectUseOfAwait, IncorrectUseOfUse, PatternMethodParamWithoutBody, QuestionMarkInType, QuestionMarkInTypeSugg, SelfParamNotFirst, StructLiteralBodyWithoutPath, - StructLiteralBodyWithoutPathSugg, StructLiteralNeedingParens, StructLiteralNeedingParensSugg, - SuggAddMissingLetStmt, SuggEscapeIdentifier, SuggRemoveComma, TernaryOperator, - UnexpectedConstInGenericParam, UnexpectedConstParamDeclaration, + StructLiteralBodyWithoutPathSugg, SuggAddMissingLetStmt, SuggEscapeIdentifier, SuggRemoveComma, + TernaryOperator, UnexpectedConstInGenericParam, UnexpectedConstParamDeclaration, UnexpectedConstParamDeclarationSugg, UnmatchedAngleBrackets, UseEqInstead, WrapType, }; use crate::parser::attr::InnerAttrPolicy; @@ -949,7 +948,6 @@ impl<'a> Parser<'a> { lo: Span, s: BlockCheckMode, maybe_struct_name: token::Token, - can_be_struct_literal: bool, ) -> Option>> { if self.token.is_ident() && self.look_ahead(1, |t| t == &token::Colon) { // We might be having a struct literal where people forgot to include the path: @@ -971,49 +969,27 @@ impl<'a> Parser<'a> { // fn foo() -> Foo { // field: value, // } - let guar = err.delay_as_bug(); + // Suggest: + // fn foo() -> Foo { Path { + // field: value, + // } } + err.cancel(); self.restore_snapshot(snapshot); - if maybe_struct_name.is_ident() && can_be_struct_literal { - // Account for `if Example { a: one(), }.is_pos() {}`. - // expand `before` so that we take care of module path such as: - // `foo::Bar { ... } ` - // we expect to suggest `(foo::Bar { ... })` instead of `foo::(Bar { ... })` - let sm = self.psess.source_map(); - let before = maybe_struct_name.span.shrink_to_lo(); - if let Ok(extend_before) = sm.span_extend_prev_while(before, |t| { - t.is_alphanumeric() || t == ':' || t == '_' - }) { - Err(self.dcx().create_err(StructLiteralNeedingParens { - span: maybe_struct_name.span.to(expr.span), - sugg: StructLiteralNeedingParensSugg { - before: extend_before.shrink_to_lo(), - after: expr.span.shrink_to_hi(), - }, - })) - } else { - return None; - } - } else { - // Suggest: - // fn foo() -> Foo { Path { - // field: value, - // } } - self.dcx().emit_err(StructLiteralBodyWithoutPath { - span: expr.span, - sugg: StructLiteralBodyWithoutPathSugg { - before: expr.span.shrink_to_lo(), - after: expr.span.shrink_to_hi(), - }, - }); - Ok(self.mk_block( - thin_vec![self.mk_stmt_err(expr.span, guar)], - s, - lo.to(self.prev_token.span), - )) - } + let guar = self.dcx().emit_err(StructLiteralBodyWithoutPath { + span: expr.span, + sugg: StructLiteralBodyWithoutPathSugg { + before: expr.span.shrink_to_lo(), + after: expr.span.shrink_to_hi(), + }, + }); + Ok(self.mk_block( + thin_vec![self.mk_stmt_err(expr.span, guar)], + s, + lo.to(self.prev_token.span), + )) } (Err(err), Ok(tail)) => { - // We have a block tail that contains a somehow valid type ascription expr. + // We have a block tail that contains a somehow valid expr. err.cancel(); Ok(tail) } diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 79d12ed4bbe..92e83577f1b 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -2296,7 +2296,7 @@ impl<'a> Parser<'a> { }); } - let (attrs, blk) = self.parse_block_common(lo, blk_mode, true, None)?; + let (attrs, blk) = self.parse_block_common(lo, blk_mode, None)?; Ok(self.mk_expr_with_attrs(blk.span, ExprKind::Block(blk, opt_label), attrs)) } diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index f4df4044dd2..77e675ea91f 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -2529,7 +2529,7 @@ impl<'a> Parser<'a> { *sig_hi = self.prev_token.span; (AttrVec::new(), None) } else if self.check(exp!(OpenBrace)) || self.token.is_whole_block() { - self.parse_block_common(self.token.span, BlockCheckMode::Default, false, None) + self.parse_block_common(self.token.span, BlockCheckMode::Default, None) .map(|(attrs, body)| (attrs, Some(body)))? } else if self.token == token::Eq { // Recover `fn foo() = $expr;`. diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 368366c60d6..97cd4d2117f 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -668,7 +668,7 @@ impl<'a> Parser<'a> { &mut self, loop_header: Option, ) -> PResult<'a, (AttrVec, P)> { - self.parse_block_common(self.token.span, BlockCheckMode::Default, true, loop_header) + self.parse_block_common(self.token.span, BlockCheckMode::Default, loop_header) } /// Parses a block. Inner attributes are allowed, block labels are not. @@ -679,7 +679,6 @@ impl<'a> Parser<'a> { &mut self, lo: Span, blk_mode: BlockCheckMode, - can_be_struct_literal: bool, loop_header: Option, ) -> PResult<'a, (AttrVec, P)> { maybe_whole!(self, NtBlock, |block| (AttrVec::new(), block)); @@ -691,12 +690,7 @@ impl<'a> Parser<'a> { } let attrs = self.parse_inner_attributes()?; - let tail = match self.maybe_suggest_struct_literal( - lo, - blk_mode, - maybe_ident, - can_be_struct_literal, - ) { + let tail = match self.maybe_suggest_struct_literal(lo, blk_mode, maybe_ident) { Some(tail) => tail?, None => self.parse_block_tail(lo, blk_mode, AttemptLocalParseRecovery::Yes)?, }; -- cgit 1.4.1-3-g733a5