@@ -842,11 +842,13 @@ defmodule Module.Types.Descr do
842842 # `{list_type, last_type}`.
843843 #
844844 # 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()`.
850852 #
851853 # none() types can be given and, while stored, it means the list type is empty.
852854 defp list_descr ( list_type , last_type , empty? ) do
@@ -855,7 +857,7 @@ defmodule Module.Types.Descr do
855857
856858 list_part =
857859 if last_type == :term do
858- list_new ( term ( ) , term ( ) )
860+ list_new ( : term, : term)
859861 else
860862 case :maps . take ( :list , last_type ) do
861863 :error ->
@@ -938,16 +940,16 @@ defmodule Module.Types.Descr do
938940 Enum . flat_map ( acc_dnf1 , fn { t1 , last1 , negs1 } ->
939941 last1 = list_tail_unfold ( last1 )
940942
941- i = intersection ( t1 , t2 )
942- l = intersection ( last1 , last2 )
943-
944943 new_negs =
945944 Enum . reduce ( negs2 , [ ] , fn { nt , nlast } , nacc ->
946945 t = intersection ( t1 , nt )
947946 last = intersection ( last1 , nlast )
948947 if empty? ( t ) or empty? ( last ) , do: nacc , else: [ { t , last , negs1 } | nacc ]
949948 end )
950949
950+ i = intersection ( t1 , t2 )
951+ l = intersection ( last1 , last2 )
952+
951953 cond do
952954 empty? ( i ) or empty? ( l ) -> [ { t1 , last1 , negs1 } ]
953955 subtype? ( t1 , t2 ) and subtype? ( last1 , last2 ) -> new_negs
0 commit comments