Skip to content

Commit 30344f7

Browse files
authored
Rollup merge of #138898 - fmease:decrustify-parser-post-ty-ascr, r=compiler-errors
Mostly parser: Eliminate code that's been dead / semi-dead since the removal of type ascription syntax **Disclaimer**: This PR is intended to mostly clean up code as opposed to bringing about behavioral changes. Therefore it doesn't aim to address any of the 'FIXME: remove after a month [dated: 2023-05-02]: "type ascription syntax has been removed, see issue [#]101728"'. --- By commit: 1. Removes truly dead code: * Since 1.71 (#109128) `let _ = { f: x };` is a syntax error as opposed to a semantic error which allows the parse-time diagnostic (suggestion) "*struct literal body without path // you might have forgotten […]*" to kick in. * The analysis-time diagnostic (suggestion) from <=1.70 "*cannot find value \`f\` in this scope // you might have forgotten […]*" is therefore no longer reachable. 2. Updates `is_certainly_not_a_block` to be in line with the current grammar: * The seq. `{ ident:` is definitely not the start of a block. Before the removal of ty ascr, `{ ident: ty_start` would begin a block expr. * This shouldn't make more code compile IINM, it should *ultimately* only affect diagnostics. * For example, `if T { f: () } {}` will now be interpreted as an `if` with struct lit `T { f: () }` as its *condition* (which is banned in the parser anyway) as opposed to just `T` (with the *consequent* being `f : ()` which is also invalid (since 1.71)). The diagnostics are almost the same because we have two separate parse recovery procedures + diagnostics: `StructLiteralNeedingParens` (*invalid struct lit*) before and `StructLiteralNotAllowedHere` (*struct lits aren't allowed here*) now, as you can see from the diff. * (As an aside, even before this PR, fn `maybe_suggest_struct_literal` should've just used the much older & clearer `StructLiteralNotAllowedHere`) * NB: This does sadly regress the compiler output for `tests/ui/parser/type-ascription-in-pattern.rs` but that can be fixed in follow-up PRs. It's not super important IMO and a natural consequence. 3. Removes code that's become dead due to the prior commit. * Basically reverts #106620 + #112475 (without regressing rustc's output!). * Now the older & more robust parse recovery procedure (cc `StructLiteralNotAllowedHere`) takes care of the cases the removed code used to handle. * This automatically fixes the suggestions for \[[playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=7e2030163b11ee96d17adc3325b01780)\]: * `if Ty::<i32> { f: K }.m() {}`: `if Ty::<i32> { SomeStruct { f: K } }.m() {}` (broken) → ` if (Ty::<i32> { f: K }).m() {}` * `if <T as Trait>::Out { f: K::<> }.m() {}`: `if <T as Trait>(::Out { f: K::<> }).m() {}` (broken) → `if (<T as Trait>::Out { f: K::<> }).m() {}` 4. Merge and simplify UI tests pertaining to this issue, so it's easier to add more regression tests like for the two cases mentioned above. 5. Merge UI tests and add the two regression tests. Best reviewed commit by commit (on request I'll partially squash after approval).
2 parents ff325e0 + b501e58 commit 30344f7

38 files changed

+411
-616
lines changed

Diff for: compiler/rustc_ast/src/ast.rs

-8
Original file line numberDiff line numberDiff line change
@@ -545,14 +545,6 @@ pub struct Block {
545545
pub rules: BlockCheckMode,
546546
pub span: Span,
547547
pub tokens: Option<LazyAttrTokenStream>,
548-
/// The following *isn't* a parse error, but will cause multiple errors in following stages.
549-
/// ```compile_fail
550-
/// let x = {
551-
/// foo: var
552-
/// };
553-
/// ```
554-
/// #34255
555-
pub could_be_bare_literal: bool,
556548
}
557549

558550
/// A match pattern.

Diff for: compiler/rustc_ast/src/mut_visit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1222,7 +1222,7 @@ fn walk_mt<T: MutVisitor>(vis: &mut T, MutTy { ty, mutbl: _ }: &mut MutTy) {
12221222
}
12231223

12241224
pub fn walk_block<T: MutVisitor>(vis: &mut T, block: &mut P<Block>) {
1225-
let Block { id, stmts, rules: _, span, tokens, could_be_bare_literal: _ } = block.deref_mut();
1225+
let Block { id, stmts, rules: _, span, tokens } = block.deref_mut();
12261226
vis.visit_id(id);
12271227
stmts.flat_map_in_place(|stmt| vis.flat_map_stmt(stmt));
12281228
visit_lazy_tts(vis, tokens);

Diff for: compiler/rustc_ast/src/visit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1067,7 +1067,7 @@ pub fn walk_field_def<'a, V: Visitor<'a>>(visitor: &mut V, field: &'a FieldDef)
10671067
}
10681068

10691069
pub fn walk_block<'a, V: Visitor<'a>>(visitor: &mut V, block: &'a Block) -> V::Result {
1070-
let Block { stmts, id: _, rules: _, span: _, tokens: _, could_be_bare_literal: _ } = block;
1070+
let Block { stmts, id: _, rules: _, span: _, tokens: _ } = block;
10711071
walk_list!(visitor, visit_stmt, stmts);
10721072
V::Result::output()
10731073
}

Diff for: compiler/rustc_builtin_macros/src/autodiff.rs

-1
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,6 @@ mod llvm_enzyme {
395395
tokens: None,
396396
rules: unsf,
397397
span,
398-
could_be_bare_literal: false,
399398
};
400399
let unsf_expr = ecx.expr_block(P(unsf_block));
401400
let blackbox_call_expr = ecx.expr_path(ecx.path(span, blackbox_path));

Diff for: compiler/rustc_builtin_macros/src/deriving/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,6 @@ fn call_unreachable(cx: &ExtCtxt<'_>, span: Span) -> P<ast::Expr> {
110110
rules: ast::BlockCheckMode::Unsafe(ast::CompilerGenerated),
111111
span,
112112
tokens: None,
113-
could_be_bare_literal: false,
114113
}))
115114
}
116115

