@@ -380,16 +380,14 @@ impl<'a, 'tcx> CastCheck<'tcx> {
380
380
err. span_label ( self . span , "invalid cast" ) ;
381
381
if self . expr_ty . is_numeric ( ) {
382
382
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
+ "try `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
+ ) ;
393
391
} else if self . expr_ty == fcx. tcx . types . i8 {
394
392
err. span_help ( self . span , "try casting from `u8` instead" ) ;
395
393
} else {
@@ -494,38 +492,31 @@ impl<'a, 'tcx> CastCheck<'tcx> {
494
492
self . cast_ty. kind( ) ,
495
493
ty:: FnDef ( ..) | ty:: FnPtr ( ..) | ty:: Closure ( ..)
496
494
) {
497
- let mut label = true ;
498
495
// 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
- {
496
+ if let Some ( from_trait) = fcx. tcx . get_diagnostic_item ( sym:: From ) {
502
497
let ty = fcx. resolve_vars_if_possible ( self . cast_ty ) ;
503
498
let expr_ty = fcx. resolve_vars_if_possible ( self . expr_ty ) ;
504
499
if fcx
505
500
. infcx
506
501
. type_implements_trait ( from_trait, [ ty, expr_ty] , fcx. param_env )
507
502
. must_apply_modulo_regions ( )
508
503
{
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
- ) ;
504
+ let to_ty = if let ty:: Adt ( def, args) = self . cast_ty . kind ( ) {
505
+ fcx. tcx . value_path_str_with_args ( def. did ( ) , args)
521
506
} 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
- ) ;
507
+ self . cast_ty . to_string ( )
528
508
} ;
509
+ err. multipart_suggestion (
510
+ "consider using the `From` trait instead" ,
511
+ vec ! [
512
+ ( self . expr_span. shrink_to_lo( ) , format!( "{to_ty}::from(" ) ) ,
513
+ (
514
+ self . expr_span. shrink_to_hi( ) . to( self . cast_span) ,
515
+ ")" . to_string( ) ,
516
+ ) ,
517
+ ] ,
518
+ Applicability :: MaybeIncorrect ,
519
+ ) ;
529
520
}
530
521
}
531
522
@@ -548,11 +539,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
548
539
)
549
540
} ;
550
541
551
- if label {
552
- err. span_label ( self . span , msg) ;
553
- } else {
554
- err. note ( msg) ;
555
- }
542
+ err. span_label ( self . span , msg) ;
556
543
557
544
if let Some ( note) = note {
558
545
err. note ( note) ;
@@ -654,38 +641,22 @@ impl<'a, 'tcx> CastCheck<'tcx> {
654
641
match self . expr_ty . kind ( ) {
655
642
ty:: Ref ( _, _, mt) => {
656
643
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
- }
644
+ err. span_suggestion_verbose (
645
+ self . cast_span . shrink_to_lo ( ) ,
646
+ "try casting to a reference instead" ,
647
+ format ! ( "&{mtstr}" ) ,
648
+ Applicability :: MachineApplicable ,
649
+ ) ;
671
650
}
672
651
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
- }
652
+ err. multipart_suggestion (
653
+ "you can cast to a `Box` instead" ,
654
+ vec ! [
655
+ ( self . cast_span. shrink_to_lo( ) , "Box<" . to_string( ) ) ,
656
+ ( self . cast_span. shrink_to_hi( ) , ">" . to_string( ) ) ,
657
+ ] ,
658
+ Applicability :: MachineApplicable ,
659
+ ) ;
689
660
}
690
661
_ => {
691
662
err. span_help ( self . expr_span , "consider using a box or reference as appropriate" ) ;
0 commit comments