|
| 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