Diff for: compiler/rustc_expand/src/build.rs

-1
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,6 @@ impl<'a> ExtCtxt<'a> {
286286
rules: BlockCheckMode::Default,
287287
span,
288288
tokens: None,
289-
could_be_bare_literal: false,
290289
})
291290
}
292291

Diff for: compiler/rustc_parse/messages.ftl

-4
Original file line numberDiff line numberDiff line change
@@ -757,10 +757,6 @@ parse_struct_literal_body_without_path =
757757
struct literal body without path
758758
.suggestion = you might have forgotten to add the struct literal inside the block
759759
760-
parse_struct_literal_needing_parens =
761-
invalid struct literal
762-
.suggestion = you might need to surround the struct literal with parentheses
763-
764760
parse_struct_literal_not_allowed_here = struct literals are not allowed here
765761
.suggestion = surround the struct literal with parentheses
766762

Diff for: compiler/rustc_parse/src/errors.rs

-18
Original file line numberDiff line numberDiff line change
@@ -1272,24 +1272,6 @@ pub(crate) struct StructLiteralBodyWithoutPathSugg {
12721272
pub after: Span,
12731273
}
12741274

1275-
#[derive(Diagnostic)]
1276-
#[diag(parse_struct_literal_needing_parens)]
1277-
pub(crate) struct StructLiteralNeedingParens {
1278-
#[primary_span]
1279-
pub span: Span,
1280-
#[subdiagnostic]
1281-
pub sugg: StructLiteralNeedingParensSugg,
1282-
}
1283-
1284-
#[derive(Subdiagnostic)]
1285-
#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
1286-
pub(crate) struct StructLiteralNeedingParensSugg {
1287-
#[suggestion_part(code = "(")]
1288-
pub before: Span,
1289-
#[suggestion_part(code = ")")]
1290-
pub after: Span,
1291-
}
1292-
12931275
#[derive(Diagnostic)]
12941276
#[diag(parse_unmatched_angle_brackets)]
12951277
pub(crate) struct UnmatchedAngleBrackets {

Diff for: compiler/rustc_parse/src/parser/diagnostics.rs

+14-43
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,8 @@ use crate::errors::{
4040
HelpIdentifierStartsWithNumber, HelpUseLatestEdition, InInTypo, IncorrectAwait,
4141
IncorrectSemicolon, IncorrectUseOfAwait, IncorrectUseOfUse, PatternMethodParamWithoutBody,
4242
QuestionMarkInType, QuestionMarkInTypeSugg, SelfParamNotFirst, StructLiteralBodyWithoutPath,
43-
StructLiteralBodyWithoutPathSugg, StructLiteralNeedingParens, StructLiteralNeedingParensSugg,
44-
SuggAddMissingLetStmt, SuggEscapeIdentifier, SuggRemoveComma, TernaryOperator,
45-
UnexpectedConstInGenericParam, UnexpectedConstParamDeclaration,
43+
StructLiteralBodyWithoutPathSugg, SuggAddMissingLetStmt, SuggEscapeIdentifier, SuggRemoveComma,
44+
TernaryOperator, UnexpectedConstInGenericParam, UnexpectedConstParamDeclaration,
4645
UnexpectedConstParamDeclarationSugg, UnmatchedAngleBrackets, UseEqInstead, WrapType,
4746
};
4847
use crate::parser::attr::InnerAttrPolicy;
@@ -949,7 +948,6 @@ impl<'a> Parser<'a> {
949948
lo: Span,
950949
s: BlockCheckMode,
951950
maybe_struct_name: token::Token,
952-
can_be_struct_literal: bool,
953951
) -> Option<PResult<'a, P<Block>>> {
954952
if self.token.is_ident() && self.look_ahead(1, |t| t == &token::Colon) {
955953
// We might be having a struct literal where people forgot to include the path:
@@ -975,47 +973,23 @@ impl<'a> Parser<'a> {
975973
// fn foo() -> Foo { Path {
976974
// field: value,
977975
// } }
978-
let guar = err.delay_as_bug();
976+
err.cancel();
979977
self.restore_snapshot(snapshot);
980-
let mut tail = self.mk_block(
978+
let guar = self.dcx().emit_err(StructLiteralBodyWithoutPath {
979+
span: expr.span,
980+
sugg: StructLiteralBodyWithoutPathSugg {
981+
before: expr.span.shrink_to_lo(),
982+
after: expr.span.shrink_to_hi(),
983+
},
984+
});
985+
Ok(self.mk_block(
981986
thin_vec![self.mk_stmt_err(expr.span, guar)],
982987
s,
983988
lo.to(self.prev_token.span),
984-
);
985-
tail.could_be_bare_literal = true;
986-
if maybe_struct_name.is_ident() && can_be_struct_literal {
987-
// Account for `if Example { a: one(), }.is_pos() {}`.
988-
// expand `before` so that we take care of module path such as:
989-
// `foo::Bar { ... } `
990-
// we expect to suggest `(foo::Bar { ... })` instead of `foo::(Bar { ... })`
991-
let sm = self.psess.source_map();
992-
let before = maybe_struct_name.span.shrink_to_lo();
993-
if let Ok(extend_before) = sm.span_extend_prev_while(before, |t| {
994-
t.is_alphanumeric() || t == ':' || t == '_'
995-
}) {
996-
Err(self.dcx().create_err(StructLiteralNeedingParens {
997-
span: maybe_struct_name.span.to(expr.span),
998-
sugg: StructLiteralNeedingParensSugg {
999-
before: extend_before.shrink_to_lo(),
1000-
after: expr.span.shrink_to_hi(),
1001-
},
1002-
}))
1003-
} else {
1004-
return None;
1005-
}
1006-
} else {
1007-
self.dcx().emit_err(StructLiteralBodyWithoutPath {
1008-
span: expr.span,
1009-
sugg: StructLiteralBodyWithoutPathSugg {
1010-
before: expr.span.shrink_to_lo(),
1011-
after: expr.span.shrink_to_hi(),
1012-
},
1013-
});
1014-
Ok(tail)
1015-
}
989+
))
1016990
}
1017991
(Err(err), Ok(tail)) => {
1018-
// We have a block tail that contains a somehow valid type ascription expr.
992+
// We have a block tail that contains a somehow valid expr.
1019993
err.cancel();
1020994
Ok(tail)
1021995
}
@@ -1025,10 +999,7 @@ impl<'a> Parser<'a> {
1025999
self.consume_block(exp!(OpenBrace), exp!(CloseBrace), ConsumeClosingDelim::Yes);
10261000
Err(err)
10271001
}
1028-
(Ok(_), Ok(mut tail)) => {
1029-
tail.could_be_bare_literal = true;
1030-
Ok(tail)
1031-
}
1002+
(Ok(_), Ok(tail)) => Ok(tail),
10321003
});
10331004
}
10341005
None

