@@ -380,20 +380,21 @@ 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
+ "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
+ ) ;
393
391
} 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" ) ;
395
393
} 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
+ ) ;
397
398
} ;
398
399
}
399
400
err. emit ( ) ;
@@ -494,38 +495,31 @@ impl<'a, 'tcx> CastCheck<'tcx> {
494
495
self . cast_ty. kind( ) ,
495
496
ty:: FnDef ( ..) | ty:: FnPtr ( ..) | ty:: Closure ( ..)
496
497
) {
497
- let mut label = true ;
498
498
// 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 ) {
502
500
let ty = fcx. resolve_vars_if_possible ( self . cast_ty ) ;
503
501
let expr_ty = fcx. resolve_vars_if_possible ( self . expr_ty ) ;
504
502
if fcx
505
503
. infcx
506
504
. type_implements_trait ( from_trait, [ ty, expr_ty] , fcx. param_env )
507
505
. must_apply_modulo_regions ( )
508
506
{
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)
521
509
} 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 ( )
528
511
} ;
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
+ ) ;
529
523
}
530
524
}
531
525
@@ -548,11 +542,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
548
542
)
549
543
} ;
550
544
551
- if label {
552
- err. span_label ( self . span , msg) ;
553
- } else {
554
- err. note ( msg) ;
555
- }
545
+ err. span_label ( self . span , msg) ;
556
546
557
547
if let Some ( note) = note {
558
548
err. note ( note) ;
@@ -654,38 +644,22 @@ impl<'a, 'tcx> CastCheck<'tcx> {
654
644
match self . expr_ty . kind ( ) {
655
645
ty:: Ref ( _, _, mt) => {
656
646
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
+ ) ;
671
653
}
672
654
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
+ ) ;
689
663
}
690
664
_ => {
691
665
err. span_help ( self . expr_span , "consider using a box or reference as appropriate" ) ;
0 commit comments