fix: diagnose indexing a non-indexable type instead of panicking (issue 0183)
lowerIndexExpr fell through to an index_get with an .unresolved element
type for any non-indexable object (*T, *[]T, struct, scalar), reaching
codegen -> 'unresolved type reached LLVM emission' panic. Add a guard
after all indexable arms: if getElementType(obj_ty) is .unresolved and
obj_ty is itself resolved (genuinely non-indexable, not a prior-error
placeholder), emit a located 'cannot index a value of type <T>'
diagnostic + placeholder (hasErrors aborts before codegen). A single
pointer hints by pointee: ptr-to-scalar -> many-pointer/dereference;
ptr-to-array/slice -> dereference first. No false-positives (generics,
aliases, late-resolved, every indexable shape verified).
Regression: examples/diagnostics/1203-diagnostics-index-non-indexable.sx.
Verified by 3 adversarial reviews, suite 799/0. Filed adjacent pre-existing
panic 0184 (untyped positional .{ } literal with no target type).
This commit is contained in:
27
examples/diagnostics/1203-diagnostics-index-non-indexable.sx
Normal file
27
examples/diagnostics/1203-diagnostics-index-non-indexable.sx
Normal file
@@ -0,0 +1,27 @@
|
||||
// Indexing a value whose type is NOT an indexable shape — a single-element
|
||||
// pointer `*T`, a pointer-to-slice `*[]T`, or a plain struct — is a type
|
||||
// error, diagnosed at lowering with a located message.
|
||||
//
|
||||
// Regression (issue 0183): `expr[i]` on a non-indexable base fell through
|
||||
// `lowerIndexExpr` to an `index_get` carrying an `.unresolved` element type,
|
||||
// which reached emit_llvm and panicked ("unresolved type reached LLVM
|
||||
// emission", exit 134) with no source location. The guard now rejects it
|
||||
// cleanly (exit 1). Indexable shapes — `[N]T` / `[]T` / `[*]T` / `string` /
|
||||
// `Vector` / `*[N]T` and the optional-chain forms — are unaffected.
|
||||
//
|
||||
// For a single pointer `*T` the message hints at the indexable alternatives
|
||||
// (many-pointer `[*]T`, or dereference first); other non-indexable types get
|
||||
// the bare "cannot index a value of type '...'" form.
|
||||
|
||||
#import "modules/std.sx";
|
||||
|
||||
S :: struct { a: i64; }
|
||||
|
||||
main :: () {
|
||||
x := 5;
|
||||
p : *i64 = @x;
|
||||
print("{}\n", p[0]); // error: '*i64' is not indexable (hint form)
|
||||
|
||||
s := S.{ a = 1 };
|
||||
print("{}\n", s[0]); // error: 'S' is not indexable (bare form)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,11 @@
|
||||
error: cannot index a value of type '*i64' — use a many-pointer '[*]T', or dereference first
|
||||
--> examples/diagnostics/1203-diagnostics-index-non-indexable.sx:23:19
|
||||
|
|
||||
23 | print("{}\n", p[0]); // error: '*i64' is not indexable (hint form)
|
||||
| ^
|
||||
|
||||
error: cannot index a value of type 'S'
|
||||
--> examples/diagnostics/1203-diagnostics-index-non-indexable.sx:26:19
|
||||
|
|
||||
26 | print("{}\n", s[0]); // error: 'S' is not indexable (bare form)
|
||||
| ^
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
Reference in New Issue
Block a user