Diff for: compiler/rustc_parse/src/parser/expr.rs

+3-13
Original file line numberDiff line numberDiff line change
@@ -2296,7 +2296,7 @@ impl<'a> Parser<'a> {
22962296
});
22972297
}
22982298

2299-
let (attrs, blk) = self.parse_block_common(lo, blk_mode, true, None)?;
2299+
let (attrs, blk) = self.parse_block_common(lo, blk_mode, None)?;
23002300
Ok(self.mk_expr_with_attrs(blk.span, ExprKind::Block(blk, opt_label), attrs))
23012301
}
23022302

@@ -3474,19 +3474,9 @@ impl<'a> Parser<'a> {
34743474
}
34753475

34763476
fn is_certainly_not_a_block(&self) -> bool {
3477+
// `{ ident, ` and `{ ident: ` cannot start a block.
34773478
self.look_ahead(1, |t| t.is_ident())
3478-
&& (
3479-
// `{ ident, ` cannot start a block.
3480-
self.look_ahead(2, |t| t == &token::Comma)
3481-
|| self.look_ahead(2, |t| t == &token::Colon)
3482-
&& (
3483-
// `{ ident: token, ` cannot start a block.
3484-
self.look_ahead(4, |t| t == &token::Comma)
3485-
// `{ ident: ` cannot start a block unless it's a type ascription
3486-
// `ident: Type`.
3487-
|| self.look_ahead(3, |t| !t.can_begin_type())
3488-
)
3489-
)
3479+
&& self.look_ahead(2, |t| t == &token::Comma || t == &token::Colon)
34903480
}
34913481

