@@ -1283,32 +1283,41 @@ defmodule Module.Types.Descr do
12831283 # avoid the list to grow when possible
12841284
12851285 # first pass trying to identify patterns where two maps can be fused as one
1286- with [ { tag1 , pos1 , [ ] } ] <- dnf1 ,
1287- [ { tag2 , pos2 , [ ] } ] <- dnf2 ,
1288- strategy when strategy != nil <- map_union_optimization_strategy ( tag1 , pos1 , tag2 , pos2 ) do
1289- case strategy do
1290- :all_equal ->
1291- dnf1
1286+ with [ map1 ] <- dnf1 ,
1287+ [ map2 ] <- dnf2 ,
1288+ optimized when optimized != nil <- maybe_optimize_map_union ( map1 , map2 ) do
1289+ [ optimized ]
1290+ else
1291+ # otherwise we just concatenate and remove structural duplicates
1292+ _ -> dnf1 ++ ( dnf2 -- dnf1 )
1293+ end
1294+ end
12921295
1293- :any_map ->
1294- [ { :open , % { } , [ ] } ]
1296+ defp maybe_optimize_map_union ( { tag1 , pos1 , [ ] } = map1 , { tag2 , pos2 , [ ] } = map2 ) do
1297+ case map_union_optimization_strategy ( tag1 , pos1 , tag2 , pos2 ) do
1298+ :all_equal ->
1299+ map1
12951300
1296- { :one_key_difference , key , v1 , v2 } ->
1297- new_pos = Map . put ( pos1 , key , union ( v1 , v2 ) )
1298- [ { tag1 , new_pos , [ ] } ]
1301+ :any_map ->
1302+ { :open , % { } , [ ] }
12991303
1300- :left_subtype_of_right ->
1301- dnf2
1304+ { :one_key_difference , key , v1 , v2 } ->
1305+ new_pos = Map . put ( pos1 , key , union ( v1 , v2 ) )
1306+ { tag1 , new_pos , [ ] }
13021307
1303- :right_subtype_of_left ->
1304- dnf1
1305- end
1306- else
1307- # otherwise we just concatenate and remove structural duplicates
1308- _ -> dnf1 ++ ( dnf2 -- dnf1 )
1308+ :left_subtype_of_right ->
1309+ map2
1310+
1311+ :right_subtype_of_left ->
1312+ map1
1313+
1314+ nil ->
1315+ nil
13091316 end
13101317 end
13111318
1319+ defp maybe_optimize_map_union ( _ , _ ) , do: nil
1320+
13121321 defp map_union_optimization_strategy ( tag1 , pos1 , tag2 , pos2 )
13131322 defp map_union_optimization_strategy ( tag , pos , tag , pos ) , do: :all_equal
13141323 defp map_union_optimization_strategy ( :open , empty , _ , _ ) when empty == % { } , do: :any_map
0 commit comments