Skip to content

Commit c7c9b92

Browse files
committed
Fix TODO: Implement Value.isUndefDeep
Now correctly returns `true` for aggregates containing only undefined elements, undefined unions without a (safety) tag.
1 parent 6d89d7b commit c7c9b92

File tree

2 files changed

+321
-310
lines changed

2 files changed

+321
-310
lines changed

src/Value.zig

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1386,11 +1386,22 @@ pub fn isUndef(val: Value, zcu: *const Zcu) bool {
13861386
return zcu.intern_pool.isUndef(val.toIntern());
13871387
}
13881388

1389-
/// TODO: check for cases such as array that is not marked undef but all the element
1390-
/// values are marked undef, or struct that is not marked undef but all fields are marked
1391-
/// undef, etc.
13921389
pub fn isUndefDeep(val: Value, zcu: *const Zcu) bool {
1393-
return val.isUndef(zcu);
1390+
if (val.toIntern() == .undef) return true;
1391+
switch (zcu.intern_pool.indexToKey(val.toIntern())) {
1392+
.undef => return true,
1393+
.int, .float => return false,
1394+
.aggregate => |agg| {
1395+
const elems = agg.storage.values();
1396+
if (elems.len == 0) return false;
1397+
for (elems) |elem_val| {
1398+
if (!Value.fromInterned(elem_val).isUndefDeep(zcu)) return false;
1399+
}
1400+
return true;
1401+
},
1402+
.un => |un| return if (un.tag == .none) Value.fromInterned(un.val).isUndefDeep(zcu) else false,
1403+
else => return false,
1404+
}
13941405
}
13951406

13961407
/// `val` must have a numeric or vector type.

0 commit comments

Comments
 (0)