Skip to content

Commit 1c7a37a

Browse files
author
José Valim
committed
Raise proper exception on invalid quoted expression
We also documented valid types in Macro.t Closes #1411
1 parent 84a0985 commit 1c7a37a

File tree

4 files changed

+45
-6
lines changed

4 files changed

+45
-6
lines changed

lib/elixir/lib/macro.ex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ defmodule Macro do
55
This module provides conveniences for working with macros.
66
"""
77

8+
@type t :: { t, t } | { t, Keyword.t, t } | atom | number | binary | list
9+
810
@doc """
911
Returns a list of binary operators. This is available
1012
as a macro so it can be used in guard clauses.

lib/elixir/src/elixir_dispatch.erl

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ expand_macro_fun(Meta, Fun, Receiver, Name, Args, Module, S) ->
189189
apply(Fun, [SArg|Args])
190190
catch
191191
Kind:Reason ->
192-
Info = { Receiver, Name, length(Args), [{ file, S#elixir_scope.file }, { line, Line }] },
192+
Info = { Receiver, Name, length(Args), location(Line, S) },
193193
erlang:raise(Kind, Reason, munge_stacktrace(Info, erlang:get_stacktrace(), SArg))
194194
end.
195195

@@ -200,10 +200,29 @@ expand_macro_named(Meta, Receiver, Name, Arity, Args, Module, S) ->
200200
expand_macro_fun(Meta, Fun, Receiver, Name, Args, Module, S).
201201

202202
translate_expansion(Meta, Tree, S) ->
203-
elixir_translator:translate_each(
204-
elixir_quote:linify(?line(Meta), Tree),
205-
S
206-
).
203+
Line = ?line(Meta),
204+
205+
try
206+
elixir_translator:translate_each(
207+
elixir_quote:linify(Line, Tree),
208+
S
209+
)
210+
catch
211+
Kind:Reason ->
212+
erlang:raise(Kind, Reason, [mfa(Line, S)|erlang:get_stacktrace()])
213+
end.
214+
215+
mfa(Line, #elixir_scope{module=nil} = S) ->
216+
{ elixir_compiler, '__FILE__', 2, location(Line, S) };
217+
218+
mfa(Line, #elixir_scope{module=Module,function=nil} = S) ->
219+
{ Module, '__MODULE__', 0, location(Line, S) };
220+
221+
mfa(Line, #elixir_scope{module=Module,function={ Name, Arity }} = S) ->
222+
{ Module, Name, Arity, location(Line, S) }.
223+
224+
location(Line, S) ->
225+
[{ file, S#elixir_scope.file }, { line, Line }].
207226

208227
%% Helpers
209228

lib/elixir/src/elixir_literal.erl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,11 @@ translate(Atom, S) when is_atom(Atom) ->
6565
{ { atom, 0, Atom }, S };
6666

6767
translate(Bitstring, S) when is_bitstring(Bitstring) ->
68-
{ elixir_tree_helpers:elixir_to_erl(Bitstring), S }.
68+
{ elixir_tree_helpers:elixir_to_erl(Bitstring), S };
69+
70+
translate(Other, S) ->
71+
elixir_errors:compile_error(0, S#elixir_scope.file, "invalid quoted expression: ~ts",
72+
['Elixir.Kernel':inspect(Other)]).
6973

7074
%% Helpers
7175

lib/elixir/test/elixir/kernel/errors_test.exs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,20 @@ defmodule Kernel.ErrorsTest do
329329
'''
330330
end
331331

332+
test :invalid_macro do
333+
assert_compile_fail CompileError,
334+
"nofile: invalid quoted expression: {:foo, :bar, :baz, :bat}",
335+
'''
336+
defmodule ErrorsTest do
337+
defmacrop oops do
338+
{ :foo, :bar, :baz, :bat }
339+
end
340+
341+
def test, do: oops
342+
end
343+
'''
344+
end
345+
332346
test :unloaded_module do
333347
assert_compile_fail CompileError,
334348
"nofile:1: module Certainly.Doesnt.Exist is not loaded and could not be found",

0 commit comments

Comments
 (0)