fix: Match arm block IIFEs missing return on last expression#974
Merged
milkyskies merged 9 commits intomainfrom Apr 3, 2026
Merged
fix: Match arm block IIFEs missing return on last expression#974milkyskies merged 9 commits intomainfrom
milkyskies merged 9 commits intomainfrom
Conversation
When a match arm body is a block (multiple statements), the codegen wraps it in an IIFE. The last expression in the block was emitted without `return`, so the IIFE returned `undefined` instead of the computed value. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sub-codegens (used for emit_expr_string, emit_arg_strings, and pipe emission) set has_jsx when encountering JSX, but never propagated it back to the parent codegen. This caused files containing JSX inside match arms, callbacks, or pipes to be output as .ts instead of .tsx. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When a stdlib template produces a ternary (e.g. Option.unwrapOr: `$0 !== undefined ? $0 : $1`) and the result is used as $0 in another template with member access (e.g. `$0.filter(...)`), the member access bound to the false-branch instead of the whole ternary. Now wraps ternary-containing args in parens when the template accesses them with `.`, `[`, or `(`. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Arrows whose body is a Block (e.g. from `use` callback desugaring) used `emit_block_items` which doesn't add `return` to the last expression. Now uses `emit_block_expr_with_return` instead, matching how function bodies handle implicit returns. This caused `use key <- Option.guard(...)` callbacks to return undefined, making the component render nothing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ports
collect_value_used_names didn't recurse into ExprKind::Object or
ExprKind::Grouped/Spread, causing names used inside JSX style props
(e.g. `style={{ color: Record.get(PRIORITY_COLORS, p) }}`) to be
treated as type-only imports and erased at runtime.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All Option stdlib functions used strict `!== undefined` checks, which missed `null` values from serde/JSON serialization. Changed to loose `!= null` which catches both null and undefined, matching how JavaScript APIs and Rust's serde actually represent absent values. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds syntax for default imports: `import [trusted] X from "module"`.
Compiles to `import X from "module"` in TypeScript.
Previously Floe only supported named imports (`import { X } from "module"`),
which breaks at runtime for packages that only have a default export
(e.g. react-markdown) in non-bundled environments.
closes #975
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
`match x > 0 { true -> ... }` emitted `x > 0 === true` where `===`
binds tighter than `>`, evaluating as `x > (0 === true)`. Now wraps
binary/pipe/unary subjects in parens: `(x > 0) === true`.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Option<T> in type annotations and .d.fl.ts now emits T | null | undefined instead of T | undefined. This matches the runtime behavior (stdlib already uses != null) and allows TS callers to pass null (standard in React, JSON, serde) without type errors. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
return, so the IIFE returnedundefinedbuildColumnsto returnundefinedinstead of the computed array, crashing withTypeError: undefined is not an object (evaluating 'boardColumns.find')Fix
Added
returnbefore the last expression item in match arm block IIFEs, in both the general case and the string-pattern case.Test plan
cargo test— 1252 tests pass (1 new regression test)floe check+floe buildon example apps — no errors.flfile🤖 Generated with Claude Code