1
+ use rustc_errors:: { Applicability , Diagnostic , DiagnosticBuilder , ErrorGuaranteed } ;
1
2
use rustc_hir as hir;
2
3
use rustc_hir:: Node ;
3
4
use rustc_middle:: hir:: map:: Map ;
@@ -12,12 +13,11 @@ use rustc_middle::{
12
13
} ;
13
14
use rustc_span:: source_map:: DesugaringKind ;
14
15
use rustc_span:: symbol:: { kw, Symbol } ;
15
- use rustc_span:: { BytePos , Span } ;
16
+ use rustc_span:: { sym , BytePos , Span } ;
16
17
17
18
use crate :: diagnostics:: BorrowedContentSource ;
18
19
use crate :: MirBorrowckCtxt ;
19
20
use rustc_const_eval:: util:: collect_writes:: FindAssignments ;
20
- use rustc_errors:: { Applicability , Diagnostic } ;
21
21
22
22
#[ derive( Copy , Clone , Debug , Eq , PartialEq ) ]
23
23
pub ( crate ) enum AccessKind {
@@ -614,6 +614,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
614
614
"trait `IndexMut` is required to modify indexed content, \
615
615
but it is not implemented for `{ty}`",
616
616
) ) ;
617
+ self . suggest_map_index_mut_alternatives ( ty, & mut err) ;
617
618
}
618
619
_ => ( ) ,
619
620
}
@@ -627,6 +628,20 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
627
628
self . buffer_error ( err) ;
628
629
}
629
630
631
+ fn suggest_map_index_mut_alternatives (
632
+ & self ,
633
+ ty : Ty < ' _ > ,
634
+ err : & mut DiagnosticBuilder < ' _ , ErrorGuaranteed > ,
635
+ ) {
636
+ let Some ( adt) = ty. ty_adt_def ( ) else { return } ;
637
+ let did = adt. did ( ) ;
638
+ if self . infcx . tcx . is_diagnostic_item ( sym:: HashMap , did)
639
+ || self . infcx . tcx . is_diagnostic_item ( sym:: BTreeMap , did)
640
+ {
641
+ err. help ( format ! ( "to modify a `{ty}`, use `.get_mut()`, `.insert()` or the entry API" ) ) ;
642
+ }
643
+ }
644
+
630
645
/// User cannot make signature of a trait mutable without changing the
631
646
/// trait. So we find if this error belongs to a trait and if so we move
632
647
/// suggestion to the trait or disable it if it is out of scope of this crate
0 commit comments