Skip to content

Commit

Permalink
Small cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
TIHan committed Jul 29, 2019
1 parent 246e82f commit cc4c9b1
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 16 deletions.
18 changes: 9 additions & 9 deletions src/fsharp/InfoReader.fs
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ type InfoReader(g: TcGlobals, amap: Import.ImportMap) as this =
ty
None

let GetIntrinsicTopInterfaceOverriderMethodSetsUncached ((optFilter, ad, allowMultiIntfInst), m, ty) =
let GetIntrinsicTopInterfaceOverrideMethodSetsUncached ((optFilter, ad, allowMultiIntfInst), m, ty) =

let checkMethod (minfo: MethInfo) (ilMethRef: ILMethodRef) =
minfo.IsFinal &&
Expand All @@ -366,7 +366,7 @@ type InfoReader(g: TcGlobals, amap: Import.ImportMap) as this =
match tryAppTy g ty with
| ValueSome (tcref, _) when tcref.IsILTycon ->
// MethodImpls contains a list of methods that override.
// OverrideBy (overrider) is the method that does the overriding.
// OverrideBy is the method that does the overriding.
// Overrides is the method being overriden.
// Find the Overrides method first with optFilter, then search for the OverrideBy method.
// If the OverrideBy method is found, add it to the method set for that type in the hierarchy.
Expand Down Expand Up @@ -480,7 +480,7 @@ type InfoReader(g: TcGlobals, amap: Import.ImportMap) as this =
let ilFieldInfoCache = MakeInfoCache GetIntrinsicILFieldInfosUncached hashFlags1
let eventInfoCache = MakeInfoCache GetIntrinsicEventInfosUncached hashFlags1
let namedItemsCache = MakeInfoCache GetIntrinsicNamedItemsUncached hashFlags2
let topInterfaceOverriderMethodInfoCache = MakeInfoCache GetIntrinsicTopInterfaceOverriderMethodSetsUncached hashFlags0
let topInterfaceOverrideMethodInfoCache = MakeInfoCache GetIntrinsicTopInterfaceOverrideMethodSetsUncached hashFlags0

let entireTypeHierarchyCache = MakeInfoCache GetEntireTypeHierachyUncached HashIdentity.Structural
let primaryTypeHierarchyCache = MakeInfoCache GetPrimaryTypeHierachyUncached HashIdentity.Structural
Expand Down Expand Up @@ -532,9 +532,9 @@ type InfoReader(g: TcGlobals, amap: Import.ImportMap) as this =
member x.TryFindNamedItemOfType (nm, ad, m, ty) =
namedItemsCache.Apply(((nm, ad), m, ty))

/// Read the raw interface method sets of a type that is a topmost overrider. Cache the result for monomorphic types
member x.GetIntrinsicTopInterfaceOverriderMethodSetsOfType (optFilter, ad, allowMultiIntfInst, m, ty) =
topInterfaceOverriderMethodInfoCache.Apply(((optFilter, ad, allowMultiIntfInst), m, ty))
/// Read the raw interface method sets of a type that is a topmost overrides. Cache the result for monomorphic types
member x.GetIntrinsicTopInterfaceOverrideMethodSetsOfType (optFilter, ad, allowMultiIntfInst, m, ty) =
topInterfaceOverrideMethodInfoCache.Apply(((optFilter, ad, allowMultiIntfInst), m, ty))

/// Get the super-types of a type, including interface types.
member x.GetEntireTypeHierachy (allowMultiIntfInst, m, ty) =
Expand Down Expand Up @@ -805,10 +805,10 @@ let TryFindIntrinsicMethInfo infoReader m ad nm ty =
let TryFindPropInfo infoReader m ad nm ty =
GetIntrinsicPropInfosOfType infoReader (Some nm) ad AllowMultiIntfInstantiations.Yes IgnoreOverrides m ty

/// Get a collection of topmost interface overrider methods.
/// Get a collection of topmost interface override methods.
/// When providing a method name, it is the name of method that is being overriden.
let GetIntrinisicTopInterfaceOverriderMethInfoSetsOfType (infoReader: InfoReader) (nm, ad) m ty =
infoReader.GetIntrinsicTopInterfaceOverriderMethodSetsOfType (nm, ad, AllowMultiIntfInstantiations.Yes, m, ty)
let GetIntrinisicTopInterfaceOverrideMethInfoSetsOfType (infoReader: InfoReader) (nm, ad) m ty =
infoReader.GetIntrinsicTopInterfaceOverrideMethodSetsOfType (nm, ad, AllowMultiIntfInstantiations.Yes, m, ty)

