- 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.
45 lines
1.7 KiB
Plaintext
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
|
|
}
|
|
}
|
|
}
|