Skip to content

Commit 97872b7

Browse files
committed
Auto merge of rust-lang#107478 - compiler-errors:anon-enum-tys-are-ambiguous, r=estebank
Revert "Teach parser to understand fake anonymous enum syntax" and related commits anonymous enum types are currently ambiguous in positions like: * `|` operator: `a as fn() -> B | C` * closure args: `|_: as fn() -> A | B` I first tried to thread around `RecoverAnonEnum` into all these positions, but the resulting complexity in the compiler is IMO not worth it, or at least worth a bit more thinking time. In the mean time, let's revert this syntax for now, so we can go back to the drawing board. Fixes rust-lang#107461 cc: `@estebank` `@cjgillot` rust-lang#106960 --- ### Squashed revert commits: Revert "review comment: Remove AST AnonTy" This reverts commit 020cca8. Revert "Ensure macros are not affected" This reverts commit 12d18e4. Revert "Emit fewer errors on patterns with possible type ascription" This reverts commit c847a01. Revert "Teach parser to understand fake anonymous enum syntax" This reverts commit 2d82420.
2 parents a9985cf + 39db65c commit 97872b7

File tree

10 files changed

+72
-265
lines changed

10 files changed

+72
-265
lines changed

compiler/rustc_ast/src/visit.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -403,8 +403,8 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) {
403403
walk_list!(visitor, visit_lifetime, opt_lifetime, LifetimeCtxt::Ref);
404404
visitor.visit_ty(&mutable_type.ty)
405405
}
406-
TyKind::Tup(tys) => {
407-
walk_list!(visitor, visit_ty, tys);
406+
TyKind::Tup(tuple_element_types) => {
407+
walk_list!(visitor, visit_ty, tuple_element_types);
408408
}
409409
TyKind::BareFn(function_declaration) => {
410410
walk_list!(visitor, visit_generic_param, &function_declaration.generic_params);

compiler/rustc_parse/src/parser/diagnostics.rs

+13-39
Original file line numberDiff line numberDiff line change
@@ -2394,7 +2394,7 @@ impl<'a> Parser<'a> {
23942394

23952395
/// Some special error handling for the "top-level" patterns in a match arm,
23962396
/// `for` loop, `let`, &c. (in contrast to subpatterns within such).
2397-
pub(crate) fn maybe_recover_colon_colon_in_pat_typo_or_anon_enum(
2397+
pub(crate) fn maybe_recover_colon_colon_in_pat_typo(
23982398
&mut self,
23992399
mut first_pat: P<Pat>,
24002400
expected: Option<Expected>,
@@ -2405,41 +2405,26 @@ impl<'a> Parser<'a> {
24052405
if !matches!(first_pat.kind, PatKind::Ident(_, _, None) | PatKind::Path(..))
24062406
|| !self.look_ahead(1, |token| token.is_ident() && !token.is_reserved_ident())
24072407
{
2408-
let mut snapshot_type = self.create_snapshot_for_diagnostic();
2409-
snapshot_type.bump(); // `:`
2410-
match snapshot_type.parse_ty() {
2411-
Err(inner_err) => {
2412-
inner_err.cancel();
2413-
}
2414-
Ok(ty) => {
2415-
let Err(mut err) = self.expected_one_of_not_found(&[], &[]) else {
2416-
return first_pat;
2417-
};
2418-
err.span_label(ty.span, "specifying the type of a pattern isn't supported");
2419-
self.restore_snapshot(snapshot_type);
2420-
let span = first_pat.span.to(ty.span);
2421-
first_pat = self.mk_pat(span, PatKind::Wild);
2422-
err.emit();
2423-
}
2424-
}
24252408
return first_pat;
24262409
}
24272410
// The pattern looks like it might be a path with a `::` -> `:` typo:
24282411
// `match foo { bar:baz => {} }`
2429-
let colon_span = self.token.span;
2412+
let span = self.token.span;
24302413
// We only emit "unexpected `:`" error here if we can successfully parse the
24312414
// whole pattern correctly in that case.
2432-
let mut snapshot_pat = self.create_snapshot_for_diagnostic();
2433-
let mut snapshot_type = self.create_snapshot_for_diagnostic();
2415+
let snapshot = self.create_snapshot_for_diagnostic();
24342416

24352417
// Create error for "unexpected `:`".
24362418
match self.expected_one_of_not_found(&[], &[]) {
24372419
Err(mut err) => {
2438-
snapshot_pat.bump(); // Skip the `:`.
2439-
snapshot_type.bump(); // Skip the `:`.
2440-
match snapshot_pat.parse_pat_no_top_alt(expected) {
2420+
self.bump(); // Skip the `:`.
2421+
match self.parse_pat_no_top_alt(expected) {
24412422
Err(inner_err) => {
2423+
// Carry on as if we had not done anything, callers will emit a
2424+
// reasonable error.
24422425
inner_err.cancel();
2426+
err.cancel();
2427+
self.restore_snapshot(snapshot);
24432428
}
24442429
Ok(mut pat) => {
24452430
// We've parsed the rest of the pattern.
@@ -2503,33 +2488,22 @@ impl<'a> Parser<'a> {
25032488
_ => {}
25042489
}
25052490
if show_sugg {
2506-
err.span_suggestion_verbose(
2507-
colon_span.until(self.look_ahead(1, |t| t.span)),
2491+
err.span_suggestion(
2492+
span,
25082493
"maybe write a path separator here",
25092494
"::",
25102495
Applicability::MaybeIncorrect,
25112496
);
25122497
} else {
25132498
first_pat = self.mk_pat(new_span, PatKind::Wild);
25142499
}
2515-
self.restore_snapshot(snapshot_pat);
2500+
err.emit();
25162501
}
25172502
}
2518-
match snapshot_type.parse_ty() {
2519-
Err(inner_err) => {
2520-
inner_err.cancel();
2521-
}
2522-
Ok(ty) => {
2523-
err.span_label(ty.span, "specifying the type of a pattern isn't supported");
2524-
self.restore_snapshot(snapshot_type);
2525-
let new_span = first_pat.span.to(ty.span);
2526-
first_pat = self.mk_pat(new_span, PatKind::Wild);
2527-
}
2528-
}
2529-
err.emit();
25302503
}
25312504
_ => {
25322505
// Carry on as if we had not done anything. This should be unreachable.
2506+
self.restore_snapshot(snapshot);
25332507
}
25342508
};
25352509
first_pat

compiler/rustc_parse/src/parser/pat.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,7 @@ impl<'a> Parser<'a> {
148148

149149
// Check if the user wrote `foo:bar` instead of `foo::bar`.
150150
if ra == RecoverColon::Yes {
151-
first_pat =
152-
self.maybe_recover_colon_colon_in_pat_typo_or_anon_enum(first_pat, expected);
151+
first_pat = self.maybe_recover_colon_colon_in_pat_typo(first_pat, expected);
153152
}
154153

155154
if let Some(leading_vert_span) = leading_vert_span {

compiler/rustc_parse/src/parser/ty.rs

+3-62
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ use rustc_ast::{
1717
self as ast, BareFnTy, FnRetTy, GenericBound, GenericBounds, GenericParam, Generics, Lifetime,
1818
MacCall, MutTy, Mutability, PolyTraitRef, TraitBoundModifier, TraitObjectSyntax, Ty, TyKind,
1919
};
20-
use rustc_ast_pretty::pprust;
2120
use rustc_errors::{Applicability, PResult};
2221
use rustc_span::source_map::Span;
2322
use rustc_span::symbol::{kw, sym, Ident};
@@ -50,24 +49,17 @@ pub(super) enum AllowPlus {
5049
No,
5150
}
5251

53-
#[derive(PartialEq, Clone, Copy)]
52+
#[derive(PartialEq)]
5453
pub(super) enum RecoverQPath {
5554
Yes,
5655
No,
5756
}
5857

59-
#[derive(PartialEq, Clone, Copy)]
6058
pub(super) enum RecoverQuestionMark {
6159
Yes,
6260
No,
6361
}
6462

65-
#[derive(PartialEq, Clone, Copy)]
66-
pub(super) enum RecoverAnonEnum {
67-
Yes,
68-
No,
69-
}
70-
7163
/// Signals whether parsing a type should recover `->`.
7264
///
7365
/// More specifically, when parsing a function like:
@@ -100,7 +92,7 @@ impl RecoverReturnSign {
10092
}
10193

10294
// Is `...` (`CVarArgs`) legal at this level of type parsing?
103-
#[derive(PartialEq, Clone, Copy)]
95+
#[derive(PartialEq)]
10496
enum AllowCVariadic {
10597
Yes,
10698
No,
@@ -125,7 +117,6 @@ impl<'a> Parser<'a> {
125117
RecoverReturnSign::Yes,
126118
None,
127119
RecoverQuestionMark::Yes,
128-
RecoverAnonEnum::No,
129120
)
130121
}
131122

@@ -140,7 +131,6 @@ impl<'a> Parser<'a> {
140131
RecoverReturnSign::Yes,
141132
Some(ty_params),
142133
RecoverQuestionMark::Yes,
143-
RecoverAnonEnum::No,
144134
)
145135
}
146136

@@ -155,7 +145,6 @@ impl<'a> Parser<'a> {
155145
RecoverReturnSign::Yes,
156146
None,
157147
RecoverQuestionMark::Yes,
158-
RecoverAnonEnum::Yes,
159148
)
160149
}
161150

@@ -173,7 +162,6 @@ impl<'a> Parser<'a> {
173162
RecoverReturnSign::Yes,
174163
None,
175164
RecoverQuestionMark::Yes,
176-
RecoverAnonEnum::No,
177165
)
178166
}
179167

@@ -187,7 +175,6 @@ impl<'a> Parser<'a> {
187175
RecoverReturnSign::Yes,
188176
None,
189177
RecoverQuestionMark::No,
190-
RecoverAnonEnum::No,
191178
)
192179
}
193180

@@ -199,7 +186,6 @@ impl<'a> Parser<'a> {
199186
RecoverReturnSign::Yes,
200187
None,
201188
RecoverQuestionMark::No,
202-
RecoverAnonEnum::No,
203189
)
204190
}
205191

@@ -212,7 +198,6 @@ impl<'a> Parser<'a> {
212198
RecoverReturnSign::OnlyFatArrow,
213199
None,
214200
RecoverQuestionMark::Yes,
215-
RecoverAnonEnum::No,
216201
)
217202
}
218203

@@ -232,7 +217,6 @@ impl<'a> Parser<'a> {
232217
recover_return_sign,
233218
None,
234219
RecoverQuestionMark::Yes,
235-
RecoverAnonEnum::Yes,
236220
)?;
237221
FnRetTy::Ty(ty)
238222
} else if recover_return_sign.can_recover(&self.token.kind) {
@@ -247,7 +231,6 @@ impl<'a> Parser<'a> {
247231
recover_return_sign,
248232
None,
249233
RecoverQuestionMark::Yes,
250-
RecoverAnonEnum::Yes,
251234
)?;
252235
FnRetTy::Ty(ty)
253236
} else {
@@ -263,7 +246,6 @@ impl<'a> Parser<'a> {
263246
recover_return_sign: RecoverReturnSign,
264247
ty_generics: Option<&Generics>,
265248
recover_question_mark: RecoverQuestionMark,
266-
recover_anon_enum: RecoverAnonEnum,
267249
) -> PResult<'a, P<Ty>> {
268250
let allow_qpath_recovery = recover_qpath == RecoverQPath::Yes;
269251
maybe_recover_from_interpolated_ty_qpath!(self, allow_qpath_recovery);
@@ -347,50 +329,9 @@ impl<'a> Parser<'a> {
347329
AllowPlus::Yes => self.maybe_recover_from_bad_type_plus(&ty)?,
348330
AllowPlus::No => self.maybe_report_ambiguous_plus(impl_dyn_multi, &ty),
349331
}
350-
if RecoverQuestionMark::Yes == recover_question_mark {
332+
if let RecoverQuestionMark::Yes = recover_question_mark {
351333
ty = self.maybe_recover_from_question_mark(ty);
352334
}
353-
if recover_anon_enum == RecoverAnonEnum::Yes
354-
&& self.check_noexpect(&token::BinOp(token::Or))
355-
&& self.look_ahead(1, |t| t.can_begin_type())
356-
{
357-
let mut pipes = vec![self.token.span];
358-
let mut types = vec![ty];
359-
loop {
360-
if !self.eat(&token::BinOp(token::Or)) {
361-
break;
362-
}
363-
pipes.push(self.prev_token.span);
364-
types.push(self.parse_ty_common(
365-
allow_plus,
366-
allow_c_variadic,
367-
recover_qpath,
368-
recover_return_sign,
369-
ty_generics,
370-
recover_question_mark,
371-
RecoverAnonEnum::No,
372-
)?);
373-
}
374-
let mut err = self.struct_span_err(pipes, "anonymous enums are not supported");
375-
for ty in &types {
376-
err.span_label(ty.span, "");
377-
}
378-
err.help(&format!(
379-
"create a named `enum` and use it here instead:\nenum Name {{\n{}\n}}",
380-
types
381-
.iter()
382-
.enumerate()
383-
.map(|(i, t)| format!(
384-
" Variant{}({}),",
385-
i + 1, // Lets not confuse people with zero-indexing :)
386-
pprust::to_string(|s| s.print_type(&t)),
387-
))
388-
.collect::<Vec<_>>()
389-
.join("\n"),
390-
));
391-
err.emit();
392-
return Ok(self.mk_ty(lo.to(self.prev_token.span), TyKind::Err));
393-
}
394335
if allow_qpath_recovery { self.maybe_recover_from_bad_qpath(ty) } else { Ok(ty) }
395336
}
396337

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// check-pass
2+
3+
macro_rules! test_expr {
4+
($expr:expr) => {};
5+
}
6+
7+
macro_rules! test_ty {
8+
($a:ty | $b:ty) => {};
9+
}
10+
11+
fn main() {
12+
test_expr!(a as fn() -> B | C);
13+
// Do not break the `|` operator.
14+
15+
test_expr!(|_: fn() -> B| C | D);
16+
// Do not break `-> Ret` in closure args.
17+
18+
test_ty!(A | B);
19+
// We can't support anon enums in arbitrary positions.
20+
21+
test_ty!(fn() -> A | B);
22+
// Don't break fn ptrs.
23+
24+
test_ty!(impl Fn() -> A | B);
25+
// Don't break parenthesized generics.
26+
}

tests/ui/parser/anon-enums.rs

-17
This file was deleted.

0 commit comments

Comments
 (0)