mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Cannot use void as a generic parameter #1546. Interfaces now support .ptr and .type directly without casting to any.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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.");
|
||||
|
||||
8
test/test_suite/any/interface_ptr.c3
Normal file
8
test/test_suite/any/interface_ptr.c3
Normal file
@@ -0,0 +1,8 @@
|
||||
interface Abc {}
|
||||
|
||||
fn void main()
|
||||
{
|
||||
Abc y;
|
||||
typeid z = y.type;
|
||||
void* x = y.ptr;
|
||||
}
|
||||
29
test/test_suite/generic/generic_void.c3t
Normal file
29
test/test_suite/generic/generic_void.c3t
Normal 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
|
||||
}
|
||||
Reference in New Issue
Block a user