@@ -20,7 +20,7 @@ use rustc_ast::{
2020 PatField , PatFieldsRest , PatKind , Path , QSelf , RangeEnd , RangeSyntax ,
2121} ;
2222use rustc_ast_pretty:: pprust;
23- use rustc_errors:: { Applicability , Diag , PResult } ;
23+ use rustc_errors:: { Applicability , Diag , PResult , StashKey } ;
2424use rustc_session:: errors:: ExprParenthesesNeeded ;
2525use rustc_span:: source_map:: { respan, Spanned } ;
2626use rustc_span:: symbol:: { kw, sym, Ident } ;
@@ -351,7 +351,7 @@ impl<'a> Parser<'a> {
351351 & mut self ,
352352 pat_span : Span ,
353353 is_end_bound : bool ,
354- ) -> Option < ErrorGuaranteed > {
354+ ) -> Option < ( ErrorGuaranteed , Span ) > {
355355 if self . prev_token . is_keyword ( kw:: Underscore ) || !self . may_recover ( ) {
356356 // Don't recover anything after an `_` or if recovery is disabled.
357357 return None ;
@@ -429,11 +429,16 @@ impl<'a> Parser<'a> {
429429 // Check that `parse_expr_assoc_with` didn't eat a rhs.
430430 let is_method_call = false && non_assoc_span == expr. span ;
431431
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+ ) ) ;
437442 }
438443 }
439444
@@ -550,7 +555,7 @@ impl<'a> Parser<'a> {
550555 self . parse_pat_tuple_struct ( qself, path) ?
551556 } else {
552557 match self . maybe_recover_trailing_expr ( span, false ) {
553- Some ( guar) => PatKind :: Err ( guar) ,
558+ Some ( ( guar, _ ) ) => PatKind :: Err ( guar) ,
554559 None => PatKind :: Path ( qself, path) ,
555560 }
556561 }
@@ -584,7 +589,7 @@ impl<'a> Parser<'a> {
584589 match self . parse_literal_maybe_minus ( ) {
585590 Ok ( begin) => {
586591 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) ,
588593 None => begin,
589594 } ;
590595
@@ -762,7 +767,25 @@ impl<'a> Parser<'a> {
762767
763768 Ok ( match self . maybe_recover_trailing_expr ( open_paren. to ( self . prev_token . span ) , false ) {
764769 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+ }
766789 } )
767790 }
768791
@@ -1014,7 +1037,7 @@ impl<'a> Parser<'a> {
10141037 }
10151038
10161039 Ok ( match recovered {
1017- Some ( guar) => self . mk_expr_err ( bound . span , guar) ,
1040+ Some ( ( guar, sp ) ) => self . mk_expr_err ( sp , guar) ,
10181041 None => bound,
10191042 } )
10201043 }
@@ -1083,7 +1106,7 @@ impl<'a> Parser<'a> {
10831106 // but not `ident @ subpat` as `subpat` was already checked and `ident` continues with `@`.
10841107
10851108 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 )
10871110 {
10881111 PatKind :: Err ( guar)
10891112 } else {
0 commit comments