34923482
fn maybe_parse_struct_expr(

Diff for: compiler/rustc_parse/src/parser/item.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2538,7 +2538,7 @@ impl<'a> Parser<'a> {
25382538
*sig_hi = self.prev_token.span;
25392539
(AttrVec::new(), None)
25402540
} else if self.check(exp!(OpenBrace)) || self.token.is_whole_block() {
2541-
self.parse_block_common(self.token.span, BlockCheckMode::Default, false, None)
2541+
self.parse_block_common(self.token.span, BlockCheckMode::Default, None)
25422542
.map(|(attrs, body)| (attrs, Some(body)))?
25432543
} else if self.token == token::Eq {
25442544
// Recover `fn foo() = $expr;`.

Diff for: compiler/rustc_parse/src/parser/stmt.rs

+3-16
Original file line numberDiff line numberDiff line change
@@ -668,7 +668,7 @@ impl<'a> Parser<'a> {
668668
&mut self,
669669
loop_header: Option<Span>,
670670
) -> PResult<'a, (AttrVec, P<Block>)> {
671-
self.parse_block_common(self.token.span, BlockCheckMode::Default, true, loop_header)
671+
self.parse_block_common(self.token.span, BlockCheckMode::Default, loop_header)
672672
}
673673

674674
/// Parses a block. Inner attributes are allowed, block labels are not.
@@ -679,7 +679,6 @@ impl<'a> Parser<'a> {
679679
&mut self,
680680
lo: Span,
681681
blk_mode: BlockCheckMode,
682-
can_be_struct_literal: bool,
683682
loop_header: Option<Span>,
684683
) -> PResult<'a, (AttrVec, P<Block>)> {
685684
maybe_whole!(self, NtBlock, |block| (AttrVec::new(), block));
@@ -691,12 +690,7 @@ impl<'a> Parser<'a> {
691690
}
692691

693692
let attrs = self.parse_inner_attributes()?;
694-
let tail = match self.maybe_suggest_struct_literal(
695-
lo,
696-
blk_mode,
697-
maybe_ident,
698-
can_be_struct_literal,
699-
) {
693+
let tail = match self.maybe_suggest_struct_literal(lo, blk_mode, maybe_ident) {
700694
Some(tail) => tail?,
701695
None => self.parse_block_tail(lo, blk_mode, AttemptLocalParseRecovery::Yes)?,
702696
};
@@ -1043,14 +1037,7 @@ impl<'a> Parser<'a> {
10431037
rules: BlockCheckMode,
10441038
span: Span,
10451039
) -> P<Block> {
1046-
P(Block {
1047-
stmts,
1048-
id: DUMMY_NODE_ID,
1049-
rules,
1050-
span,
1051-
tokens: None,
1052-
could_be_bare_literal: false,
1053-
})
1040+
P(Block { stmts, id: DUMMY_NODE_ID, rules, span, tokens: None })
10541041
}
10551042

10561043
pub(super) fn mk_stmt(&self, span: Span, kind: StmtKind) -> Stmt {

Diff for: compiler/rustc_resolve/src/late.rs

-13
Original file line numberDiff line numberDiff line change
@@ -675,11 +675,6 @@ struct DiagMetadata<'ast> {
675675
/// they are used (in a `break` or `continue` statement)
676676
unused_labels: FxIndexMap<NodeId, Span>,
677677

678-
/// Only used for better errors on `let x = { foo: bar };`.
679-
/// In the case of a parse error with `let x = { foo: bar, };`, this isn't needed, it's only
680-
/// needed for cases where this parses as a correct type ascription.
681-
current_block_could_be_bare_struct_literal: Option<Span>,
682-
683678
/// Only used for better errors on `let <pat>: <expr, not type>;`.
684679
current_let_binding: Option<(Span, Option<Span>, Option<Span>)>,
685680

@@ -4661,13 +4656,6 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
46614656
self.ribs[ValueNS].push(Rib::new(RibKind::Normal));
46624657
}
46634658

4664-
let prev = self.diag_metadata.current_block_could_be_bare_struct_literal.take();
4665-
if let (true, [Stmt { kind: StmtKind::Expr(expr), .. }]) =
4666-
(block.could_be_bare_literal, &block.stmts[..])
4667-
&& let ExprKind::Type(..) = expr.kind
4668-
{
4669-
self.diag_metadata.current_block_could_be_bare_struct_literal = Some(block.span);
4670-
}
46714659
// Descend into the block.
46724660
for stmt in &block.stmts {
46734661
if let StmtKind::Item(ref item) = stmt.kind
@@ -4681,7 +4669,6 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
46814669

46824670
self.visit_stmt(stmt);
46834671
}
4684-
self.diag_metadata.current_block_could_be_bare_struct_literal = prev;
46854672

46864673
// Move back up.
46874674
self.parent_scope.module = orig_module;

Diff for: compiler/rustc_resolve/src/late/diagnostics.rs

-14
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,6 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
450450
err.span_suggestion_verbose(sugg.0, sugg.1, &sugg.2, Applicability::MaybeIncorrect);
451451
}
452452

453-
self.suggest_bare_struct_literal(&mut err);
454453
self.suggest_changing_type_to_const_param(&mut err, res, source, span);
455454
self.explain_functions_in_pattern(&mut err, res, source);
456455

@@ -1279,19 +1278,6 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
12791278
}
12801279
}
12811280

