Skip to content

Commit 61157aa

Browse files
committed
Avoid showing duplicate traces
1 parent 8e455b7 commit 61157aa

File tree

2 files changed

+34
-7
lines changed

2 files changed

+34
-7
lines changed

lib/elixir/lib/module/types/helpers.ex

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -147,25 +147,30 @@ defmodule Module.Types.Helpers do
147147

148148
defp format_trace(%{type: :variable, name: name, context: context, traces: traces}) do
149149
traces =
150-
for trace <- traces do
150+
traces
151+
|> Enum.map(fn trace ->
151152
location =
152153
trace.file
153154
|> Path.relative_to_cwd()
154155
|> Exception.format_file_line(trace.meta[:line])
155156
|> String.replace_suffix(":", "")
156157

158+
{trace.formatted_type, location, trace.formatted_expr, trace.formatted_hints}
159+
end)
160+
|> Enum.dedup()
161+
|> Enum.map(fn {formatted_type, location, formatted_expr, formatted_hints} ->
157162
[
158163
"""
159164
160-
# type: #{indent(trace.formatted_type, 4)}
165+
# type: #{indent(formatted_type, 4)}
161166
# from: #{location}
162167
\
163168
""",
164-
indent(trace.formatted_expr, 4),
169+
indent(formatted_expr, 4),
165170
?\n,
166-
trace.formatted_hints
171+
formatted_hints
167172
]
168-
end
173+
end)
169174

170175
type_or_types = pluralize(traces, "type", "types")
171176
["\nwhere #{format_var(name, context)} was given the #{type_or_types}:\n" | traces]

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

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,28 @@ defmodule Module.Types.PatternTest do
2525
assert typecheck!([%y{}, %x{}, x = y, x = Point], y) == dynamic(atom([Point]))
2626
end
2727

28+
test "repeated refinements are ignored on reporting" do
29+
assert typeerror!([{name, arity}, arity = 123], hd(Atom.to_charlist(name))) == ~l"""
30+
incompatible types given to Kernel.hd/1:
31+
32+
hd(Atom.to_charlist(name))
33+
34+
expected types:
35+
36+
non_empty_list(term(), term())
37+
38+
but got types:
39+
40+
empty_list() or non_empty_list(integer())
41+
42+
where "name" was given the type:
43+
44+
# type: dynamic()
45+
# from: types_test.ex
46+
{name, arity}
47+
"""
48+
end
49+
2850
test "errors on conflicting refinements" do
2951
assert typeerror!([a = b, a = :foo, b = :bar], {a, b}) ==
3052
~l"""
@@ -35,13 +57,13 @@ defmodule Module.Types.PatternTest do
3557
where "a" was given the type:
3658
3759
# type: dynamic(:foo)
38-
# from: types_test.ex:29
60+
# from: types_test.ex:LINE-1
3961
a = :foo
4062
4163
where "b" was given the type:
4264
4365
# type: dynamic(:bar)
44-
# from: types_test.ex:29
66+
# from: types_test.ex:LINE-1
4567
b = :bar
4668
"""
4769
end

0 commit comments

Comments
 (0)