fix(lower): pin defining-module context for pack/comptime metaprograms; drop #insert exemption [stdlib B attempt-3]
ROOT FIX for issue 0106's library-metaprogram half — no exemption.
attempt-2 masked the 0106 fallout with an `in_insert_expansion` flag that
made the visibility adapters fall open during ANY `#insert` expansion,
including a USER's `#insert <expr>` — so a bare reach into a namespaced-only
import from user `#insert` code wrongly compiled (Adi's blocker). The flag
was the wrong shape. This removes it and fixes the real cause.
Root cause: a metaprogram's body (`std.print` / `std.format` / `log.*`,
whose `#insert build_format(fmt)` + `#insert "out(result);"` reference
std-internal bare names) was lowered under the CALL SITE's
`current_source_file`, so those names were policed against the consumer's
imports. Normal functions get this right via `lowerFunctionBodyInto`, which
pins `func.source_file`; the two monomorphizers don't:
- `monomorphizePackFn` — bare `print(...)` / `format(...)` (pack path).
- `lowerComptimeCall` — namespaced `std.print` / `log.warn` (reached via
the field-access `hasComptimeParams` branch).
Fix: both paths now save/set/restore `current_source_file` to the body's
DEFINING module around the BODY lowering only (call-site args stay in the
caller's context). The defining path is stamped onto each function body node
by `resolveImports` (`stampFnBodySource`), mirroring `Function.source_file`.
So library internals resolve in std.sx/log.sx naturally, while a USER's
`#insert <expr>` is still checked in the user's context.
- Exemption GONE: `in_insert_expansion` flag + both adapter fall-open checks
deleted; `isNameVisible`/`isCImportVisible` are byte-identical adapters.
- New pinned regression: examples/0737-modules-insert-bare-not-visible.sx
(+ a.sx) — a USER `#insert secret()` into a namespaced-only import errors
('secret' is not visible). fail-before exit 0 on the attempt-2 binary /
pass-after exit 1.
- face #1 (0736) still errors; face #2 (0015/0700/0718/1030) pass again WITH
NO exemption — the metaprogram body resolves in its own module.
- run_examples 472 -> 473; zig build test 412/412; m3te ios-sim build exit 0.
- issues/0106 RESOLVED banner updated (root cause + no-exemption fix).
This commit is contained in:
15
examples/0737-modules-insert-bare-not-visible.sx
Normal file
15
examples/0737-modules-insert-bare-not-visible.sx
Normal file
@@ -0,0 +1,15 @@
|
||||
// A bare name inside a USER `#insert <expr>` is visibility-checked in the
|
||||
// USER's module, not skipped (regression, issue 0106). `a.sx` is imported only
|
||||
// as `m :: #import` — its top-level `secret` is reachable ONLY as `m.secret`.
|
||||
// A BARE `secret()` driving a `#insert` must error just like any other bare
|
||||
// reference into a namespaced-only import: `#insert` expansion does NOT exempt
|
||||
// user-typed code from visibility. (Library metaprograms like `std.print` keep
|
||||
// working because their bodies lower in their OWN module's context — see
|
||||
// `monomorphizePackFn` / `lowerComptimeCall` pinning `current_source_file` to
|
||||
// the body's defining module — not because `#insert` is exempt.)
|
||||
m :: #import "0737-modules-insert-bare-not-visible/a.sx";
|
||||
|
||||
main :: () -> s32 {
|
||||
#insert secret();
|
||||
0
|
||||
}
|
||||
1
examples/0737-modules-insert-bare-not-visible/a.sx
Normal file
1
examples/0737-modules-insert-bare-not-visible/a.sx
Normal file
@@ -0,0 +1 @@
|
||||
secret :: () -> string { "leaked := 1;" }
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,5 @@
|
||||
error: 'secret' is not visible; #import the module that declares it
|
||||
--> examples/0737-modules-insert-bare-not-visible.sx:13:13
|
||||
|
|
||||
13 | #insert secret();
|
||||
| ^^^^^^
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
Reference in New Issue
Block a user