mirror of
https://github.com/odin-lang/Odin.git
synced 2026-04-18 20:40:28 +00:00
Implement Allow .? operator to unwrap any union #549
This commit is contained in:
@@ -8897,12 +8897,31 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type
|
||||
if (ta->type != nullptr && ta->type->kind == Ast_UnaryExpr && ta->type->UnaryExpr.op.kind == Token_Question) {
|
||||
if (!is_type_union(src)) {
|
||||
gbString str = type_to_string(o->type);
|
||||
error(o->expr, "Type assertions with .? can only operate on unions with 1 variant, got %s", str);
|
||||
error(o->expr, "Type assertions with .? can only operate on unions, got %s", str);
|
||||
gb_string_free(str);
|
||||
o->mode = Addressing_Invalid;
|
||||
o->expr = node;
|
||||
return kind;
|
||||
}
|
||||
|
||||
if (bsrc->Union.variants.count != 1 && type_hint != nullptr) {
|
||||
bool allowed = false;
|
||||
for_array(i, bsrc->Union.variants) {
|
||||
Type *vt = bsrc->Union.variants[i];
|
||||
if (are_types_identical(vt, type_hint)) {
|
||||
allowed = true;
|
||||
add_type_info_type(c, vt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (allowed) {
|
||||
add_type_info_type(c, o->type);
|
||||
o->type = type_hint;
|
||||
o->mode = Addressing_OptionalOk;
|
||||
return kind;
|
||||
}
|
||||
}
|
||||
|
||||
if (bsrc->Union.variants.count != 1) {
|
||||
error(o->expr, "Type assertions with .? can only operate on unions with 1 variant, got %lld", cast(long long)bsrc->Union.variants.count);
|
||||
o->mode = Addressing_Invalid;
|
||||
|
||||
@@ -292,7 +292,7 @@ AST_KIND(_ExprBegin, "", bool) \
|
||||
AST_KIND(TernaryExpr, "ternary expression", struct { Ast *cond, *x, *y; }) \
|
||||
AST_KIND(TernaryIfExpr, "ternary if expression", struct { Ast *x, *cond, *y; }) \
|
||||
AST_KIND(TernaryWhenExpr, "ternary when expression", struct { Ast *x, *cond, *y; }) \
|
||||
AST_KIND(TypeAssertion, "type assertion", struct { Ast *expr; Token dot; Ast *type; }) \
|
||||
AST_KIND(TypeAssertion, "type assertion", struct { Ast *expr; Token dot; Ast *type; Type *type_hint; }) \
|
||||
AST_KIND(TypeCast, "type cast", struct { Token token; Ast *type, *expr; }) \
|
||||
AST_KIND(AutoCast, "auto_cast", struct { Token token; Ast *expr; }) \
|
||||
AST_KIND(_ExprEnd, "", bool) \
|
||||
|
||||
Reference in New Issue
Block a user