Skip to content

Commit 2ab8a54

Browse files
committed
Improve docs around list handling
1 parent fc348d7 commit 2ab8a54

File tree

1 file changed

+11
-9
lines changed

1 file changed

+11
-9
lines changed

lib/elixir/lib/module/types/descr.ex

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)