diff --git a/flake.lock b/flake.lock index cbdd465..93b865c 100644 --- a/flake.lock +++ b/flake.lock @@ -2,16 +2,18 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1698318101, - "narHash": "sha256-gUihHt3yPD7bVqg+k/UVHgngyaJ3DMEBchbymBMvK1E=", + "lastModified": 1711715736, + "narHash": "sha256-9slQ609YqT9bT/MNX9+5k5jltL9zgpn36DpFB7TkttM=", "owner": "nixos", "repo": "nixpkgs", - "rev": "63678e9f3d3afecfeafa0acead6239cdb447574c", + "rev": "807c549feabce7eddbf259dbdcec9e0600a0660d", "type": "github" }, "original": { - "id": "nixpkgs", - "type": "indirect" + "owner": "nixos", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" } }, "root": { diff --git a/flake.nix b/flake.nix index 348f51a..e1918e0 100644 --- a/flake.nix +++ b/flake.nix @@ -1,6 +1,7 @@ { description = "Tria: optimizing Elixir compiler and infrastructure"; - outputs = { self, nixpkgs, ... }: + inputs.nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; + outputs = { nixpkgs, ... }: let pkgs = nixpkgs.legacyPackages.x86_64-linux; in { devShells.x86_64-linux.default = import ./shell.nix { inherit pkgs; }; diff --git a/lib/mix/tasks/compile.tria.ex b/lib/mix/tasks/compile.tria.ex index a1c20d5..ac610f4 100644 --- a/lib/mix/tasks/compile.tria.ex +++ b/lib/mix/tasks/compile.tria.ex @@ -139,6 +139,7 @@ defmodule Mix.Tasks.Compile.Tria do |> File.mkdir_p!() Debug.inspect(manifest, label: :manifest) + manifest = %Manifest{manifest | new: false} File.write!(manifest_path, :erlang.term_to_binary(manifest)) end diff --git a/lib/mix/tasks/tria.warmup.ex b/lib/mix/tasks/tria.warmup.ex index 462ca1f..0f5a569 100644 --- a/lib/mix/tasks/tria.warmup.ex +++ b/lib/mix/tasks/tria.warmup.ex @@ -46,7 +46,15 @@ defmodule Mix.Tasks.Tria.Warmup do alias Tria.Language.Analyzer.Purity def run(args) when is_list(args) do - run parse_args args + {functions, modules} = run parse_args args + + IO.write [ + IO.ANSI.clear_line(), + IO.ANSI.green(), + "\nWarmup completed", + IO.ANSI.reset(), + "\nChecked #{functions} functions in #{modules - 1} modules\n" + ] end def run(%{from: :loaded}) do @@ -64,7 +72,7 @@ defmodule Mix.Tasks.Tria.Warmup do def check(modules) do length = length modules - Enum.reduce(modules, 1, fn module, index -> + Enum.reduce(modules, {0, 1}, fn module, {all_functions, index} -> with( {:ok, object_code} <- Beam.object_code(module), {:ok, abstract_code} <- Beam.abstract_code(object_code) @@ -87,8 +95,13 @@ defmodule Mix.Tasks.Tria.Warmup do {findex + 1, now} end) end + |> case do + {functions, _} -> + {all_functions + functions, index + 1} - index + 1 + _ -> + {all_functions, index + 1} + end end) end diff --git a/lib/tria/compiler.ex b/lib/tria/compiler.ex index f2accc9..dcdd48f 100644 --- a/lib/tria/compiler.ex +++ b/lib/tria/compiler.ex @@ -100,13 +100,14 @@ defmodule Tria.Compiler do _paths, %{build_path: build_path, context: context, manifest: manifest} = opts ) do - caller = self() + ContextServer.restore!(context, present: not manifest.new, build_path: build_path) added_and_changed = for {status, file} when status in ~w[added changed]a <- files_diff do file end + caller = self() result = ElixirCompiler.parallel_compile(added_and_changed, # Code options @@ -117,10 +118,10 @@ defmodule Tria.Compiler do # ParallelCompiler options dest: build_path, - each_module: fn file, module, bytecode -> + each_module: fn file, module, beam -> Debug.inspect(module, label: :each_module) - Beam.store_object_code(module, bytecode) - send(caller, {:last_cycle_compiled, {module, bytecode, file}}) + Beam.store_object_code(module, beam) + send(caller, {:last_cycle_compiled, {module, beam, file}}) end, each_cycle: fn graphs -> modules = @@ -172,7 +173,6 @@ defmodule Tria.Compiler do |> Manifest.apply_diff(files_diff) |> Manifest.update_file_to_modules(file_to_modules) - ContextServer.restore(opts.context) ContextServer.emit_difference(opts.context, new_modules, removed_modules, changed_modules) modules = diff --git a/lib/tria/compiler/context_server.ex b/lib/tria/compiler/context_server.ex index 9fdb7f4..2da6f71 100644 --- a/lib/tria/compiler/context_server.ex +++ b/lib/tria/compiler/context_server.ex @@ -50,7 +50,7 @@ defmodule Tria.Compiler.ContextServer do Mark `module` ready. Context module can only be generated when all modules are ready """ - @spec mark_ready(t(), module()) :: :ok + @spec mark_ready(t(), module()) :: :ok | :error def mark_ready(context, module) do call(context, {:ready, module}) end @@ -74,11 +74,26 @@ defmodule Tria.Compiler.ContextServer do @doc """ Restores state of the context server from already existing context module """ - @spec restore(t(), Keyword.t()) :: :ok + @spec restore(t(), Keyword.t()) :: :ok | :error def restore(context, opts \\ []) do call(context, {:restore, opts}) end + @doc """ + Restores state of the context server from already existing context module. Raises on error + """ + @spec restore!(t(), Keyword.t()) :: :ok | no_return() + def restore!(context, opts \\ []) do + {present, opts} = Keyword.pop!(opts, :present) + case restore(context, opts) do + :error when present -> + raise CompileError, description: "Failed to restore the #{inspect context}" + + _ -> + :ok + end + end + @spec emit_difference(t(), Enumerable.t(module()), Enumerable.t(module()), Enumerable.t(module())) :: :ok def emit_difference(context, new_modules, removed_modules, changed_modules) do call(context, {:emit_difference, new_modules, removed_modules, changed_modules}) @@ -118,14 +133,15 @@ defmodule Tria.Compiler.ContextServer do {:reply, :ok, %{state | definitions: definitions}} end - def handle_call({:restore, _opts}, _from, state) do + def handle_call({:restore, opts}, _from, state) do context = state.name - case Beam.object_code(context) do + case Beam.object_code_from_path(context, opts[:build_path]) do {:ok, object_code} -> definitions = object_code |> Beam.abstract_code!() |> Beam.tria_functions() + |> Debug.inspect_ast(label: :restored_functions) |> Enum.reduce(%{}, fn {{_module, kind, name, arity}, clauses}, acc -> {module, name} = Compiler.unfname(name) Tracer.tag_ast({:fn, [], clauses}, key: {module, name, arity}, label: :restored) @@ -202,6 +218,8 @@ defmodule Tria.Compiler.ContextServer do end end + Debug.inspect_ast(module, label: :context_module) + if Debug.debugging?(:write_tria) do File.write!("tria_global_context.ex", ast_to_string(module)) end diff --git a/lib/tria/compiler/manifest.ex b/lib/tria/compiler/manifest.ex index baf4451..bfdaad7 100644 --- a/lib/tria/compiler/manifest.ex +++ b/lib/tria/compiler/manifest.ex @@ -1,5 +1,4 @@ defmodule Tria.Compiler.Manifest do - @moduledoc """ Compiler manifest. @@ -20,6 +19,7 @@ defmodule Tria.Compiler.Manifest do @tria_version Tria.MixProject.project[:version] defstruct [ + new: true, tria_version: @tria_version, file_inputs: %{}, file_to_modules: %{}, diff --git a/lib/tria/compiler/translator/abstract.ex b/lib/tria/compiler/translator/abstract.ex index d2951a4..586bcde 100644 --- a/lib/tria/compiler/translator/abstract.ex +++ b/lib/tria/compiler/translator/abstract.ex @@ -105,14 +105,16 @@ defmodule Tria.Compiler.AbstractTranslator do |> postwalk(&with_meta(&1, meta)) # List comprehension - {:lc, anno, body, [{:b_generate, banno, bin, input}]} -> - {:<<>>, _, bin} = traverse(bin) - {last, heading} = List.pop_at(bin, -1) - input = traverse(input) - {:for, meta(anno), [{:<<>>, meta(banno), heading ++ [{:"<-", [], [last, input]}]}, [do: traverse_block body]]} - {:lc, anno, body, loops} -> - {:for, meta(anno), traverse(loops) ++ [[do: traverse_block body]]} + {:for, meta(anno), traverse_loops(loops) ++ [[do: traverse_block body]]} + + # Map comprehension + {:mc, anno, {:map_field_assoc, _anno, left, right}, loops} -> + meta = meta(anno) + left = traverse_block(left) + right = traverse_block(right) + traversed_loops = traverse_loops(loops) + {:for, meta, traversed_loops ++ [[into: {:%{}, meta, []}, do: {left, right}]]} {:block, anno, block} -> {:__block__, meta(anno), Enum.map(block, &traverse/1)} @@ -175,6 +177,9 @@ defmodule Tria.Compiler.AbstractTranslator do {:b_generate, anno, left, right} -> {:"<-", meta(anno), [traverse(left), traverse(right)]} + {:m_generate, anno, left, right} -> + {:"<-", meta(anno), [traverse(left), traverse(right)]} + # Binary {:bin, anno, elements} -> # Why flatten? @@ -339,6 +344,34 @@ defmodule Tria.Compiler.AbstractTranslator do ## Context-specific traversal + ### Comprehension loops + + defguardp is_generate(g) when g in ~w[generate m_generate]a + + def traverse_loops([]), do: [] + def traverse_loops([loop | loops]) do + loop = + case loop do + {:b_generate, anno, binary, iterable} -> + {:<<>>, _, traversed_binary} = traverse(binary) + {last, heading} = List.pop_at(traversed_binary, -1) + iterable = traverse(iterable) + meta = meta(anno) + {:<<>>, meta, heading ++ [{:"<-", anno, [last, iterable]}]} + + {g, anno, {:map_field_exact, _mfe_anno, left, right}, iterable} when is_generate(g) -> + {:"<-", meta(anno), [{traverse(left), traverse(right)}, traverse(iterable)]} + + {g, anno, item, iterable} when is_generate(g) -> + {:"<-", meta(anno), [traverse(item) , traverse(iterable)]} + + other -> + traverse(other) + end + + [loop | traverse_loops(loops)] + end + ### Try # try/rescue actually generates `catch` clauses. diff --git a/lib/tria/compiler/translator/elixir.ex b/lib/tria/compiler/translator/elixir.ex index 2f356eb..47f5acc 100644 --- a/lib/tria/compiler/translator/elixir.ex +++ b/lib/tria/compiler/translator/elixir.ex @@ -97,6 +97,29 @@ defmodule Tria.Compiler.ElixirTranslator do @doc """ Returns full module atom from an alias """ + # Here I don't write `%Macro.Env{}` because sometime I use field-polymorphic structure + @spec unalias(Macro.t(), Macro.Env.t() | map()) :: module() | Macro.t() + def unalias(module, _env) when is_atom(module), do: module + def unalias({:__aliases__, _, [{:__MODULE__, _, _} | tail]}, %{module: module} = env) do + unalias({:__aliases__, [], [module | tail]}, env) + end + def unalias({:__aliases__, _, [module | tail]} = aliased, %{aliases: aliases} = env) do + case Keyword.fetch(aliases, Module.concat([module])) do + {:ok, found} -> + Module.concat([found | tail]) + + :error -> + case Macro.expand(aliased, env) do + module when is_atom(module) -> + module + + other -> + unalias(other) + end + end + end + def unalias(other, _env), do: other + @spec unalias(Macro.t()) :: module() | Macro.t() def unalias({:__aliases__, meta, names} = ast) when is_aliases(ast) do if the_alias = meta[:alias], do: the_alias, else: Module.concat(names) @@ -793,28 +816,6 @@ defmodule Tria.Compiler.ElixirTranslator do %Macro.Env{env | versioned_vars: versioned_vars} end - # Here I don't write Macro.Env because sometime I use field-polymorphic structure - defp unalias(module, _env) when is_atom(module), do: module - defp unalias({:__aliases__, _, [{:__MODULE__, _, _} | tail]}, %{module: module} = env) do - unalias({:__aliases__, [], [module | tail]}, env) - end - defp unalias({:__aliases__, _, [module | tail]} = aliased, %{aliases: aliases} = env) do - case Keyword.fetch(aliases, Module.concat([module])) do - {:ok, found} -> - Module.concat([found | tail]) - - :error -> - case Macro.expand(aliased, env) do - module when is_atom(module) -> - module - - other -> - unalias(other) - end - end - end - defp unalias(other, _env), do: other - defp normalize_alias_to({:__aliases__, _, modules}), do: Module.concat(modules) defp normalize_alias_to(module), do: Module.concat([module]) diff --git a/lib/tria/language/analyzer.ex b/lib/tria/language/analyzer.ex index ecca1b0..647c365 100644 --- a/lib/tria/language/analyzer.ex +++ b/lib/tria/language/analyzer.ex @@ -39,6 +39,10 @@ defmodule Tria.Language.Analyzer do :error -> nil end + rescue + error -> + IO.inspect mfarity, label: :failed + reraise error, __STACKTRACE__ end end diff --git a/lib/tria/language/beam.ex b/lib/tria/language/beam.ex index 8da46df..5ba048f 100644 --- a/lib/tria/language/beam.ex +++ b/lib/tria/language/beam.ex @@ -65,6 +65,26 @@ defmodule Tria.Language.Beam do end end + @doc """ + Fetches obeject_code from module name + """ + @spec object_code_from_path(module(), Path.t()) :: {:ok, object_code()} | :error + def object_code_from_path(module, nil) do + object_code(module) + end + + def object_code_from_path(module, path) do + with {:error, _} <- File.read(Path.join(path, "#{module}.beam")) do + case :code.get_object_code(module) do + {^module, object_code, _filename} -> + {:ok, object_code} + + _ -> + :error + end + end + end + @doc """ Fetches obeject_code from module name in raising manner """ diff --git a/lib/tria/language/tri.ex b/lib/tria/language/tri.ex index 5555a9f..c6831f3 100644 --- a/lib/tria/language/tri.ex +++ b/lib/tria/language/tri.ex @@ -23,10 +23,12 @@ defmodule Tria.Language.Tri do - `:to_ssa` — translates the pattern to SSA form (default: `false`) - `:isolate` — defines that the variables should not be fetches from outer context (default: `false`) - `:meta` — whether meta field should be empty in pattern or in AST + - `:unalias` — whether to remove `{:__aliases__, _, _}` tuples """ @type option :: {:debug, atom()} | {:to_tria, :force | true | false} | {:to_ssa, boolean()} + | {:unalias, boolean()} | {:isolate, boolean()} | {:meta, boolean()} @@ -86,6 +88,7 @@ defmodule Tria.Language.Tri do defp to_pattern(quoted, opts, env) do quoted + |> maybe_unalias(env, opts) |> then(fn quoted -> case opts[:to_tria] do :force -> ElixirTranslator.to_tria!(quoted) @@ -106,6 +109,7 @@ defmodule Tria.Language.Tri do defp to_quote(code, opts, %Macro.Env{versioned_vars: versioned_vars} = env) do code + |> maybe_unalias(env, opts) |> maybe_translate(env, opts) |> Macro.escape() |> then(fn x -> @@ -150,6 +154,14 @@ defmodule Tria.Language.Tri do end end + defp maybe_unalias(ast, env, opts) do + if Keyword.get(opts, :unalias, false) do + Macro.prewalk(ast, &ElixirTranslator.unalias(&1, env)) + else + ast + end + end + ## This function drops meta in escaped AST ## and unescapes code diff --git a/mix.lock b/mix.lock index 76b7155..f09a9c3 100644 --- a/mix.lock +++ b/mix.lock @@ -9,9 +9,8 @@ "jason": {:hex, :jason, "1.4.0", "e855647bc964a44e2f67df589ccf49105ae039d4179db7f6271dfd3843dc27e6", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "79a3791085b2a0f743ca04cec0f7be26443738779d09302e01318f97bdb82121"}, "makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"}, "makeup_elixir": {:hex, :makeup_elixir, "0.16.0", "f8c570a0d33f8039513fbccaf7108c5d750f47d8defd44088371191b76492b0b", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "28b2cbdc13960a46ae9a8858c4bebdec3c9a6d7b4b9e7f4ed1502f8159f338e7"}, - "mix_tester": {:hex, :mix_tester, "1.0.0", "c49a7f026adb2c65f4f8598b60a9b17db04e62dddc8cba47b99fe611b321f672", [:mix], [{:sourceror, "~> 0.12", [hex: :sourceror, repo: "hexpm", optional: false]}], "hexpm", "3cf1850b0009ccde1cac3663a51b06946504baa90c6f27c7889654bfa6ee9058"}, + "mix_tester": {:hex, :mix_tester, "1.1.1", "3cb546cdc739163a7b5ebfa7908006f2db540943cf0c40872a753dae6a9e4dfa", [:mix], [], "hexpm", "4495a503a47220d6a6c27d957a9296b47e2411ad11ac8b503a25bdd3cee0a5d8"}, "nimble_parsec": {:hex, :nimble_parsec, "1.2.3", "244836e6e3f1200c7f30cb56733fd808744eca61fd182f731eac4af635cc6d0b", [:mix], [], "hexpm", "c8d789e39b9131acf7b99291e93dae60ab48ef14a7ee9d58c6964f59efb570b0"}, "redbug": {:hex, :redbug, "1.2.2", "366d8961770ddc7bb5d209fbadddfa7271005487f938c087a0e385a57abfee33", [:rebar3], [], "hexpm", "b5fe7b94e487be559cb0ec1c0e938c9761205d3e91a96bf263bdf1beaebea729"}, "rexbug": {:hex, :rexbug, "1.0.6", "024071c67d970151fbdc06f299faf8db3e1b2ac759a28623a9cc80a517fc74f2", [:mix], [{:mix_test_watch, ">= 0.5.0", [hex: :mix_test_watch, repo: "hexpm", optional: true]}, {:redbug, "~> 1.2", [hex: :redbug, repo: "hexpm", optional: false]}], "hexpm", "148ea724979413e9fd84ca3b4bb5d2d8b840ac481adfd645f5846fda409a642c"}, - "sourceror": {:hex, :sourceror, "0.12.3", "a2ad3a1a4554b486d8a113ae7adad5646f938cad99bf8bfcef26dc0c88e8fade", [:mix], [], "hexpm", "4d4e78010ca046524e8194ffc4683422f34a96f6b82901abbb45acc79ace0316"}, } diff --git a/shell.nix b/shell.nix index eb8a273..1b958fb 100644 --- a/shell.nix +++ b/shell.nix @@ -3,10 +3,10 @@ with pkgs; let otp = beam.packages.erlangR26; in pkgs.mkShell { buildInputs = [ - otp.elixir_1_15 + otp.elixir_1_16 otp.erlang ((if otp ? elixir-ls then otp.elixir-ls else otp.elixir_ls).override { - elixir = otp.elixir_1_15; + elixir = otp.elixir_1_16; }) ]; diff --git a/test/tria/compiler/incremental_compilation_test.exs b/test/tria/compiler/incremental_compilation_test.exs index e6771e7..598cbef 100644 --- a/test/tria/compiler/incremental_compilation_test.exs +++ b/test/tria/compiler/incremental_compilation_test.exs @@ -15,6 +15,44 @@ defmodule Tria.Compiler.IncrementalCompilationTest do {:ok, project: project} end + test "basic", %{project: project} do + write_ast(project, "lib/x.ex", quote do + defmodule X do + def f(x), do: x + 1 + end + end) + + write_ast(project, "test/subject/x_test.exs", quote do + defmodule XGTest do + use ExUnit.Case, async: true + + test "X.f(1) == 2" do + assert X.f(1) == 2 + end + end + end) + + assert MixTester.mix_test(project) + + write_ast(project, "lib/x.ex", quote do + defmodule X do + def f(x), do: x + 2 + end + end) + + write_ast(project, "test/subject/x_test.exs", quote do + defmodule XGTest do + use ExUnit.Case, async: true + + test "X.f(1) == 3" do + assert X.f(1) == 3 + end + end + end) + + assert MixTester.mix_cmd(project, "test") + end + test "Compiles and recompiles macros", %{project: project} do write_ast(project, "lib/x.ex", quote do defmodule X do @@ -58,7 +96,7 @@ defmodule Tria.Compiler.IncrementalCompilationTest do end end) - assert {_, 0} = MixTester.mix_cmd(project, "test") + assert MixTester.mix_test(project) write_ast(project, "lib/z.ex", quote do defmodule Z do @@ -68,7 +106,9 @@ defmodule Tria.Compiler.IncrementalCompilationTest do end end) - assert {_, 2} = MixTester.mix_cmd(project, "test") + ExUnit.CaptureIO.capture_io(fn -> + refute MixTester.mix_test(project) + end) write_ast(project, "test/subject/x_f_test.exs", quote do defmodule XFTest do @@ -80,7 +120,7 @@ defmodule Tria.Compiler.IncrementalCompilationTest do end end) - assert {_, 0} = MixTester.mix_cmd(project, "test") + assert MixTester.mix_test(project) end test "constant evaluation", %{project: project} do @@ -105,7 +145,7 @@ defmodule Tria.Compiler.IncrementalCompilationTest do end end) - assert {_, 0} = MixTester.mix_cmd(project, "test") + assert MixTester.mix_test(project) write_ast(project, "lib/x.ex", quote do defmodule X do @@ -122,7 +162,7 @@ defmodule Tria.Compiler.IncrementalCompilationTest do end end) - assert {_, 0} = MixTester.mix_cmd(project, "test") + assert MixTester.mix_test(project) end test "function to macro", %{project: project} do @@ -148,7 +188,7 @@ defmodule Tria.Compiler.IncrementalCompilationTest do end end) - assert {_, 0} = MixTester.mix_cmd(project, "test") + assert MixTester.mix_test(project) write_ast(project, "lib/x.ex", quote do defmodule X do @@ -165,7 +205,7 @@ defmodule Tria.Compiler.IncrementalCompilationTest do end end) - assert {_, 0} = MixTester.mix_cmd(project, "test") + assert MixTester.mix_test(project) write_ast(project, "lib/x.ex", quote do defmodule X do @@ -182,7 +222,7 @@ defmodule Tria.Compiler.IncrementalCompilationTest do end end) - assert {_, 0} = MixTester.mix_cmd(project, "test") + assert MixTester.mix_test(project) end test "private calls handled correctly", %{project: project} do @@ -203,7 +243,7 @@ defmodule Tria.Compiler.IncrementalCompilationTest do end end) - assert {_, 0} = MixTester.mix_cmd(project, "test") + assert MixTester.mix_test(project) write_ast(project, "lib/y.ex", quote do defmodule Y do @@ -211,7 +251,7 @@ defmodule Tria.Compiler.IncrementalCompilationTest do end end) - assert {_, 0} = MixTester.mix_cmd(project, "test") + assert MixTester.mix_test(project) end test "string interpolation works correctly", %{project: project} do @@ -235,7 +275,7 @@ defmodule Tria.Compiler.IncrementalCompilationTest do end end) - assert {_, 0} = MixTester.mix_cmd(project, "test") + assert MixTester.mix_test(project) write_ast(project, "lib/y.ex", quote do defmodule Y do @@ -259,6 +299,6 @@ defmodule Tria.Compiler.IncrementalCompilationTest do end end) - assert {_, 0} = MixTester.mix_cmd(project, "test") + assert MixTester.mix_test(project) end end diff --git a/test/tria/optimizer/pass/evaluation_test.exs b/test/tria/optimizer/pass/evaluation_test.exs index 23ae74a..7ab468d 100644 --- a/test/tria/optimizer/pass/evaluation_test.exs +++ b/test/tria/optimizer/pass/evaluation_test.exs @@ -467,7 +467,7 @@ defmodule Tria.Optimizer.Pass.EvaluationTest do end |> run_while() - assert tri(Kernel.+(tri(^x), tri(^y))) = last_line evaluated + assert tri([unalias: true], Kernel.+(tri(^x), tri(^y))) = last_line evaluated end test "maybe case" do