@@ -6,7 +6,7 @@ use rustc_middle::mir::{Mutability, Place, PlaceRef, ProjectionElem};
6
6
use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
7
7
use rustc_middle:: {
8
8
hir:: place:: PlaceBase ,
9
- mir:: { self , ClearCrossCrate , Local , LocalDecl , LocalInfo , Location } ,
9
+ mir:: { self , ClearCrossCrate , Local , LocalDecl , LocalInfo , LocalKind , Location } ,
10
10
} ;
11
11
use rustc_span:: source_map:: DesugaringKind ;
12
12
use rustc_span:: symbol:: { kw, Symbol } ;
@@ -424,15 +424,108 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
424
424
425
425
match label {
426
426
Some ( ( true , err_help_span, suggested_code) ) => {
427
- err. span_suggestion (
428
- err_help_span,
429
- & format ! (
430
- "consider changing this to be a mutable {}" ,
431
- pointer_desc
432
- ) ,
433
- suggested_code,
434
- Applicability :: MachineApplicable ,
435
- ) ;
427
+ /// User cannot make signature of a trait mutable
428
+ /// without changing the trait. So we find if this
429
+ /// error belongs to a trait and if so we move
430
+ /// suggestion to the trait or disable it if it is
431
+ /// out of scope of this crate
432
+ let ( is_trait_sig, local_trait) = {
433
+ if self . body . local_kind ( local) != LocalKind :: Arg {
434
+ ( false , None )
435
+ } else {
436
+ let hir_map = self . infcx . tcx . hir ( ) ;
437
+ let my_hir = hir_map. local_def_id_to_hir_id (
438
+ self . body . source . def_id ( ) . as_local ( ) . unwrap ( ) ,
439
+ ) ;
440
+ match hir_map. find ( hir_map. get_parent_node ( my_hir) ) {
441
+ Some ( Node :: Item ( hir:: Item {
442
+ kind :
443
+ hir:: ItemKind :: Impl ( hir:: Impl {
444
+ of_trait :
445
+ Some ( hir:: TraitRef {
446
+ path :
447
+ hir:: Path {
448
+ res :
449
+ hir:: def:: Res :: Def ( _, td) ,
450
+ ..
451
+ } ,
452
+ ..
453
+ } ) ,
454
+ ..
455
+ } ) ,
456
+ ..
457
+ } ) ) => {
458
+ ( true , td. as_local ( ) . and_then ( |tld| {
459
+ let h = hir_map. local_def_id_to_hir_id ( tld) ;
460
+ match hir_map. find ( h) {
461
+ Some ( Node :: Item ( hir:: Item {
462
+ kind : hir:: ItemKind :: Trait (
463
+ _, _, _, _,
464
+ items
465
+ ) ,
466
+ ..
467
+ } ) ) => {
468
+ let mut f_in_trait_opt = None ;
469
+ for hir:: TraitItemRef { id : fi, kind : k, .. } in * items {
470
+ let hi = fi. hir_id ( ) ;
471
+ if !matches ! ( k, hir:: AssocItemKind :: Fn { .. } ) {
472
+ continue ;
473
+ }
474
+ if hir_map. name ( hi) != hir_map. name ( my_hir) {
475
+ continue ;
476
+ }
477
+ f_in_trait_opt = Some ( hi) ;
478
+ break ;
479
+ }
480
+ f_in_trait_opt. and_then ( |f_in_trait| {
481
+ match hir_map. find ( f_in_trait) {
482
+ Some ( Node :: TraitItem ( hir:: TraitItem {
483
+ kind : hir:: TraitItemKind :: Fn ( hir:: FnSig {
484
+ decl : hir:: FnDecl {
485
+ inputs,
486
+ ..
487
+ } ,
488
+ ..
489
+ } , _) ,
490
+ ..
491
+ } ) ) => {
492
+ let hir:: Ty { span, .. } = inputs[ local. index ( ) - 1 ] ;
493
+ Some ( span)
494
+ } ,
495
+ _ => None ,
496
+ }
497
+ } )
498
+ //Some(hir_map.span(h))
499
+ }
500
+ _ => None
501
+ }
502
+ } ) )
503
+ }
504
+ _ => ( false , None ) ,
505
+ }
506
+ }
507
+ } ;
508
+ if !is_trait_sig {
509
+ err. span_suggestion (
510
+ err_help_span,
511
+ & format ! (
512
+ "consider changing this to be a mutable {}" ,
513
+ pointer_desc
514
+ ) ,
515
+ suggested_code,
516
+ Applicability :: MachineApplicable ,
517
+ ) ;
518
+ } else if let Some ( x) = local_trait {
519
+ err. span_suggestion (
520
+ x,
521
+ & format ! (
522
+ "consider changing that to be a mutable {}" ,
523
+ pointer_desc
524
+ ) ,
525
+ suggested_code,
526
+ Applicability :: MachineApplicable ,
527
+ ) ;
528
+ }
436
529
}
437
530
Some ( ( false , err_label_span, message) ) => {
438
531
err. span_label ( err_label_span, & message) ;
0 commit comments