diff --git a/src/fsharp/FSharp.Core/map.fs b/src/fsharp/FSharp.Core/map.fs index 05f56b54688..f05e218184a 100644 --- a/src/fsharp/FSharp.Core/map.fs +++ b/src/fsharp/FSharp.Core/map.fs @@ -2,6 +2,7 @@ namespace Microsoft.FSharp.Collections open System +open System.Collections open System.Collections.Generic open System.Diagnostics open System.Numerics @@ -39,22 +40,29 @@ module MapTree = static member private CompareCG<'U when 'U :> IComparable<'U>>(l:'U, r:'U):int = l.CompareTo(r) // A call to IComparable.CompareTo -// static member private CompareC<'U when 'U :> IComparable>(l:'U, r:'U):int = l.CompareTo(r) + static member private CompareC<'U when 'U :> IComparable>(l:'U, r:'U):int = l.CompareTo(r) static member val CompareToDlg : Func<'T,'T,int> = let dlg = - try - // See #816, IComparable<'T> actually does not satisfy comparison constraint, but it should be preferred - if typeof>.IsAssignableFrom(typeof<'T>) then - let m = - typeof>.GetMethod("CompareCG", BindingFlags.NonPublic ||| BindingFlags.Static) - .MakeGenericMethod([|typeof<'T>|]) - Delegate.CreateDelegate(typeof>, m) :?> Func<'T,'T,int> -// elif typeof.IsAssignableFrom(typeof<'T>) then -// let m = -// typeof>.GetMethod("CompareC", BindingFlags.NonPublic ||| BindingFlags.Static) -// .MakeGenericMethod([|typeof<'T>|]) -// Delegate.CreateDelegate(typeof>, m) :?> Func<'T,'T,int> + let ty = typeof<'T> + try + if not (typeof.IsAssignableFrom(ty)) + && isNull (Attribute.GetCustomAttribute(ty, typeof)) + && isNull (Attribute.GetCustomAttribute(ty, typeof)) + && not (ty.IsArray) then + + // See #816, IComparable<'T> actually does not satisfy comparison constraint, but it should be preferred + if typeof>.IsAssignableFrom(ty) then + let m = + typeof>.GetMethod("CompareCG", BindingFlags.NonPublic ||| BindingFlags.Static) + .MakeGenericMethod([|ty|]) + Delegate.CreateDelegate(typeof>, m) :?> Func<'T,'T,int> + elif typeof.IsAssignableFrom(ty) then + let m = + typeof>.GetMethod("CompareC", BindingFlags.NonPublic ||| BindingFlags.Static) + .MakeGenericMethod([|typeof<'T>|]) + Delegate.CreateDelegate(typeof>, m) :?> Func<'T,'T,int> + else null else null with _ -> null dlg @@ -128,6 +136,7 @@ module MapTree = else if Type.op_Equality(typeof<'T>, typeof) then unbox(box(l)).CompareTo(unbox(box(r))) else if Type.op_Equality(typeof<'T>, typeof) then unbox(box(l)).CompareTo(unbox(box(r))) + else if Type.op_Equality(typeof<'T>, typeof) then unbox(box(l)).CompareTo(unbox(box(r))) else if Type.op_Equality(typeof<'T>, typeof) then // same as in GenericComparisonFast