@@ -20,7 +20,7 @@ use rustc_ast::{
20
20
PatField , PatFieldsRest , PatKind , Path , QSelf , RangeEnd , RangeSyntax ,
21
21
} ;
22
22
use rustc_ast_pretty:: pprust;
23
- use rustc_errors:: { Applicability , Diag , PResult } ;
23
+ use rustc_errors:: { Applicability , Diag , PResult , StashKey } ;
24
24
use rustc_session:: errors:: ExprParenthesesNeeded ;
25
25
use rustc_span:: source_map:: { respan, Spanned } ;
26
26
use rustc_span:: symbol:: { kw, sym, Ident } ;
@@ -351,7 +351,7 @@ impl<'a> Parser<'a> {
351
351
& mut self ,
352
352
pat_span : Span ,
353
353
is_end_bound : bool ,
354
- ) -> Option < ErrorGuaranteed > {
354
+ ) -> Option < ( ErrorGuaranteed , Span ) > {
355
355
if self . prev_token . is_keyword ( kw:: Underscore ) || !self . may_recover ( ) {
356
356
// Don't recover anything after an `_` or if recovery is disabled.
357
357
return None ;
@@ -429,11 +429,16 @@ impl<'a> Parser<'a> {
429
429
// Check that `parse_expr_assoc_with` didn't eat a rhs.
430
430
let is_method_call = false && non_assoc_span == expr. span ;
431
431
432
- return Some ( self . dcx ( ) . emit_err ( UnexpectedExpressionInPattern {
433
- span : expr. span ,
434
- is_bound,
435
- is_method_call,
436
- } ) ) ;
432
+ let span = expr. span ;
433
+
434
+ return Some ( (
435
+ self . dcx ( ) . stash_err (
436
+ span,
437
+ StashKey :: ExprInPat ,
438
+ UnexpectedExpressionInPattern { span, is_bound, is_method_call } ,
439
+ ) ,
440
+ span,
441
+ ) ) ;
437
442
}
438
443
}
439
444
@@ -550,7 +555,7 @@ impl<'a> Parser<'a> {
550
555
self . parse_pat_tuple_struct ( qself, path) ?
551
556
} else {
552
557
match self . maybe_recover_trailing_expr ( span, false ) {
553
- Some ( guar) => PatKind :: Err ( guar) ,
558
+ Some ( ( guar, _ ) ) => PatKind :: Err ( guar) ,
554
559
None => PatKind :: Path ( qself, path) ,
555
560
}
556
561
}
@@ -584,7 +589,7 @@ impl<'a> Parser<'a> {
584
589
match self . parse_literal_maybe_minus ( ) {
585
590
Ok ( begin) => {
586
591
let begin = match self . maybe_recover_trailing_expr ( begin. span , false ) {
587
- Some ( guar) => self . mk_expr_err ( begin . span , guar) ,
592
+ Some ( ( guar, sp ) ) => self . mk_expr_err ( sp , guar) ,
588
593
None => begin,
589
594
} ;
590
595
@@ -762,7 +767,25 @@ impl<'a> Parser<'a> {
762
767
763
768
Ok ( match self . maybe_recover_trailing_expr ( open_paren. to ( self . prev_token . span ) , false ) {
764
769
None => pat,
765
- Some ( guar) => PatKind :: Err ( guar)
770
+ Some ( ( guar, _) ) => {
771
+ // We just recovered a bigger expression, so cancel its children
772
+ // (e.g. `(1 + 2) * 3`, cancel “`1 + 2` is not a pattern”).
773
+ match pat {
774
+ PatKind :: Paren ( pat) => {
775
+ self . dcx ( ) . steal_err ( pat. span , StashKey :: ExprInPat , guar) ;
776
+ }
777
+
778
+ PatKind :: Tuple ( fields) => {
779
+ for pat in fields {
780
+ self . dcx ( ) . steal_err ( pat. span , StashKey :: ExprInPat , guar) ;
781
+ }
782
+ }
783
+
784
+ _ => unreachable ! ( ) ,
785
+ }
786
+
787
+ PatKind :: Err ( guar)
788
+ }
766
789
} )
767
790
}
768
791
@@ -1014,7 +1037,7 @@ impl<'a> Parser<'a> {
1014
1037
}
1015
1038
1016
1039
Ok ( match recovered {
1017
- Some ( guar) => self . mk_expr_err ( bound . span , guar) ,
1040
+ Some ( ( guar, sp ) ) => self . mk_expr_err ( sp , guar) ,
1018
1041
None => bound,
1019
1042
} )
1020
1043
}
@@ -1083,7 +1106,7 @@ impl<'a> Parser<'a> {
1083
1106
// but not `ident @ subpat` as `subpat` was already checked and `ident` continues with `@`.
1084
1107
1085
1108
let pat = if sub. is_none ( )
1086
- && let Some ( guar) = self . maybe_recover_trailing_expr ( ident. span , false )
1109
+ && let Some ( ( guar, _ ) ) = self . maybe_recover_trailing_expr ( ident. span , false )
1087
1110
{
1088
1111
PatKind :: Err ( guar)
1089
1112
} else {
0 commit comments