Skip to content

Commit 7e1aaac

Browse files
committed
Add more tests around list hd/tl
1 parent e54b87c commit 7e1aaac

File tree

2 files changed

+20
-28
lines changed

2 files changed

+20
-28
lines changed

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

Lines changed: 13 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -561,15 +561,6 @@ defmodule Module.Types.Descr do
561561
def number_type?(%{bitmap: bitmap}) when (bitmap &&& @bit_number) != 0, do: true
562562
def number_type?(_), do: false
563563

564-
@doc """
565-
Optimized version of `not empty?(intersection(list(), type))`.
566-
"""
567-
def list_type?(:term), do: true
568-
def list_type?(%{dynamic: :term}), do: true
569-
def list_type?(%{dynamic: %{list: _}}), do: true
570-
def list_type?(%{list: _}), do: true
571-
def list_type?(_), do: false
572-
573564
## Bitmaps
574565

575566
defp bitmap_to_quoted(val) do
@@ -917,7 +908,7 @@ defmodule Module.Types.Descr do
917908
end)
918909
end
919910

920-
defp list_only?(descr), do: subtype?(Map.delete(descr, :list), empty_list())
911+
defp non_empty_list_only?(descr), do: empty?(Map.delete(descr, :list))
921912

922913
@doc """
923914
Returns the head of a list.
@@ -931,22 +922,19 @@ defmodule Module.Types.Descr do
931922
def list_hd(%{} = descr) do
932923
case :maps.take(:dynamic, descr) do
933924
:error ->
934-
has_empty = empty_list_type?(descr)
935-
is_list_type = list_only?(descr)
925+
static_value = list_hd_static(descr)
936926

937-
if is_list_type and not has_empty do
938-
{false, list_hd_static(descr)}
927+
if non_empty_list_only?(descr) and not empty?(static_value) do
928+
{false, static_value}
939929
else
940930
:badnonemptylist
941931
end
942932

943933
{dynamic, static} ->
944-
has_empty = empty_list_type?(static)
945-
only_list = list_only?(static)
946-
is_dynamic_list = list_type?(dynamic)
934+
dynamic_value = list_hd_static(dynamic)
947935

948-
if is_dynamic_list and only_list and not has_empty do
949-
{is_dynamic_list, union(dynamic(list_hd_static(dynamic)), list_hd_static(static))}
936+
if non_empty_list_only?(static) and not empty?(dynamic_value) do
937+
{true, union(dynamic(dynamic_value), list_hd_static(static))}
950938
else
951939
:badnonemptylist
952940
end
@@ -981,22 +969,19 @@ defmodule Module.Types.Descr do
981969
def list_tl(descr) do
982970
case :maps.take(:dynamic, descr) do
983971
:error ->
984-
has_empty = empty_list_type?(descr)
985-
is_list_type = list_only?(descr)
972+
static_value = list_tl_static(descr)
986973

987-
if is_list_type and not has_empty do
988-
{false, list_tl_static(descr)}
974+
if non_empty_list_only?(descr) and not empty?(static_value) do
975+
{false, static_value}
989976
else
990977
:badnonemptylist
991978
end
992979

993980
{dynamic, static} ->
994-
has_empty = empty_list_type?(static)
995-
only_list = list_only?(static)
996-
is_dynamic_list = list_type?(dynamic)
981+
dynamic_value = list_tl_static(dynamic)
997982

998-
if is_dynamic_list and only_list and not has_empty do
999-
{is_dynamic_list, union(dynamic(list_tl_static(dynamic)), list_tl_static(static))}
983+
if non_empty_list_only?(static) and not empty?(dynamic_value) do
984+
{true, union(dynamic(dynamic_value), list_tl_static(static))}
1000985
else
1001986
:badnonemptylist
1002987
end

lib/elixir/test/elixir/module/types/descr_test.exs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,7 @@ defmodule Module.Types.DescrTest do
627627
end
628628

629629
test "list_hd" do
630+
assert list_hd(none()) == :badnonemptylist
630631
assert list_hd(term()) == :badnonemptylist
631632
assert list_hd(list(term())) == :badnonemptylist
632633
assert list_hd(empty_list()) == :badnonemptylist
@@ -639,6 +640,9 @@ defmodule Module.Types.DescrTest do
639640
assert list_hd(union(dynamic(), atom())) == :badnonemptylist
640641
assert list_hd(union(dynamic(), list(term()))) == :badnonemptylist
641642

643+
assert list_hd(difference(list(number()), list(number()))) == :badnonemptylist
644+
assert list_hd(dynamic(difference(list(number()), list(number())))) == :badnonemptylist
645+
642646
assert list_hd(union(dynamic(list(float())), non_empty_list(atom()))) ==
643647
{true, union(dynamic(float()), atom())}
644648

@@ -649,9 +653,12 @@ defmodule Module.Types.DescrTest do
649653
end
650654

651655
test "list_tl" do
656+
assert list_tl(none()) == :badnonemptylist
652657
assert list_tl(term()) == :badnonemptylist
653658
assert list_tl(empty_list()) == :badnonemptylist
654659
assert list_tl(list(integer())) == :badnonemptylist
660+
assert list_tl(difference(list(number()), list(number()))) == :badnonemptylist
661+
655662
assert list_tl(non_empty_list(integer())) == {false, list(integer())}
656663

657664
assert list_tl(non_empty_list(integer(), atom())) ==

0 commit comments

Comments
 (0)