@@ -478,134 +478,138 @@ impl<'tcx> EnclosingBreakables<'tcx> {
478478 }
479479 }
480480}
481-
482- fn report_unexpected_variant_res (
483- tcx : TyCtxt < ' _ > ,
484- res : Res ,
485- expr : Option < & hir:: Expr < ' _ > > ,
486- sub_pats : & [ hir:: Pat < ' _ > ] ,
487- qpath : & hir:: QPath < ' _ > ,
488- span : Span ,
489- err_code : ErrCode ,
490- expected : & str ,
491- ) -> ErrorGuaranteed {
492- let res_descr = match res {
493- Res :: Def ( DefKind :: Variant , _) => "struct variant" ,
494- _ => res. descr ( ) ,
495- } ;
496- let path_str = rustc_hir_pretty:: qpath_to_string ( & tcx, qpath) ;
497- let mut err = tcx
498- . dcx ( )
499- . struct_span_err ( span, format ! ( "expected {expected}, found {res_descr} `{path_str}`" ) )
500- . with_code ( err_code) ;
501- match res {
502- Res :: Def ( DefKind :: Fn | DefKind :: AssocFn , _) if err_code == E0164 => {
503- let patterns_url = "https://doc.rust-lang.org/book/ch19-00-patterns.html" ;
504- err. with_span_label ( span, "`fn` calls are not allowed in patterns" )
505- . with_help ( format ! ( "for more information, visit {patterns_url}" ) )
506- }
507- Res :: Def ( DefKind :: Variant , _) if let Some ( expr) = expr => {
508- err. span_label ( span, format ! ( "not a {expected}" ) ) ;
509- let variant = tcx. expect_variant_res ( res) ;
510- let sugg = if variant. fields . is_empty ( ) {
511- " {}" . to_string ( )
512- } else {
513- format ! (
514- " {{ {} }}" ,
515- variant
516- . fields
517- . iter( )
518- . map( |f| format!( "{}: /* value */" , f. name) )
519- . collect:: <Vec <_>>( )
520- . join( ", " )
521- )
522- } ;
523- let descr = "you might have meant to create a new value of the struct" ;
524- let mut suggestion = vec ! [ ] ;
525- match tcx. parent_hir_node ( expr. hir_id ) {
526- hir:: Node :: Expr ( hir:: Expr {
527- kind : hir:: ExprKind :: Call ( ..) ,
528- span : call_span,
529- ..
530- } ) => {
531- suggestion. push ( ( span. shrink_to_hi ( ) . with_hi ( call_span. hi ( ) ) , sugg) ) ;
532- }
533- hir:: Node :: Expr ( hir:: Expr { kind : hir:: ExprKind :: Binary ( ..) , hir_id, .. } ) => {
534- suggestion. push ( ( expr. span . shrink_to_lo ( ) , "(" . to_string ( ) ) ) ;
535- if let hir:: Node :: Expr ( parent) = tcx. parent_hir_node ( * hir_id)
536- && let hir:: ExprKind :: If ( condition, block, None ) = parent. kind
537- && condition. hir_id == * hir_id
538- && let hir:: ExprKind :: Block ( block, _) = block. kind
539- && block. stmts . is_empty ( )
540- && let Some ( expr) = block. expr
541- && let hir:: ExprKind :: Path ( ..) = expr. kind
542- {
543- // Special case: you can incorrectly write an equality condition:
544- // if foo == Struct { field } { /* if body */ }
545- // which should have been written
546- // if foo == (Struct { field }) { /* if body */ }
547- suggestion. push ( ( block. span . shrink_to_hi ( ) , ")" . to_string ( ) ) ) ;
548- } else {
549- suggestion. push ( ( span. shrink_to_hi ( ) . with_hi ( expr. span . hi ( ) ) , sugg) ) ;
481+ impl < ' a , ' tcx > FnCtxt < ' a , ' tcx > {
482+ fn report_unexpected_variant_res (
483+ & self ,
484+ res : Res ,
485+ expr : Option < & hir:: Expr < ' _ > > ,
486+ sub_pats : & [ hir:: Pat < ' _ > ] ,
487+ qpath : & hir:: QPath < ' _ > ,
488+ span : Span ,
489+ err_code : ErrCode ,
490+ expected : & str ,
491+ ) -> ErrorGuaranteed {
492+ let tcx = self . tcx ;
493+ let res_descr = match res {
494+ Res :: Def ( DefKind :: Variant , _) => "struct variant" ,
495+ _ => res. descr ( ) ,
496+ } ;
497+ let path_str = rustc_hir_pretty:: qpath_to_string ( self , qpath) ;
498+ let mut err = tcx
499+ . dcx ( )
500+ . struct_span_err ( span, format ! ( "expected {expected}, found {res_descr} `{path_str}`" ) )
501+ . with_code ( err_code) ;
502+ match res {
503+ Res :: Def ( DefKind :: Fn | DefKind :: AssocFn , _) if err_code == E0164 => {
504+ let patterns_url = "https://doc.rust-lang.org/book/ch19-00-patterns.html" ;
505+ err. with_span_label ( span, "`fn` calls are not allowed in patterns" )
506+ . with_help ( format ! ( "for more information, visit {patterns_url}" ) )
507+ }
508+ Res :: Def ( DefKind :: Variant , _) if let Some ( expr) = expr => {
509+ err. span_label ( span, format ! ( "not a {expected}" ) ) ;
510+ let variant = tcx. expect_variant_res ( res) ;
511+ let sugg = if variant. fields . is_empty ( ) {
512+ " {}" . to_string ( )
513+ } else {
514+ format ! (
515+ " {{ {} }}" ,
516+ variant
517+ . fields
518+ . iter( )
519+ . map( |f| format!( "{}: /* value */" , f. name) )
520+ . collect:: <Vec <_>>( )
521+ . join( ", " )
522+ )
523+ } ;
524+ let descr = "you might have meant to create a new value of the struct" ;
525+ let mut suggestion = vec ! [ ] ;
526+ match tcx. parent_hir_node ( expr. hir_id ) {
527+ hir:: Node :: Expr ( hir:: Expr {
528+ kind : hir:: ExprKind :: Call ( ..) ,
529+ span : call_span,
530+ ..
531+ } ) => {
532+ suggestion. push ( ( span. shrink_to_hi ( ) . with_hi ( call_span. hi ( ) ) , sugg) ) ;
533+ }
534+ hir:: Node :: Expr ( hir:: Expr {
535+ kind : hir:: ExprKind :: Binary ( ..) , hir_id, ..
536+ } ) => {
537+ suggestion. push ( ( expr. span . shrink_to_lo ( ) , "(" . to_string ( ) ) ) ;
538+ if let hir:: Node :: Expr ( parent) = tcx. parent_hir_node ( * hir_id)
539+ && let hir:: ExprKind :: If ( condition, block, None ) = parent. kind
540+ && condition. hir_id == * hir_id
541+ && let hir:: ExprKind :: Block ( block, _) = block. kind
542+ && block. stmts . is_empty ( )
543+ && let Some ( expr) = block. expr
544+ && let hir:: ExprKind :: Path ( ..) = expr. kind
545+ {
546+ // Special case: you can incorrectly write an equality condition:
547+ // if foo == Struct { field } { /* if body */ }
548+ // which should have been written
549+ // if foo == (Struct { field }) { /* if body */ }
550+ suggestion. push ( ( block. span . shrink_to_hi ( ) , ")" . to_string ( ) ) ) ;
551+ } else {
552+ suggestion. push ( ( span. shrink_to_hi ( ) . with_hi ( expr. span . hi ( ) ) , sugg) ) ;
553+ }
554+ }
555+ _ => {
556+ suggestion. push ( ( span. shrink_to_hi ( ) , sugg) ) ;
550557 }
551558 }
552- _ => {
553- suggestion . push ( ( span . shrink_to_hi ( ) , sugg ) ) ;
554- }
559+
560+ err . multipart_suggestion ( descr , suggestion , Applicability :: HasPlaceholders ) ;
561+ err
555562 }
563+ Res :: Def ( DefKind :: Variant , _) if expr. is_none ( ) => {
564+ err. span_label ( span, format ! ( "not a {expected}" ) ) ;
556565
557- err. multipart_suggestion ( descr, suggestion, Applicability :: HasPlaceholders ) ;
558- err
559- }
560- Res :: Def ( DefKind :: Variant , _) if expr. is_none ( ) => {
561- err. span_label ( span, format ! ( "not a {expected}" ) ) ;
562-
563- let fields = & tcx. expect_variant_res ( res) . fields . raw ;
564- let span = qpath. span ( ) . shrink_to_hi ( ) . to ( span. shrink_to_hi ( ) ) ;
565- let ( msg, sugg) = if fields. is_empty ( ) {
566- ( "use the struct variant pattern syntax" , " {}" . to_string ( ) )
567- } else {
568- let msg = if fields. is_empty ( ) {
569- "use struct variant pattern syntax"
566+ let fields = & tcx. expect_variant_res ( res) . fields . raw ;
567+ let span = qpath. span ( ) . shrink_to_hi ( ) . to ( span. shrink_to_hi ( ) ) ;
568+ let ( msg, sugg) = if fields. is_empty ( ) {
569+ ( "use the struct variant pattern syntax" , " {}" . to_string ( ) )
570570 } else {
571- "add the names to match a struct variant's fields"
571+ let msg = if fields. is_empty ( ) {
572+ "use struct variant pattern syntax"
573+ } else {
574+ "add the names to match a struct variant's fields"
575+ } ;
576+ let fields_sugg = fields
577+ . iter ( )
578+ . enumerate ( )
579+ . map ( |( i, field) | {
580+ let field_name = field. ident ( tcx) . to_string ( ) ;
581+
582+ let pat_snippet = sub_pats
583+ . get ( i)
584+ . and_then ( |sub_pat| {
585+ tcx. sess . source_map ( ) . span_to_snippet ( sub_pat. span ) . ok ( )
586+ } )
587+ . unwrap_or_else ( || "_" . to_string ( ) ) ;
588+
589+ if field_name == pat_snippet {
590+ field_name
591+ } else {
592+ format ! ( "{field_name}: {pat_snippet}" )
593+ }
594+ } )
595+ . collect :: < Vec < _ > > ( )
596+ . join ( ", " ) ;
597+ let sugg = format ! ( " {{ {} }}" , fields_sugg) ;
598+ ( msg, sugg)
572599 } ;
573- let fields_sugg = fields
574- . iter ( )
575- . enumerate ( )
576- . map ( |( i, field) | {
577- let field_name = field. ident ( tcx) . to_string ( ) ;
578-
579- let pat_snippet = sub_pats
580- . get ( i)
581- . and_then ( |sub_pat| {
582- tcx. sess . source_map ( ) . span_to_snippet ( sub_pat. span ) . ok ( )
583- } )
584- . unwrap_or_else ( || "_" . to_string ( ) ) ;
585-
586- if field_name == pat_snippet {
587- field_name
588- } else {
589- format ! ( "{field_name}: {pat_snippet}" )
590- }
591- } )
592- . collect :: < Vec < _ > > ( )
593- . join ( ", " ) ;
594- let sugg = format ! ( " {{ {} }}" , fields_sugg) ;
595- ( msg, sugg)
596- } ;
597-
598- err. span_suggestion_verbose (
599- qpath. span ( ) . shrink_to_hi ( ) . to ( span. shrink_to_hi ( ) ) ,
600- msg,
601- sugg,
602- Applicability :: HasPlaceholders ,
603- ) ;
604- err
600+
601+ err. span_suggestion_verbose (
602+ qpath. span ( ) . shrink_to_hi ( ) . to ( span. shrink_to_hi ( ) ) ,
603+ msg,
604+ sugg,
605+ Applicability :: HasPlaceholders ,
606+ ) ;
607+ err
608+ }
609+ _ => err. with_span_label ( span, format ! ( "not a {expected}" ) ) ,
605610 }
606- _ => err . with_span_label ( span , format ! ( "not a {expected}" ) ) ,
611+ . emit ( )
607612 }
608- . emit ( )
609613}
610614
611615/// Controls whether all arguments are tupled. This is used for the call operator only.
0 commit comments