@@ -41,8 +41,9 @@ use crate::errors::{
4141    IncorrectSemicolon ,  IncorrectUseOfAwait ,  IncorrectUseOfUse ,  PatternMethodParamWithoutBody , 
4242    QuestionMarkInType ,  QuestionMarkInTypeSugg ,  SelfParamNotFirst ,  StructLiteralBodyWithoutPath , 
4343    StructLiteralBodyWithoutPathSugg ,  SuggAddMissingLetStmt ,  SuggEscapeIdentifier ,  SuggRemoveComma , 
44-     TernaryOperator ,  UnexpectedConstInGenericParam ,  UnexpectedConstParamDeclaration , 
45-     UnexpectedConstParamDeclarationSugg ,  UnmatchedAngleBrackets ,  UseEqInstead ,  WrapType , 
44+     TernaryOperator ,  TernaryOperatorSuggestion ,  UnexpectedConstInGenericParam , 
45+     UnexpectedConstParamDeclaration ,  UnexpectedConstParamDeclarationSugg ,  UnmatchedAngleBrackets , 
46+     UseEqInstead ,  WrapType , 
4647} ; 
4748use  crate :: parser:: attr:: InnerAttrPolicy ; 
4849use  crate :: { exp,  fluent_generated as  fluent} ; 
@@ -497,7 +498,7 @@ impl<'a> Parser<'a> {
497498            // If the user is trying to write a ternary expression, recover it and 
498499            // return an Err to prevent a cascade of irrelevant diagnostics. 
499500            if  self . prev_token  == token:: Question 
500-                 && let  Err ( e)  = self . maybe_recover_from_ternary_operator ( ) 
501+                 && let  Err ( e)  = self . maybe_recover_from_ternary_operator ( None ) 
501502            { 
502503                return  Err ( e) ; 
503504            } 
@@ -1602,12 +1603,18 @@ impl<'a> Parser<'a> {
16021603    /// Rust has no ternary operator (`cond ? then : else`). Parse it and try 
16031604     /// to recover from it if `then` and `else` are valid expressions. Returns 
16041605     /// an err if this appears to be a ternary expression. 
1605-      pub ( super )  fn  maybe_recover_from_ternary_operator ( & mut  self )  -> PResult < ' a ,  ( ) >  { 
1606+      /// If we have the span of the condition, we can provide a better error span 
1607+      /// and code suggestion. 
1608+      pub ( super )  fn  maybe_recover_from_ternary_operator ( 
1609+         & mut  self , 
1610+         cond :  Option < Span > , 
1611+     )  -> PResult < ' a ,  ( ) >  { 
16061612        if  self . prev_token  != token:: Question  { 
16071613            return  PResult :: Ok ( ( ) ) ; 
16081614        } 
16091615
1610-         let  lo = self . prev_token . span . lo ( ) ; 
1616+         let  question = self . prev_token . span ; 
1617+         let  lo = cond. unwrap_or ( question) . lo ( ) ; 
16111618        let  snapshot = self . create_snapshot_for_diagnostic ( ) ; 
16121619
16131620        if  match  self . parse_expr ( )  { 
@@ -1620,11 +1627,20 @@ impl<'a> Parser<'a> {
16201627            } 
16211628        }  { 
16221629            if  self . eat_noexpect ( & token:: Colon )  { 
1630+                 let  colon = self . prev_token . span ; 
16231631                match  self . parse_expr ( )  { 
1624-                     Ok ( _)  => { 
1625-                         return  Err ( self 
1626-                             . dcx ( ) 
1627-                             . create_err ( TernaryOperator  {  span :  self . token . span . with_lo ( lo)  } ) ) ; 
1632+                     Ok ( expr)  => { 
1633+                         let  sugg = cond. map ( |cond| TernaryOperatorSuggestion  { 
1634+                             before_cond :  cond. shrink_to_lo ( ) , 
1635+                             question, 
1636+                             colon, 
1637+                             end :  expr. span . shrink_to_hi ( ) , 
1638+                         } ) ; 
1639+                         return  Err ( self . dcx ( ) . create_err ( TernaryOperator  { 
1640+                             span :  self . prev_token . span . with_lo ( lo) , 
1641+                             sugg, 
1642+                             no_sugg :  sugg. is_none ( ) , 
1643+                         } ) ) ; 
16281644                    } 
16291645                    Err ( err)  => { 
16301646                        err. cancel ( ) ; 
0 commit comments