Skip to content

Commit 8270cac

Browse files
jfecherTomAFrench
authored andcommitted
feat: Implement automatic dereferencing for index expressions (#3082)
1 parent d337fa0 commit 8270cac

3 files changed

Lines changed: 25 additions & 3 deletions

File tree

  • compiler/noirc_frontend/src/hir/type_check
  • tooling/nargo_cli/tests/compile_success_empty/auto_deref

compiler/noirc_frontend/src/hir/type_check/expr.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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(),
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[package]
2+
name = "auto_deref"
3+
type = "bin"
4+
authors = [""]
5+
compiler_version = "0.16.0"
6+
7+
[dependencies]
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
fn main() {
3+
let a = &mut [1, 2, 3];
4+
assert(a[0] == 1);
5+
}

0 commit comments

Comments
 (0)