Skip to content

Commit d984cc9

Browse files
committed
1 parent 8f7ab69 commit d984cc9

File tree

7 files changed

+84
-23
lines changed

7 files changed

+84
-23
lines changed

src/Fable.Cli/CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## Unreleased
99

10+
### Fixed
11+
12+
* [All] Fixed passing delegates with unit args (#3862) (by @ncave)
13+
1014
## 4.19.3 - 2024-06-17
1115

1216
### Fixed

src/Fable.Transforms/FSharp2Fable.Util.fs

+17-16
Original file line numberDiff line numberDiff line change
@@ -762,8 +762,8 @@ module Helpers =
762762
atts
763763
|> Seq.tryPick (fun att ->
764764
match (nonAbbreviatedDefinition att.AttributeType).TryFullName with
765-
| Some fullName' ->
766-
if fullName = fullName' then
765+
| Some fullName2 ->
766+
if fullName = fullName2 then
767767
Some att
768768
else
769769
None
@@ -932,13 +932,13 @@ module Helpers =
932932
}
933933

934934
/// Test if the name corresponds to this interface or anyone in its hierarchy
935-
let rec testInterfaceHierarchy interfaceFullname interfaceType =
935+
let rec testInterfaceHierarchy interfaceFullName interfaceType =
936936
match tryDefinition interfaceType with
937-
| Some(e, Some fullname2) ->
938-
if interfaceFullname = fullname2 then
937+
| Some(e, Some fullName) ->
938+
if interfaceFullName = fullName then
939939
true
940940
else
941-
e.DeclaredInterfaces |> Seq.exists (testInterfaceHierarchy interfaceFullname)
941+
e.DeclaredInterfaces |> Seq.exists (testInterfaceHierarchy interfaceFullName)
942942
| _ -> false
943943

944944
let hasParamArray (memb: FSharpMemberOrFunctionOrValue) =
@@ -1111,7 +1111,7 @@ module Patterns =
11111111
| Let((_, value, _), // Coercion to seq
11121112
Let((_, Call(None, meth, _, [], []), _), TryFinally(WhileLoop(_, Let((ident, _, _), body), _), _, _, _)))
11131113
| Let((_, Call(Some value, meth, _, [], []), _), TryFinally(WhileLoop(_, Let((ident, _, _), body), _), _, _, _)) when
1114-
// Using only the compiled name is riskier but with the fullname we miss some cases
1114+
// Using only the compiled name is riskier but with the fullName we miss some cases
11151115
// TODO: Check the return type of meth is or implements IEnumerator
11161116
meth.CompiledName = "GetEnumerator"
11171117
->
@@ -1432,11 +1432,11 @@ module TypeHelpers =
14321432
let private getMeasureFullName (genArgs: IList<FSharpType>) =
14331433
if genArgs.Count > 0 then
14341434
// TODO: Check it's effectively measure?
1435-
// TODO: Raise error if we cannot get the measure fullname?
1435+
// TODO: Raise error if we cannot get the measure fullName?
14361436
match tryDefinition genArgs[0] with
1437-
| Some(_, Some fullname) ->
1437+
| Some(_, Some fullName) ->
14381438
// Not sure why, but when precompiling F# changes measure types to MeasureProduct<'M, MeasureOne>
1439-
match fullname with
1439+
match fullName with
14401440
| Types.measureProduct2 ->
14411441
match
14421442
(nonAbbreviatedType genArgs[0]).GenericArguments
@@ -1445,8 +1445,8 @@ module TypeHelpers =
14451445
with
14461446
// TODO: generalize it to support aggregate units such as <m/s> or more complex
14471447
| [ Some measure; Some Types.measureOne ] -> measure
1448-
| _ -> fullname
1449-
| _ -> fullname
1448+
| _ -> fullName
1449+
| _ -> fullName
14501450
| _ -> Naming.unknown
14511451
else
14521452
Naming.unknown
@@ -2289,7 +2289,7 @@ module Util =
22892289
| _ -> not (isGlobalOrImportedFSharpEntity ent || isAttachMembersEntity com ent)
22902290

22912291
let getMangledAbstractMemberName (ent: FSharpEntity) memberName overloadHash =
2292-
// TODO: Error if entity doesn't have fullname?
2292+
// TODO: Error if entity doesn't have fullName?
22932293
let entityName = defaultArg ent.TryFullName ""
22942294
entityName + "." + memberName + overloadHash
22952295

@@ -2756,11 +2756,12 @@ module Util =
27562756

27572757
| _ ->
27582758
// If member looks like a value but behaves like a function (has generic args) the type from F# AST is wrong (#2045).
2759-
let typ = makeType ctx.GenericArgs memb.ReturnParameter.Type
2759+
let typ = makeType ctx.GenericArgs memb.FullType
2760+
let retTyp = makeType ctx.GenericArgs memb.ReturnParameter.Type
27602761

27612762
let callExpr =
2762-
memberIdent com r Fable.Any memb membRef
2763-
|> makeCall r typ { callInfo with Tags = "value" :: callInfo.Tags }
2763+
memberIdent com r typ memb membRef
2764+
|> makeCall r retTyp { callInfo with Tags = "value" :: callInfo.Tags }
27642765

27652766
let fableMember = FsMemberFunctionOrValue(memb)
27662767
// TODO: Move plugin application to FableTransforms

src/Fable.Transforms/FSharp2Fable.fs

+6-5
Original file line numberDiff line numberDiff line change
@@ -471,10 +471,11 @@ let private transformDelegate com ctx (delegateType: FSharpType) expr =
471471
// applies a unit arg to the expression, see #2400
472472
let expr =
473473
match tryDefinition delegateType with
474-
| Some(_, Some "System.Func`1") ->
474+
| Some(_, Some _fullName) ->
475475
match expr with
476-
| Fable.CurriedApply(expr, [ Fable.Value(Fable.UnitConstant, _) ], _, _) -> expr
477-
| Fable.Call(expr, { Args = [ Fable.Value(Fable.UnitConstant, _) ] }, _, _) -> expr
476+
| Fable.CurriedApply(expr2, [ Fable.Value(Fable.UnitConstant, _) ], _, _) -> expr2
477+
| Fable.Call(expr2, { Args = [ Fable.Value(Fable.UnitConstant, _) ] }, _, _) -> // expr2
478+
Fable.Delegate([], expr, None, Fable.Tags.empty)
478479
| _ -> expr
479480
| _ -> expr
480481

@@ -2103,8 +2104,8 @@ let getRootModule (declarations: FSharpImplementationFileDeclaration list) =
21032104
let resolveFieldType (ctx: Context) (entityType: FSharpType) (fieldType: FSharpType) =
21042105
let entityGenArgs =
21052106
match tryDefinition entityType with
2106-
| Some(def, _) when def.GenericParameters.Count = entityType.GenericArguments.Count ->
2107-
Seq.zip def.GenericParameters entityType.GenericArguments
2107+
| Some(tdef, _) when tdef.GenericParameters.Count = entityType.GenericArguments.Count ->
2108+
Seq.zip tdef.GenericParameters entityType.GenericArguments
21082109
|> Seq.map (fun (p, a) -> genParamName p, makeType Map.empty a)
21092110
|> Map
21102111
| _ -> Map.empty

src/fable-library-rust/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ num-integer = { version = "0.1", optional = true }
2626
num-traits = { version = "0.2", optional = true }
2727
rust_decimal = { version = "1.35", features = ["maths"], default-features = false, optional = true }
2828
futures = { version = "0.3", features = ["executor", "thread-pool"], optional = true }
29-
uuid = { version = "1.8", features = ["v4"], default-features = false, optional = true }
29+
uuid = { version = "1.10", features = ["v4"], default-features = false, optional = true }
3030
chrono = { version = "0.4", optional = true }
3131
regex = { version = "1.10", optional = true }
3232

tests/Js/Main/MiscTests.fs

+18
Original file line numberDiff line numberDiff line change
@@ -481,9 +481,27 @@ let inline inlineToString (f: 'T -> string): 'T -> string =
481481
let unused = f
482482
fun a -> $"{a}"
483483

484+
type MyIntDelegate = delegate of unit -> int
485+
486+
let get42 () = 42
487+
488+
let dtest1 (f: MyIntDelegate -> int) =
489+
f get42
490+
491+
let dtest2 (f: MyIntDelegate -> int) =
492+
let get43 () = 43
493+
f get43
494+
495+
let dInvoke (d: MyIntDelegate) =
496+
d.Invoke ()
497+
484498
let tests =
485499
testList "Miscellaneous" [
486500

501+
testCase "Passing delegate works" <| fun _ -> // #3862
502+
dtest1 dInvoke |> equal 42
503+
dtest2 dInvoke |> equal 43
504+
487505
testCase "Generic unit args work" <| fun _ -> // #3584
488506
let to_str = inlineToString (fun (props: unit) -> "s")
489507
to_str () |> equal $"{()}"

tests/Python/TestMisc.fs

+19-1
Original file line numberDiff line numberDiff line change
@@ -451,14 +451,32 @@ let inline inlineToString (f: 'T -> string): 'T -> string =
451451
let unused = f
452452
fun a -> $"{a}"
453453

454+
type MyIntDelegate = delegate of unit -> int
455+
456+
let get42 () = 42
457+
458+
let dtest1 (f: MyIntDelegate -> int) =
459+
f get42
460+
461+
let dtest2 (f: MyIntDelegate -> int) =
462+
let get43 () = 43
463+
f get43
464+
465+
let dInvoke (d: MyIntDelegate) =
466+
d.Invoke ()
467+
454468
type Union_TestUnionTag = Union_TestUnionTag of int
455469

456470
[<AttachMembers>]
457471
type FooWithAttachedMembers () =
458472
member x.Bar = 42
459-
460473
static member Foo = FooWithAttachedMembers()
461474

475+
[<Fact>]
476+
let ``test Passing delegate works`` () = // #3862
477+
dtest1 dInvoke |> equal 42
478+
dtest2 dInvoke |> equal 43
479+
462480
[<Fact>]
463481
let ``test Generic unit args work`` () = // #3584
464482
let to_str = inlineToString (fun (props: unit) -> "s")

tests/Rust/tests/src/MiscTests.fs

+19
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,25 @@ let inline inlineToString (f: 'T -> string): 'T -> string =
506506
let unused = f
507507
fun a -> sprintf "%A" a
508508

509+
type MyIntDelegate = delegate of unit -> int
510+
511+
let get42 () = 42
512+
513+
let dtest1 (f: MyIntDelegate -> int) =
514+
f get42
515+
516+
let dtest2 (f: MyIntDelegate -> int) =
517+
let get43 () = 43
518+
f get43
519+
520+
let dInvoke (d: MyIntDelegate) =
521+
d.Invoke ()
522+
523+
[<Fact>]
524+
let ``Passing delegate works`` () = // #3862
525+
dtest1 dInvoke |> equal 42
526+
dtest2 dInvoke |> equal 43
527+
509528
[<Fact>]
510529
let ``Generic unit args work`` () = // #3584
511530
let to_str = inlineToString (fun (props: unit) -> "s")

0 commit comments

Comments
 (0)