fix interop and indexing oversights

This commit is contained in:
2026-07-01 09:08:58 +02:00
parent 7fe3552c01
commit 870f946b52
15 changed files with 593 additions and 116 deletions
+24 -2
View File
@@ -80,6 +80,7 @@ Node :: struct {
child: Type,
extra: Type,
count: u64,
count_expr: u32,
sentinel: u64,
explicit_size: u64,
field_start: u32,
@@ -93,6 +94,7 @@ Node :: struct {
many: bool,
has_sentinel: bool,
inferred_count: bool,
unresolved_count: bool,
c_abi: bool,
variadic: bool,
c_layout: bool,
@@ -1308,6 +1310,8 @@ with_array_count :: proc(store: ^Store, value: Type, count: u64) -> Type {
}
item.count = count
item.inferred_count = false
item.unresolved_count = false
item.count_expr = 0
return intern(store, item)
}
@@ -1339,6 +1343,16 @@ can_weaken_slice :: proc(from, to: Type, store: ^Store) -> bool {
(from_node.has_sentinel && from_node.sentinel == to_node.sentinel))
}
can_decay_slice_c_string :: proc(from, to: Type, store: ^Store) -> bool {
from_node, from_ok := node(store, from)
to_node, to_ok := node(store, to)
return from_ok && to_ok &&
from_node.kind == .Slice && to_node.kind == .Pointer && to_node.many &&
from_node.child == U8 && to_node.child == C_CHAR &&
from_node.has_sentinel && from_node.sentinel == 0 && !from_node.mutable &&
!to_node.mutable
}
can_decay_array_pointer :: proc(from, to: Type, store: ^Store) -> bool {
from_pointer, array, from_ok := array_pointer(from, store)
to_node, to_ok := node(store, to)
@@ -1536,10 +1550,18 @@ can_widen :: proc(from, to: Type) -> bool {
// make C interop cumbersome. Scope: widening (sext/zext) and same-width
// signedness changes (no-op reinterpret); narrowing is intentionally excluded so
// lossy conversions stay an error, matching brolang's trap-on-narrow philosophy.
can_coerce_c_integer :: proc(from, to: Type) -> bool {
can_coerce_c_integer :: proc(from, to: Type, selected := target.DEFAULT) -> bool {
return from != to && is_c(from) && is_c(to) &&
is_concrete_integer(from) && is_concrete_integer(to) &&
bits(from) <= bits(to)
bits(from, selected) <= bits(to, selected)
}
can_coerce_c_scalar :: proc(from, to: Type, selected := target.DEFAULT) -> bool {
return from != to && !is_c(from) && is_c(to) &&
is_concrete_scalar(from) && is_concrete_scalar(to) &&
category(from, selected) == category(to, selected) &&
category(from, selected) != .None &&
bits(from, selected) <= bits(to, selected)
}
widest :: proc(a, b: Type) -> Type {