wcc+w6c_ww: loud-gate try-propagation over multi-success unions (F8/F9 interim)

? and ! assume ONE success member end-to-end: the checker collapses
the result to the first non-error variant (check.c tagged_success_type
/ check.ww exprtype) and cgen emits a single tag compare, so any other
success member is silently mistaken for an error — ? propagates it to
the caller (p11h: []capture read back as nomem, exit 21), ! aborts on
it. Until the honest subset-union result typing lands (task #14, harec
check.c:2759-2835), both stages loud-reject |success| > 1 at the
checker choke-points (one per stage), identical diagnostic, both ops
per rob's one-class ruling (#133 precedent). (T|err1|err2) — one
success, many errors — stays legal (925 canary + new accept rows).

F9 rides along (task #12): wwstage scruttype only resolves IDENT/DOT,
so the direct forms f()? is T / match(f()?) / f()! is T slipped its
lenient-miss contract and were silently ACCEPTED where cstage rejects
(cs!=ww, gate-blind). checkisas/checkmatchexhaust now resolve the
try-result via exprtype, keyed on the RESOLVED success type — a named
tagged success ((ab|nomem)? is i32) keeps being accepted, matching
cstage's verdict empirically.

test/wcc/806: 11 rows x dual driver + byte-id accepts (26 fixtures);
reject rows pin exact per-stage diagnostic text; p11h + q_card2_unw
graduated to rejects; call-arg-position reject + void-success accept
pin position-independence and the dominant lib/ (void|err)? shape.
Tasks #5 + #12; #14 lifts both gates together.
This commit is contained in:
2026-06-04 10:10:35 +09:00
parent cfc2985c61
commit 48df04a8ca
6 changed files with 686 additions and 20 deletions

View File

@@ -391,6 +391,7 @@ TESTS = $(BIN)/test_smoke $(BIN)/test_lex $(BIN)/test_parse $(BIN)/test_check \
$(BIN)/test_append_wide_elem \
$(BIN)/test_delete_elem \
$(BIN)/test_placeaddr_store \
$(BIN)/test_tryprop_multisuccess \
$(BIN)/test_struct_tuple_field_slot \
$(BIN)/test_widen_pad_zero_run \
$(BIN)/test_named_ptr_alias_variant_widen \
@@ -1023,6 +1024,17 @@ $(BIN)/test_placeaddr_store: test/wcc/805_placeaddr_store.c \
$(LIB)/libwwrt.a | $(BIN)
$(CC) $(CFLAGS) -o $@ $<
# F8+F9 (tasks #5/#12, regex fold-2b): `?` interim single-success gate
# (|success| > 1 loud-rejected on BOTH stages until task #14's
# subset-union typing) + direct `f()? is T` / `match (f()?)` reject
# parity — reject rows w/ exact per-stage diagnostic text, accept rows
# runtime + cs==ww asm byte-id.
$(BIN)/test_tryprop_multisuccess: test/wcc/806_tryprop_multisuccess.c \
$(BIN)/ww $(BIN)/w6c $(BIN)/w6c_ww $(BIN)/w6a $(BIN)/w6l \
$(BIN)/ww_ww \
$(LIB)/libwwrt.a | $(BIN)
$(CC) $(CFLAGS) -o $@ $<
# #237: a tuple-typed struct field must contribute its real slot width to
# the enclosing struct's slotsize — pure cs==ww .s byte-id (frame size).
$(BIN)/test_struct_tuple_field_slot: test/wcc/930_struct_tuple_field_slot.c \