Files
lux/docs/STRESS_TEST_FINDINGS.md
Brandon Lucas c81349d82c fix: resolve all stress test bugs
- 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>
2026-02-14 02:45:52 -05:00

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 42 shows "(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: Returns inf (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 implemented
  • String.charAt(s, i) - not implemented

REPL Issues

Working Well

  • State persistence between lines
  • Function redefinition
  • Multi-line input
  • :help, :quit, :load commands
  • Tab completion (noted in help)

Issues

  • :type expr doesn't show the type, just "(type checking passed)"
  • No :ast or :tokens debugging 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 call crash()
  • false && crash() - doesn't call crash()
  • if true then 1 else crash() - doesn't call crash()

Recommendations

High Priority

  1. Fix record equality
  2. Error on invalid escape sequences
  3. Validate effect names at declaration time

Medium Priority

  1. Add forward reference support for mutual recursion
  2. Improve parser error messages with context
  3. Add list pattern matching support
  4. Error on circular type definitions

Low Priority

  1. Add hex/binary/octal literal support
  2. Add scientific notation support
  3. Fix :type command to show actual type
  4. 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