Skip to content

Commit 4e478b3

Browse files
authored
Correctly Macro.escape :quote triplet without meta (#13594)
Closes #13593.
1 parent 9651afa commit 4e478b3

File tree

2 files changed

+13
-9
lines changed

2 files changed

+13
-9
lines changed

lib/elixir/src/elixir_quote.erl

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ escape(Expr, Op, Unquote) ->
139139
unquote=Unquote
140140
}).
141141

142-
do_escape({Left, Meta, Right}, #elixir_quote{op=prune_metadata} = Q) ->
142+
do_escape({Left, Meta, Right}, #elixir_quote{op=prune_metadata} = Q) when is_list(Meta) ->
143143
TM = [{K, V} || {K, V} <- Meta, (K == no_parens) orelse (K == line)],
144144
TL = do_quote(Left, Q),
145145
TR = do_quote(Right, Q),
@@ -263,7 +263,7 @@ quote(Expr, Q) ->
263263

264264
%% quote/unquote
265265

266-
do_quote({quote, Meta, [Arg]}, Q) ->
266+
do_quote({quote, Meta, [Arg]}, Q) when is_list(Meta) ->
267267
TArg = do_quote(Arg, Q#elixir_quote{unquote=false}),
268268

269269
NewMeta = case Q of
@@ -273,7 +273,7 @@ do_quote({quote, Meta, [Arg]}, Q) ->
273273

274274
{'{}', [], [quote, meta(NewMeta, Q), [TArg]]};
275275

276-
do_quote({quote, Meta, [Opts, Arg]}, Q) ->
276+
do_quote({quote, Meta, [Opts, Arg]}, Q) when is_list(Meta) ->
277277
TOpts = do_quote(Opts, Q),
278278
TArg = do_quote(Arg, Q#elixir_quote{unquote=false}),
279279

@@ -284,13 +284,13 @@ do_quote({quote, Meta, [Opts, Arg]}, Q) ->
284284

285285
{'{}', [], [quote, meta(NewMeta, Q), [TOpts, TArg]]};
286286

287-
do_quote({unquote, _Meta, [Expr]}, #elixir_quote{unquote=true}) ->
287+
do_quote({unquote, Meta, [Expr]}, #elixir_quote{unquote=true}) when is_list(Meta) ->
288288
Expr;
289289

290290
%% Aliases
291291

292292
do_quote({'__aliases__', Meta, [H | T]}, #elixir_quote{aliases_hygiene=(#{}=E)} = Q)
293-
when is_atom(H), H /= 'Elixir' ->
293+
when is_list(Meta), is_atom(H), H /= 'Elixir' ->
294294
Annotation =
295295
case elixir_aliases:expand(Meta, [H | T], E, true) of
296296
Atom when is_atom(Atom) -> Atom;
@@ -312,16 +312,16 @@ do_quote({Name, Meta, nil}, #elixir_quote{op=add_context} = Q)
312312

313313
%% Unquote
314314

315-
do_quote({{{'.', Meta, [Left, unquote]}, _, [Expr]}, _, Args}, #elixir_quote{unquote=true} = Q) ->
315+
do_quote({{{'.', Meta, [Left, unquote]}, _, [Expr]}, _, Args}, #elixir_quote{unquote=true} = Q) when is_list(Meta) ->
316316
do_quote_call(Left, Meta, Expr, Args, Q);
317317

318-
do_quote({{'.', Meta, [Left, unquote]}, _, [Expr]}, #elixir_quote{unquote=true} = Q) ->
318+
do_quote({{'.', Meta, [Left, unquote]}, _, [Expr]}, #elixir_quote{unquote=true} = Q) when is_list(Meta) ->
319319
do_quote_call(Left, Meta, Expr, nil, Q);
320320

321321
%% Imports
322322

323323
do_quote({'&', Meta, [{'/', _, [{F, _, C}, A]}] = Args},
324-
#elixir_quote{imports_hygiene=(#{}=E)} = Q) when is_atom(F), is_integer(A), is_atom(C) ->
324+
#elixir_quote{imports_hygiene=(#{}=E)} = Q) when is_atom(F), is_integer(A), is_atom(C), is_list(Meta) ->
325325
NewMeta =
326326
case elixir_dispatch:find_import(Meta, F, A, E) of
327327
false ->
@@ -571,4 +571,4 @@ annotate_def({'when', Meta, [Left, Right]}, Context) ->
571571
annotate_def({Fun, Meta, Args}, Context) ->
572572
{Fun, keystore(context, Meta, Context), Args};
573573
annotate_def(Other, _Context) ->
574-
Other.
574+
Other.

lib/elixir/test/elixir/macro_test.exs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ defmodule MacroTest do
3636
assert Macro.escape({:a}) == {:{}, [], [:a]}
3737
assert Macro.escape({:a, :b, :c}) == {:{}, [], [:a, :b, :c]}
3838
assert Macro.escape({:a, {1, 2, 3}, :c}) == {:{}, [], [:a, {:{}, [], [1, 2, 3]}, :c]}
39+
40+
# False positives
41+
assert Macro.escape({:quote, :foo, [:bar]}) == {:{}, [], [:quote, :foo, [:bar]]}
42+
assert Macro.escape({:quote, :foo, [:bar, :baz]}) == {:{}, [], [:quote, :foo, [:bar, :baz]]}
3943
end
4044

4145
test "escapes maps" do

0 commit comments

Comments
 (0)