aboutsummaryrefslogtreecommitdiff
path: root/compile.c
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-10-27 20:25:16 -0400
committerBruce Hill <bruce@bruce-hill.com>2024-10-27 20:35:30 -0400
commit63a5032ca06cd9f9bfaea6b0ea077d49a3034654 (patch)
treee925fa942bbb3a9d61aedbbfcf92ca5f2f96d7f1 /compile.c
parent052316261a94f2846e7547b65b2bb089979ce5ba (diff)
Disallow mutation of read-only views
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/compile.c b/compile.c
index a0069b34..775c17df 100644
--- a/compile.c
+++ b/compile.c
@@ -278,9 +278,20 @@ CORD compile_type(type_t *t)
static CORD compile_lvalue(env_t *env, ast_t *ast)
{
if (!can_be_mutated(env, ast)) {
- if (ast->tag == Index || ast->tag == FieldAccess) {
- ast_t *subject = ast->tag == Index ? Match(ast, Index)->indexed : Match(ast, FieldAccess)->fielded;
- code_err(subject, "This is an immutable value, you can't assign to it");
+ if (ast->tag == Index) {
+ ast_t *subject = Match(ast, Index)->indexed;
+ type_t *t = get_type(env, subject);
+ if (t->tag == PointerType && Match(t, PointerType)->is_view)
+ code_err(ast, "This is a read-only view and you can't mutate its contents");
+ else
+ code_err(subject, "This is an immutable value, you can't mutate its contents");
+ } else if (ast->tag == FieldAccess) {
+ ast_t *subject = Match(ast, FieldAccess)->fielded;
+ type_t *t = get_type(env, subject);
+ if (t->tag == PointerType && Match(t, PointerType)->is_view)
+ code_err(subject, "This is a read-only view and you can't mutate its fields");
+ else
+ code_err(subject, "This is an immutable value, you can't assign to its fields");
} else {
code_err(ast, "This is a value of type %T and can't be used as an assignment target", get_type(env, ast));
}