harec

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 533ba755deb3a724908edcbd2dd01af2c86e6654
parent 3017c9c4f12e11c392c9c7bc3d0cf70ca1b3440e
Author: Ajay R <ar324@protonmail.com>
Date:   Thu, 10 Mar 2022 10:03:43 +0000

types: disallow assignment of non-void types and error types to void

Signed-off-by: Ajay R <ar324@protonmail.com>

Diffstat:
Msrc/types.c | 5+++--
Mtests/23-errors.ha | 25+++++++++++++++++++++++++
2 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/src/types.c b/src/types.c @@ -719,7 +719,7 @@ type_is_assignable(const struct type *to, const struct type *from) struct type _to, _from; const struct type *to_orig = to, *from_orig = from; to = strip_flags(to, &_to), from = strip_flags(from, &_from); - if (to->id == from->id) { + if (to->id == from->id && to->storage != STORAGE_VOID) { return true; } @@ -799,7 +799,8 @@ type_is_assignable(const struct type *to, const struct type *from) case STORAGE_STRING: return to->id == builtin_type_ptr_const_char.id; case STORAGE_VOID: - return true; + return to_orig->id == from_orig->id && + (from_orig->flags & TYPE_ERROR) == (to_orig->flags & TYPE_ERROR); case STORAGE_SLICE: if (from->storage == STORAGE_POINTER) { from = type_dealias(from->pointer.referent); diff --git a/tests/23-errors.ha b/tests/23-errors.ha @@ -38,8 +38,33 @@ export fn main() int = { err_if_false(true)!; }; +fn void_assignability() void = { + assert(rt::compile(`type err = !void; + +fn reterr() (int | err) = { + return err; +}; + +fn properr() void = { + reterr()?; +}; + +export fn main() void = void;`) != 0); // error types cannot be assigned to void + + assert(rt::compile(`fn disallow_1() void = { + return "I am illegal"; +}; + +fn disallow_2() void = { + return 12; +}; + +export fn main() void = void;`) != 0); // non-void types cannot be assigned to void +}; + export fn main() void = { assignability(); propagate(); cannotignore(); + void_assignability(); };