Skip to content

Commit e4bc6ae

Browse files
T-GroCopilot
andcommitted
Add inverse conformance tests for unit param overload
- Consumer cannot call d.M() when impl is M(()) with overloads (FS0503 expected) - Consumer can call d.M() when impl is M() with sig M: unit -> unit Covers both directions of sig↔impl conformance with consumer validation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 03521b2 commit e4bc6ae

1 file changed

Lines changed: 81 additions & 0 deletions

File tree

tests/FSharp.Compiler.ComponentTests/Signatures/TypeTests.fs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,87 @@ type D() =
856856
member x.M(()) = ()
857857
"""
858858

859+
// Inverse direction 1: impl M(()) but consumer calls d.M() (no parens) — must fail with FS0503
860+
[<Fact>]
861+
let ``Unit param overload - consumer cannot call M() when impl is M(()) with overloads`` () =
862+
let sigSource = """
863+
module Lib
864+
865+
type R1 =
866+
{ f1: int }
867+
868+
type D =
869+
new: unit -> D
870+
member M: unit -> unit
871+
member M: y: R1 -> unit
872+
member N: unit
873+
"""
874+
let implSource = """
875+
module Lib
876+
type R1 = { f1 : int }
877+
type D() =
878+
member x.N = x.M { f1 = 3 }
879+
member x.M((y: R1)) = ()
880+
member x.M(()) = ()
881+
"""
882+
let consumerSource = """
883+
module Consumer
884+
open Lib
885+
let test() =
886+
let d = D()
887+
d.M()
888+
d.M { f1 = 42 }
889+
d.N
890+
"""
891+
Fsi sigSource
892+
|> withAdditionalSourceFile (FsSourceWithFileName "Lib.fs" implSource)
893+
|> withAdditionalSourceFile (FsSourceWithFileName "Consumer.fs" consumerSource)
894+
|> ignoreWarnings
895+
|> compile
896+
|> shouldFail
897+
|> withErrorCode 503
898+
|> ignore
899+
900+
// Inverse direction 2: impl M() (no explicit unit), sig M: unit -> unit, consumer calls d.M()
901+
[<Fact>]
902+
let ``Unit param overload - consumer calls M() with normal impl and sig`` () =
903+
let sigSource = """
904+
module Lib
905+
906+
type R1 =
907+
{ f1: int }
908+
909+
type D =
910+
new: unit -> D
911+
member M: unit -> unit
912+
member M: y: R1 -> unit
913+
member N: unit
914+
"""
915+
let implSource = """
916+
module Lib
917+
type R1 = { f1 : int }
918+
type D() =
919+
member x.N = x.M { f1 = 3 }
920+
member x.M((y: R1)) = ()
921+
member x.M() = ()
922+
"""
923+
let consumerSource = """
924+
module Consumer
925+
open Lib
926+
let test() =
927+
let d = D()
928+
d.M()
929+
d.M { f1 = 42 }
930+
d.N
931+
"""
932+
Fsi sigSource
933+
|> withAdditionalSourceFile (FsSourceWithFileName "Lib.fs" implSource)
934+
|> withAdditionalSourceFile (FsSourceWithFileName "Consumer.fs" consumerSource)
935+
|> ignoreWarnings
936+
|> compile
937+
|> shouldSucceed
938+
|> ignore
939+
859940
// Verify M(()) and M() produce identical IL method signatures
860941
[<Fact>]
861942
let ``Unit param - M(()) and M() produce same IL method signature`` () =

0 commit comments

Comments
 (0)