about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast/src/ast.rs8
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs2
-rw-r--r--compiler/rustc_ast/src/visit.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/autodiff.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/mod.rs1
-rw-r--r--compiler/rustc_expand/src/build.rs1
-rw-r--r--compiler/rustc_parse/messages.ftl4
-rw-r--r--compiler/rustc_parse/src/errors.rs18
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs57
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs16
-rw-r--r--compiler/rustc_parse/src/parser/item.rs2
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs19
-rw-r--r--compiler/rustc_resolve/src/late.rs13
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs14
-rw-r--r--src/tools/rustfmt/src/closures.rs1
-rw-r--r--src/tools/rustfmt/src/macros.rs1
-rw-r--r--src/tools/tidy/src/issues.txt1
-rw-r--r--tests/ui-fulldeps/pprust-expr-roundtrip.rs1
-rw-r--r--tests/ui/parser/issues/issue-111692.rs32
-rw-r--r--tests/ui/parser/issues/issue-111692.stderr46
-rw-r--r--tests/ui/parser/method-call-on-struct-literal-in-if-condition.rs13
-rw-r--r--tests/ui/parser/method-call-on-struct-literal-in-if-condition.stderr13
-rw-r--r--tests/ui/parser/struct-literal-in-for.rs17
-rw-r--r--tests/ui/parser/struct-literal-in-for.stderr31
-rw-r--r--tests/ui/parser/struct-literal-in-if.rs22
-rw-r--r--tests/ui/parser/struct-literal-in-if.stderr34
-rw-r--r--tests/ui/parser/struct-literal-in-match-discriminant.rs13
-rw-r--r--tests/ui/parser/struct-literal-in-match-discriminant.stderr18
-rw-r--r--tests/ui/parser/struct-literal-in-while.rs22
-rw-r--r--tests/ui/parser/struct-literal-in-while.stderr34
-rw-r--r--tests/ui/parser/struct-literal-restrictions-in-lamda.rs17
-rw-r--r--tests/ui/parser/struct-literal-restrictions-in-lamda.stderr37
-rw-r--r--tests/ui/parser/struct-literal-variant-in-if.rs25
-rw-r--r--tests/ui/parser/struct-literal-variant-in-if.stderr76
-rw-r--r--tests/ui/parser/struct-literals-in-invalid-places.rs92
-rw-r--r--tests/ui/parser/struct-literals-in-invalid-places.stderr234
-rw-r--r--tests/ui/parser/type-ascription-in-pattern.rs9
-rw-r--r--tests/ui/parser/type-ascription-in-pattern.stderr80
38 files changed, 411 insertions, 616 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index fd27be21326..064f05ef1f3 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -545,14 +545,6 @@ pub struct Block {
     pub rules: BlockCheckMode,
     pub span: Span,
     pub tokens: Option<LazyAttrTokenStream>,
-    /// The following *isn't* a parse error, but will cause multiple errors in following stages.
-    /// ```compile_fail
-    /// let x = {
-    ///     foo: var
-    /// };
-    /// ```
-    /// #34255
-    pub could_be_bare_literal: bool,
 }
 
 /// A match pattern.
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 474d38fceef..274fe312f7f 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -1222,7 +1222,7 @@ fn walk_mt<T: MutVisitor>(vis: &mut T, MutTy { ty, mutbl: _ }: &mut MutTy) {
 }
 
 pub fn walk_block<T: MutVisitor>(vis: &mut T, block: &mut P<Block>) {
-    let Block { id, stmts, rules: _, span, tokens, could_be_bare_literal: _ } = block.deref_mut();
+    let Block { id, stmts, rules: _, span, tokens } = block.deref_mut();
     vis.visit_id(id);
     stmts.flat_map_in_place(|stmt| vis.flat_map_stmt(stmt));
     visit_lazy_tts(vis, tokens);
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index dcf1d00910a..2716601ca4f 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -1067,7 +1067,7 @@ pub fn walk_field_def<'a, V: Visitor<'a>>(visitor: &mut V, field: &'a FieldDef)
 }
 
 pub fn walk_block<'a, V: Visitor<'a>>(visitor: &mut V, block: &'a Block) -> V::Result {
-    let Block { stmts, id: _, rules: _, span: _, tokens: _, could_be_bare_literal: _ } = block;
+    let Block { stmts, id: _, rules: _, span: _, tokens: _ } = block;
     walk_list!(visitor, visit_stmt, stmts);
     V::Result::output()
 }
diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs
index 5cd653c7945..be11711757e 100644
--- a/compiler/rustc_builtin_macros/src/autodiff.rs
+++ b/compiler/rustc_builtin_macros/src/autodiff.rs
@@ -395,7 +395,6 @@ mod llvm_enzyme {
             tokens: None,
             rules: unsf,
             span,
-            could_be_bare_literal: false,
         };
         let unsf_expr = ecx.expr_block(P(unsf_block));
         let blackbox_call_expr = ecx.expr_path(ecx.path(span, blackbox_path));
diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs
index c112589b131..50e7b989ed8 100644
--- a/compiler/rustc_builtin_macros/src/deriving/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs
@@ -110,7 +110,6 @@ fn call_unreachable(cx: &ExtCtxt<'_>, span: Span) -> P<ast::Expr> {
         rules: ast::BlockCheckMode::Unsafe(ast::CompilerGenerated),
         span,
         tokens: None,
-        could_be_bare_literal: false,
     }))
 }
 
diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs
index 2c9b5f40d0d..89a750bb39f 100644
--- a/compiler/rustc_expand/src/build.rs
+++ b/compiler/rustc_expand/src/build.rs
@@ -286,7 +286,6 @@ impl<'a> ExtCtxt<'a> {
             rules: BlockCheckMode::Default,
             span,
             tokens: None,
-            could_be_bare_literal: false,
         })
     }
 
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
@@ -1273,24 +1273,6 @@ pub(crate) struct StructLiteralBodyWithoutPathSugg {
 }
 
 #[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 {
     #[primary_span]
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index c1cca1186af..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<PResult<'a, P<Block>>> {
         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:
@@ -975,47 +973,23 @@ impl<'a> Parser<'a> {
                     // fn foo() -> Foo { Path {
                     //     field: value,
                     // } }
-                    let guar = err.delay_as_bug();
+                    err.cancel();
                     self.restore_snapshot(snapshot);
-                    let mut tail = self.mk_block(
+                    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),
-                    );
-                    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:
-                        // `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 {
-                        self.dcx().emit_err(StructLiteralBodyWithoutPath {
-                            span: expr.span,
-                            sugg: StructLiteralBodyWithoutPathSugg {
-                                before: expr.span.shrink_to_lo(),
-                                after: expr.span.shrink_to_hi(),
-                            },
-                        });
-                        Ok(tail)
-                    }
+                    ))
                 }
                 (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)
                 }
@@ -1025,10 +999,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/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index c48f91643e8..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))
     }
 
@@ -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/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index c32a79f6909..aad18578375 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -2538,7 +2538,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 0fe247078d5..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<Span>,
     ) -> PResult<'a, (AttrVec, P<Block>)> {
-        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<Span>,
     ) -> PResult<'a, (AttrVec, P<Block>)> {
         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)?,
         };
@@ -1043,14 +1037,7 @@ impl<'a> Parser<'a> {
         rules: BlockCheckMode,
         span: Span,
     ) -> P<Block> {
-        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 {
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 11d07407aa1..6bc644e9e11 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -675,11 +675,6 @@ struct DiagMetadata<'ast> {
     /// they are used (in a `break` or `continue` statement)
     unused_labels: FxIndexMap<NodeId, Span>,
 
-    /// Only used for better errors on `let x = { foo: bar };`.
-    /// In the case of a parse error with `let x = { foo: bar, };`, this isn't needed, it's only
-    /// needed for cases where this parses as a correct type ascription.
-    current_block_could_be_bare_struct_literal: Option<Span>,
-
     /// Only used for better errors on `let <pat>: <expr, not type>;`.
     current_let_binding: Option<(Span, Option<Span>, Option<Span>)>,
 
@@ -4661,13 +4656,6 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
             self.ribs[ValueNS].push(Rib::new(RibKind::Normal));
         }
 
-        let prev = self.diag_metadata.current_block_could_be_bare_struct_literal.take();
-        if let (true, [Stmt { kind: StmtKind::Expr(expr), .. }]) =
-            (block.could_be_bare_literal, &block.stmts[..])
-            && let ExprKind::Type(..) = expr.kind
-        {
-            self.diag_metadata.current_block_could_be_bare_struct_literal = Some(block.span);
-        }
         // Descend into the block.
         for stmt in &block.stmts {
             if let StmtKind::Item(ref item) = stmt.kind
@@ -4681,7 +4669,6 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
 
             self.visit_stmt(stmt);
         }
-        self.diag_metadata.current_block_could_be_bare_struct_literal = prev;
 
         // Move back up.
         self.parent_scope.module = orig_module;
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 75232e0de00..cf8db2267f4 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -450,7 +450,6 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
             err.span_suggestion_verbose(sugg.0, sugg.1, &sugg.2, Applicability::MaybeIncorrect);
         }
 
-        self.suggest_bare_struct_literal(&mut err);
         self.suggest_changing_type_to_const_param(&mut err, res, source, span);
         self.explain_functions_in_pattern(&mut err, res, source);
 
@@ -1279,19 +1278,6 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
         }
     }
 
