@@ -1862,7 +1862,7 @@ defmodule Module.Types.Descr do
18621862 if map_empty_negation? ( tag , acc_fields , neg ) do
18631863 { acc_fields , acc_negs }
18641864 else
1865- case map_all_but_one? ( tag , acc_fields , neg_tag , neg_fields ) do
1865+ case map_all_but_one ( tag , acc_fields , neg_tag , neg_fields ) do
18661866 { :one , diff_key } ->
18671867 { Map . update! ( acc_fields , diff_key , & difference ( & 1 , neg_fields [ diff_key ] ) ) ,
18681868 acc_negs }
@@ -1913,19 +1913,20 @@ defmodule Module.Types.Descr do
19131913 end
19141914
19151915 # If all fields are the same except one, we can optimize map difference.
1916- defp map_all_but_one? ( tag1 , fields1 , tag2 , fields2 ) do
1917- keys1 = Map . keys ( fields1 )
1918- keys2 = Map . keys ( fields2 )
1919-
1920- if { tag1 , tag2 } == { :open , :closed } or
1921- :sets . from_list ( keys1 , version: 2 ) != :sets . from_list ( keys2 , version: 2 ) do
1922- :no
1916+ defp map_all_but_one ( tag1 , fields1 , tag2 , fields2 ) do
1917+ with true <- { tag1 , tag2 } != { :open , :closed } ,
1918+ true <- map_size ( fields1 ) == map_size ( fields2 ) ,
1919+ keys = :maps . keys ( fields1 ) ,
1920+ true <- Enum . all? ( keys , fn key -> is_map_key ( fields2 , key ) end ) ,
1921+ 1 <-
1922+ Enum . count_until (
1923+ keys ,
1924+ fn key -> Map . fetch! ( fields1 , key ) != Map . fetch! ( fields2 , key ) end ,
1925+ _limit = 2
1926+ ) do
1927+ { :one , Enum . find ( keys , & ( Map . fetch! ( fields1 , & 1 ) != Map . fetch! ( fields2 , & 1 ) ) ) }
19231928 else
1924- Enum . count ( keys1 , fn key -> Map . get ( fields1 , key ) != Map . get ( fields2 , key ) end )
1925- |> case do
1926- 1 -> { :one , Enum . find ( keys1 , & ( Map . get ( fields1 , & 1 ) != Map . get ( fields2 , & 1 ) ) ) }
1927- _ -> :no
1928- end
1929+ _ -> :no
19291930 end
19301931 end
19311932
0 commit comments