mirror of
https://github.com/odin-lang/Odin.git
synced 2026-09-02 10:13:35 +00:00
Implement fixes for constant unions
Note that with this commit, casting through
multiply-nested unions is forbidden, e.g.
```
U :: union {int, V}
V :: union {bool}
x: U = true
```
does not compile.
(Previously the compiler would simply crash)
This is to avoid situations where adding variants
can lead to unexpected changes in the value.
For example if `U` is changed to have a `bool`
variant of its own:
```
U :: union {int, bool, V}
```
Then `x: U = true` would equal
`U(true)` instead of `U(V(true))`.
Single-variant unions are exempt, primarily to
improve the ergonomics of `Maybe` in cases like:
```
x: Maybe(union{int, bool}) = 1
```
Fix #6100
Fix #6699
Fix #6895
Fix #6896
Fix #6897
Fix #7036
Fix #7083
Fix #7091
This commit is contained in:
@@ -1951,6 +1951,13 @@ gb_internal Type *core_array_type(Type *t) {
|
||||
}
|
||||
}
|
||||
|
||||
gb_internal Type *core_broadcastable_elem_type(Type *t) {
|
||||
while (is_type_array(t)) {
|
||||
t = base_array_type(t);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
gb_internal i32 type_math_rank(Type *t) {
|
||||
i32 rank = 0;
|
||||
for (;;) {
|
||||
@@ -3609,6 +3616,23 @@ gb_internal Type *union_tag_type(Type *u) {
|
||||
return t_uint;
|
||||
}
|
||||
|
||||
gb_internal bool type_conversion_is_variant(Type *dst, Type *src) {
|
||||
dst = base_type(core_broadcastable_elem_type(dst));
|
||||
if (dst == nullptr) { return false; }
|
||||
|
||||
switch (dst->kind) {
|
||||
case Type_Union:
|
||||
if (union_is_variant_of(dst, src)) {
|
||||
return true;
|
||||
}
|
||||
if (dst->Union.variants.count == 1) {
|
||||
return type_conversion_is_variant(dst->Union.variants[0], src);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
gb_internal int matched_target_features(TypeProc *t) {
|
||||
if (t->require_target_feature.len == 0) {
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user