Skip to content

Commit 51dce31

Browse files
committed
Preserve file meta from each clause in type system warnings
1 parent 0dd4cb4 commit 51dce31

2 files changed

Lines changed: 43 additions & 7 deletions

File tree

lib/elixir/lib/module/types.ex

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ defmodule Module.Types do
266266

267267
Enum.reduce(unused_indexes, context, fn clause_index, context ->
268268
{meta, _args, _guards, _body} = Enum.fetch!(clauses, clause_index)
269-
stack = %{stack | function: fun_arity}
269+
stack = %{stack | function: fun_arity} |> with_file_meta(meta)
270270
Helpers.warn(__MODULE__, {:unused_clause, kind, fun_arity}, meta, stack, context)
271271
end)
272272
else
@@ -299,11 +299,11 @@ defmodule Module.Types do
299299

300300
local_sigs ->
301301
case finder.(fun_arity) do
302-
{mode, {fun_arity, kind, meta, clauses}, expected} ->
302+
{mode, {fun_arity, kind, _meta, clauses}, expected} ->
303303
context = put_in(context.local_sigs, Map.put(local_sigs, fun_arity, kind))
304304

305305
{inferred, mapping, context} =
306-
local_handler(mode, fun_arity, kind, meta, clauses, expected, stack, context)
306+
local_handler(mode, fun_arity, kind, clauses, expected, stack, context)
307307

308308
context =
309309
update_in(context.local_sigs, &Map.put(&1, fun_arity, {kind, inferred, mapping}))
@@ -316,19 +316,20 @@ defmodule Module.Types do
316316
end
317317
end
318318

319-
defp local_handler(:traverse, {_, arity}, _kind, _meta, clauses, _expected, stack, context) do
319+
defp local_handler(:traverse, {_, arity}, _kind, clauses, _expected, stack, context) do
320320
context =
321-
Enum.reduce(clauses, context, fn {_meta, _args, _guards, body}, context ->
321+
Enum.reduce(clauses, context, fn {meta, _args, _guards, body}, context ->
322+
stack = with_file_meta(stack, meta)
322323
Module.Types.Traverse.of_expr(body, stack, context)
323324
end)
324325

325326
inferred = {:infer, nil, [{List.duplicate(Descr.term(), arity), Descr.dynamic()}]}
326327
{inferred, [{0, 0}], context}
327328
end
328329

329-
defp local_handler(mode, fun_arity, kind, meta, clauses, expected, stack, context) do
330+
defp local_handler(mode, fun_arity, kind, clauses, expected, stack, context) do
330331
{fun, _arity} = fun_arity
331-
stack = stack |> fresh_stack(mode, fun_arity) |> with_file_meta(meta)
332+
stack = fresh_stack(stack, mode, fun_arity)
332333
base_info = {:def, kind, fun, expected}
333334

334335
case clauses do
@@ -341,6 +342,7 @@ defmodule Module.Types do
341342
end
342343

343344
defp default_local_handler(meta, args, body, base_info, kind, fun, expected, stack, context) do
345+
stack = with_file_meta(stack, meta)
344346
guards = []
345347
previous = Pattern.init_previous()
346348
fresh_context = fresh_context(context)
@@ -400,6 +402,7 @@ defmodule Module.Types do
400402
Enum.reduce(clauses, {0, 0, Pattern.init_previous(), [], [], [], context}, fn
401403
{meta, args, guards, body},
402404
{index, total, previous, domain, mapping, inferred, acc_context} ->
405+
stack = with_file_meta(stack, meta)
403406
fresh_context = fresh_context(acc_context)
404407
info = {base_info, args, guards}
405408

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,39 @@ defmodule Module.Types.IntegrationTest do
333333
assert_warnings(files, warnings)
334334
end
335335

336+
test "warning location respects file metadata in clauses" do
337+
files = %{
338+
"bug.ex" => """
339+
defmodule Bug do
340+
def render(x)
341+
342+
@file "template.heex"
343+
def render(x) do
344+
label = describe(x)
345+
_ = label == :only
346+
x
347+
end
348+
349+
defp describe(_), do: "page"
350+
end
351+
"""
352+
}
353+
354+
warnings = [
355+
"""
356+
warning: comparison between distinct types found:
357+
358+
label == :only
359+
""",
360+
"binary() == :only",
361+
"# type: binary()",
362+
"# from: template.heex:6:11",
363+
"└─ template.heex:7:15: Bug.render/1"
364+
]
365+
366+
assert_warnings(files, warnings)
367+
end
368+
336369
test "unused private clauses" do
337370
files = %{
338371
"a.ex" => """

0 commit comments

Comments
 (0)