Skip to content

Commit

Permalink
feat: Implement automatic dereferencing for indexing lvalues (#3083)
Browse files Browse the repository at this point in the history
  • Loading branch information
jfecher authored and TomAFrench committed Oct 12, 2023
1 parent 0b5eecf commit b8d8268
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 4 deletions.
17 changes: 14 additions & 3 deletions compiler/noirc_frontend/src/hir/type_check/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,10 +248,20 @@ impl<'interner> TypeChecker<'interner> {
},
);

let (array_type, array, mutable) = self.check_lvalue(array, assign_span);
let array = Box::new(array);
let (mut lvalue_type, mut lvalue, mut mutable) =
self.check_lvalue(array, assign_span);

// Before we check that the lvalue is an array, try to dereference it as many times
// as needed to unwrap any &mut wrappers.
while let Type::MutableReference(element) = lvalue_type.follow_bindings() {
let element_type = element.as_ref().clone();
lvalue = HirLValue::Dereference { lvalue: Box::new(lvalue), element_type };
lvalue_type = *element;
// We know this value to be mutable now since we found an `&mut`
mutable = true;
}

let typ = match array_type.follow_bindings() {
let typ = match lvalue_type.follow_bindings() {
Type::Array(_, elem_type) => *elem_type,
Type::Error => Type::Error,
other => {
Expand All @@ -265,6 +275,7 @@ impl<'interner> TypeChecker<'interner> {
}
};

let array = Box::new(lvalue);
(typ.clone(), HirLValue::Index { array, index: *index, typ }, mutable)
}
HirLValue::Dereference { lvalue, element_type: _ } => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@

fn main() {
let a = &mut [1, 2, 3];
let a = &mut &mut &mut [1, 2, 3];
assert(a[0] == 1);

a[0] = 4;
assert(a[0] == 4);
}

0 comments on commit b8d8268

Please sign in to comment.