fix: diagnose unknown generic #builtin instead of silently returning 0 (issue 0144)
A bodiless #builtin with a $T: Type param routes through monomorphization. When resolveBuiltin returned null for an unrecognized name, the builtin-body branch fell through to ensureTerminator's constInt(0) -- a silent-fallback default the CLAUDE.md REJECTED PATTERNS forbid. Emit a loud 'error: unknown #builtin <name>' diagnostic instead. Regression: examples/1189-diagnostics-unknown-builtin.sx
This commit is contained in:
16
examples/1189-diagnostics-unknown-builtin.sx
Normal file
16
examples/1189-diagnostics-unknown-builtin.sx
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
// A bodiless `#builtin` carrying a `$T: Type` parameter, whose name the
|
||||||
|
// compiler does not recognize, must fail LOUDLY with an "unknown #builtin"
|
||||||
|
// diagnostic — not silently evaluate to 0 (the CLAUDE.md silent-fallback
|
||||||
|
// pattern). The generic monomorphization path (monomorphizeFunction's
|
||||||
|
// builtin-body branch) now diagnoses an unresolved builtin name instead of
|
||||||
|
// falling through to `ensureTerminator`'s `constInt(0)`.
|
||||||
|
//
|
||||||
|
// Regression (issue 0144).
|
||||||
|
#import "modules/std.sx";
|
||||||
|
|
||||||
|
// `mystery` is not a recognized builtin.
|
||||||
|
mystery :: ($T: Type, x: T) -> T #builtin;
|
||||||
|
|
||||||
|
main :: () {
|
||||||
|
print("mystery(42) = {}\n", mystery(i64, 42));
|
||||||
|
}
|
||||||
1
examples/expected/1189-diagnostics-unknown-builtin.exit
Normal file
1
examples/expected/1189-diagnostics-unknown-builtin.exit
Normal file
@@ -0,0 +1 @@
|
|||||||
|
1
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
error: unknown #builtin 'mystery'
|
||||||
|
--> examples/1189-diagnostics-unknown-builtin.sx:12:1
|
||||||
|
|
|
||||||
|
12 | mystery :: ($T: Type, x: T) -> T #builtin;
|
||||||
|
| ^^^^^^^
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
@@ -1,5 +1,13 @@
|
|||||||
# 0144 — unrecognized `$T`-param `#builtin` silently returns 0
|
# 0144 — unrecognized `$T`-param `#builtin` silently returns 0
|
||||||
|
|
||||||
|
> **RESOLVED.** The generic monomorphization path (`monomorphizeFunction`'s
|
||||||
|
> `builtin_expr` body branch in `src/ir/lower/generic.zig`) no longer falls
|
||||||
|
> through to `ensureTerminator`'s silent `constInt(0)` when `resolveBuiltin`
|
||||||
|
> returns null for an unknown name. It now emits a loud
|
||||||
|
> `error: unknown #builtin '<name>'` diagnostic — removing exactly the
|
||||||
|
> silent-fallback-default the CLAUDE.md REJECTED PATTERNS forbid. Regression
|
||||||
|
> test: `examples/1189-diagnostics-unknown-builtin.sx`.
|
||||||
|
|
||||||
## Symptom
|
## Symptom
|
||||||
|
|
||||||
A **bodiless `#builtin`** whose signature takes a `$T: Type` parameter, when the
|
A **bodiless `#builtin`** whose signature takes a `$T: Type` parameter, when the
|
||||||
|
|||||||
@@ -152,6 +152,16 @@ pub fn monomorphizeFunction(self: *Lowering, fd: *const ast.FnDecl, mangled_name
|
|||||||
const result = self.builder.callBuiltin(bid, &.{param0}, ret_ty);
|
const result = self.builder.callBuiltin(bid, &.{param0}, ret_ty);
|
||||||
self.builder.ret(result, ret_ty);
|
self.builder.ret(result, ret_ty);
|
||||||
} else {
|
} else {
|
||||||
|
// Unknown bodiless #builtin: the name is not claimed by any
|
||||||
|
// recognizer (atomics/reflection are handled earlier in call.zig).
|
||||||
|
// Emitting `ensureTerminator(ret_ty)` here would synthesize a
|
||||||
|
// silent `constInt(0, ret_ty)` for a non-void return — a silent
|
||||||
|
// fallback default (issue 0144). Surface the failure loudly.
|
||||||
|
const span = if (fd.name_span.end != 0) fd.name_span else fd.body.span;
|
||||||
|
if (self.diagnostics) |d|
|
||||||
|
d.addFmt(.err, span, "unknown #builtin '{s}'", .{fd.name});
|
||||||
|
// Lowering has already failed; close the block with a terminator
|
||||||
|
// so the IR stays well-formed for the rest of the pass.
|
||||||
self.ensureTerminator(ret_ty);
|
self.ensureTerminator(ret_ty);
|
||||||
}
|
}
|
||||||
self.builder.finalize();
|
self.builder.finalize();
|
||||||
|
|||||||
Reference in New Issue
Block a user