bug: a lambda parameter carries no type, so indexing or len() inside a lambda reads the wrong value
- Langage dominant
- Rust
- Étoiles
- 22
- Forks
- 6
- Merge moyen
- 1 j 3 h
- PR mergées (30 j)
- 6
Description
## 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
Guide de contribution
Ouvrir le guide de contribution
Piste de recherche
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.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- python, rust, wasm
- Domaine
- compilers
- Type d'issue
- Bug
- Difficulté
- 5/5
- Temps estimé
- Plus d'une semaine
- Activité
- Active
- Clarté
- Plutôt claire
- Accessibilité débutants
- 35/100