@@ -1197,7 +1197,7 @@ fn reference_is_exclusive(reference: &FileReference, ctx: &AssistContext<'_, '_>
11971197 expr_require_exclusive_access ( ctx, & path) . unwrap_or ( false )
11981198}
11991199
1200- /// checks if this expr requires `&mut` access, recurses on field access
1200+ /// checks if this expr requires `&mut` access, recurses on field/index access
12011201fn expr_require_exclusive_access ( ctx : & AssistContext < ' _ , ' _ > , expr : & ast:: Expr ) -> Option < bool > {
12021202 let parent = expr. syntax ( ) . parent ( ) ?;
12031203
@@ -1220,10 +1220,17 @@ fn expr_require_exclusive_access(ctx: &AssistContext<'_, '_>, expr: &ast::Expr)
12201220 return Some ( matches ! ( access, hir:: Access :: Exclusive ) ) ;
12211221 }
12221222
1223- if let Some ( field) = ast:: FieldExpr :: cast ( parent) {
1223+ if let Some ( field) = ast:: FieldExpr :: cast ( parent. clone ( ) ) {
12241224 return expr_require_exclusive_access ( ctx, & field. into ( ) ) ;
12251225 }
12261226
1227+ // `container[i].mut_method()` needs `&mut container` but WRITE is not set (no direct assignment).
1228+ if let Some ( index_expr) = ast:: IndexExpr :: cast ( parent)
1229+ && index_expr. base ( ) . is_some_and ( |base| base. syntax ( ) == expr. syntax ( ) )
1230+ {
1231+ return expr_require_exclusive_access ( ctx, & index_expr. into ( ) ) ;
1232+ }
1233+
12271234 Some ( false )
12281235}
12291236
@@ -3250,6 +3257,54 @@ fn $0fun_name(arr: &mut [i32; 1]) {
32503257 ) ;
32513258 }
32523259
3260+ #[ test]
3261+ fn mut_index_element_method_call ( ) {
3262+ check_assist (
3263+ extract_function,
3264+ r#"
3265+ //- minicore: index
3266+ use core::ops::{Index, IndexMut};
3267+ struct Container([S; 2]);
3268+ struct S;
3269+ impl S { fn mutate(&mut self) {} }
3270+ impl Index<usize> for Container {
3271+ type Output = S;
3272+ fn index(&self, i: usize) -> &S { &self.0[i] }
3273+ }
3274+ impl IndexMut<usize> for Container {
3275+ fn index_mut(&mut self, i: usize) -> &mut S { &mut self.0[i] }
3276+ }
3277+ fn foo() {
3278+ let mut c = Container([S, S]);
3279+ $0c[0].mutate();$0
3280+ let _ = c;
3281+ }
3282+ "# ,
3283+ r#"
3284+ use core::ops::{Index, IndexMut};
3285+ struct Container([S; 2]);
3286+ struct S;
3287+ impl S { fn mutate(&mut self) {} }
3288+ impl Index<usize> for Container {
3289+ type Output = S;
3290+ fn index(&self, i: usize) -> &S { &self.0[i] }
3291+ }
3292+ impl IndexMut<usize> for Container {
3293+ fn index_mut(&mut self, i: usize) -> &mut S { &mut self.0[i] }
3294+ }
3295+ fn foo() {
3296+ let mut c = Container([S, S]);
3297+ fun_name(&mut c);
3298+ let _ = c;
3299+ }
3300+
3301+ fn $0fun_name(c: &mut Container) {
3302+ c[0].mutate();
3303+ }
3304+ "# ,
3305+ ) ;
3306+ }
3307+
32533308 #[ test]
32543309 fn mut_field_from_outer_scope ( ) {
32553310 check_assist (
0 commit comments