@@ -842,11 +842,13 @@ defmodule Module.Types.Descr do
842
842
# `{list_type, last_type}`.
843
843
#
844
844
# We compute if it is a proper or improper list based if the last_type
845
- # is an empty_list() or a list(). In particular, the last_type is not
846
- # pruned to remove the empty_list() or list(), and therefore it may
847
- # contain the list itself. This is ok because operations like `tl`
848
- # effectively return the list itself plus the union of the tail (and
849
- # if the tail includes the list itself, they are equivalent).
845
+ # is an empty_list() or a list(). In particular, the last_type may be
846
+ # stored as `:term` for optimization purposes. This is ok because operations
847
+ # like `tl` effectively return the list itself plus the union of the tail
848
+ # (and if the tail includes the list itself, they are equivalent). And,
849
+ # for other operations like difference, we expand the tail_type back into
850
+ # `not non_empty_list()` via `list_tail_unfold/1`. Overall, this simplifies
851
+ # the code because we don't need to special case `not non_empty_list()`.
850
852
#
851
853
# none() types can be given and, while stored, it means the list type is empty.
852
854
defp list_descr ( list_type , last_type , empty? ) do
@@ -855,7 +857,7 @@ defmodule Module.Types.Descr do
855
857
856
858
list_part =
857
859
if last_type == :term do
858
- list_new ( term ( ) , term ( ) )
860
+ list_new ( : term, : term)
859
861
else
860
862
case :maps . take ( :list , last_type ) do
861
863
:error ->
@@ -938,16 +940,16 @@ defmodule Module.Types.Descr do
938
940
Enum . flat_map ( acc_dnf1 , fn { t1 , last1 , negs1 } ->
939
941
last1 = list_tail_unfold ( last1 )
940
942
941
- i = intersection ( t1 , t2 )
942
- l = intersection ( last1 , last2 )
943
-
944
943
new_negs =
945
944
Enum . reduce ( negs2 , [ ] , fn { nt , nlast } , nacc ->
946
945
t = intersection ( t1 , nt )
947
946
last = intersection ( last1 , nlast )
948
947
if empty? ( t ) or empty? ( last ) , do: nacc , else: [ { t , last , negs1 } | nacc ]
949
948
end )
950
949
950
+ i = intersection ( t1 , t2 )
951
+ l = intersection ( last1 , last2 )
952
+
951
953
cond do
952
954
empty? ( i ) or empty? ( l ) -> [ { t1 , last1 , negs1 } ]
953
955
subtype? ( t1 , t2 ) and subtype? ( last1 , last2 ) -> new_negs
0 commit comments