@@ -128,7 +128,7 @@ impl<'interner> TypeChecker<'interner> {
128128 Type :: Error
129129 } )
130130 }
131- HirExpression :: Index ( index_expr) => self . check_index_expression ( index_expr) ,
131+ HirExpression :: Index ( index_expr) => self . check_index_expression ( expr_id , index_expr) ,
132132 HirExpression :: Call ( call_expr) => {
133133 self . check_if_deprecated ( & call_expr. func ) ;
134134
@@ -396,7 +396,11 @@ impl<'interner> TypeChecker<'interner> {
396396 }
397397 }
398398
399- fn check_index_expression ( & mut self , index_expr : expr:: HirIndexExpression ) -> Type {
399+ fn check_index_expression (
400+ & mut self ,
401+ id : & ExprId ,
402+ mut index_expr : expr:: HirIndexExpression ,
403+ ) -> Type {
400404 let index_type = self . check_expression ( & index_expr. index ) ;
401405 let span = self . interner . expr_span ( & index_expr. index ) ;
402406
@@ -408,14 +412,20 @@ impl<'interner> TypeChecker<'interner> {
408412 }
409413 } ) ;
410414
415+ // When writing `a[i]`, if `a : &mut ...` then automatically dereference `a` as many
416+ // times as needed to get the underlying array.
411417 let lhs_type = self . check_expression ( & index_expr. collection ) ;
418+ let ( new_lhs, lhs_type) = self . insert_auto_dereferences ( index_expr. collection , lhs_type) ;
419+ index_expr. collection = new_lhs;
420+ self . interner . replace_expr ( id, HirExpression :: Index ( index_expr) ) ;
421+
412422 match lhs_type. follow_bindings ( ) {
413423 // XXX: We can check the array bounds here also, but it may be better to constant fold first
414424 // and have ConstId instead of ExprId for constants
415425 Type :: Array ( _, base_type) => * base_type,
416426 Type :: Error => Type :: Error ,
417427 typ => {
418- let span = self . interner . expr_span ( & index_expr . collection ) ;
428+ let span = self . interner . expr_span ( & new_lhs ) ;
419429 self . errors . push ( TypeCheckError :: TypeMismatch {
420430 expected_typ : "Array" . to_owned ( ) ,
421431 expr_typ : typ. to_string ( ) ,
0 commit comments