mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 03:51:18 +00:00
Distinct types could not be used with tagof #2152
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
- Deprecate `SomeFn.params`.
|
||||
- Improve error message when encountering recursively defined structs. #2146
|
||||
- Limit vector max size, default is 4096 bits, but may be increased using --max-vector-size.
|
||||
- Allow the use of `has_tagof` on builtin types.
|
||||
|
||||
### Fixes
|
||||
- Assert triggered when casting from `int[2]` to `uint[2]` #2115
|
||||
@@ -41,6 +42,7 @@
|
||||
- `--path` does not interact correctly with relative path arguments #2149.
|
||||
- Add missing `@noreturn` to `os::exit`.
|
||||
- Implicit casting from struct to interface failure for inheriting interfaces #2151.
|
||||
- Distinct types could not be used with tagof #2152.
|
||||
|
||||
### Stdlib changes
|
||||
- Added `String.quick_ztr` and `String.is_zstr`
|
||||
|
||||
@@ -2521,7 +2521,7 @@ INLINE BitSize type_bit_size(Type *type);
|
||||
INLINE Type *type_vector_type(Type *type);
|
||||
|
||||
static inline CanonicalType *type_pointer_type(Type *type);
|
||||
static inline Type *type_flatten(Type *type);
|
||||
static inline CanonicalType *type_flatten(Type *type);
|
||||
static inline bool type_flat_is_char_array(Type *type);
|
||||
static inline Type *type_base(Type *type);
|
||||
|
||||
@@ -3030,7 +3030,7 @@ static inline Type *type_flatten_to_int(Type *type)
|
||||
}
|
||||
}
|
||||
|
||||
static inline Type *type_flatten(Type *type)
|
||||
static inline CanonicalType *type_flatten(Type *type)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
|
||||
@@ -1346,13 +1346,13 @@ typedef enum
|
||||
TYPE_F128,
|
||||
TYPE_FLOAT_LAST = TYPE_F128,
|
||||
TYPE_NUM_LAST = TYPE_FLOAT_LAST,
|
||||
TYPE_DISTINCT,
|
||||
TYPE_ANY,
|
||||
TYPE_INTERFACE,
|
||||
TYPE_ANYFAULT,
|
||||
TYPE_TYPEID,
|
||||
TYPE_FUNC_PTR,
|
||||
TYPE_POINTER,
|
||||
TYPE_DISTINCT,
|
||||
TYPE_ENUM,
|
||||
TYPE_FUNC_RAW,
|
||||
TYPE_STRUCT,
|
||||
|
||||
@@ -2937,7 +2937,6 @@ static inline bool sema_expr_analyse_typecall(SemaContext *context, Expr *expr)
|
||||
}
|
||||
Expr **args = expr->call_expr.arguments;
|
||||
unsigned arg_count = vec_size(args);
|
||||
Decl *decl = tag->type_call_expr.type;
|
||||
bool is_has = tag->type_call_expr.property == TYPE_PROPERTY_HAS_TAGOF;
|
||||
const char *name = is_has ? "has_tagof" : "tagof";
|
||||
if (arg_count != 1) RETURN_SEMA_ERROR(expr, "Expected a single string argument to '%s'.", name);
|
||||
@@ -2947,9 +2946,11 @@ static inline bool sema_expr_analyse_typecall(SemaContext *context, Expr *expr)
|
||||
{
|
||||
RETURN_SEMA_ERROR(key, "The tag name should be a string constant.");
|
||||
}
|
||||
Decl *decl = tag->type_call_expr.type;
|
||||
const char *tagname = key->const_expr.bytes.ptr;
|
||||
if (!decl) goto NOT_FOUND;
|
||||
ASSERT_SPAN(expr, decl->resolved_attributes);
|
||||
ResolvedAttrData *attrs = decl->attrs_resolved;
|
||||
const char *tagname = key->const_expr.bytes.ptr;
|
||||
if (!attrs || !attrs->tags) goto NOT_FOUND;
|
||||
Expr *value = NULL;
|
||||
FOREACH(Attr *, attr, attrs->tags)
|
||||
@@ -4990,7 +4991,7 @@ EVAL:
|
||||
|
||||
static bool sema_type_property_is_valid_for_type(Type *original_type, TypeProperty property)
|
||||
{
|
||||
Type *type = type_flatten(original_type);
|
||||
CanonicalType *type = type_flatten(original_type);
|
||||
switch (property)
|
||||
{
|
||||
case TYPE_PROPERTY_NONE:
|
||||
@@ -5042,7 +5043,7 @@ static bool sema_type_property_is_valid_for_type(Type *original_type, TypeProper
|
||||
case TYPE_PROPERTY_FROM_ORDINAL:
|
||||
case TYPE_PROPERTY_LOOKUP:
|
||||
case TYPE_PROPERTY_LOOKUP_FIELD:
|
||||
return type->canonical->type_kind == TYPE_ENUM;
|
||||
return type->type_kind == TYPE_ENUM;
|
||||
case TYPE_PROPERTY_MIN:
|
||||
case TYPE_PROPERTY_MAX:
|
||||
return type_is_float(type) || type_is_integer(type);
|
||||
@@ -5084,8 +5085,9 @@ static bool sema_type_property_is_valid_for_type(Type *original_type, TypeProper
|
||||
return type_is_func_ptr(type);
|
||||
case TYPE_PROPERTY_TAGOF:
|
||||
case TYPE_PROPERTY_HAS_TAGOF:
|
||||
return true;
|
||||
case TYPE_PROPERTY_EXTNAMEOF:
|
||||
return !type_is_builtin(type->type_kind);
|
||||
return !type_is_builtin(original_type->canonical->type_kind);
|
||||
}
|
||||
UNREACHABLE
|
||||
}
|
||||
@@ -5194,7 +5196,22 @@ static bool sema_expr_rewrite_to_type_property(SemaContext *context, Expr *expr,
|
||||
sema_expr_rewrite_to_type_nameof(expr, type, TOKEN_CT_EXTNAMEOF);
|
||||
return true;
|
||||
case TYPE_PROPERTY_TAGOF:
|
||||
if (!type_is_user_defined(type))
|
||||
{
|
||||
RETURN_SEMA_ERROR(expr, "'tagof' is not defined for builtin types like %s.", type_quoted_error_string(type));
|
||||
}
|
||||
FALLTHROUGH;
|
||||
case TYPE_PROPERTY_HAS_TAGOF:
|
||||
if (!type_is_user_defined(type))
|
||||
{
|
||||
|
||||
expr->expr_kind = EXPR_TYPECALL;
|
||||
expr->type_call_expr = (ExprTypeCall) {
|
||||
.type = NULL,
|
||||
.property = property };
|
||||
return true;
|
||||
}
|
||||
FALLTHROUGH;
|
||||
case TYPE_PROPERTY_FROM_ORDINAL:
|
||||
case TYPE_PROPERTY_LOOKUP:
|
||||
case TYPE_PROPERTY_LOOKUP_FIELD:
|
||||
|
||||
@@ -18,9 +18,8 @@ fn int main()
|
||||
|
||||
@.str.2 = private unnamed_addr constant [4 x i8] c"int\00", align 1
|
||||
@.str.4 = private unnamed_addr constant [7 x i8] c"double\00", align 1
|
||||
@.str.6 = private unnamed_addr constant [7 x i8] c"String\00", align 1
|
||||
@.str.6 = private unnamed_addr constant [18 x i8] c"std::core::String\00", align 1
|
||||
|
||||
; Function Attrs:
|
||||
define i32 @main() #0 {
|
||||
entry:
|
||||
%varargslots = alloca [1 x %any], align 16
|
||||
@@ -42,7 +41,7 @@ entry:
|
||||
%4 = insertvalue %any %3, i64 ptrtoint (ptr @"$ct.String" to i64), 1
|
||||
store %any %4, ptr %varargslots1, align 16
|
||||
%5 = call i64 @std.io.printfn(ptr %retparam3, ptr @.str.3, i64 2, ptr %varargslots1, i64 1)
|
||||
store %"char[]" { ptr @.str.6, i64 6 }, ptr %taddr5, align 8
|
||||
store %"char[]" { ptr @.str.6, i64 17 }, ptr %taddr5, align 8
|
||||
%6 = insertvalue %any undef, ptr %taddr5, 0
|
||||
%7 = insertvalue %any %6, i64 ptrtoint (ptr @"$ct.String" to i64), 1
|
||||
store %any %7, ptr %varargslots4, align 16
|
||||
|
||||
13
test/test_suite/macros/tagof_distinct.c3
Normal file
13
test/test_suite/macros/tagof_distinct.c3
Normal file
@@ -0,0 +1,13 @@
|
||||
macro @foo(#type)
|
||||
{
|
||||
return $typeof(#type).has_tagof("hello");
|
||||
}
|
||||
|
||||
typedef Foo = uint;
|
||||
|
||||
fn int main()
|
||||
{
|
||||
Foo f = 1;
|
||||
@foo(f);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user