Conversation
Summary Root cause: The type checker was allowing operations like rot (which needs 3 stack values) to be called with fewer values because implicit row polymorphism (( -- ) parses as ( ..rest -- ..rest )) allowed row variables to "grow" during unification. Fix: Added an underflow check in typechecker.rs:apply_effect that: 1. Counts concrete types in the effect's input vs current stack 2. Checks if the stack's base row variable is "rigid" (exactly named rest from declared effects) 3. Rejects operations that need more concrete values than available when on a rigid row variable Key insight: Only the original rest row variable (from declared effects) should be rigid. Freshened row variables like rest$680 (from callee effects during type checking) should be flexible. Changes Made 1. crates/compiler/src/typechecker.rs - Added underflow detection in apply_effect 2. crates/compiler/stdlib/http.seq - Fixed real bug: drop drop "" → drop "" after string.split (line 173) 3. examples/http/http_server.seq - Fixed same bug in the copied function (line 245) Result $ ./seqc build should_fail.seq Error: In 'main': rot: stack underflow - requires 3 value(s), only 2 provided The fix catches the phantom stack entries bug at compile time while maintaining compatibility with all existing code (CI passes: 231 unit tests, 124 integration tests).
Code Review - PR #170: Fix Stack Underflow Detection (Issue #169)SummaryThis PR addresses the phantom stack entries bug where operations like rot (requiring 3 stack values) were incorrectly accepted when only 2 values were present. The fix adds compile-time underflow detection to the type checker while maintaining compatibility with existing code. Strengths
Concerns1. CRITICAL: .gitignore Change May Be Too BroadLocation: .gitignore:6 adds *.seq Issue: This ignores ALL .seq files, including those in the repository like crates/compiler/stdlib/http.seq and examples/http/http_server.seq Impact: This could cause developers to accidentally exclude important source files from version control. Recommendation: Either remove this line entirely if it was added by mistake, or use a more specific pattern like /tmp/.seq or /.seq to only ignore test files in specific directories. This is the most concerning change in the PR and should be addressed before merging. 2. Test Coverage: Missing Direct TestThe PR mentions that existing tests pass (231 unit tests, 124 integration tests), but there doesn't appear to be a new test specifically for the rot underflow case that was the original bug report. Recommendation: Add a test case for the rot underflow scenario to serve as regression protection and documentation of the fix. 3. Row Variable Naming Convention AssumptionLocation: typechecker.rs:1050 uses let is_rigid = row_var_name == rest; This relies on an exact string match with rest to determine rigidity. Is this naming convention guaranteed by the parser/type system? Could future changes break this assumption? Recommendation: Add a reference to where this convention is established, or consider adding an assertion that validates this assumption. Overall AssessmentQuality: High quality fix with good documentation Recommendation: Approve with ChangesMust Address:
Should Address:
Great work on identifying and fixing a subtle type system bug! Once the .gitignore issue is resolved, this will be a solid improvement to the type checker. |
Code Review - PR #170: Stack Underflow DetectionSummaryThis PR successfully addresses issue #169 by adding compile-time detection of stack underflow conditions. The implementation is sound and the fix is well-motivated. However, I have some recommendations for improvement. Strengths1. Correct Root Cause Analysis 2. Minimal, Focused Fix 3. Real Bugs Found 4. Backwards Compatible Code Quality Observations1. The is_rigid Check (Line 1050) Concern: The string comparison let is_rigid = row_var_name == rest; is fragile. If the parser or naming conventions change, this breaks silently. Recommendation: Consider one of:
2. Error Message Quality Good: Clear, actionable error message that tells the user exactly what's wrong. Suggestion: Consider showing the expected stack signature for even better UX. 3. Helper Function Clarity Potential Issues1. Missing Unit Test for the Fix 2. Freshened Variables Pattern Assumption Performance Considerations1. Linear Stack Traversal Security ConsiderationsNo security concerns. This is a compile-time check that prevents a soundness bug in the type system. The fix makes the language more secure by catching errors earlier. Test CoverageCurrent State: The PR states CI passes with 231 unit + 124 integration tests. Gaps:
Recommendation: Add at least:
Final RecommendationsMust Fix:
Should Fix: Nice to Have: VerdictThis is a well-implemented fix that addresses a real soundness issue in the type system. The approach is correct, and the code is clear. With the addition of explicit tests for the new behavior, this will be excellent. The main concern is the reliance on string comparison for determining rigidity, which could be more robust. Consider addressing this in a follow-up if not in this PR. Approval Status: Approve with minor recommendations for improvement. Great work tracking down this subtle type system bug! |
Changes made: 1. Added test case for issue #169 (typechecker.rs:1592-1629) - test_stack_underflow_rot_issue_169 - Tests that rot with only 2 values fails - Includes comments explaining the RowVar("rest") usage 2. Documented row variable naming convention (typechecker.rs:1046-1057) - Explains "rest" (rigid, from parser), "rest$N" (freshened, flexible), "input" (inference) - References where the convention is established (parser.rs:build_stack_type) The PR now addresses all reviewer concerns: - ✅ .gitignore fixed (you did this) - ✅ Test coverage for issue #169 - ✅ Row variable naming convention documented
Code Review for PR #170SummaryThis PR addresses issue #169 (phantom stack entries) by adding compile-time stack underflow detection to the type checker. The fix prevents operations like ✅ Code Quality & Best PracticesExcellent:
Minor suggestions:
✅ Bug Fixes & CorrectnessBug fixes identified and corrected:
Both fixes are correct and demonstrate that the new type checker successfully caught real bugs in existing code. ✅ Test CoverageStrong test coverage:
Test quality observations:
✅ Performance ConsiderationsMinimal performance impact:
No concerns - this is a compile-time check with negligible impact. ✅ Security ConsiderationsNo security concerns:
This actually improves security by making the type system more sound. 🔍 Architecture & DesignKey insight (well-documented in code):
This is a sophisticated type system design that maintains row polymorphism while preventing unsound operations. Design questions to consider:
📋 RecommendationsRequired: None - This PR is ready to merge as-is. Optional enhancements (future work):
Final AssessmentStrong approval ✅ This PR demonstrates:
The fix is sound, well-implemented, and catches a real class of bugs at compile time. The code quality is high with excellent explanatory comments. Great work! Impact: This prevents a subtle class of bugs (phantom stack entries) that would be very difficult to debug at runtime. |
Summary
#169
Root cause: The type checker was allowing operations like rot (which needs 3 stack values) to be called with fewer values because implicit row polymorphism (( -- ) parses as ( ..rest -- ..rest )) allowed row variables to "grow" during unification.
Fix: Added an underflow check in typechecker.rs:apply_effect that:
Key insight: Only the original rest row variable (from declared effects) should be rigid. Freshened row variables like rest$680 (from callee effects during type checking) should be flexible.
Changes Made
Result
$ ./seqc build should_fail.seq
Error: In 'main': rot: stack underflow - requires 3 value(s), only 2 provided
The fix catches the phantom stack entries bug at compile time while maintaining compatibility with all existing code (CI passes: 231 unit tests, 124 integration tests).