summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/eval/mod.rs25
-rw-r--r--tests/typ/code/dict.typ23
2 files changed, 42 insertions, 6 deletions
diff --git a/src/eval/mod.rs b/src/eval/mod.rs
index 0021b93c..db50ee82 100644
--- a/src/eval/mod.rs
+++ b/src/eval/mod.rs
@@ -1000,8 +1000,9 @@ impl Access for Expr {
scp: &'a mut Scopes,
) -> TypResult<Location<'a>> {
match self {
- Expr::Ident(ident) => ident.access(ctx, scp),
- Expr::FuncCall(call) => call.access(ctx, scp),
+ Expr::Ident(v) => v.access(ctx, scp),
+ Expr::FieldAccess(v) => v.access(ctx, scp),
+ Expr::FuncCall(v) => v.access(ctx, scp),
_ => bail!(self.span(), "cannot mutate a temporary value"),
}
}
@@ -1023,6 +1024,26 @@ impl Access for Ident {
}
}
+impl Access for FieldAccess {
+ fn access<'a>(
+ &self,
+ ctx: &mut Context,
+ scp: &'a mut Scopes,
+ ) -> TypResult<Location<'a>> {
+ let guard = self.object().access(ctx, scp)?;
+ try_map(guard, |value| {
+ Ok(match value {
+ Value::Dict(dict) => dict.get_mut(self.field().take()),
+ v => bail!(
+ self.object().span(),
+ "expected dictionary, found {}",
+ v.type_name(),
+ ),
+ })
+ })
+ }
+}
+
impl Access for FuncCall {
fn access<'a>(
&self,
diff --git a/tests/typ/code/dict.typ b/tests/typ/code/dict.typ
index 80097761..182f53d9 100644
--- a/tests/typ/code/dict.typ
+++ b/tests/typ/code/dict.typ
@@ -17,10 +17,14 @@
---
// Test lvalue and rvalue access.
{
- let dict = (a: 1, b: 1)
- dict("b") += 1
- dict("c") = 3
- test(dict, (a: 1, b: 2, c: 3))
+ let dict = (a: 1, "b b": 1)
+ dict("b b") += 1
+ dict.state = (ok: true, err: false)
+ test(dict, (a: 1, "b b": 2, state: (ok: true, err: false)))
+ test(dict.state.ok, true)
+ dict("state").ok = false
+ test(dict.state.ok, false)
+ test(dict.state.err, false)
}
---
@@ -58,3 +62,14 @@
// Error: 12-16 expected identifier or string, found boolean
// Error: 17-18 expected expression, found colon
{(:1 b:"", true::)}
+
+---
+// Error: 3-15 cannot mutate a temporary value
+{ (key: value).other = "some" }
+
+---
+{
+ let object = none
+ // Error: 3-9 expected dictionary, found none
+ object.property = "value"
+}