//-------------------------------------------------------------------------
// Helpers related to delegates and events - these use method searching hence are in this file
Expand Down
15 changes: 8 additions & 7 deletions src/fsharp/MethodOverrides.fs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ type RequiredSlotFlags =
| IsOptional = 0x001

/// A slot which has a default interface implementation.
/// A combination of this flag and the lack of IsOptional means the slot may have been reabstracted.
| HasDefaultInterfaceImplementation = 0x010

/// A slot that *might* have ambiguity due to multiple inheritance; happens with default interface implementations.
Expand Down Expand Up @@ -470,11 +471,11 @@ module DispatchSlotChecking =
let amap = infoReader.amap

if isInterfaceTy g interfaceTy then
// This is to find overrider methods that are at the topmost hierarchy out of the interfaces.
let rec getTopOverriderMethods (minfo: MethInfo) =
// This is to find override methods that are at the topmost hierarchy out of the interfaces.
let rec getTopOverrideMethods (minfo: MethInfo) =
topInterfaceTys
|> List.map (fun (ty, _) ->
GetIntrinisicTopInterfaceOverriderMethInfoSetsOfType infoReader (Some minfo.LogicalName, AccessibleFromSomewhere) m ty
GetIntrinisicTopInterfaceOverrideMethInfoSetsOfType infoReader (Some minfo.LogicalName, AccessibleFromSomewhere) m ty
|> List.concat
|> List.filter (fun minfo2 ->
let overrideBy = GetInheritedMemberOverrideInfo g amap m OverrideCanImplement.CanImplementAnyInterfaceSlot minfo2
Expand Down Expand Up @@ -517,14 +518,14 @@ module DispatchSlotChecking =
// IL methods might have default implementations.
else
let dispatchFlags =
match getTopOverriderMethods minfo with
// no overrides, then get default flags
match getTopOverrideMethods minfo with
// No override, then get default flags.
| [] -> GetDefaultDispatchSlotFlags minfo

// one overrider, get its default flags
// One override, get its default flags.
| [ minfo2 ] -> GetDefaultDispatchSlotFlags minfo2

// we found multiple overrider methods, means we might have ambiguity
// We found multiple override methods, means we might have ambiguity.
| _ -> RequiredSlotFlags.PossiblyNoMostSpecificImplementation

yield RequiredSlot (minfo, checkDispatchFlags dispatchFlags) ]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4495,6 +4495,107 @@ let test =
}
])

[<Test>]
let ``C# diamond inheritance with no most specific problem - Runs`` () =
let csharpSource =
"""
using System;
namespace CSharpTest
{
public interface IA
{
void M()
{
}
}
public interface IB : IA
{
void IA.M()
{
Console.Write("IB.IA.M");
}
}
public interface IC : IA
{
}
}
"""

let fsharpSource =
"""
open CSharpTest
open System
type Test () =
interface IA
interface IC
interface IB
[<EntryPoint>]
let main _ =
let test = Test () :> IC
test.M();
0
"""

let c = CompilationUtil.CreateCSharpCompilation (csharpSource, RoslynLanguageVersion.CSharp8, TargetFramework.NetCoreApp30)
CompilerAssert.CompileExeAndRun (fsharpSource, c, "IB.IA.M")

[<Test>]
let ``C# diamond inheritance with no most specific problem - Runs - 2`` () =
let csharpSource =
"""
using System;
namespace CSharpTest
{
public interface IA
{
void M()
{
}
}
public interface IB : IA
{
void IA.M()
{
Console.Write("IB.IA.M");
}
}
public interface IC : IA
{
}
}
"""

let fsharpSource =
"""
open CSharpTest
open System
type Test () =
interface IC
interface IB
[<EntryPoint>]
let main _ =
let test = Test () :> IC
test.M();
0
"""

let c = CompilationUtil.CreateCSharpCompilation (csharpSource, RoslynLanguageVersion.CSharp8, TargetFramework.NetCoreApp30)
CompilerAssert.CompileExeAndRun (fsharpSource, c, "IB.IA.M")

#else

[<TestFixture>]
Expand Down

0 comments on commit cc4c9b1

Please sign in to comment.