Skip to content

Commit 2a53036

Browse files
committed
Fix trace tagging of internal type variable
1 parent ef0f17d commit 2a53036

File tree

2 files changed

+22
-8
lines changed

2 files changed

+22
-8
lines changed

lib/elixir/lib/module/types/infer.ex

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ defmodule Module.Types.Infer do
287287
end
288288

289289
@doc """
290-
Adds a variable to the typing context and returns its type variables.
290+
Adds a variable to the typing context and returns its type variable.
291291
If the variable has already been added, return the existing type variable.
292292
"""
293293
def new_var(var, context) do
@@ -315,6 +315,11 @@ defmodule Module.Types.Infer do
315315
end
316316
end
317317

318+
@doc """
319+
Adds an internal variable to the typing context and returns its type variable.
320+
An internal variable is used to help unify complex expressions,
321+
it does not belong to a specific AST expression.
322+
"""
318323
def add_var(context) do
319324
type = {:var, context.counter}
320325
types = Map.put(context.types, context.counter, :unbound)
@@ -543,13 +548,11 @@ defmodule Module.Types.Infer do
543548
# Tag if trace is for a concrete type or type variable
544549
defp tag_traces(traces, context) do
545550
Enum.flat_map(traces, fn {var, {type, expr, location}} ->
546-
case type do
547-
{:var, var_index} ->
548-
var2 = Map.fetch!(context.types_to_vars, var_index)
549-
[{var, {:var, var2, expr, location}}]
550-
551-
_ ->
552-
[{var, {:type, type, expr, location}}]
551+
with {:var, var_index} <- type,
552+
%{^var_index => expr_var} <- context.types_to_vars do
553+
[{var, {:var, expr_var, expr, location}}]
554+
else
555+
_ -> [{var, {:type, type, expr, location}}]
553556
end
554557
end)
555558
end

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,17 @@ defmodule Module.Types.InferTest do
371371
assert {:error, {{:unable_unify, {:var, 0}, {:tuple, [{:var, 0}]}, _}, _}} =
372372
unify_lift({:var, 2}, {:tuple, [{:var, 0}]}, context)
373373
end
374+
375+
test "error with internal variable" do
376+
context = new_context()
377+
{var_integer, context} = add_var(context)
378+
{var_atom, context} = add_var(context)
379+
380+
{:ok, _, context} = unify(var_integer, :integer, context)
381+
{:ok, _, context} = unify(var_atom, :atom, context)
382+
383+
assert {:error, _} = unify(var_integer, var_atom, context)
384+
end
374385
end
375386

376387
test "subtype?/3" do

0 commit comments

Comments
 (0)