Skip to content

Commit

Permalink
Map: optimize comparer: IComparable<T> should always be used when ava…
Browse files Browse the repository at this point in the history
…ilable

It's unambiguous. If it does something different than other ways to compare then it's very weird.

F# records implement IComparable<T> that works as expected.
  • Loading branch information
buybackoff committed Jan 10, 2021
1 parent 0c9b3fe commit f509008
Showing 1 changed file with 14 additions and 14 deletions.
28 changes: 14 additions & 14 deletions src/fsharp/FSharp.Core/map.fs
Original file line number Diff line number Diff line change
Expand Up @@ -46,23 +46,23 @@ module MapTree =
let dlg =
let ty = typeof<'T>
try
if not (typeof<IStructuralComparable>.IsAssignableFrom(ty))
let specialCmp =
not (typeof<IStructuralComparable>.IsAssignableFrom(ty))
&& isNull (Attribute.GetCustomAttribute(ty, typeof<NoComparisonAttribute>))
&& isNull (Attribute.GetCustomAttribute(ty, typeof<StructuralComparisonAttribute>))
&& not (ty.IsArray) then
&& not (ty.IsArray)

// See #816, IComparable<'T> actually does not satisfy comparison constraint, but it should be preferred
if typeof<IComparable<'T>>.IsAssignableFrom(ty) then
let m =
typeof<CompareHelper<'T>>.GetMethod("CompareCG", BindingFlags.NonPublic ||| BindingFlags.Static)
.MakeGenericMethod([|ty|])
Delegate.CreateDelegate(typeof<Func<'T,'T,int>>, m) :?> Func<'T,'T,int>
elif typeof<IComparable>.IsAssignableFrom(ty) then
let m =
typeof<CompareHelper<'T>>.GetMethod("CompareC", BindingFlags.NonPublic ||| BindingFlags.Static)
.MakeGenericMethod([|typeof<'T>|])
Delegate.CreateDelegate(typeof<Func<'T,'T,int>>, m) :?> Func<'T,'T,int>
else null
// See #816, IComparable<'T> actually does not satisfy comparison constraint, but it should be preferred
if typeof<IComparable<'T>>.IsAssignableFrom(ty) then
let m =
typeof<CompareHelper<'T>>.GetMethod("CompareCG", BindingFlags.NonPublic ||| BindingFlags.Static)
.MakeGenericMethod([|ty|])
Delegate.CreateDelegate(typeof<Func<'T,'T,int>>, m) :?> Func<'T,'T,int>
elif typeof<IComparable>.IsAssignableFrom(ty) && not specialCmp then
let m =
typeof<CompareHelper<'T>>.GetMethod("CompareC", BindingFlags.NonPublic ||| BindingFlags.Static)
.MakeGenericMethod([|typeof<'T>|])
Delegate.CreateDelegate(typeof<Func<'T,'T,int>>, m) :?> Func<'T,'T,int>
else null
with _ -> null
dlg
Expand Down

0 comments on commit f509008

Please sign in to comment.