Feat: add mutable pointer type *mut T and *mut opaque

- Grammar: update pointer_type to support optional mut keyword;
  LL(1) verified (56 named rules, no conflicts)
- AST: update Type enum with mutable: bool field for Pointer and
  OpaquePointer variants
- Parser: consume optional mut token in parse_type; update all
  existing pointer tests; add 4 new mut pointer tests (85 pass)
- VSCode extension: add *mut capture-group pattern for syntax
  highlighting; update SYNTAX.md with pointer mutability table

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-11 10:37:21 +01:00
parent 53c66a3d03
commit 7cdcad7df3
5 changed files with 97 additions and 29 deletions

View File

@@ -291,20 +291,36 @@ Node // struct Node { value: i64, next: *Node }
### Pointer Types
A pointer type is written with a leading `*`.
A pointer type is written with a leading `*`. The optional `mut` keyword following
`*` marks the pointer as **mutable** — the pointee can be written through.
Without `mut` the pointer is **immutable** — the pointee can only be read.
| Syntax | Description |
| --------- | ------------------------------------------------------------------------------------- |
| `*T` | Typed pointer — points to a value of type `T` |
| `*opaque` | Opaque pointer — no compile-time pointee type information; equivalent to C's `void *` |
| Syntax | C equivalent | Description |
| ------------- | ----------------- | -------------------------------------------------- |
| `*T` | `const T *` | Immutable typed pointer — read-only through ptr |
| `*mut T` | `T *` | Mutable typed pointer — read-write through ptr |
| `*opaque` | `const void *` | Immutable untyped pointer — no pointee type info |
| `*mut opaque` | `void *` | Mutable untyped pointer — no pointee type info |
Pointer types may be nested: `**u8` is a pointer to a pointer to `u8`.
Pointer mutability (`*mut`) and binding mutability (`let mut`) are **independent**:
| Declaration | Can reassign ptr? | Can write through ptr? |
| ------------------------- | ----------------- | ---------------------- |
| `let p: *T` | no | no |
| `let mut p: *T` | yes | no |
| `let p: *mut T` | no | yes |
| `let mut p: *mut T` | yes | yes |
Pointer types may be nested. The `mut` qualifier applies only to the outermost
indirection; each `*` in the chain can independently carry `mut`.
```flux
*u8 // pointer to u8
**i32 // pointer to pointer to i32
*opaque // untyped pointer
**opaque // pointer to untyped pointer
*u8 // immutable pointer to u8 (cannot write *p)
*mut u8 // mutable pointer to u8 (can write *p)
**u8 // immutable pointer to immutable pointer to u8
*mut *mut u8 // mutable pointer to mutable pointer to u8
*opaque // immutable untyped pointer
*mut opaque // mutable untyped pointer
```
### Array Types
@@ -333,7 +349,7 @@ primitive_type = "u8" | "u16" | "u32" | "u64"
| "i8" | "i16" | "i32" | "i64"
| "f32" | "f64" | "bool" | "char" ;
named_type = IDENT ;
pointer_type = "*" , ( "opaque" | type ) ;
pointer_type = "*" , [ "mut" ] , ( "opaque" | type ) ;
array_type = "[" , type , ";" , INT_LIT , "]" ;
```