fix(check): qualify cross-module kernel type-cons in user ADT fields
A consumer module's ADT field could reference a kernel-tier auto-imported type by its bare name in op/value positions (`(new RawBuf ...)`, `RawBuf.get`) but NOT in the type-constructor position of the field declaration: `(con RawBuf (con Int))` stayed the unqualified `RawBuf<Int>` and failed to unify with the constructor argument's `raw_buf.RawBuf<Int>`, so a RawBuf could not be stored in a user ADT field without spelling the qualified `raw_buf.RawBuf`. `qualify_workspace_module` skipped `Def::Type` entirely, and the `Term::Ctor` arm only qualified field types of cross-module *owning* types — a *local* type carrying a cross-module field was the uncovered case. The fix qualifies each ctor field type in the `Def::Type` arm via the existing `qualify_workspace_types`, which upgrades only genuinely cross-module type-cons (skips `own_local_types` and primitives), so a purely-local field is never spuriously rewritten. This is a check-side workspace transform, not the on-disk canonical form, so no module hash drifts (both hash-pin tests stay green). RED test `rawbuf_in_user_adt_field_resolves_bare_name` in crates/ailang-check/tests/workspace.rs, with the bare-name fixture (now checks/builds/runs -> 42, live=0, the ADT drop cascade frees the buffer slab) and the qualified control twin. This is the Series-substrate shape (a RawBuf wrapped in a user ADT), so the inconsistency would have bitten the pending series milestone. closes #50
This commit is contained in:
@@ -4591,11 +4591,25 @@ pub fn qualify_workspace_module(
|
||||
c.ty = qualify_workspace_types(&c.ty, own_local_types, module_types);
|
||||
qualify_workspace_term(&mut c.value, own_local_types, module_types, module_mono_fns);
|
||||
}
|
||||
Def::Type(_) | Def::Class(_) | Def::Instance(_) => {
|
||||
// TypeDef.ctors carry field types in the owner's local
|
||||
// namespace by convention — no qualification at the
|
||||
// owner's own definition site. Class / Instance defs
|
||||
// hold types qualified through other mechanisms.
|
||||
Def::Type(td) => {
|
||||
// #50: a consumer module's ADT field can reference a
|
||||
// *cross-module* (kernel-tier auto-imported) type-con by
|
||||
// its bare name (`(con RawBuf …)`). The owner's own type
|
||||
// names stay bare — `qualify_workspace_types` skips
|
||||
// `own_local_types` and primitives — so only genuinely
|
||||
// cross-module field types are upgraded to `<home>.<T>`,
|
||||
// matching the qualification the op/value positions and
|
||||
// the imported-fn signatures already receive.
|
||||
for ctor in &mut td.ctors {
|
||||
for field in &mut ctor.fields {
|
||||
*field =
|
||||
qualify_workspace_types(field, own_local_types, module_types);
|
||||
}
|
||||
}
|
||||
}
|
||||
Def::Class(_) | Def::Instance(_) => {
|
||||
// Class / Instance defs hold types qualified through
|
||||
// other mechanisms.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user