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 cc5cb76 commit 9567146
Showing 1 changed file with 17 additions and 17 deletions.
34 changes: 17 additions & 17 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))
&& isNull (Attribute.GetCustomAttribute(ty, typeof<NoComparisonAttribute>))
&& isNull (Attribute.GetCustomAttribute(ty, typeof<StructuralComparisonAttribute>))
&& not (ty.IsArray) then

// 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
let normalCmp =
not (typeof<IStructuralComparable>.IsAssignableFrom(ty))
&& isNull (Attribute.GetCustomAttribute(ty, typeof<NoComparisonAttribute>))
&& isNull (Attribute.GetCustomAttribute(ty, typeof<StructuralComparisonAttribute>))
&& 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) && normalCmp 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 9567146

Please sign in to comment.