Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: dotnet/fsharp
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: main
Choose a base ref
...
head repository: fsharp-wasm/fsharp
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: features/ce-enhancements-desugaring
Choose a head ref
Checking mergeability… Don’t worry, you can still create the pull request.
  • 1 commit
  • 26 files changed
  • 1 contributor

Commits on Apr 8, 2026

  1. Better CE Builder

    Task 2: Allow if! and for! tokens - lexer, parser, LexFilter,
    LanguageFeatures
    
    - Add IF_BANG and FOR_BANG token rules in lex.fsl
    - Add token declarations and grammar rules in pars.fsy
    - if! desugars to MatchBang with bool pattern clauses at parser level
    - for! desugars to ForEach with isFromSource=false (no Source wrapping)
    - Add IfBang and ForBang language features (preview)
    - Handle new tokens in LexFilter.fs and ServiceLexing.fs
    
    Task 5: Desugar while! to recursive Bind/Combine/Zero (carrier-free)
    
    Replace the old while! desugaring (which required While(unit->bool,...))
    with
    a recursive Bind/Combine/Zero pattern that only requires Bind, Combine,
    and Zero.
    
    while! guard do body now desugars to:
      let rec __whileLoop () =
          builder.Bind(guard, fun __res ->
              if __res then
                  builder.Combine(translatedBody, builder.Delay(fun () ->
    __whileLoop()))
              else
                  builder.Zero())
      __whileLoop()
    
    Fix BindReturn poisoning do!, add tests and documentation
    
    - When consumePat is a unit pattern (from do! desugaring), skip
    BindReturn
      optimization and fall back to Bind + Return. This prevents FS0001 when
      a builder defines BindReturn(M, M->M) but do! produces unit->unit.
    - Add CEEnhancementsTests.fs with 13 tests covering:
      - BindReturn/do! poisoning fix
      - if! desugaring with else, without else, version gating, missing Bind
      - for! desugaring without IEnumerable constraint, version gating
      - while! carrier-free desugaring
      - Regression tests for async, task, seq
    - Add docs/ce-enhancements/CHANGES.md and RFC-DRAFT.md
    
    Improve BindReturn fix comment to clarify Bind overload selection
    
    FS0041 fix: type-annotate unit continuation in CE Bind to disambiguate
    overloads
    
    When consumePat is a unit pattern (from do! desugaring), wrap the
    continuation MatchLambda in SynExpr.Typed with (unit -> _) annotation.
    This gives overload resolution enough type info to disambiguate between
    Bind(M, unit -> M) and Bind(M, Expr -> M) without FS0041.
    
    Add comprehensive tests for mixed let!/do!/and! with overloaded Bind
    and BindReturn, including FS0041 regression tests.
    
    WIP: WhileBang builder method + comprehensive tests (40/40 pass, 0
    regressions)
    
    feat(compiler): wrap while! guard in builder.Source and add design docs
    
    Updated while! desugaring to pass the guard through builder.Source
    before WhileBang, ensuring consistency with let! and match!.
    Updated CheckComputationExpressions.fs to include the Source call.
    Added "Design Principles" section to RFC-DRAFT.md outlining the minimal
    extension approach for CE enhancements.
    Updated CHANGES.md to reflect the technical desugaring change.
    aiqs4 committed Apr 8, 2026
    Configuration menu
    Copy the full SHA
    148a581 View commit details
    Browse the repository at this point in the history
Loading