diff --git a/lib/elixir/src/elixir_quote.erl b/lib/elixir/src/elixir_quote.erl index 65a7049d7cc..9e60ede10bf 100644 --- a/lib/elixir/src/elixir_quote.erl +++ b/lib/elixir/src/elixir_quote.erl @@ -139,7 +139,7 @@ escape(Expr, Op, Unquote) -> unquote=Unquote }). -do_escape({Left, Meta, Right}, #elixir_quote{op=prune_metadata} = Q) -> +do_escape({Left, Meta, Right}, #elixir_quote{op=prune_metadata} = Q) when is_list(Meta) -> TM = [{K, V} || {K, V} <- Meta, (K == no_parens) orelse (K == line)], TL = do_quote(Left, Q), TR = do_quote(Right, Q), @@ -263,7 +263,7 @@ quote(Expr, Q) -> %% quote/unquote -do_quote({quote, Meta, [Arg]}, Q) -> +do_quote({quote, Meta, [Arg]}, Q) when is_list(Meta) -> TArg = do_quote(Arg, Q#elixir_quote{unquote=false}), NewMeta = case Q of @@ -273,7 +273,7 @@ do_quote({quote, Meta, [Arg]}, Q) -> {'{}', [], [quote, meta(NewMeta, Q), [TArg]]}; -do_quote({quote, Meta, [Opts, Arg]}, Q) -> +do_quote({quote, Meta, [Opts, Arg]}, Q) when is_list(Meta) -> TOpts = do_quote(Opts, Q), TArg = do_quote(Arg, Q#elixir_quote{unquote=false}), @@ -284,13 +284,13 @@ do_quote({quote, Meta, [Opts, Arg]}, Q) -> {'{}', [], [quote, meta(NewMeta, Q), [TOpts, TArg]]}; -do_quote({unquote, _Meta, [Expr]}, #elixir_quote{unquote=true}) -> +do_quote({unquote, Meta, [Expr]}, #elixir_quote{unquote=true}) when is_list(Meta) -> Expr; %% Aliases do_quote({'__aliases__', Meta, [H | T]}, #elixir_quote{aliases_hygiene=(#{}=E)} = Q) - when is_atom(H), H /= 'Elixir' -> + when is_list(Meta), is_atom(H), H /= 'Elixir' -> Annotation = case elixir_aliases:expand(Meta, [H | T], E, true) of Atom when is_atom(Atom) -> Atom; @@ -312,16 +312,16 @@ do_quote({Name, Meta, nil}, #elixir_quote{op=add_context} = Q) %% Unquote -do_quote({{{'.', Meta, [Left, unquote]}, _, [Expr]}, _, Args}, #elixir_quote{unquote=true} = Q) -> +do_quote({{{'.', Meta, [Left, unquote]}, _, [Expr]}, _, Args}, #elixir_quote{unquote=true} = Q) when is_list(Meta) -> do_quote_call(Left, Meta, Expr, Args, Q); -do_quote({{'.', Meta, [Left, unquote]}, _, [Expr]}, #elixir_quote{unquote=true} = Q) -> +do_quote({{'.', Meta, [Left, unquote]}, _, [Expr]}, #elixir_quote{unquote=true} = Q) when is_list(Meta) -> do_quote_call(Left, Meta, Expr, nil, Q); %% Imports do_quote({'&', Meta, [{'/', _, [{F, _, C}, A]}] = Args}, - #elixir_quote{imports_hygiene=(#{}=E)} = Q) when is_atom(F), is_integer(A), is_atom(C) -> + #elixir_quote{imports_hygiene=(#{}=E)} = Q) when is_atom(F), is_integer(A), is_atom(C), is_list(Meta) -> NewMeta = case elixir_dispatch:find_import(Meta, F, A, E) of false -> @@ -571,4 +571,4 @@ annotate_def({'when', Meta, [Left, Right]}, Context) -> annotate_def({Fun, Meta, Args}, Context) -> {Fun, keystore(context, Meta, Context), Args}; annotate_def(Other, _Context) -> - Other. \ No newline at end of file + Other. diff --git a/lib/elixir/test/elixir/macro_test.exs b/lib/elixir/test/elixir/macro_test.exs index 0b4aecb8ee1..a1f697685a8 100644 --- a/lib/elixir/test/elixir/macro_test.exs +++ b/lib/elixir/test/elixir/macro_test.exs @@ -36,6 +36,10 @@ defmodule MacroTest do assert Macro.escape({:a}) == {:{}, [], [:a]} assert Macro.escape({:a, :b, :c}) == {:{}, [], [:a, :b, :c]} assert Macro.escape({:a, {1, 2, 3}, :c}) == {:{}, [], [:a, {:{}, [], [1, 2, 3]}, :c]} + + # False positives + assert Macro.escape({:quote, :foo, [:bar]}) == {:{}, [], [:quote, :foo, [:bar]]} + assert Macro.escape({:quote, :foo, [:bar, :baz]}) == {:{}, [], [:quote, :foo, [:bar, :baz]]} end test "escapes maps" do