bug: a lambda parameter carries no type, so indexing or len() inside a lambda reads the wrong value
- Ngôn ngữ chính
- Rust
- Star
- 22
- Fork
- 6
- Merge trung bình
- 1 ngày 3 giờ
- Pull request đã merge (30 ngày)
- 6
Mô tả
## Description
A lambda's parameters carry no type, so any expression inside a lambda that needs its parameter's type reads the value as an untyped word. Indexing it, calling `len()` on it, or calling a method on it all produce a wrong answer, and compilation reports success.
This is a silent miscompile, which `plan/OVERVIEW.md`'s correctness rule treats as the highest-priority class: a compilation that reports success must give Python's answer or fail loudly.
## Steps to Reproduce
```python
def swap_first() -> int:
pair = (1, 5)
f = lambda kv: kv[1]
return f(pair)
def len_in_lambda() -> int:
g = lambda w: len(w)
return g("hello")
```
Compile with `just compile .py` (it succeeds) and run the exports:
| Function | waspy | CPython |
| --- | --- | --- |
| `swap_first()` | `0` | `5` |
| `len_in_lambda()` | `1819043176` | `5` |
`1819043176` is the first four bytes of `"hello"` read as an i32, which is what `len()` does when it treats a string offset as a collection pointer.
## Environment
- waspy 0.15.0, commit d7dcbc4
- Verified under both `wasmi` (the test harness) and Node 22
## Additional Context
A lambda parameter has no annotation, so `process_function_params` types it `Unknown`: https://github.com/anistark/waspy/blob/d7dcbc4/src/ir/converter.rs#L1056-L1059
The finalize pass lifts the lambda into a real module function and clones those params as they are, so the lifted function's parameter stays `Unknown`: https://github.com/anistark/waspy/blob/d7dcbc4/src/ir/finalize.rs#L163
`sorted()` refuses a key that reaches into its parameter rather than miscompiling it, which is the current mitigation and not a fix: https://github.com/anistark/waspy/blob/d7dcbc4/src/compiler/expression.rs#L2233
The fix is to type a lambda's parameters from its call sites, which is a typing pass of its own rather than a local change.
This is what stops `sorted(counts.items(), key=lambda kv: (-kv[1], kv[0]))` from being written the obvious way. `examples/text_report.py` sorts an explicit list of `(-count, word)` tuples instead, and says so in its docstring: https://github.com/anistark/waspy/blob/d7dcbc4/examples/text_report.py
Hướng dẫn đóng góp
Hướng nghiên cứu
Start by compiling the two Python reproductions with `just compile` and compare the exported results with CPython. Read `src/ir/converter.rs` around `process_function_params`, `src/ir/finalize.rs` around lambda parameter lifting, and the mitigation in `src/compiler/expression.rs`; inspect `examples/text_report.py` for the affected sorting use case. Done means lambda expressions needing parameter types produce Python-compatible results or fail loudly.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Đánh giá
- Công nghệ
- python, rust, wasm
- Lĩnh vực
- compilers
- Loại issue
- Lỗi
- Độ khó
- 5/5
- Thời gian dự kiến
- Hơn một tuần
- Mức độ hoạt động
- Sôi nổi
- Độ rõ ràng
- Khá rõ ràng
- Mức phù hợp với người mới
- 35/100