Files
sx/issues/0132-protocol-return-enum-case-payload-field-unresolved.sx
agra 45befed698 docs(issues): correct 0132 root cause; file 0133 and 0134
- 0132: rewrite to the verified root cause -- protocol method signature
  registration resolves type names via flat findByName and picks the wrong
  same-name author. Original payload-field hypothesis kept as superseded;
  repro switched to canonical `impl ... for` syntax. Still open (the
  protocol path is unchanged).
- 0133: assigning a struct literal to a union member panics ("unresolved
  type reached LLVM emission"); pre-existing, surfaced while testing.
- 0134: a same-name `error` set collapses into a namespaced import's set --
  error-set declarations lack per-decl nominal identity (E6a gap); this is
  what keeps the 0132-class error-ref resolution dormant.
2026-06-13 13:41:30 +03:00

45 lines
1.7 KiB
Plaintext

// issue 0132 — protocol method return/param type resolves to the WRONG
// same-name type (visibility-unaware registration).
//
// ROOT CAUSE (corrected — see the .md): `registerProtocolDecl` resolves
// the method return type `Event` through a flat, visibility-UNAWARE lookup
// (type_bridge.resolveAstType → findByName). The user's `Event` enum
// collides by NAME with the stdlib `std/event.sx` `Event :: struct`
// (pulled in by `#import "modules/std.sx"`, namespaced as `event`). The
// flat lookup picks the stdlib struct, so `ev := g_plat.one_event()` is
// typed as a fieldless struct; the `case .key_up:(e)` payload then binds
// `.unresolved`, and `.escape` has no destination type.
//
// EXPECT (today): build FAILS —
// error: enum literal '.escape' has no destination type to resolve against
// EXPECT (after fix): prints `escape!`, exit 0.
//
// Proof it's a name collision: rename `Event` -> `Evt` everywhere and the
// inferred form compiles and prints `escape!`. Annotating
// `ev : Event = g_plat.one_event();` also sidesteps it (the annotation
// path is visibility-aware). See the .md for the full bisection.
#import "modules/std.sx";
Keycode :: enum { unknown; escape; enter; }
KeyData :: struct { key: Keycode; }
Event :: enum { none; key_up: KeyData; }
Plat :: protocol { one_event :: () -> Event; }
Impl :: struct { dummy: i64; }
impl Plat for Impl {
one_event :: (self: *Impl) -> Event { return .key_up(.{ key = .escape }); }
}
main :: () {
impl : Impl = .{ dummy = 0 };
g_plat : Plat = xx @impl;
ev := g_plat.one_event(); // type INFERRED from protocol return
if ev == {
case .key_up: (e) {
if e.key == .escape { print("escape!\n"); } // <-- errors here
}
}
}