Skip to content

Commit

Permalink
Fix overriding with Elixir. prefixed defmodule (#13011)
Browse files Browse the repository at this point in the history
Closes #12456.
  • Loading branch information
sabiwara authored Oct 17, 2023
1 parent ddb2434 commit ec4dafa
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 8 deletions.
15 changes: 7 additions & 8 deletions lib/elixir/lib/kernel.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down
31 changes: 31 additions & 0 deletions lib/elixir/test/elixir/kernel/alias_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit ec4dafa

Please sign in to comment.