@@ -380,20 +380,21 @@ impl<'a, 'tcx> CastCheck<'tcx> {
380380 err. span_label ( self . span , "invalid cast" ) ;
381381 if self . expr_ty . is_numeric ( ) {
382382 if self . expr_ty == fcx. tcx . types . u32 {
383- match fcx. tcx . sess . source_map ( ) . span_to_snippet ( self . expr . span ) {
384- Ok ( snippet) => err. span_suggestion (
385- self . span ,
386- "try `char::from_u32` instead" ,
387- format ! ( "char::from_u32({snippet})" ) ,
388- Applicability :: MachineApplicable ,
389- ) ,
390-
391- Err ( _) => err. span_help ( self . span , "try `char::from_u32` instead" ) ,
392- } ;
383+ err. multipart_suggestion (
384+ "consider using `char::from_u32` instead" ,
385+ vec ! [
386+ ( self . expr_span. shrink_to_lo( ) , "char::from_u32(" . to_string( ) ) ,
387+ ( self . expr_span. shrink_to_hi( ) . to( self . cast_span) , ")" . to_string( ) ) ,
388+ ] ,
389+ Applicability :: MachineApplicable ,
390+ ) ;
393391 } else if self . expr_ty == fcx. tcx . types . i8 {
394- err. span_help ( self . span , "try casting from `u8` instead" ) ;
392+ err. span_help ( self . span , "consider casting from `u8` instead" ) ;
395393 } else {
396- err. span_help ( self . span , "try `char::from_u32` instead (via a `u32`)" ) ;
394+ err. span_help (
395+ self . span ,
396+ "consider using `char::from_u32` instead (via a `u32`)" ,
397+ ) ;
397398 } ;
398399 }
399400 err. emit ( ) ;
@@ -494,38 +495,31 @@ impl<'a, 'tcx> CastCheck<'tcx> {
494495 self . cast_ty. kind( ) ,
495496 ty:: FnDef ( ..) | ty:: FnPtr ( ..) | ty:: Closure ( ..)
496497 ) {
497- let mut label = true ;
498498 // Check `impl From<self.expr_ty> for self.cast_ty {}` for accurate suggestion:
499- if let Ok ( snippet) = fcx. tcx . sess . source_map ( ) . span_to_snippet ( self . expr_span )
500- && let Some ( from_trait) = fcx. tcx . get_diagnostic_item ( sym:: From )
501- {
499+ if let Some ( from_trait) = fcx. tcx . get_diagnostic_item ( sym:: From ) {
502500 let ty = fcx. resolve_vars_if_possible ( self . cast_ty ) ;
503501 let expr_ty = fcx. resolve_vars_if_possible ( self . expr_ty ) ;
504502 if fcx
505503 . infcx
506504 . type_implements_trait ( from_trait, [ ty, expr_ty] , fcx. param_env )
507505 . must_apply_modulo_regions ( )
508506 {
509- label = false ;
510- if let ty:: Adt ( def, args) = self . cast_ty . kind ( ) {
511- err. span_suggestion_verbose (
512- self . span ,
513- "consider using the `From` trait instead" ,
514- format ! (
515- "{}::from({})" ,
516- fcx. tcx. value_path_str_with_args( def. did( ) , args) ,
517- snippet
518- ) ,
519- Applicability :: MaybeIncorrect ,
520- ) ;
507+ let to_ty = if let ty:: Adt ( def, args) = self . cast_ty . kind ( ) {
508+ fcx. tcx . value_path_str_with_args ( def. did ( ) , args)
521509 } else {
522- err. span_suggestion (
523- self . span ,
524- "consider using the `From` trait instead" ,
525- format ! ( "{}::from({})" , self . cast_ty, snippet) ,
526- Applicability :: MaybeIncorrect ,
527- ) ;
510+ self . cast_ty . to_string ( )
528511 } ;
512+ err. multipart_suggestion (
513+ "consider using the `From` trait instead" ,
514+ vec ! [
515+ ( self . expr_span. shrink_to_lo( ) , format!( "{to_ty}::from(" ) ) ,
516+ (
517+ self . expr_span. shrink_to_hi( ) . to( self . cast_span) ,
518+ ")" . to_string( ) ,
519+ ) ,
520+ ] ,
521+ Applicability :: MaybeIncorrect ,
522+ ) ;
529523 }
530524 }
531525
@@ -548,11 +542,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
548542 )
549543 } ;
550544
551- if label {
552- err. span_label ( self . span , msg) ;
553- } else {
554- err. note ( msg) ;
555- }
545+ err. span_label ( self . span , msg) ;
556546
557547 if let Some ( note) = note {
558548 err. note ( note) ;
@@ -654,38 +644,22 @@ impl<'a, 'tcx> CastCheck<'tcx> {
654644 match self . expr_ty . kind ( ) {
655645 ty:: Ref ( _, _, mt) => {
656646 let mtstr = mt. prefix_str ( ) ;
657- match fcx. tcx . sess . source_map ( ) . span_to_snippet ( self . cast_span ) {
658- Ok ( s) => {
659- err. span_suggestion (
660- self . cast_span ,
661- "try casting to a reference instead" ,
662- format ! ( "&{mtstr}{s}" ) ,
663- Applicability :: MachineApplicable ,
664- ) ;
665- }
666- Err ( _) => {
667- let msg = format ! ( "did you mean `&{mtstr}{tstr}`?" ) ;
668- err. span_help ( self . cast_span , msg) ;
669- }
670- }
647+ err. span_suggestion_verbose (
648+ self . cast_span . shrink_to_lo ( ) ,
649+ "consider casting to a reference instead" ,
650+ format ! ( "&{mtstr}" ) ,
651+ Applicability :: MachineApplicable ,
652+ ) ;
671653 }
672654 ty:: Adt ( def, ..) if def. is_box ( ) => {
673- match fcx. tcx . sess . source_map ( ) . span_to_snippet ( self . cast_span ) {
674- Ok ( s) => {
675- err. span_suggestion (
676- self . cast_span ,
677- "you can cast to a `Box` instead" ,
678- format ! ( "Box<{s}>" ) ,
679- Applicability :: MachineApplicable ,
680- ) ;
681- }
682- Err ( _) => {
683- err. span_help (
684- self . cast_span ,
685- format ! ( "you might have meant `Box<{tstr}>`" ) ,
686- ) ;
687- }
688- }
655+ err. multipart_suggestion (
656+ "you can cast to a `Box` instead" ,
657+ vec ! [
658+ ( self . cast_span. shrink_to_lo( ) , "Box<" . to_string( ) ) ,
659+ ( self . cast_span. shrink_to_hi( ) , ">" . to_string( ) ) ,
660+ ] ,
661+ Applicability :: MachineApplicable ,
662+ ) ;
689663 }
690664 _ => {
691665 err. span_help ( self . expr_span , "consider using a box or reference as appropriate" ) ;
0 commit comments