-    fn suggest_bare_struct_literal(&mut self, err: &mut Diag<'_>) {
-        if let Some(span) = self.diag_metadata.current_block_could_be_bare_struct_literal {
-            err.multipart_suggestion(
-                "you might have meant to write a `struct` literal",
-                vec![
-                    (span.shrink_to_lo(), "{ SomeStruct ".to_string()),
-                    (span.shrink_to_hi(), "}".to_string()),
-                ],
-                Applicability::HasPlaceholders,
-            );
-        }
-    }
-
     fn explain_functions_in_pattern(
         &mut self,
         err: &mut Diag<'_>,
diff --git a/src/tools/rustfmt/src/closures.rs b/src/tools/rustfmt/src/closures.rs
index a37b47e3bc9..61e148cdf18 100644
--- a/src/tools/rustfmt/src/closures.rs
+++ b/src/tools/rustfmt/src/closures.rs
@@ -176,7 +176,6 @@ fn rewrite_closure_with_block(
             .first()
             .map(|attr| attr.span.to(body.span))
             .unwrap_or(body.span),
-        could_be_bare_literal: false,
     };
     let block = crate::expr::rewrite_block_with_visitor(
         context,
diff --git a/src/tools/rustfmt/src/macros.rs b/src/tools/rustfmt/src/macros.rs
index 664c90b991a..e239ff47c04 100644
--- a/src/tools/rustfmt/src/macros.rs
+++ b/src/tools/rustfmt/src/macros.rs
@@ -423,7 +423,6 @@ fn rewrite_empty_macro_def_body(
         rules: ast::BlockCheckMode::Default,
         span,
         tokens: None,
-        could_be_bare_literal: false,
     };
     block.rewrite_result(context, shape)
 }
diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt
index 4a929a376d7..a33e03d5861 100644
--- a/src/tools/tidy/src/issues.txt
+++ b/src/tools/tidy/src/issues.txt
@@ -3189,7 +3189,6 @@ ui/parser/issues/issue-108495-dec.rs
 ui/parser/issues/issue-110014.rs
 ui/parser/issues/issue-111148.rs
 ui/parser/issues/issue-111416.rs
-ui/parser/issues/issue-111692.rs
 ui/parser/issues/issue-112188.rs
 ui/parser/issues/issue-112458.rs
 ui/parser/issues/issue-113110-non-item-at-module-root.rs
diff --git a/tests/ui-fulldeps/pprust-expr-roundtrip.rs b/tests/ui-fulldeps/pprust-expr-roundtrip.rs
index 37e328a315f..4a866560e79 100644
--- a/tests/ui-fulldeps/pprust-expr-roundtrip.rs
+++ b/tests/ui-fulldeps/pprust-expr-roundtrip.rs
@@ -114,7 +114,6 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) {
                     rules: BlockCheckMode::Default,
                     span: DUMMY_SP,
                     tokens: None,
-                    could_be_bare_literal: false,
                 });
                 iter_exprs(depth - 1, &mut |e| g(ExprKind::If(e, block.clone(), None)));
             }
