diff --git a/ISSUES.md b/ISSUES.md index daf1346..f1c6f65 100644 --- a/ISSUES.md +++ b/ISSUES.md @@ -123,45 +123,29 @@ List.map(items, addOne) ## Issue 7: Effectful callbacks in `List.map`/`forEach`/`fold` -**Category**: Type checker limitation +**Category**: Type checker limitation → **Fixed** **Severity**: Medium The type checker requires pure callbacks for higher-order List functions, but effectful callbacks are often needed (e.g., reading files in a map operation). -**Reproduction**: -```lux -fn readFile(path: String): String with {File} = File.read(path) -let contents = List.map(paths, fn(p: String): String => readFile(p)); -// ERROR: Effect mismatch: expected {File}, got {} -``` - -**Workaround**: Use manual recursion instead of List.map/forEach: -```lux -fn mapRead(paths: List): List with {File} = - match List.head(paths) { - None => [], - Some(p) => { - let content = readFile(p); - match List.tail(paths) { - Some(rest) => List.concat([content], mapRead(rest)), - None => [content] - } - } - } -``` +**Fix**: Added effect propagation in `src/typechecker.rs`: callback arguments with effect annotations now propagate their effects to the enclosing function's inferred effect set, in `infer_call`, `infer_effect_op` (module access path), and `infer_effect_op` (effect op path). --- -## Issue 8: `String.indexOf` and `String.lastIndexOf` missing from type checker +## Issue 8: `String.indexOf` and `String.lastIndexOf` broken in C backend -**Category**: Type checker gap → **Fixed** +**Category**: C backend bug → **Fixed** **Severity**: Medium -These functions exist in the interpreter but were not registered in the type checker, causing "Module 'String' has no member" errors. +Type registrations were added previously, but C compilation of code using `String.indexOf`/`lastIndexOf` failed with type errors. Three root causes: +1. Global `let` bindings always declared as `static LuxInt` regardless of value type +2. `Option` inner type not tracked through function parameters, causing match extraction to default to `LuxString` +3. `indexOf`/`lastIndexOf` stored ints as `(void*)(intptr_t)` but extraction expected boxed pointers (inconsistent with `parseInt`) -**Fix**: Added type registrations in src/types.rs: -- `String.indexOf(String, String) -> Option` -- `String.lastIndexOf(String, String) -> Option` +**Fix**: Fixed in `src/codegen/c_backend.rs`: +- `emit_global_let` now infers type from value expression +- Added `var_option_inner_types` map; function params with `Option` annotations are tracked +- `indexOf`/`lastIndexOf` now use `lux_box_int` consistently; extraction dereferences via `*(LuxInt*)` --- @@ -243,12 +227,10 @@ let json = match Json.parse(raw) { Ok(j) => j, Err(_) => ... }; ## Issue 14: No `File.copy` -**Category**: Missing feature +**Category**: Missing feature → **Fixed** **Severity**: Low -Must shell out to copy files/directories. - -**Workaround**: `Process.exec("cp -r static/* _site/")`. +**Fix**: Added `File.copy(source, dest)` to types.rs, interpreter.rs (using `std::fs::copy`), and C backend (fread/fwrite buffer copy). --- @@ -273,12 +255,12 @@ Must manually scan directories and filter by extension. | 4 | Tuple field access `.0` `.1` | High | Open | | 5 | Multi-line function arguments | High | Open | | 6 | Multi-line lambdas in calls | High | Open | -| 7 | Effectful callbacks in List HOFs | Medium | Open | -| 8 | String.indexOf/lastIndexOf types | Medium | **Fixed** | +| 7 | Effectful callbacks in List HOFs | Medium | **Fixed** | +| 8 | String.indexOf/lastIndexOf C backend | Medium | **Fixed** | | 9 | No List.sort | Medium | Open | | 10 | No HashMap/Map | Medium | Open | | 11 | No regex | Medium | Open | | 12 | No multiline strings | Medium | Open | | 13 | Json.parse return type docs | Low | Open | -| 14 | No File.copy | Low | Open | +| 14 | No File.copy | Low | **Fixed** | | 15 | No file globbing | Low | Open |