- Record equality: add Record case to values_equal in interpreter - Invalid escapes: error on unknown escape sequences in lexer - Unknown effects: validate effect names in check_function with suggestions - Circular types: add DFS cycle detection in check_type_cycles - Parser: require | for enum variants, enabling proper type alias syntax All 265 tests pass. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
5.5 KiB
5.5 KiB
Lux Stress Test Findings
This document summarizes issues found during systematic stress testing of the Lux parser, typechecker, and REPL.
Critical Bugs (All Fixed)
1. Record Equality Returns False for Equal Records (FIXED)
let r1 = { x: 1, y: 2 }
let r2 = { x: 1, y: 2 }
r1 == r2 // Now returns true
Fix: Added Record case to Interpreter::values_equal in src/interpreter.rs
2. Invalid Escape Sequences Silently Accepted (FIXED)
"\z" // Now produces error: "Invalid escape sequence: \z"
Fix: Modified lexer in src/lexer.rs to error on unknown escape sequences
3. Unknown Effects Silently Accepted in Declarations (FIXED)
fn test(): Unit with {CompletelyFakeEffect} = () // Now produces error with suggestions
Fix: Added effect validation in TypeChecker::check_function in src/typechecker.rs
4. No Forward References for Mutual Recursion (FIXED/DOCUMENTED)
fn isEven(n: Int): Bool = if n == 0 then true else isOdd(n - 1)
fn isOdd(n: Int): Bool = if n == 0 then false else isEven(n - 1)
// Works in files (two-pass type checking), REPL limitation documented
Note: Works when loaded from files due to two-pass type checking. REPL processes line-by-line, so forward references don't work there.
5. Circular Type Definitions Silently Fail (FIXED)
type A = B
type B = A
// Now produces error: "Circular type definition detected: A -> B -> A"
Fix: Added check_type_cycles method with DFS cycle detection in src/typechecker.rs. Also fixed parser to require | for enum variants, allowing type A = B to be parsed as a type alias.
Parser Issues
Missing Features
| Feature | Status | Notes |
|---|---|---|
Hex literals (0x10) |
Not supported | Generic parse error |
Binary literals (0b101) |
Not supported | Generic parse error |
Octal literals (0o77) |
Not supported | Generic parse error |
Scientific notation (1e10) |
Not supported | Generic parse error |
Leading dot floats (.5) |
Not supported | Generic parse error |
Trailing dot floats (1.) |
Not supported | Generic parse error |
Underscore separators (1_000_000) |
Supported | Works correctly |
List patterns in match ([a, b, c]) |
Not supported | Parse error |
Guard clauses (x if x > 0 =>) |
Not working | Shows redundant pattern error |
Poor Error Messages
| Input | Current Error | Better Error |
|---|---|---|
[1 2 3] |
"Expected declaration" | "Missing comma between list elements" |
{ x 1 } |
"Undefined variable: x" | "Missing colon in record field" |
funtion foo() |
"Expected declaration" | "Unknown keyword 'funtion'. Did you mean 'fn'?" |
(1 + 2 |
No error | "Unclosed parenthesis" |
{ x: 1 |
No error | "Unclosed brace" |
[1,, 2] |
No output | "Unexpected comma" |
Identifier Issues
- Double underscore identifiers (
__name) not allowed - Unicode identifiers (
café) partially work but may have issues
Type Checker Issues
Good Error Messages
- Type mismatches: Clear "Cannot unify X with Y"
- Undefined variables: Includes "Did you mean..." suggestions
- Wrong argument count: Clear arity mismatch message
- Non-exhaustive match: Lists uncovered patterns
- Effect mismatches: Shows expected vs actual effects
- Undefined record field: Clear "Record has no field"
- Calling non-function: Clear type mismatch
Issues
:type 42shows "(type checking passed)" but not the actual type- No type inference for function parameters - must be annotated
Runtime Issues
Division Handling
- Integer
/0: Proper "Division by zero" error - Integer
%0: Proper "Modulo by zero" error - Float
/0.0: Returnsinf(IEEE 754 compliant)
Recursion
- Deep recursion (10,000 calls): Works! Good tail call optimization
- Infinite recursion: Eventually times out (expected)
Missing Stdlib Functions
String.get(s, i)- not implementedString.charAt(s, i)- not implemented
REPL Issues
Working Well
- State persistence between lines
- Function redefinition
- Multi-line input
:help,:quit,:loadcommands- Tab completion (noted in help)
Issues
:type exprdoesn't show the type, just "(type checking passed)"- No
:astor:tokensdebugging commands - String interpolation syntax is
{x}not${x}(unexpected)"Hello {name}"works"Hello ${name}"outputs"Hello $<value>"(keeps literal$)
Comparison & Equality
| Type | == Works? |
|---|---|
| Int | Yes |
| Float | Yes |
| Bool | Yes |
| String | Yes |
| List | Yes |
| Tuple | Yes |
| Option/Result | Yes |
| Record | NO (BUG) |
| Function | No (expected) |
Short-Circuit Evaluation
Works correctly:
true || crash()- doesn't callcrash()false && crash()- doesn't callcrash()if true then 1 else crash()- doesn't callcrash()
Recommendations
High Priority
- Fix record equality
- Error on invalid escape sequences
- Validate effect names at declaration time
Medium Priority
- Add forward reference support for mutual recursion
- Improve parser error messages with context
- Add list pattern matching support
- Error on circular type definitions
Low Priority
- Add hex/binary/octal literal support
- Add scientific notation support
- Fix
:typecommand to show actual type - Document actual string interpolation syntax
Test Commands Used
# Run stress tests
./target/release/lux test examples/test_math.lux
# Test specific edge case
echo 'let r1 = {x: 1}; let r2 = {x: 1}; r1 == r2' | ./target/release/lux