Skip to content

Commit

Permalink
Check for missing fields in object literals (#2332)
Browse files Browse the repository at this point in the history
fixes #2331
  • Loading branch information
nomeata authored Feb 10, 2021
1 parent 3f9f3f8 commit 912e481
Show file tree
Hide file tree
Showing 11 changed files with 39 additions and 2 deletions.
3 changes: 3 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
`x.vals()` is introduced. It works like `x.bytes()`, but returns the elements
as type `Nat8`.

* Bugfix: Certain ill-typed object literals are now prevented by the type
checker.

== 0.5.7 (2021-02-05)

* The type checker now exploits the expected type, if any,
Expand Down
1 change: 1 addition & 0 deletions src/lang_utils/error_codes.ml
Original file line number Diff line number Diff line change
Expand Up @@ -154,4 +154,5 @@ let error_codes : (string * string option) list =
"M0148", None; (* Block syntax is deprecated in this position *)
"M0149", Some([%blob "error_codes/M0149.adoc"]); (* Expected mutable 'var' field, found immutable field *)
"M0150", Some([%blob "error_codes/M0150.adoc"]); (* Expected immutable field, found mutable 'var' field *)
"M0151", Some([%blob "error_codes/M0151.adoc"]); (* missing field in object literal *)
]
18 changes: 18 additions & 0 deletions src/lang_utils/error_codes/M0151.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
= M0151

This error means that a object literal is missing some fields, maybe because of a typo.

Erroneous code examples:

```
{ first_name = "Fred" } : { firstName : Text }
{ firstName = "Fred" } : { firstName : Text; lastName : Text }
```

If you encounter this error, you need to add the missing field name to the
object literal.

```
{ firstName = "Fred" } : { firstName : Text }
{ firstName = "Fred"; lastName = "Flintstone" } : { firstName : Text; lastName : Text }
```
6 changes: 6 additions & 0 deletions src/mo_frontend/typing.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1236,6 +1236,12 @@ and check_exp' env0 t exp : T.typ =
check_ids env "object" "field"
(List.map (fun (ef : exp_field) -> ef.it.id) exp_fields);
List.iter (fun ef -> check_exp_field env ef fts) exp_fields;
List.iter (fun ft ->
if not (List.exists (fun (ef : exp_field) -> ft.T.lab = ef.it.id.it) exp_fields)
then local_error env exp.at "M0151"
"object literal is missing field %s from expected type\n %s"
ft.T.lab (T.string_of_typ_expand t);
) fts;
t
| OptE exp1, _ when T.is_opt t ->
check_exp env (T.as_opt t) exp1;
Expand Down
2 changes: 2 additions & 0 deletions test/fail/check-record.mo
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ ignore ({ a = 0; var v = 0} : { var a : Int; v : Int }); // reject, mutability

ignore ({} : { a: Nat }); // reject

ignore ({ a = 0; b = 1} : { a: Nat }); // accept (but warn in the future?)

do {
let a = 1;
let b = 2;
Expand Down
1 change: 1 addition & 0 deletions test/fail/issue2331.mo
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ignore ({foo = 0} : { bar : Nat });
4 changes: 3 additions & 1 deletion test/fail/ok/check-record.tc.ok
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ but found mutable 'var' field (delete 'var'?)
check-record.mo:12.11-12.16: type error [M0149], expected mutable 'var' field a of type
Int
but found immutable field (insert 'var'?)
check-record.mo:19.30-19.31: type error [M0057], unbound variable c
check-record.mo:14.9-14.11: type error [M0151], object literal is missing field a from expected type
{a : Nat}
check-record.mo:21.30-21.31: type error [M0057], unbound variable c
2 changes: 2 additions & 0 deletions test/fail/ok/issue2331.tc.ok
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
issue2331.mo:1.9-1.18: type error [M0151], object literal is missing field bar from expected type
{bar : Nat}
1 change: 1 addition & 0 deletions test/fail/ok/issue2331.tc.ret.ok
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Return code 1
2 changes: 1 addition & 1 deletion test/run-drun/await-without-yield.mo
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ actor a {
ignore(0/0);
};

public func go() {
public func go() : async () {
try {
await bar();
Prim.debugPrint("Huh, bar() replied?");
Expand Down
1 change: 1 addition & 0 deletions test/run-drun/ok/await-without-yield.drun-run.ok
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
ingress Completed: Reply: 0x4449444c016c01b3c4b1f204680100010a00000000000000000101
ingress Completed: Reply: 0x4449444c0000
debug.print: 2
ingress Completed: Reply: 0x4449444c0000

0 comments on commit 912e481

Please sign in to comment.