1+ use rustc_errors:: { Applicability , Diagnostic , DiagnosticBuilder , ErrorGuaranteed } ;
12use rustc_hir as hir;
23use rustc_hir:: Node ;
34use rustc_middle:: hir:: map:: Map ;
@@ -12,12 +13,11 @@ use rustc_middle::{
1213} ;
1314use rustc_span:: source_map:: DesugaringKind ;
1415use rustc_span:: symbol:: { kw, Symbol } ;
15- use rustc_span:: { BytePos , Span } ;
16+ use rustc_span:: { sym , BytePos , Span } ;
1617
1718use crate :: diagnostics:: BorrowedContentSource ;
1819use crate :: MirBorrowckCtxt ;
1920use rustc_const_eval:: util:: collect_writes:: FindAssignments ;
20- use rustc_errors:: { Applicability , Diagnostic } ;
2121
2222#[ derive( Copy , Clone , Debug , Eq , PartialEq ) ]
2323pub ( crate ) enum AccessKind {
@@ -614,6 +614,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
614614 "trait `IndexMut` is required to modify indexed content, \
615615 but it is not implemented for `{ty}`",
616616 ) ) ;
617+ self . suggest_map_index_mut_alternatives ( ty, & mut err) ;
617618 }
618619 _ => ( ) ,
619620 }
@@ -627,6 +628,20 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
627628 self . buffer_error ( err) ;
628629 }
629630
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+
630645 /// User cannot make signature of a trait mutable without changing the
631646 /// trait. So we find if this error belongs to a trait and if so we move
632647 /// suggestion to the trait or disable it if it is out of scope of this crate
0 commit comments