Add contracts on @catch / @ok. Taking the $typeof of a wildcard optional returns void!

This commit is contained in:
Christoffer Lerno
2024-11-05 10:50:38 +01:00
parent 741707273d
commit 08d1b29301
5 changed files with 29 additions and 7 deletions

View File

@@ -324,13 +324,24 @@ macro swizzle2(v, v2, ...) @builtin
{
return $$swizzle2(v, v2, $vasplat);
}
<*
Return the excuse in the Optional if it is Empty, otherwise
return a null fault.
@require @typekind(#expr) == OPTIONAL : `@catch expects an Optional value`
*>
macro anyfault @catch(#expr) @builtin
{
if (catch f = #expr) return f;
return anyfault {};
}
<*
Check if an Optional expression holds a value or is empty, returning true
if it has a value.
@require @typekind(#expr) == OPTIONAL : `@ok expects an Optional value`
*>
macro bool @ok(#expr) @builtin
{
if (catch #expr) return false;

View File

@@ -57,6 +57,7 @@
- Fixes with error handling recursive `@tag` #1583.
- Sometimes generating introspection info would not be in the global scope causing a crash #1586.
- @tag on macros cannot be retrieved with tagof #1582
- Taking the $typeof of a wildcard optional returns `void!`.
### Stdlib changes
- Remove unintended print of `char[]` as String

View File

@@ -325,6 +325,11 @@ INLINE bool sema_resolve_typeof(SemaContext *context, TypeInfo *type_info)
type_info->type = expr_type;
return true;
case STORAGE_WILDCARD:
if (expr_type->type_kind == TYPE_OPTIONAL)
{
type_info->type = type_get_optional(type_void);
return true;
}
RETURN_SEMA_ERROR(expr, "This %sexpression lacks a concrete type.", type_is_optional(expr_type) ? "optional " : "");
case STORAGE_COMPILE_TIME:
RETURN_SEMA_ERROR(expr, "This expression has a compile time type %s.", type_quoted_error_string(expr_type));

View File

@@ -7,7 +7,7 @@ fn void test()
{
int! x;
double! y;
int! d = ($typeof(MyErr.FOO?))(x); // #error: optional expression lacks a concrete
int! d = ($typeof(MyErr.FOO?))(x); // #error: Casting to an optional
int! df = ($typeof(y))(x); // #error: Casting to an optional type is not allowed
double! df2 = ($typeof(y!!))(x);
}

View File

@@ -3,36 +3,41 @@ fn int! abc()
return 1;
}
macro test()
{
return @catch(abc())?!!;
}
macro test2()
{
return @catch(abc())?;
}
fn void a()
{
String s = $typeof(test()).qnameof; // #error: This optional expression lacks
String s = $typeof(test()).qnameof; // #error: This expression lacks
}
fn void b()
{
$sizeof(test()); // #error: This optional expression lacks
$sizeof(test()); // #error: This expression lacks
}
fn void c()
{
$sizeof(test() ?? 1);
$sizeof(test2() ?? 1);
}
fn void! d()
{
$typeof(test()!) g; // #error: This expression lacks a concrete type
$typeof(test2()!) g; // #error: This expression lacks a concrete type
}
macro e()
{
var g = test()!; // #error: No type can be inferred from the optional result
var g = test2()!; // #error: No type can be inferred from the optional result
}
fn void! h()
{
e();
}
}