Skip to content

Commit 71c4ec7

Browse files
Andre Ferreiraclaude
andcommitted
task: create phase0_codegen-module-resolution — 18 items, 4 bugs
Critical codegen fixes blocking HTTP server and deep module imports: Bug 1 (8 items): Recursive private_imports loading - env_module_load.cpp only loads 1 level deep - Transitive deps (A→B→C) don't get declare statements Bug 2 (5 items): pub use re-exports invisible to codegen - Type checker resolves pub use chains - Codegen doesn't emit declare/define for re-exported symbols Bug 3 (3 items): AST path struct param ABI - MIR path fixed but AST path may still pass structs by-value Bug 4 (2 items): Restore Response builder with middleware imports - After fixing 1-3, revert the inline workaround Blocker for: HTTP server, NestJS framework, DI HTTP integration Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 1c48a0e commit 71c4ec7

3 files changed

Lines changed: 107 additions & 0 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"status": "pending",
3+
"createdAt": "2026-04-03T16:14:54.422Z",
4+
"updatedAt": "2026-04-03T16:14:54.422Z"
5+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Proposal: Fix Codegen Module Resolution — Transitive Imports + pub use
2+
3+
## Why
4+
The HTTP server, Response builder, DI module, and any code using deep module paths (4+ segments)
5+
CANNOT compile because the codegen fails to emit `declare`/`define` for transitively imported
6+
functions. The type checker resolves them fine but the codegen is blind to them. This blocks:
7+
- HTTP server sample (`samples/11-http-server/server.tml`)
8+
- Response builder using middleware modules (cors, security, etag, cache_control)
9+
- Any library code that imports types from reorganized subdirectories
10+
- The entire NestJS-style framework (phase0_nestjs-http-decorators)
11+
12+
## What Changes
13+
1. Recursive private_imports loading in env_module_load.cpp
14+
2. pub use re-export resolution in codegen (emit declares for re-exported symbols)
15+
3. AST codegen struct param ABI alignment with MIR path fix
16+
17+
## Impact
18+
- Affected code: compiler/src/types/env_module_load*.cpp, compiler/src/codegen/llvm/core/
19+
- Breaking change: NO
20+
- User benefit: Deep module imports work correctly — any reorganized library compiles
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# Tasks: Fix Codegen Module Resolution — Transitive Imports + pub use
2+
3+
**Status**: Planning. 0% (0/18).
4+
**Blocker for**: HTTP server, Response builder, NestJS framework, any deep module import
5+
**Reproducer**: `tml run samples/11-http-server/server.tml` → crashes with missing declares
6+
7+
## Bug 1: Private Imports Not Loaded Recursively (8 items)
8+
9+
When module A imports module B that imports module C, C's functions don't get
10+
`declare` statements in the IR. The type checker finds them but the codegen doesn't.
11+
12+
**Root cause**: `env_module_load.cpp` loads private_imports for directly imported modules
13+
but NOT for their transitive dependencies. The binary cache path and GlobalModuleCache
14+
path DO load private imports, but the file-loading path only goes 1 level deep.
15+
16+
- [ ] 1.1 `env_module_load.cpp` — make private_imports loading recursive (BFS or DFS with visited set)
17+
- [ ] 1.2 Add visited set to prevent circular import loops (A→B→A)
18+
- [ ] 1.3 Limit recursion depth to 10 (safety — no real app has deeper chains)
19+
- [ ] 1.4 Test: A imports B imports C → C's functions get `declare` in A's IR
20+
- [ ] 1.5 Test: A imports B imports C imports D → D's functions available
21+
- [ ] 1.6 Test: circular A→B→A doesn't infinite loop
22+
- [ ] 1.7 Verify: `samples/11-http-server/server.tml` compiles (Response uses cache_control, security, etag)
23+
- [ ] 1.8 Verify: all `std/http` tests still pass (161/161)
24+
25+
## Bug 2: pub use Re-Exports Invisible to Codegen (5 items)
26+
27+
`pub use std::http::router::router::{node_new}` in `router/mod.tml` makes `node_new`
28+
visible to the type checker at `std::http::router::node_new`, but the codegen doesn't
29+
emit a `declare`/`define` for it. The call site references `@tml_node_new` which LLVM
30+
can't find, so it infers `i32` return type.
31+
32+
**Root cause**: The codegen scans `env_.module_registry()->get_all_modules()` and emits
33+
declares for functions in each module's `functions` map. But `pub use` re-exports add
34+
symbols to the PARENT module's namespace without adding them to the module's `functions` map.
35+
36+
- [ ] 2.1 `runtime_modules_tml.cpp` — when emitting declares, also resolve `pub use` re-exports
37+
- [ ] 2.2 Module registry: store re-exported function signatures under the re-exporting module
38+
- [ ] 2.3 OR: during codegen first pass, collect ALL referenced function names and emit declares for each
39+
- [ ] 2.4 Test: `pub use` re-exported function gets correct `declare` with correct return type
40+
- [ ] 2.5 Test: `router/mod.tml` re-exports `node_new` → call site gets `call i64` not `call i32`
41+
42+
## Bug 3: AST Path Struct Param ABI (3 items)
43+
44+
The MIR codegen path was fixed (struct params → ptr), but the AST codegen path
45+
in `func.cpp` may still generate by-value struct params for some cases.
46+
47+
- [ ] 3.1 `compiler/src/codegen/llvm/decl/func.cpp` — audit ALL struct param generation
48+
- [ ] 3.2 Ensure ALL `%struct.*` params become `ptr` in function signatures (AST path)
49+
- [ ] 3.3 Test: free function with struct param compiles via AST path without segfault
50+
51+
## Bug 4: Response Builder Restore (2 items)
52+
53+
After fixing bugs 1-3, restore the Response builder to use middleware modules properly.
54+
55+
- [ ] 4.1 Revert `response_builder.tml` to version that imports cors, security, etag, cache_control
56+
- [ ] 4.2 Verify: `res.json(data)` internally calls `cors_headers()`, `security_headers()`, etc.
57+
58+
## Success Criteria
59+
60+
```bash
61+
# All must pass:
62+
tml run samples/11-http-server/server.tml
63+
# → prints "TML HTTP Server on http://localhost:3000"
64+
# → curl http://localhost:3000/api/users returns JSON with CORS + Security + ETag headers
65+
66+
tml test --suite std/http --no-cache
67+
# → 161/161 pass
68+
69+
tml test --suite core/str --no-cache
70+
# → 25/25 pass
71+
```
72+
73+
## Key Files
74+
75+
| File | What to Change |
76+
|------|---------------|
77+
| `compiler/src/types/env_module_load.cpp` | Recursive private_imports loading |
78+
| `compiler/src/types/env_module_loading.cpp` | Native module loading (may also need recursion) |
79+
| `compiler/src/codegen/llvm/core/runtime_modules_tml.cpp` | Emit declares for pub use re-exports |
80+
| `compiler/src/codegen/llvm/core/generate.cpp` | First pass — collect all referenced symbols |
81+
| `compiler/src/codegen/llvm/decl/func.cpp` | AST path struct param → ptr |
82+
| `lib/std/src/http/framework/response_builder.tml` | Restore middleware imports after fix |

0 commit comments

Comments
 (0)