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
7 changes: 6 additions & 1 deletion src/Fable.Build/Quicktest/Rust.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@ module Build.Quicktest.Rust

open Build.FableLibrary
open Build.Quicktest.Core
open SimpleExec

let handle (args: string list) =
let projectDir = "src/quicktest-rust"

Command.Run("cargo", "clean", workingDirectory = projectDir)

genericQuicktest
{
Language = "rust"
FableLibBuilder = BuildFableLibraryRust()
ProjectDir = "src/quicktest-rust"
ProjectDir = projectDir
Extension = ".rs"
RunMode = RunScript
}
Expand Down
34 changes: 24 additions & 10 deletions src/Fable.Transforms/Rust/Fable2Rust.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1469,6 +1469,14 @@ module Util =
// transformIdent com ctx None id
// | _ -> com.TransformExpr(ctx, expr)

let isTempLocal (ident: Fable.Ident) =
ident.IsCompilerGenerated
&& (ident.Name = "copyOfStruct" || ident.Name = "inputRecord")

// let isMutableOrByRef (ident: Fable.Ident) =
// (ident.IsMutable || isByRefType ident)
// && not (isTempLocal ident)

let transformIdentGet com ctx r (ident: Fable.Ident) =
let expr = transformIdent com ctx r ident

Expand All @@ -1487,16 +1495,22 @@ module Util =
mutableSet expr value

let transformIdentType com ctx isCaptured (ident: Fable.Ident) =
let ty = transformType com ctx ident.Type

if isByRefType com ident.Type then
ty // already wrapped
elif ident.IsMutable && isCaptured then
ty |> makeMutTy com ctx |> makeLrcPtrTy com ctx
elif ident.IsMutable then
ty |> makeMutTy com ctx
else
ty
// let typ = Replacements.Util.getIdentValueType com ident ident.Type
match ident.Type with
| Replacements.Util.IsByRefType com typ when isTempLocal ident ->
// transform temporary local byref type to a reference type
transformType com ctx typ |> mkRefTy None
| _ ->
let ty = transformType com ctx ident.Type

if isByRefType com ident.Type then
ty // already wrapped
elif ident.IsMutable && isCaptured then
ty |> makeMutTy com ctx |> makeLrcPtrTy com ctx
elif ident.IsMutable then
ty |> makeMutTy com ctx
else
ty

let getField r (expr: Rust.Expr) (fieldName: string) =
mkFieldExpr expr (fieldName |> sanitizeMember) // ?loc=r)
Expand Down
12 changes: 10 additions & 2 deletions tests/Rust/tests/src/RecordTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -126,14 +126,22 @@ let processStructByValue (s: StructRecord) =

[<Fact>]
let ``Struct record works`` () =
let r1 = { i=1; s="hello" }
let r2 = { i=1; s="world" }
let r1 = { i = 1; s = "hello" }
let r2 = { i = 1; s = "world" }
let (sres1, ires1) = r1 |> processStructByValue
let (sres2, ires2) = r1 |> processStructByValue
let (sres3, ires3) = r2 |> processStructByValue //cannot actually test this, but since this is the only reference, the output should not .clone()
ires2 |> equal 2
sres3.s |> equal "world"

[<Fact>]
let ``Struct record temp locals work`` () =
let r1 = { i = 1; s = "hello" }
let r2 = { i = 2; s = "world" }
let r3 = { r1 with i = r2.i ; s = r2.s }
r3.i |> equal 2
r3.s |> equal "world"

type MutableRecord = {
mutable MutValue: int
}
Expand Down
Loading