Skip to content

feat(rust): various codegen and runtime improvements - #4781

Merged
MangelMaxime merged 3 commits into
fable-compiler:mainfrom
Thorium:pr/2-rust-improvements
Jul 15, 2026
Merged

MangelMaxime merged 3 commits into
fable-compiler:mainfrom
Thorium:pr/2-rust-improvements

Conversation

@Thorium

@Thorium Thorium commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

This is split from #4774 and is dependent on #4780 (so that should be merged first).

Copilot generated description:
This pull request significantly improves Fable's support for F# quotations, especially for statically typed targets like Rust. The changes ensure that quoted expressions preserve .NET member metadata, generate portable representations for values like null and unit, and improve compatibility and fidelity for pattern matching, options, lists, and type information. Several helpers and code paths are refactored to produce correct and target-agnostic quotation trees.

Quotations emission and representation improvements:

  • Quoted expressions now preserve .NET member calls and metadata by introducing a CapturingQuotation flag in the Context, ensuring that member calls are not replaced or inlined when capturing quotations. This preserves necessary metadata for downstream consumers like the QuotationEmitter. [1] [2] [3] [4]
  • The quotation emitter now emits runtime-constructed null nodes (via mkNullExpr) for instance-less calls, unit, null, option None, and empty lists, improving compatibility with statically typed targets such as Rust and Dart. [1] [2] [3]
  • Pattern matching and decision trees in quotations are now faithfully inlined and transformed into trees of IfThenElse and Let expressions, matching F#'s quotation semantics.
  • Quotation emission for pattern tests (union case, option, list, type tests) now generates explicit method/property calls, using the correct type names and method names, so that the structure is preserved and recognized in all targets. [1] [2]

Target-specific and cross-target compatibility:

  • Rust-specific handling for quotations: union cases, records, and options are now emitted with additional type and case information, and empty quotation-expr arrays are routed through a runtime helper to ensure correct typing. [1] [2]
  • All targets now receive a four-argument form for mkCall in quotations, ensuring compatibility with Rust's stricter function arity and maintaining back-compatibility with other runtimes.

General improvements and refactoring:

  • Type and number kind stringification for quotations is made more robust and comprehensive, covering all relevant F# and .NET types.
  • The Rust backend now supports casting from bool to integer types, matching Rust's native casting semantics.

These changes together make Fable's quotation support more robust, portable, and faithful to F# semantics across all supported targets.

References:
[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12]

@MangelMaxime
MangelMaxime force-pushed the pr/2-rust-improvements branch from 9dfb673 to 68ab383 Compare July 15, 2026 16:24
@Thorium

Thorium commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

Let me know if you need any help rebasing these. I just don't want to do it at the same time as you, because of the "force".

@MangelMaxime

Copy link
Copy Markdown
Member

Thank you for proposing.

For this PR, it was easy enough as just dropping the commit. I am now working on reviewing the changes, adding tests if needed etc.

Hopefully, the other issues will be as simple to rebase 🤞

@MangelMaxime MangelMaxime changed the title feat(rust): codegen and runtime improvements feat(rust): various codegen and runtime improvements Jul 15, 2026
@MangelMaxime
MangelMaxime merged commit fb4b896 into fable-compiler:main Jul 15, 2026
23 checks passed
MangelMaxime added a commit that referenced this pull request Jul 16, 2026
=== changelog ===
* Cast `bool` to integer types; support `**` via `.powf`
* Add `Decimal.IsInteger/IsEvenInteger/IsOddInteger/IsCanonical`
* Fix two-switch decision trees dispatching to the wrong target
* Fix reference-typed match bindings panicking via `mem::zeroed`
* Fix string and non-ident option pattern matches emitting invalid Rust
`match` arms
* Fix `Convert.ToXxx(bool)`
* Fix `Char.ToUpper/ToLower` truncating multi-char case mappings
* Fix `Random.nextDouble` panic message
* Fix `Map.find/tryFind` panicking on reference-typed values
=== changelog ===

Co-authored-by: Mangel Maxime <me@mangelmaxime.fr>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants