Description
Currently, formality doesn't distinguish between let x and let mut x. All variables are implicitly mutable. We need to:
- Add
mut as an optional annotation on let declarations in the grammar
- Add "mut place" checks into the borrow checker rules — when performing a mutable access (assignment,
&mut borrow), verify that the target place is mutable:
- A local variable and the data it owns is
mut if declared let mut x
- When passing through a deref, deref of
& is not mut, but deref of &mut is
Mentoring notes
Where to start:
-
Grammar: Look at crates/formality-rust/src/grammar/expr/mod.rs for how local variable declarations work. You'll need to add a Mutability field (or just a bool) to the let statement representation.
-
Borrow checker: Look at crates/formality-rust/src/check/borrow_check/ — when an assignment or &mut borrow is processed, add a check that the target local was declared mut.
-
Existing tests: The existing borrow check tests in tests/borrowck.rs will need updating — they'll need mut annotations where variables are mutated.
Steps:
- Add
Mutability enum (Mut/Not) to the grammar for local declarations
- Thread it through parsing/lowering
- Create a judgment
prove_place_is_mut(place) => () with rules:
- A local variable
x is mut if declared let mut x
- A deref of
&mut T is mut
- A deref of
&T is NOT mut
- A field access
place.field is mut if place is mut
- In the borrow checker, when you see a write to a place or a
&mut borrow of a place, call prove_place_is_mut
- Add test cases: mutable access to non-mut variable (should error), mutable access to mut variable (should pass), write through
&mut (should pass), write through & (should error)
- Update all existing tests that mutate variables to use
mut
Description
Currently, formality doesn't distinguish between
let xandlet mut x. All variables are implicitly mutable. We need to:mutas an optional annotation onletdeclarations in the grammar&mutborrow), verify that the target place is mutable:mutif declaredlet mut x&is not mut, but deref of&mutisMentoring notes
Where to start:
Grammar: Look at
crates/formality-rust/src/grammar/expr/mod.rsfor how local variable declarations work. You'll need to add aMutabilityfield (or just a bool) to theletstatement representation.Borrow checker: Look at
crates/formality-rust/src/check/borrow_check/— when an assignment or&mutborrow is processed, add a check that the target local was declaredmut.Existing tests: The existing borrow check tests in
tests/borrowck.rswill need updating — they'll needmutannotations where variables are mutated.Steps:
Mutabilityenum (Mut/Not) to the grammar for local declarationsprove_place_is_mut(place) => ()with rules:xis mut if declaredlet mut x&mut Tis mut&Tis NOT mutplace.fieldis mut ifplaceis mut&mutborrow of a place, callprove_place_is_mut&mut(should pass), write through&(should error)mut