diff --git a/releasenotes.md b/releasenotes.md index 5eb92de97..4721edd1c 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -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 diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index 80ae4feed..a7db3f3b7 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -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) diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index e28d47d3c..51841ad7c 100755 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -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: diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 96842babc..ecbf6eb83 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -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."); diff --git a/test/test_suite/any/interface_ptr.c3 b/test/test_suite/any/interface_ptr.c3 new file mode 100644 index 000000000..ae66baa06 --- /dev/null +++ b/test/test_suite/any/interface_ptr.c3 @@ -0,0 +1,8 @@ +interface Abc {} + +fn void main() +{ + Abc y; + typeid z = y.type; + void* x = y.ptr; +} diff --git a/test/test_suite/generic/generic_void.c3t b/test/test_suite/generic/generic_void.c3t new file mode 100644 index 000000000..5e63ce2d4 --- /dev/null +++ b/test/test_suite/generic/generic_void.c3t @@ -0,0 +1,29 @@ +// #target: macos-x64 +module test(); + +def Callback = fn Type(); + +module mymain; + +import std::io; +import test; + +def VoidCb = test::Callback(); + +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 +} \ No newline at end of file