1282-
fn suggest_bare_struct_literal(&mut self, err: &mut Diag<'_>) {
1283-
if let Some(span) = self.diag_metadata.current_block_could_be_bare_struct_literal {
1284-
err.multipart_suggestion(
1285-
"you might have meant to write a `struct` literal",
1286-
vec![
1287-
(span.shrink_to_lo(), "{ SomeStruct ".to_string()),
1288-
(span.shrink_to_hi(), "}".to_string()),
1289-
],
1290-
Applicability::HasPlaceholders,
1291-
);
1292-
}
1293-
}
1294-
12951281
fn explain_functions_in_pattern(
12961282
&mut self,
12971283
err: &mut Diag<'_>,

Diff for: src/tools/rustfmt/src/closures.rs

-1
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,6 @@ fn rewrite_closure_with_block(
176176
.first()
177177
.map(|attr| attr.span.to(body.span))
178178
.unwrap_or(body.span),
179-
could_be_bare_literal: false,
180179
};
181180
let block = crate::expr::rewrite_block_with_visitor(
182181
context,

Diff for: src/tools/rustfmt/src/macros.rs

-1
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,6 @@ fn rewrite_empty_macro_def_body(
423423
rules: ast::BlockCheckMode::Default,
424424
span,
425425
tokens: None,
426-
could_be_bare_literal: false,
427426
};
428427
block.rewrite_result(context, shape)
429428
}

Diff for: src/tools/tidy/src/issues.txt

-1
Original file line numberDiff line numberDiff line change
@@ -3189,7 +3189,6 @@ ui/parser/issues/issue-108495-dec.rs
31893189
ui/parser/issues/issue-110014.rs
31903190
ui/parser/issues/issue-111148.rs
31913191
ui/parser/issues/issue-111416.rs
3192-
ui/parser/issues/issue-111692.rs
31933192
ui/parser/issues/issue-112188.rs
31943193
ui/parser/issues/issue-112458.rs
31953194
ui/parser/issues/issue-113110-non-item-at-module-root.rs

Diff for: tests/ui-fulldeps/pprust-expr-roundtrip.rs

-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,6 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) {
114114
rules: BlockCheckMode::Default,
115115
span: DUMMY_SP,
116116
tokens: None,
117-
could_be_bare_literal: false,
118117
});
119118
iter_exprs(depth - 1, &mut |e| g(ExprKind::If(e, block.clone(), None)));
120119
}

Diff for: tests/ui/parser/issues/issue-111692.rs

-32
This file was deleted.

0 commit comments

Comments
 (0)