Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
1 change: 1 addition & 0 deletions docs/release-notes/.FSharp.Compiler.Service/8.0.300.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
* Obsolete attribute is ignored in constructor property assignment ([PR #16900](https://github.com/dotnet/fsharp/pull/16900))
* Completion: fix completion in empty dot lambda prefix ([#16829](https://github.com/dotnet/fsharp/pull/16829))
* Fix StackOverflow when checking non-recursive bindings in module or namespace in `fscAnyCpu`/`fsiAnyCpu`. ([PR #16908](https://github.com/dotnet/fsharp/pull/16908))
* Fix calling an overridden virtual static method via the interface ([PR #17013](https://github.com/dotnet/fsharp/pull/17013))

### Added

Expand Down
4 changes: 2 additions & 2 deletions src/Compiler/Checking/MethodCalls.fs
Original file line number Diff line number Diff line change
Expand Up @@ -906,8 +906,8 @@ let IsBaseCall objArgs =
/// For example, when calling an interface method on a struct, or a method on a constrained
/// variable type.
let ComputeConstrainedCallInfo g amap m staticTyOpt args (minfo: MethInfo) =
match args, staticTyOpt with
| _, Some staticTy when not minfo.IsExtensionMember && not minfo.IsInstance && minfo.IsAbstract -> Some staticTy
match args, staticTyOpt with
| _, Some staticTy when not minfo.IsExtensionMember && not minfo.IsInstance && (minfo.IsAbstract || minfo.IsVirtual) -> Some staticTy

| (objArgExpr :: _), _ when minfo.IsInstance && not minfo.IsExtensionMember ->
let methObjTy = minfo.ApparentEnclosingType
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,36 @@ module Test =
#endif
]

[<FactForNETCOREAPP>]
let ``F# can call overwritten static virtual member from interface``() =
let CSharpLib =
CSharp """
namespace Test;

public interface I
{
static virtual string Echo(string x) => x;
}
"""
|> withCSharpLanguageVersion CSharpLanguageVersion.CSharp11
|> withName "CsLibAssembly"

FSharp """
type Imp() =
interface Test.I with
static member Echo (x: string) = x + "_imp"

let echo<'T when 'T :> Test.I> x = 'T.Echo(x)

if echo<Imp> "a" <> "a_imp" then
failwith "incorrect value"
"""
|> withReferences [CSharpLib]
|> withLangVersion80
|> asExe
|> compileAndRun
|> shouldSucceed

[<FactForNETCOREAPP>]
let ``C# can call constrained method defined in F#`` () =
let FSharpLib =
Expand Down
26 changes: 13 additions & 13 deletions tests/FSharp.Compiler.ComponentTests/Language/InterfaceTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ open Xunit
open FSharp.Test.Compiler

[<Fact>]
let ``Concrete instance method is not allowed in interfaces in lang preview``() =
FSharp $"""
let ``Concrete instance method is not allowed in interfaces in lang version80``() =
FSharp """
[<Interface>]
type I =
member _.X () = 1
Expand All @@ -18,8 +18,8 @@ type I =
]

[<Fact>]
let ``Concrete instance property is not allowed in interfaces in lang preview``() =
FSharp $"""
let ``Concrete instance property is not allowed in interfaces in lang version80``() =
FSharp """
[<Interface>]
type I =
member _.Prop = "x"
Expand All @@ -32,8 +32,8 @@ type I =
]

[<Fact>]
let ``Concrete static members are allowed in interfaces in lang preview``() =
FSharp $"""
let ``Concrete static members are allowed in interfaces in lang version80``() =
FSharp """
[<Interface>]
type I<'T> =
static member Echo (x: 'T) = x
Expand All @@ -49,7 +49,7 @@ if I<int>.Echo 42 <> 42 || I<int>.Prop <> 0 || not (isNull I<string>.Prop) then

[<Fact>]
let ``Concrete static members are not allowed in interfaces in lang version70``() =
FSharp $"""
FSharp """
[<Interface>]
type I<'T> =
static member Echo (x: 'T) = x
Expand All @@ -63,8 +63,8 @@ type I<'T> =
]

[<Fact>]
let ``Concrete static members are allowed in interfaces as intrinsics in lang preview``() =
FSharp $"""
let ``Concrete static members are allowed in interfaces as intrinsics in lang version80``() =
FSharp """
[<Interface>]
type I<'T> =
static member Prop = Unchecked.defaultof<'T>
Expand All @@ -81,8 +81,8 @@ if I<int>.Echo 42 <> 42 || I<int>.Prop <> 0 || not (isNull I<string>.Prop) then


[<Fact>]
let ``Interface with concrete static members can be implemented in lang preview``() =
FSharp $"""
let ``Interface with concrete static members can be implemented in lang version80``() =
FSharp """
[<Interface>]
type I =
static member Echo (x: string) = x
Expand All @@ -92,12 +92,12 @@ type Imp () =
interface I with
member _.Blah = 3

let o = {{ new I with member _.Blah = 4 }}
let o = { new I with member _.Blah = 4 }

if I.Echo "yup" <> "yup" || (Imp() :> I).Blah <> 3 || o.Blah <> 4 then
failwith "failed"
"""
|> withLangVersion80
|> asExe
|> compileAndRun
|> shouldSucceed
|> shouldSucceed