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
12 changes: 11 additions & 1 deletion src/Fable.Transforms/FableTransforms.fs
Original file line number Diff line number Diff line change
Expand Up @@ -409,11 +409,21 @@ module private Transforms =
| _ -> ValueNone

let tryInlineBinding (com: Compiler) (ident: Ident) value letBody =
let readsMutableValue callee =
match callee with
| IdentExpr id -> id.IsMutable
| Import({ Kind = MemberImport memberRef }, _, _) ->
com.TryGetMember(memberRef) |> Option.exists (fun memb -> memb.IsMutable)
| _ -> false

let canInlineBinding =
match value with
| Import(i, _, _) -> i.IsCompilerGenerated
| Call(callee, info, _, _) when List.isEmpty info.Args && List.contains "value" info.Tags ->
canInlineArg com ident.Name callee letBody
if readsMutableValue callee then
canInlineArg com ident.Name value letBody
else
canInlineArg com ident.Name callee letBody
// Replace non-recursive lambda bindings
| NestedLambda(_args, lambdaBody, _name) ->
match lambdaBody with
Expand Down
5 changes: 5 additions & 0 deletions tests/Js/Main/MiscTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@

let mutable mutableValue = 0

let rec recursive1 = delay (fun () -> recursive2())

Check warning on line 385 in tests/Js/Main/MiscTests.fs

View workflow job for this annotation

GitHub Actions / build-javascript (ubuntu-latest)

This and other recursive references to the object(s) being defined will be checked for initialization-soundness at runtime through the use of a delayed reference. This is because you are defining one or more recursive objects, rather than recursive functions. This warning may be suppressed by using '#nowarn "40"' or '--nowarn:40'.

Check warning on line 385 in tests/Js/Main/MiscTests.fs

View workflow job for this annotation

GitHub Actions / build-javascript (windows-latest)

This and other recursive references to the object(s) being defined will be checked for initialization-soundness at runtime through the use of a delayed reference. This is because you are defining one or more recursive objects, rather than recursive functions. This warning may be suppressed by using '#nowarn "40"' or '--nowarn:40'.
and recursive2 =
mutableValue <- 5
fun () -> mutableValue <- mutableValue * 2
Expand Down Expand Up @@ -1314,6 +1314,11 @@
Option.defaultWith (fun () -> invalidOp "This is invalid") (Some 3) |> equal 3
throwsError "This is invalid" (fun () -> Option.defaultWith (fun () -> invalidOp "This is invalid") None)

testCase "A read of another file's mutable value is not moved past side effects" <| fun () -> // See #5156
let before = MiscTestsHelper.trackedCalls
MiscTestsHelper.track 1 |> ignore
MiscTestsHelper.trackedCalls - before |> equal 1

testCase "Pattern matching optimization works (switch statement)" <| fun () ->
let mutable x = ""
let i = 4
Expand All @@ -1322,7 +1327,7 @@
| 2 -> x <- "2"
| 3 | 4 -> x <- "3" // Multiple cases are allowed
// | 5 | 6 as j -> x <- string j // This prevents the optimization
| 4 -> x <- "4" // Unreachable cases are removed

Check warning on line 1330 in tests/Js/Main/MiscTests.fs

View workflow job for this annotation

GitHub Actions / build-javascript (ubuntu-latest)

This rule will never be matched

Check warning on line 1330 in tests/Js/Main/MiscTests.fs

View workflow job for this annotation

GitHub Actions / build-javascript (windows-latest)

This rule will never be matched
| _ -> x <- "?"
equal "3" x

Expand Down
6 changes: 6 additions & 0 deletions tests/Js/Main/MiscTestsHelper.fs
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,9 @@ type Vector2<[<Measure>] 'u> = Vector2 of x: float<'u> * y: float<'u> with

static member inline ( + ) (Vector2(ax, ay), Vector2(bx, by)) = Vector2(ax + bx, ay + by)
static member inline ( * ) (scalar, Vector2(x, y)) = Vector2(scalar * x, scalar * y)

let mutable trackedCalls = 0

let track x =
trackedCalls <- trackedCalls + 1
x
6 changes: 6 additions & 0 deletions tests/Python/MiscTestsHelper.fs
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,9 @@ type CrossModuleDemo =

static member propDefault = A "prop"
static member methDefault() = A "meth"

let mutable trackedCalls = 0

let track x =
trackedCalls <- trackedCalls + 1
x
6 changes: 6 additions & 0 deletions tests/Python/TestMisc.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1336,7 +1336,7 @@
| 2 -> x <- "2"
| 3 | 4 -> x <- "3" // Multiple cases are allowed
// | 5 | 6 as j -> x <- string j // This prevents the optimization
| 4 -> x <- "4" // Unreachable cases are removed

Check warning on line 1339 in tests/Python/TestMisc.fs

View workflow job for this annotation

GitHub Actions / build-python (windows-latest, 3.14)

This rule will never be matched

Check warning on line 1339 in tests/Python/TestMisc.fs

View workflow job for this annotation

GitHub Actions / build-python (windows-latest, 3.13)

This rule will never be matched

Check warning on line 1339 in tests/Python/TestMisc.fs

View workflow job for this annotation

GitHub Actions / build-python (windows-latest, 3.15)

This rule will never be matched

Check warning on line 1339 in tests/Python/TestMisc.fs

View workflow job for this annotation

GitHub Actions / build-python (ubuntu-latest, 3.15)

This rule will never be matched

Check warning on line 1339 in tests/Python/TestMisc.fs

View workflow job for this annotation

GitHub Actions / build-python (ubuntu-latest, 3.13)

This rule will never be matched

Check warning on line 1339 in tests/Python/TestMisc.fs

View workflow job for this annotation

GitHub Actions / build-python (ubuntu-latest, 3.14)

This rule will never be matched
| _ -> x <- "?"
equal "3" x

Expand Down Expand Up @@ -1833,3 +1833,9 @@
with _ -> ()
equal before storage.count
#endif

[<Fact>]
let ``test A read of another file's mutable value is not moved past side effects`` () = // See #5156
let before = MiscTestsHelper.trackedCalls
MiscTestsHelper.track 1 |> ignore
MiscTestsHelper.trackedCalls - before |> equal 1
Loading