wcc/ww: tag sep-built dotted-path packages by full path not leaf (#57)
A separately-compiled package's primary body was emitted under a bare `//ww:module-reset`, so its own `package <leaf>;` clause set curmod to the leaf (e.g. utf8) while the importer spliced the .wwi under the full `//ww:module encoding.utf8` — definer mangled `utf8.X`, importer wanted `encoding.utf8.X`, unresolved. Thread the dotted path through the directive: `//ww:module-reset <path>` sets curmod to the dotted path (imported stays 0, so the root `fn main` stays bare per #32), and the body's package clause is demoted to a leaf==last-component assertion instead of overwriting curmod. Aligns sep-build to the M1 path-mangle model; only the SEP emitter changes (the combined build_one arm is untouched, so all combined byte-id gates hold). Both stages mirrored. Commit-6 broad-soak prerequisite. Gate 989_sepdotpath_run sep-builds a 2-level dotted package and proves definer==importer qualification + single-component non-vacuity, cs==ww.
This commit is contained in:
@@ -1373,17 +1373,22 @@ parsefile(Parser *p)
|
||||
advance(p);
|
||||
const char *name = expectident(p);
|
||||
expect(p, TK_SEMI);
|
||||
if (p->pathmod != NULL) {
|
||||
if (p->pathmod != NULL || p->resetmod != NULL) {
|
||||
/* M1 #22: while an import path is active the
|
||||
* in-file `package` clause is an ASSERTION — its
|
||||
* leaf must equal the path's last component; it
|
||||
* does NOT overwrite the path-derived module. */
|
||||
const char *dot = strrchr(p->pathmod, '.');
|
||||
const char *last = dot ? dot + 1 : p->pathmod;
|
||||
* does NOT overwrite the path-derived module.
|
||||
* #57 extends this to the sep primary-reset path
|
||||
* (resetmod): the dotted reset path is the
|
||||
* authoritative identity, the clause asserts. */
|
||||
const char *active =
|
||||
p->pathmod ? p->pathmod : p->resetmod;
|
||||
const char *dot = strrchr(active, '.');
|
||||
const char *last = dot ? dot + 1 : active;
|
||||
if (strcmp(name, last) != 0) {
|
||||
errorf(p->cur.pos,
|
||||
"package %s does not match import path %s",
|
||||
name, p->pathmod);
|
||||
name, active);
|
||||
p->errs++;
|
||||
}
|
||||
} else {
|
||||
@@ -1398,6 +1403,7 @@ parsefile(Parser *p)
|
||||
if (p->cur.kind == TK_MODPATH) {
|
||||
p->pathmod = p->cur.text;
|
||||
p->curmod = p->cur.text;
|
||||
p->resetmod = NULL;
|
||||
advance(p);
|
||||
continue;
|
||||
}
|
||||
@@ -1410,9 +1416,23 @@ parsefile(Parser *p)
|
||||
* directive after a mid-file `package` would strip subsequent
|
||||
* decls to bare — that usage is deliberate-only. */
|
||||
if (p->cur.kind == TK_MODRESET) {
|
||||
/* #57: a path-carrying reset (sep primary body) mangles
|
||||
* decls on the dotted path so definer == importer, but
|
||||
* leaves imported==0 (curmod set, pathmod NULL) so -c
|
||||
* primary-ness and the #32 bare-main rule are intact;
|
||||
* the body's `package` clause then asserts (resetmod).
|
||||
* A bare reset is the root/package-less boundary: curmod
|
||||
* NULL → bare symbols, today's behavior. */
|
||||
const char *rp = p->cur.text;
|
||||
advance(p);
|
||||
p->curmod = NULL;
|
||||
p->pathmod = NULL;
|
||||
if (rp != NULL) {
|
||||
p->curmod = rp;
|
||||
p->resetmod = rp;
|
||||
} else {
|
||||
p->curmod = NULL;
|
||||
p->resetmod = NULL;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
Node *attrs = parseattrs(p);
|
||||
|
||||
Reference in New Issue
Block a user