From ec4dafae0c71f9d3e5e2f721b99b672bee3a370e Mon Sep 17 00:00:00 2001 From: Jean Klingler Date: Tue, 17 Oct 2023 17:53:10 +0900 Subject: [PATCH] Fix overriding with Elixir. prefixed defmodule (#13011) Closes #12456. --- lib/elixir/lib/kernel.ex | 15 +++++----- lib/elixir/test/elixir/kernel/alias_test.exs | 31 ++++++++++++++++++++ 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/lib/elixir/lib/kernel.ex b/lib/elixir/lib/kernel.ex index 2c9ab81c7c..f55b3d827d 100644 --- a/lib/elixir/lib/kernel.ex +++ b/lib/elixir/lib/kernel.ex @@ -4889,14 +4889,13 @@ defmodule Kernel do expanded = expand_module_alias(alias, env) {expanded, with_alias} = - case is_atom(expanded) do - true -> + case alias_defmodule(alias, expanded, env) do + {full, old, new} -> # Expand the module considering the current environment/nesting - {full, old, new} = alias_defmodule(alias, expanded, env) meta = [defined: full, context: env.module] ++ alias_meta(alias) {full, {:alias, meta, [old, [as: new, warn: false]]}} - false -> + nil -> {expanded, nil} end @@ -4955,13 +4954,13 @@ defmodule Kernel do defp expand_module_alias(other, env), do: Macro.expand(other, env) + defp alias_defmodule(_raw, module, _env) when not is_atom(module), do: nil + # defmodule Elixir.Alias - defp alias_defmodule({:__aliases__, _, [:"Elixir", _ | _]}, module, _env), - do: {module, module, nil} + defp alias_defmodule({:__aliases__, _, [:"Elixir", _ | _]}, _module, _env), do: nil # defmodule Alias in root - defp alias_defmodule({:__aliases__, _, _}, module, %{module: nil}), - do: {module, module, nil} + defp alias_defmodule({:__aliases__, _, _}, _module, %{module: nil}), do: nil # defmodule Alias nested defp alias_defmodule({:__aliases__, _, [h | t]}, _module, env) when is_atom(h) do diff --git a/lib/elixir/test/elixir/kernel/alias_test.exs b/lib/elixir/test/elixir/kernel/alias_test.exs index e91b31d157..a1e3d0f5cb 100644 --- a/lib/elixir/test/elixir/kernel/alias_test.exs +++ b/lib/elixir/test/elixir/kernel/alias_test.exs @@ -147,3 +147,34 @@ defmodule Macro.AliasTest.User do assert is_map(struct(Macro.AliasTest.User.Second, []).baz) end end + +defmodule Kernel.AliasNestingEnvTest do + use ExUnit.Case, async: true + + alias Another.AliasEnv, warn: false + + def aliases_before, do: __ENV__.aliases + + defmodule Elixir.AliasEnv do + def aliases_nested, do: __ENV__.aliases + end + + def aliases_after, do: __ENV__.aliases + + test "keeps env after overriding nested Elixir module of the same name" do + assert aliases_before() == [ + {Elixir.Nested, Kernel.AliasTest.Nested}, + {Elixir.AliasEnv, Another.AliasEnv} + ] + + assert Elixir.AliasEnv.aliases_nested() == [ + {Elixir.Nested, Kernel.AliasTest.Nested}, + {Elixir.AliasEnv, Another.AliasEnv} + ] + + assert aliases_after() == [ + {Elixir.Nested, Kernel.AliasTest.Nested}, + {Elixir.AliasEnv, Another.AliasEnv} + ] + end +end