diff --git a/tests/ui/parser/issues/issue-111692.rs b/tests/ui/parser/issues/issue-111692.rs
deleted file mode 100644
index 56096f706a8..00000000000
--- a/tests/ui/parser/issues/issue-111692.rs
+++ /dev/null
@@ -1,32 +0,0 @@
-mod module {
-    #[derive(Eq, PartialEq)]
-    pub struct Type {
-        pub x: u8,
-        pub y: u8,
-    }
-
-    pub const C: u8 = 32u8;
-}
-
-fn test(x: module::Type) {
-    if x == module::Type { x: module::C, y: 1 } { //~ ERROR invalid struct literal
-    }
-}
-
-fn test2(x: module::Type) {
-    if x ==module::Type { x: module::C, y: 1 } { //~ ERROR invalid struct literal
-    }
-}
-
-
-fn test3(x: module::Type) {
-    if x == Type { x: module::C, y: 1 } { //~ ERROR invalid struct literal
-    }
-}
-
-fn test4(x: module::Type) {
-    if x == demo_module::Type { x: module::C, y: 1 } { //~ ERROR invalid struct literal
-    }
-}
-
-fn main() { }
diff --git a/tests/ui/parser/issues/issue-111692.stderr b/tests/ui/parser/issues/issue-111692.stderr
deleted file mode 100644
index 068b0483b0f..00000000000
--- a/tests/ui/parser/issues/issue-111692.stderr
+++ /dev/null
@@ -1,46 +0,0 @@
-error: invalid struct literal
-  --> $DIR/issue-111692.rs:12:21
-   |
-LL |     if x == module::Type { x: module::C, y: 1 } {
-   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: you might need to 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
-   |
-LL |     if x ==module::Type { x: module::C, y: 1 } {
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: you might need to 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
-   |
-LL |     if x == Type { x: module::C, y: 1 } {
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: you might need to 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
-   |
-LL |     if x == demo_module::Type { x: module::C, y: 1 } {
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: you might need to surround the struct literal with parentheses
-   |
-LL |     if x == (demo_module::Type { x: module::C, y: 1 }) {
-   |             +                                        +
-
-error: aborting due to 4 previous errors
-
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
deleted file mode 100644
index 8be7c9ee8ac..00000000000
--- a/tests/ui/parser/method-call-on-struct-literal-in-if-condition.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-pub struct Example { a: i32 }
-
-impl Example {
-    fn is_pos(&self) -> bool { self.a > 0 }
-}
-
-fn one() -> i32 { 1 }
-
-fn main() {
-    if Example { a: one(), }.is_pos() { //~ ERROR invalid struct literal
-        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
deleted file mode 100644
index f7822ba1124..00000000000
--- a/tests/ui/parser/method-call-on-struct-literal-in-if-condition.stderr
+++ /dev/null
@@ -1,13 +0,0 @@
-error: invalid struct literal
-  --> $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
-   |
-LL |     if (Example { a: one(), }).is_pos() {
-   |        +                     +
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/parser/struct-literal-in-for.rs b/tests/ui/parser/struct-literal-in-for.rs
deleted file mode 100644
index 3227ae37bfd..00000000000
--- a/tests/ui/parser/struct-literal-in-for.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-struct Foo {
-    x: isize,
-}
-
-impl Foo {
-    fn hi(&self) -> bool {
-        true
-    }
-}
-
-fn main() {
-    for x in Foo { //~ ERROR struct literals are not allowed here
-        x: 3       //~^ ERROR `bool` is not an iterator
-    }.hi() {
-        println!("yo");
-    }
-}
diff --git a/tests/ui/parser/struct-literal-in-for.stderr b/tests/ui/parser/struct-literal-in-for.stderr
deleted file mode 100644
index 1c91eba68e3..00000000000
--- a/tests/ui/parser/struct-literal-in-for.stderr
+++ /dev/null
@@ -1,31 +0,0 @@
-error: struct literals are not allowed here
-  --> $DIR/struct-literal-in-for.rs:12:14
-   |
-LL |       for x in Foo {
-   |  ______________^
-LL | |         x: 3
-LL | |     }.hi() {
-   | |_____^
-   |
-help: surround the struct literal with parentheses
-   |
-LL ~     for x in (Foo {
-LL |         x: 3
-LL ~     }).hi() {
-   |
-
-error[E0277]: `bool` is not an iterator
-  --> $DIR/struct-literal-in-for.rs:12:14
-   |
-LL |       for x in Foo {
-   |  ______________^
-LL | |         x: 3
-LL | |     }.hi() {
-   | |__________^ `bool` is not an iterator
-   |
-   = help: the trait `Iterator` is not implemented for `bool`
-   = note: required for `bool` to implement `IntoIterator`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/parser/struct-literal-in-if.rs b/tests/ui/parser/struct-literal-in-if.rs
deleted file mode 100644
index c4a253c3da2..00000000000
--- a/tests/ui/parser/struct-literal-in-if.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-struct Foo {
-    x: isize,
-}
-
-impl Foo {
-    fn hi(&self) -> bool {
-        true
-    }
-}
-
-fn main() {
-    if Foo { //~ ERROR struct literals are not allowed here
-        x: 3
-    }.hi() {
-        println!("yo");
-    }
-    if let true = Foo { //~ ERROR struct literals are not allowed here
-        x: 3
-    }.hi() {
-        println!("yo");
-    }
-}
diff --git a/tests/ui/parser/struct-literal-in-if.stderr b/tests/ui/parser/struct-literal-in-if.stderr
deleted file mode 100644
index 8b72469fcf5..00000000000
--- a/tests/ui/parser/struct-literal-in-if.stderr
+++ /dev/null
@@ -1,34 +0,0 @@
-error: struct literals are not allowed here
-  --> $DIR/struct-literal-in-if.rs:12:8
-   |
-LL |       if Foo {
-   |  ________^
-LL | |         x: 3
-LL | |     }.hi() {
-   | |_____^
-   |
-help: surround the struct literal with parentheses
-   |
-LL ~     if (Foo {
-LL |         x: 3
-LL ~     }).hi() {
-   |
-
-error: struct literals are not allowed here
-  --> $DIR/struct-literal-in-if.rs:17:19
-   |
-LL |       if let true = Foo {
-   |  ___________________^
-LL | |         x: 3
-LL | |     }.hi() {
-   | |_____^
-   |
-help: surround the struct literal with parentheses
-   |
-LL ~     if let true = (Foo {
-LL |         x: 3
-LL ~     }).hi() {
-   |
-
-error: aborting due to 2 previous errors
-
diff --git a/tests/ui/parser/struct-literal-in-match-discriminant.rs b/tests/ui/parser/struct-literal-in-match-discriminant.rs
deleted file mode 100644
index ce132df5a88..00000000000
--- a/tests/ui/parser/struct-literal-in-match-discriminant.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-struct Foo {
-    x: isize,
-}
-
-fn main() {
-    match Foo { //~ ERROR struct literals are not allowed here
-        x: 3
-    } {
-        Foo {
-            x: x
-        } => {}
-    }
-}
diff --git a/tests/ui/parser/struct-literal-in-match-discriminant.stderr b/tests/ui/parser/struct-literal-in-match-discriminant.stderr
deleted file mode 100644
index 5177f5f126e..00000000000
--- a/tests/ui/parser/struct-literal-in-match-discriminant.stderr
+++ /dev/null
@@ -1,18 +0,0 @@
-error: struct literals are not allowed here
-  --> $DIR/struct-literal-in-match-discriminant.rs:6:11
-   |
-LL |       match Foo {
-   |  ___________^
-LL | |         x: 3
-LL | |     } {
-   | |_____^
-   |
-help: surround the struct literal with parentheses
-   |
-LL ~     match (Foo {
-LL |         x: 3
-LL ~     }) {
-   |
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/parser/struct-literal-in-while.rs b/tests/ui/parser/struct-literal-in-while.rs
deleted file mode 100644
index 86931f7888d..00000000000
--- a/tests/ui/parser/struct-literal-in-while.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-struct Foo {
-    x: isize,
-}
-
-impl Foo {
-    fn hi(&self) -> bool {
-        true
-    }
-}
-
-fn main() {
-    while Foo { //~ ERROR struct literals are not allowed here
-        x: 3
-    }.hi() {
-        println!("yo");
-    }
-    while let true = Foo { //~ ERROR struct literals are not allowed here
-        x: 3
-    }.hi() {
-        println!("yo");
-    }
-}
diff --git a/tests/ui/parser/struct-literal-in-while.stderr b/tests/ui/parser/struct-literal-in-while.stderr
deleted file mode 100644
index 13d003608a1..00000000000
--- a/tests/ui/parser/struct-literal-in-while.stderr
+++ /dev/null
@@ -1,34 +0,0 @@
-error: struct literals are not allowed here
-  --> $DIR/struct-literal-in-while.rs:12:11
-   |
-LL |       while Foo {
-   |  ___________^
-LL | |         x: 3
-LL | |     }.hi() {
-   | |_____^
-   |
-help: surround the struct literal with parentheses
-   |
-LL ~     while (Foo {
-LL |         x: 3
-LL ~     }).hi() {
-   |
-
-error: struct literals are not allowed here
-  --> $DIR/struct-literal-in-while.rs:17:22
-   |
-LL |       while let true = Foo {
-   |  ______________________^
-LL | |         x: 3
-LL | |     }.hi() {
-   | |_____^
-   |
-help: surround the struct literal with parentheses
-   |
-LL ~     while let true = (Foo {
-LL |         x: 3
-LL ~     }).hi() {
-   |
-
-error: aborting due to 2 previous errors
-
diff --git a/tests/ui/parser/struct-literal-restrictions-in-lamda.rs b/tests/ui/parser/struct-literal-restrictions-in-lamda.rs
deleted file mode 100644
index e185153dcf6..00000000000
--- a/tests/ui/parser/struct-literal-restrictions-in-lamda.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-struct Foo {
-    x: isize,
-}
-
-impl Foo {
-    fn hi(&self) -> bool {
-        true
-    }
-}
-
-fn main() {
-    while || Foo { //~ ERROR struct literals are not allowed here
-        x: 3       //~^ ERROR mismatched types
-    }.hi() {
-        println!("yo");
-    }
-}
diff --git a/tests/ui/parser/struct-literal-restrictions-in-lamda.stderr b/tests/ui/parser/struct-literal-restrictions-in-lamda.stderr
deleted file mode 100644
index c715486e2da..00000000000
--- a/tests/ui/parser/struct-literal-restrictions-in-lamda.stderr
+++ /dev/null
@@ -1,37 +0,0 @@
-error: struct literals are not allowed here
-  --> $DIR/struct-literal-restrictions-in-lamda.rs:12:14
-   |
-LL |       while || Foo {
-   |  ______________^
-LL | |         x: 3
-LL | |     }.hi() {
-   | |_____^
-   |
-help: surround the struct literal with parentheses
-   |
-LL ~     while || (Foo {
-LL |         x: 3
-LL ~     }).hi() {
-   |
-
-error[E0308]: mismatched types
-  --> $DIR/struct-literal-restrictions-in-lamda.rs:12:11
-   |
-LL |       while || Foo {
-   |  ___________^
-LL | |         x: 3
-LL | |     }.hi() {
-   | |__________^ expected `bool`, found closure
-   |
-   = note: expected type `bool`
-           found closure `{closure@$DIR/struct-literal-restrictions-in-lamda.rs:12:11: 12:13}`
-help: use parentheses to call this closure
-   |
-LL ~     while (|| Foo {
-LL |         x: 3
-LL ~     }.hi())() {
-   |
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/parser/struct-literal-variant-in-if.rs b/tests/ui/parser/struct-literal-variant-in-if.rs
deleted file mode 100644
index 4ef8effaf1f..00000000000
--- a/tests/ui/parser/struct-literal-variant-in-if.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
-enum E {
-    V { field: bool },
-    I { field1: bool, field2: usize },
-    J { field: isize },
-    K { field: &'static str},
-}
-fn test_E(x: E) {
-    let field = true;
-    if x == E::V { field } {}
-    //~^ ERROR expected value, found struct variant `E::V`
-    //~| ERROR mismatched types
-    if x == E::I { field1: true, field2: 42 } {}
-    //~^ ERROR struct literals are not allowed here
-    if x == E::V { field: false } {}
-    //~^ ERROR struct literals are not allowed here
-    if x == E::J { field: -42 } {}
-    //~^ ERROR struct literals are not allowed here
-    if x == E::K { field: "" } {}
-    //~^ ERROR struct literals are not allowed here
-    let y: usize = ();
-    //~^ ERROR mismatched types
-}
-
-fn main() {}
diff --git a/tests/ui/parser/struct-literal-variant-in-if.stderr b/tests/ui/parser/struct-literal-variant-in-if.stderr
deleted file mode 100644
index 15f059f145b..00000000000
--- a/tests/ui/parser/struct-literal-variant-in-if.stderr
+++ /dev/null
@@ -1,76 +0,0 @@
-error: struct literals are not allowed here
-  --> $DIR/struct-literal-variant-in-if.rs:13:13
-   |
-LL |     if x == E::I { field1: true, field2: 42 } {}
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: surround the struct literal with parentheses
-   |
-LL |     if x == (E::I { field1: true, field2: 42 }) {}
-   |             +                                 +
-
-error: struct literals are not allowed here
-  --> $DIR/struct-literal-variant-in-if.rs:15:13
-   |
-LL |     if x == E::V { field: false } {}
-   |             ^^^^^^^^^^^^^^^^^^^^^
-   |
-help: surround the struct literal with parentheses
-   |
-LL |     if x == (E::V { field: false }) {}
-   |             +                     +
-
-error: struct literals are not allowed here
-  --> $DIR/struct-literal-variant-in-if.rs:17:13
-   |
-LL |     if x == E::J { field: -42 } {}
-   |             ^^^^^^^^^^^^^^^^^^^
-   |
-help: surround the struct literal with parentheses
-   |
-LL |     if x == (E::J { field: -42 }) {}
-   |             +                   +
-
-error: struct literals are not allowed here
-  --> $DIR/struct-literal-variant-in-if.rs:19:13
-   |
-LL |     if x == E::K { field: "" } {}
-   |             ^^^^^^^^^^^^^^^^^^
-   |
-help: surround the struct literal with parentheses
-   |
-LL |     if x == (E::K { field: "" }) {}
-   |             +                  +
-
-error[E0533]: expected value, found struct variant `E::V`
-  --> $DIR/struct-literal-variant-in-if.rs:10:13
-   |
-LL |     if x == E::V { field } {}
-   |             ^^^^ not a value
-   |
-help: you might have meant to create a new value of the struct
-   |
-LL |     if x == (E::V { field }) {}
-   |             +              +
-
-error[E0308]: mismatched types
-  --> $DIR/struct-literal-variant-in-if.rs:10:20
-   |
-LL |     if x == E::V { field } {}
-   |     ---------------^^^^^--
-   |     |              |
-   |     |              expected `()`, found `bool`
-   |     expected this to be `()`
-
-error[E0308]: mismatched types
-  --> $DIR/struct-literal-variant-in-if.rs:21:20
-   |
-LL |     let y: usize = ();
-   |            -----   ^^ expected `usize`, found `()`
-   |            |
-   |            expected due to this
-
-error: aborting due to 7 previous errors
-
-Some errors have detailed explanations: E0308, E0533.
-For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/parser/struct-literals-in-invalid-places.rs b/tests/ui/parser/struct-literals-in-invalid-places.rs
new file mode 100644
index 00000000000..eed51b94583
--- /dev/null
+++ b/tests/ui/parser/struct-literals-in-invalid-places.rs
@@ -0,0 +1,92 @@
+fn main() {
+    if Foo { x: 3 }.hi() { //~ ERROR struct literals are not allowed here
+        println!("yo");
+    }
+    if let true = Foo { x: 3 }.hi() { //~ ERROR struct literals are not allowed here
+        println!("yo");
+    }
+
+    for x in Foo { x: 3 }.hi() { //~ ERROR struct literals are not allowed here
+        //~^ ERROR `bool` is not an iterator
+        println!("yo");
+    }
+
+    while Foo { x: 3 }.hi() { //~ ERROR struct literals are not allowed here
+        println!("yo");
+    }
+    while let true = Foo { x: 3 }.hi() { //~ ERROR struct literals are not allowed here
+        println!("yo");
+    }
+
+    match Foo { x: 3 } { //~ ERROR struct literals are not allowed here
+        Foo { x: x } => {}
+    }
+
+    let _ = |x: E| {
+        let field = true;
+        if x == E::V { field } {}
+        //~^ ERROR expected value, found struct variant `E::V`
+        //~| ERROR mismatched types
+        if x == E::I { field1: true, field2: 42 } {}
+        //~^ ERROR struct literals are not allowed here
+        if x == E::V { field: false } {}
+        //~^ ERROR struct literals are not allowed here
+        if x == E::J { field: -42 } {}
+        //~^ ERROR struct literals are not allowed here
+        if x == E::K { field: "" } {}
+        //~^ ERROR struct literals are not allowed here
+        let y: usize = ();
+        //~^ ERROR mismatched types
+    };
+
+    // Regression test for <https://github.com/rust-lang/rust/issues/43412>.
+    while || Foo { x: 3 }.hi() { //~ ERROR struct literals are not allowed here
+        //~^ ERROR mismatched types
+        println!("yo");
+    }
+
+    // This uses `one()` over `1` as token `one` may begin a type and thus back when type ascription
+    // `$expr : $ty` still existed, `{ x: one` could've been the start of a block expr which used to
+    // make the compiler take a different execution path. Now it no longer makes a difference tho.
+
+    // Regression test for <https://github.com/rust-lang/rust/issues/82051>.
+    if Foo { x: one(), }.hi() { //~ ERROR struct literals are not allowed here
+        println!("Positive!");
+    }
+
+    const FOO: Foo = Foo { x: 1 };
+    // Below, test that we correctly parenthesize the struct literals.
+
+    // Regression test for <https://github.com/rust-lang/rust/issues/112278>.
+    if FOO == self::Foo { x: one() } {} //~ ERROR struct literals are not allowed here
+
+    if FOO == Foo::<> { x: one() } {} //~ ERROR struct literals are not allowed here
+
+    fn env<T: Trait<Out = Foo>>() {
+        if FOO == <T as Trait>::Out { x: one() } {} //~ ERROR struct literals are not allowed here
+        //~^ ERROR usage of qualified paths in this context is experimental
+    }
+}
+
+#[derive(PartialEq, Eq)]
+struct Foo {
+    x: isize,
+}
+
+impl Foo {
+    fn hi(&self) -> bool {
+        true
+    }
+}
+
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
+enum E {
+    V { field: bool },
+    I { field1: bool, field2: usize },
+    J { field: isize },
+    K { field: &'static str},
+}
+
+fn one() -> isize { 1 }
+
+trait Trait { type Out; }
diff --git a/tests/ui/parser/struct-literals-in-invalid-places.stderr b/tests/ui/parser/struct-literals-in-invalid-places.stderr
new file mode 100644
index 00000000000..39dc2d2efb7
--- /dev/null
+++ b/tests/ui/parser/struct-literals-in-invalid-places.stderr
@@ -0,0 +1,234 @@
+error: struct literals are not allowed here
+  --> $DIR/struct-literals-in-invalid-places.rs:2:8
+   |
+LL |     if Foo { x: 3 }.hi() {
+   |        ^^^^^^^^^^^^
+   |
+help: surround the struct literal with parentheses
+   |
+LL |     if (Foo { x: 3 }).hi() {
+   |        +            +
+
+error: struct literals are not allowed here
+  --> $DIR/struct-literals-in-invalid-places.rs:5:19
+   |
+LL |     if let true = Foo { x: 3 }.hi() {
+   |                   ^^^^^^^^^^^^
+   |
+help: surround the struct literal with parentheses
+   |
+LL |     if let true = (Foo { x: 3 }).hi() {
+   |                   +            +
+
+error: struct literals are not allowed here
+  --> $DIR/struct-literals-in-invalid-places.rs:9:14
+   |
+LL |     for x in Foo { x: 3 }.hi() {
+   |              ^^^^^^^^^^^^
+   |
+help: surround the struct literal with parentheses
+   |
+LL |     for x in (Foo { x: 3 }).hi() {
+   |              +            +
+
+error: struct literals are not allowed here
+  --> $DIR/struct-literals-in-invalid-places.rs:14:11
+   |
+LL |     while Foo { x: 3 }.hi() {
+   |           ^^^^^^^^^^^^
+   |
+help: surround the struct literal with parentheses
+   |
+LL |     while (Foo { x: 3 }).hi() {
+   |           +            +
+
+error: struct literals are not allowed here
+  --> $DIR/struct-literals-in-invalid-places.rs:17:22
+   |
+LL |     while let true = Foo { x: 3 }.hi() {
+   |                      ^^^^^^^^^^^^
+   |
+help: surround the struct literal with parentheses
+   |
+LL |     while let true = (Foo { x: 3 }).hi() {
+   |                      +            +
+
+error: struct literals are not allowed here
+  --> $DIR/struct-literals-in-invalid-places.rs:21:11
+   |
+LL |     match Foo { x: 3 } {
+   |           ^^^^^^^^^^^^
+   |
+help: surround the struct literal with parentheses
+   |
+LL |     match (Foo { x: 3 }) {
+   |           +            +
+
+error: struct literals are not allowed here
+  --> $DIR/struct-literals-in-invalid-places.rs:30:17
+   |
+LL |         if x == E::I { field1: true, field2: 42 } {}
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: surround the struct literal with parentheses
+   |
+LL |         if x == (E::I { field1: true, field2: 42 }) {}
+   |                 +                                 +
+
+error: struct literals are not allowed here
+  --> $DIR/struct-literals-in-invalid-places.rs:32:17
+   |
+LL |         if x == E::V { field: false } {}
+   |                 ^^^^^^^^^^^^^^^^^^^^^
+   |
+help: surround the struct literal with parentheses
+   |
+LL |         if x == (E::V { field: false }) {}
+   |                 +                     +
+
+error: struct literals are not allowed here
+  --> $DIR/struct-literals-in-invalid-places.rs:34:17
+   |
+LL |         if x == E::J { field: -42 } {}
+   |                 ^^^^^^^^^^^^^^^^^^^
+   |
+help: surround the struct literal with parentheses
+   |
+LL |         if x == (E::J { field: -42 }) {}
+   |                 +                   +
+
+error: struct literals are not allowed here
+  --> $DIR/struct-literals-in-invalid-places.rs:36:17
+   |
+LL |         if x == E::K { field: "" } {}
+   |                 ^^^^^^^^^^^^^^^^^^
+   |
+help: surround the struct literal with parentheses
+   |
+LL |         if x == (E::K { field: "" }) {}
+   |                 +                  +
+
+error: struct literals are not allowed here
+  --> $DIR/struct-literals-in-invalid-places.rs:43:14
+   |
+LL |     while || Foo { x: 3 }.hi() {
+   |              ^^^^^^^^^^^^
+   |
+help: surround the struct literal with parentheses
+   |
+LL |     while || (Foo { x: 3 }).hi() {
+   |              +            +
+
+error: struct literals are not allowed here
+  --> $DIR/struct-literals-in-invalid-places.rs:53:8
+   |
+LL |     if Foo { x: one(), }.hi() {
+   |        ^^^^^^^^^^^^^^^^^
+   |
+help: surround the struct literal with parentheses
+   |
+LL |     if (Foo { x: one(), }).hi() {
+   |        +                 +
+
+error: struct literals are not allowed here
+  --> $DIR/struct-literals-in-invalid-places.rs:61:15
+   |
+LL |     if FOO == self::Foo { x: one() } {}
+   |               ^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: surround the struct literal with parentheses
+   |
+LL |     if FOO == (self::Foo { x: one() }) {}
+   |               +                      +
+
+error: struct literals are not allowed here
+  --> $DIR/struct-literals-in-invalid-places.rs:63:15
+   |
+LL |     if FOO == Foo::<> { x: one() } {}
+   |               ^^^^^^^^^^^^^^^^^^^^
+   |
+help: surround the struct literal with parentheses
+   |
+LL |     if FOO == (Foo::<> { x: one() }) {}
+   |               +                    +
+
+error: struct literals are not allowed here
+  --> $DIR/struct-literals-in-invalid-places.rs:66:19
+   |
+LL |         if FOO == <T as Trait>::Out { x: one() } {}
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: surround the struct literal with parentheses
+   |
+LL |         if FOO == (<T as Trait>::Out { x: one() }) {}
+   |                   +                              +
+
+error[E0658]: usage of qualified paths in this context is experimental
+  --> $DIR/struct-literals-in-invalid-places.rs:66:19
+   |
+LL |         if FOO == <T as Trait>::Out { x: one() } {}
+   |                   ^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #86935 <https://github.com/rust-lang/rust/issues/86935> for more information
+   = help: add `#![feature(more_qualified_paths)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0277]: `bool` is not an iterator
+  --> $DIR/struct-literals-in-invalid-places.rs:9:14
+   |
+LL |     for x in Foo { x: 3 }.hi() {
+   |              ^^^^^^^^^^^^^^^^^ `bool` is not an iterator
+   |
+   = help: the trait `Iterator` is not implemented for `bool`
+   = note: required for `bool` to implement `IntoIterator`
+
+error[E0533]: expected value, found struct variant `E::V`
+  --> $DIR/struct-literals-in-invalid-places.rs:27:17
+   |
+LL |         if x == E::V { field } {}
+   |                 ^^^^ not a value
+   |
+help: you might have meant to create a new value of the struct
+   |
+LL |         if x == (E::V { field }) {}
+   |                 +              +
+
+error[E0308]: mismatched types
+  --> $DIR/struct-literals-in-invalid-places.rs:27:24
+   |
+LL |         if x == E::V { field } {}
+   |         ---------------^^^^^--
+   |         |              |
+   |         |              expected `()`, found `bool`
+   |         expected this to be `()`
+   |
+help: you might have meant to return this value
+   |
+LL |         if x == E::V { return field; } {}
+   |                        ++++++      +
+
+error[E0308]: mismatched types
+  --> $DIR/struct-literals-in-invalid-places.rs:38:24
+   |
+LL |         let y: usize = ();
+   |                -----   ^^ expected `usize`, found `()`
+   |                |
+   |                expected due to this
+
+error[E0308]: mismatched types
+  --> $DIR/struct-literals-in-invalid-places.rs:43:11
+   |
+LL |     while || Foo { x: 3 }.hi() {
+   |           ^^^^^^^^^^^^^^^^^^^^ expected `bool`, found closure
+   |
+   = note: expected type `bool`
+           found closure `{closure@$DIR/struct-literals-in-invalid-places.rs:43:11: 43:13}`
+help: use parentheses to call this closure
+   |
+LL |     while (|| Foo { x: 3 }.hi())() {
+   |           +                    +++
+
+error: aborting due to 21 previous errors
+
+Some errors have detailed explanations: E0277, E0308, E0533, E0658.
+For more information about an error, try `rustc --explain E0277`.
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`.