Cannot use void as a generic parameter #1546. Interfaces now support .ptr and .type directly without casting to any.

This commit is contained in:
Christoffer Lerno
2024-10-11 12:10:35 +02:00
parent 1adad860f4
commit 8e24f15d58
6 changed files with 57 additions and 7 deletions

View File

@@ -11,6 +11,7 @@
- Deprecate `@adhoc`, allow non-nested ad hoc generic types.
- Constant bytes <=> char[] conversion should work #1514.
- Infer now works across ternary.
- Interfaces now support .ptr and .type directly without casting to `any`.
### Fixes
- `Unsupported int[*] $x = { 1, 2, 3, 4 }` #1489.
@@ -27,6 +28,7 @@
- Crash returning struct or vector from function using ternary expression #1537.
- Improved error message on invalid subscript index type #1535.
- Improved error message when declaring a variable `void!`.
- Cannot use void as a generic parameter #1546
### Stdlib changes
- Remove unintended print of `char[]` as String

View File

@@ -2584,6 +2584,17 @@ INLINE bool type_is_wildcard(Type *type)
return type == type_wildcard || type == type_wildcard_optional;
}
INLINE bool type_is_fault_raw(Type *type)
{
switch (type->type_kind)
{
case TYPE_FAULTTYPE:
case TYPE_ANYFAULT:
return true;
default:
return false;
}
}
INLINE bool type_is_any_raw(Type *type)
{
switch (type->type_kind)

View File

@@ -4080,9 +4080,8 @@ static bool sema_generate_parameterized_name_to_scratch(SemaContext *context, Mo
switch (type_storage_type(type))
{
case STORAGE_NORMAL:
break;
case STORAGE_VOID:
RETURN_SEMA_ERROR(type_info, "A 'void' type cannot be used as a parameter type.");
break;
case STORAGE_WILDCARD:
RETURN_SEMA_ERROR(type_info, "The type is undefined and cannot be used as a parameter type.");
case STORAGE_COMPILE_TIME:

View File

@@ -4749,7 +4749,7 @@ static inline bool sema_expr_analyse_access(SemaContext *context, Expr *expr, bo
const char *kw = identifier->identifier_expr.ident;
if (kw_type == kw)
{
if (flat_type->type_kind == TYPE_ANY)
if (type_is_any_raw(flat_type))
{
expr_rewrite_to_builtin_access(expr, parent, ACCESS_TYPEOFANY, type_typeid);
return true;
@@ -4816,7 +4816,7 @@ CHECK_DEEPER:
expr_rewrite_to_builtin_access(expr, current_parent, ACCESS_PTR, type_get_ptr(flat_type->array.base));
return true;
}
if (flat_type->type_kind == TYPE_ANY)
if (type_is_any_raw(flat_type))
{
expr_rewrite_to_builtin_access(expr, current_parent, ACCESS_PTR, type_voidptr);
return true;
@@ -4864,7 +4864,7 @@ CHECK_DEEPER:
return true;
}
}
if (flat_type->type_kind == TYPE_FAULTTYPE || flat_type->type_kind == TYPE_ANYFAULT)
if (type_is_fault_raw(flat_type))
{
if (sema_cast_const(current_parent))
{
@@ -7461,7 +7461,7 @@ static inline bool sema_expr_analyse_optional(SemaContext *context, Expr *expr,
Type *type = inner->type->canonical;
if (type->type_kind != TYPE_FAULTTYPE && type->type_kind != TYPE_ANYFAULT)
if (!type_is_fault_raw(type))
{
if (failed_ref) goto ON_FAILED;
RETURN_SEMA_ERROR(inner, "You cannot use the '?' operator on expressions of type %s",
@@ -7726,6 +7726,7 @@ static inline bool sema_expr_analyse_decl_element(SemaContext *context, Designat
*member_ref = NULL;
*return_type = actual_type->array.base;
return true;
case TYPE_INTERFACE:
case TYPE_ANY:
*member_ref = NULL;
*return_type = type_voidptr;
@@ -9160,7 +9161,7 @@ bool sema_analyse_expr_rhs(SemaContext *context, Type *to, Expr *expr, bool allo
if (to && allow_optional && to_canonical != rhs_type_canonical && rhs_type_canonical->type_kind == TYPE_FAULTTYPE)
{
Type *flat = type_flatten(to);
if (flat != type_anyfault && flat->type_kind != TYPE_FAULTTYPE && sema_cast_const(expr))
if (!type_is_fault_raw(flat) && sema_cast_const(expr))
{
if (no_match_ref) goto NO_MATCH_REF;
print_error_after(expr->span, "You need to add a trailing '?' here to make this an optional.");

View File

@@ -0,0 +1,8 @@
interface Abc {}
fn void main()
{
Abc y;
typeid z = y.type;
void* x = y.ptr;
}

View File

@@ -0,0 +1,29 @@
// #target: macos-x64
module test(<Type>);
def Callback = fn Type();
module mymain;
import std::io;
import test;
def VoidCb = test::Callback(<void>);
fn int main()
{
VoidCb a = null;
void *b = a;
return 0;
}
/* #expect: mymain.ll
define i32 @main() #0 {
entry:
%a = alloca ptr, align 8
%b = alloca ptr, align 8
store ptr null, ptr %a, align 8
%0 = load ptr, ptr %a, align 8
store ptr %0, ptr %b, align 8
ret i32 0
}