Skip to content

Commit 67f7c6b

Browse files
eksperimentaljosevalim
authored andcommitted
Fix bug with edge-case when converting to algebra quoted Elixir alias (#11572)
The following code would crash: iex> Code.quoted_to_algebra(Elixir) ** (MatchError) no match of right hand side value: "Elixir" (elixir 1.13.1) lib/code/normalizer.ex:254: Code.Normalizer.normalize_literal/3 (elixir 1.13.1) lib/code.ex:1107: Code.quoted_to_algebra/2 Therefore, this as well: iex> Macro.to_string(Elixir) ** (MatchError) no match of right hand side value: "Elixir" (elixir 1.13.1) lib/code/normalizer.ex:254: Code.Normalizer.normalize_literal/3 (elixir 1.13.1) lib/code.ex:1107: Code.quoted_to_algebra/2 (elixir 1.13.1) lib/macro.ex:948: Macro.to_string/1
1 parent c99a17b commit 67f7c6b

File tree

5 files changed

+16
-5
lines changed

5 files changed

+16
-5
lines changed

lib/elixir/lib/code/normalizer.ex

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -251,12 +251,16 @@ defmodule Code.Normalizer do
251251

252252
if is_atom(literal) and Code.Identifier.classify(literal) == :alias and
253253
is_nil(meta[:delimiter]) do
254-
"Elixir." <> segments = Atom.to_string(literal)
255-
256254
segments =
257-
segments
258-
|> String.split(".")
259-
|> Enum.map(&String.to_atom/1)
255+
case Atom.to_string(literal) do
256+
"Elixir" ->
257+
[:"Elixir"]
258+
259+
"Elixir." <> segments ->
260+
segments
261+
|> String.split(".")
262+
|> Enum.map(&String.to_atom/1)
263+
end
260264

261265
{:__aliases__, meta, segments}
262266
else

lib/elixir/test/elixir/code_normalizer/formatted_ast_test.exs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ defmodule Code.Normalizer.FormatterASTTest do
115115

116116
test "does not reformat aliases" do
117117
assert_same ~S[:"Elixir.String"]
118+
assert_same ~S[:"Elixir"]
118119
end
119120

120121
test "quoted operators" do

lib/elixir/test/elixir/code_normalizer/quoted_ast_test.exs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,7 @@ defmodule Code.Normalizer.QuotedASTTest do
620620
assert quoted_to_string({:__block__, [], [:"a\nb\tc"]}, escape: false) == ~s/:"a\nb\tc"/
621621
assert quoted_to_string({:__block__, [], [:"a\nb\tc"]}) == ~S/:"a\nb\tc"/
622622

623+
assert quoted_to_string(quote(do: :"Elixir")) == "Elixir"
623624
assert quoted_to_string(quote(do: :"Elixir.Foo")) == "Foo"
624625
assert quoted_to_string(quote(do: :"Elixir.Foo.Bar")) == "Foo.Bar"
625626
assert quoted_to_string(quote(do: :"Elixir.foobar")) == ~S/:"Elixir.foobar"/

lib/elixir/test/elixir/kernel/quote_test.exs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,9 @@ defmodule Kernel.QuoteTest.AliasHygieneTest do
521521
assert {:__aliases__, [alias: false], [:Foo, :Bar]} = quote(do: Foo.Bar)
522522
assert {:__aliases__, [alias: false], [:Dict, :Bar]} = quote(do: Dict.Bar)
523523
assert {:__aliases__, [alias: Dict.Bar], [:SuperDict, :Bar]} = quote(do: SuperDict.Bar)
524+
525+
# Edge-case
526+
assert {:__aliases__, _, [Elixir]} = quote(do: Elixir)
524527
end
525528

526529
test "expand aliases" do

lib/elixir/test/elixir/macro_test.exs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,8 @@ defmodule MacroTest do
326326
end
327327

328328
test "aliases call" do
329+
assert macro_to_string(quote(do: Elixir)) == "Elixir"
330+
assert macro_to_string(quote(do: Foo)) == "Foo"
329331
assert macro_to_string(quote(do: Foo.Bar.baz(1, 2, 3))) == "Foo.Bar.baz(1, 2, 3)"
330332
assert macro_to_string(quote(do: Foo.Bar.baz([1, 2, 3]))) == "Foo.Bar.baz([1, 2, 3])"
331333
assert macro_to_string(quote(do: Foo.bar(<<>>, []))) == "Foo.bar(<<>>, [])"

0 commit comments

Comments
 (0)