Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
### Fixed

- Exception abbreviation loses its right-hand side. [#3511](https://github.com/fsprojects/fantomas/issues/3511)
- Static optimization when ^T struct loses struct. [#3514](https://github.com/fsprojects/fantomas/issues/3514)
- Static optimization loses the `and` between its conditions, and reverses its conditions and `when` clauses. [#3516](https://github.com/fsprojects/fantomas/pull/3516)

## [8.0.6] - 2026-10-01

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let inline f (x: ^T) (y: ^U) = 0 when ^T : int and ^U struct = 1
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let inline f (x: ^T) (y: ^U) = 0 when ^T: int and ^U struct = 1
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let inline f (x: ^T) = 0 when ^T : int = 1 when ^T : float = 2
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let inline f (x: ^T) = 0 when ^T: int = 1 when ^T: float = 2
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let inline retype (x: ^T) : ^U = (# "" x : ^U #) when ^T struct = 0

This file was deleted.

55 changes: 34 additions & 21 deletions src/Fantomas.Core/ASTTransformer.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1923,29 +1923,42 @@ let mkExpr (creationAide: CreationAide) (e: SynExpr) : Expr =
ExprSetNode(mkExpr creationAide e1, mkExpr creationAide e2, exprRange)
|> Expr.Set

| SynExpr.LibraryOnlyStaticOptimization(constraints, e, optExpr, _) ->
let constraints =
constraints
|> List.map (
function
| SynStaticOptimizationConstraint.WhenTyparTyconEqualsTycon(t1, t2, _) ->
StaticOptimizationConstraintWhenTyparTyconEqualsTyconNode(
mkSynTypar t1,
mkType creationAide t2,
unionRanges t1.Range t2.Range
| SynExpr.LibraryOnlyStaticOptimization _ ->
let mkConstraint (c: SynStaticOptimizationConstraint) : StaticOptimizationConstraint =
match c with
| SynStaticOptimizationConstraint.WhenTyparTyconEqualsTycon(t1, t2, _) ->
StaticOptimizationConstraintWhenTyparTyconEqualsTyconNode(
mkSynTypar t1,
mkType creationAide t2,
unionRanges t1.Range t2.Range
)
|> StaticOptimizationConstraint.WhenTyparTyconEqualsTycon
| SynStaticOptimizationConstraint.WhenTyparIsStruct(t, _) ->
mkSynTypar t |> StaticOptimizationConstraint.WhenTyparIsStruct

// The parser nests `e when A = a when B = b` as A(a, B(b, e)), with the first clause outermost, while the
// Oak puts the last clause outermost: B(b, A(a, e)). `wrap` builds the clauses seen so far around `e`.
let rec collect (wrap: Expr -> Expr) (expr: SynExpr) : Expr =
match expr with
| SynExpr.LibraryOnlyStaticOptimization(constraints, e, optExpr, _) ->
collect
(fun inner ->
let optimizedExpr: Expr = wrap inner
let expr: Expr = mkExpr creationAide e

ExprLibraryOnlyStaticOptimizationNode(
optimizedExpr,
// The parser keeps the conditions of a `when` in reverse.
constraints |> List.rev |> List.map mkConstraint,
expr,
unionRanges (Expr.Node optimizedExpr).Range (Expr.Node expr).Range
)
|> Expr.LibraryOnlyStaticOptimization
)
|> StaticOptimizationConstraint.WhenTyparTyconEqualsTycon
| SynStaticOptimizationConstraint.WhenTyparIsStruct(t, _) ->
mkSynTypar t |> StaticOptimizationConstraint.WhenTyparIsStruct
)
optExpr
| _ -> wrap (mkExpr creationAide expr)

ExprLibraryOnlyStaticOptimizationNode(
mkExpr creationAide optExpr,
constraints,
mkExpr creationAide e,
exprRange
)
|> Expr.LibraryOnlyStaticOptimization
collect id e
| SynExpr.InterpolatedString(parts, _, _) ->
let lastIndex = parts.Length - 1

Expand Down
4 changes: 2 additions & 2 deletions src/Fantomas.Core/CodePrinter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2339,10 +2339,10 @@ let genExpr (e: Expr) =
genExpr node.OptimizedExpr
+> onlyIfNot node.Constraints.IsEmpty (!-" when ")
+> col
sepSpace
(sepSpace +> wordAndFixed +> sepSpace)
node.Constraints
(function
| StaticOptimizationConstraint.WhenTyparIsStruct t -> genSingleTextNode t
| StaticOptimizationConstraint.WhenTyparIsStruct t -> genSingleTextNode t +> !-" struct"
| StaticOptimizationConstraint.WhenTyparTyconEqualsTycon n ->
genSingleTextNode n.TypeParameter +> sepColon +> sepSpace +> genType n.Type
)
Expand Down
Loading