Skip to content

Commit 5e5f00c

Browse files
authored
Document all built-in types internally (#10327)
Also document which functions must be changed once new types are introduced and which functions must handle them. Make sure all of these functions comply to the spec and improve performance for tuples.
1 parent a59fe07 commit 5e5f00c

File tree

8 files changed

+335
-178
lines changed

8 files changed

+335
-178
lines changed

lib/elixir/lib/module/types.ex

Lines changed: 6 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ defmodule Module.Types do
66
end
77

88
import Module.Types.Helpers
9-
alias Module.Types.{Expr, Pattern}
9+
alias Module.Types.{Expr, Pattern, Infer}
1010

1111
@doc false
1212
def warnings(module, file, defs, no_warn_undefined, cache) do
@@ -179,9 +179,9 @@ defmodule Module.Types do
179179
end
180180
end
181181

182-
defp do_lift_type({:tuple, types}, context) do
182+
defp do_lift_type({:tuple, n, types}, context) do
183183
{types, context} = Enum.map_reduce(types, context, &do_lift_type/2)
184-
{{:tuple, types}, context}
184+
{{:tuple, n, types}, context}
185185
end
186186

187187
defp do_lift_type({:map, pairs}, context) do
@@ -300,9 +300,9 @@ defmodule Module.Types do
300300

301301
[
302302
"incompatible types:\n\n ",
303-
format_type(left, simplify_left?),
303+
Infer.format_type(left, simplify_left?),
304304
" !~ ",
305-
format_type(right, simplify_right?),
305+
Infer.format_type(right, simplify_right?),
306306
"\n\n",
307307
format_expr(expr, location),
308308
traces,
@@ -352,7 +352,7 @@ defmodule Module.Types do
352352
"where \"",
353353
Macro.to_string(var),
354354
"\" was given the type ",
355-
format_type(type, simplify?),
355+
Infer.format_type(type, simplify?),
356356
hint,
357357
" in:\n\n # ",
358358
format_location(location),
@@ -390,73 +390,10 @@ defmodule Module.Types do
390390
[file, ?:, line, ?\n]
391391
end
392392

393-
## TYPE FORMATTING
394-
395393
defp simplify_type?(type, other) do
396394
map_type?(type) and not map_type?(other)
397395
end
398396

399-
@doc false
400-
def format_type({:map, pairs}, true) do
401-
case List.keyfind(pairs, {:atom, :__struct__}, 1) do
402-
{:required, {:atom, :__struct__}, {:atom, struct}} ->
403-
"%#{inspect(struct)}{}"
404-
405-
_ ->
406-
"map()"
407-
end
408-
end
409-
410-
def format_type({:union, types}, simplify?) do
411-
"#{Enum.map_join(types, " | ", &format_type(&1, simplify?))}"
412-
end
413-
414-
def format_type({:tuple, types}, simplify?) do
415-
"{#{Enum.map_join(types, ", ", &format_type(&1, simplify?))}}"
416-
end
417-
418-
def format_type({:list, type}, simplify?) do
419-
"[#{format_type(type, simplify?)}]"
420-
end
421-
422-
def format_type({:map, pairs}, false) do
423-
case List.keytake(pairs, {:atom, :__struct__}, 1) do
424-
{{:required, {:atom, :__struct__}, {:atom, struct}}, pairs} ->
425-
"%#{inspect(struct)}{#{format_map_pairs(pairs)}}"
426-
427-
_ ->
428-
"%{#{format_map_pairs(pairs)}}"
429-
end
430-
end
431-
432-
def format_type({:atom, literal}, _simplify?) do
433-
inspect(literal)
434-
end
435-
436-
def format_type({:var, index}, _simplify?) do
437-
"var#{index}"
438-
end
439-
440-
def format_type(atom, _simplify?) when is_atom(atom) do
441-
"#{atom}()"
442-
end
443-
444-
defp format_map_pairs(pairs) do
445-
{atoms, others} = Enum.split_with(pairs, &match?({:required, {:atom, _}, _}, &1))
446-
{required, optional} = Enum.split_with(others, &match?({:required, _, _}, &1))
447-
448-
Enum.map_join(atoms ++ required ++ optional, ", ", fn
449-
{:required, {:atom, atom}, right} ->
450-
"#{atom}: #{format_type(right, false)}"
451-
452-
{:required, left, right} ->
453-
"#{format_type(left, false)} => #{format_type(right, false)}"
454-
455-
{:optional, left, right} ->
456-
"optional(#{format_type(left, false)}) => #{format_type(right, false)}"
457-
end)
458-
end
459-
460397
## EXPRESSION FORMATTING
461398

462399
defp format_expr(nil, _location) do

lib/elixir/lib/module/types/expr.ex

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,10 @@ defmodule Module.Types.Expr do
100100

101101
# __STACKTRACE__
102102
def of_expr({:__STACKTRACE__, _meta, var_context}, _stack, context) when is_atom(var_context) do
103-
file = {:tuple, [{:atom, :file}, {:list, :integer}]}
104-
line = {:tuple, [{:atom, :line}, :integer]}
103+
file = {:tuple, 2, [{:atom, :file}, {:list, :integer}]}
104+
line = {:tuple, 2, [{:atom, :line}, :integer]}
105105
file_line = {:list, {:union, [file, line]}}
106-
type = {:list, {:tuple, [:atom, :atom, :integer, file_line]}}
106+
type = {:list, {:tuple, 4, [:atom, :atom, :integer, file_line]}}
107107
{:ok, type, context}
108108
end
109109

@@ -123,7 +123,7 @@ defmodule Module.Types.Expr do
123123
stack = push_expr_stack(expr, stack)
124124

125125
case map_reduce_ok(exprs, context, &of_expr(&1, stack, &2)) do
126-
{:ok, types, context} -> {:ok, {:tuple, types}, context}
126+
{:ok, types, context} -> {:ok, {:tuple, length(types), types}, context}
127127
{:error, reason} -> {:error, reason}
128128
end
129129
end

0 commit comments

Comments
 (0)