Skip to content

Commit 1177c50

Browse files
committed
More precise error message when escaping a regex with a ref
1 parent 443d96a commit 1177c50

File tree

2 files changed

+16
-5
lines changed

2 files changed

+16
-5
lines changed

lib/elixir/src/elixir_quote.erl

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -165,12 +165,12 @@ do_escape(BitString, _) when is_bitstring(BitString) ->
165165

166166
do_escape(Map, Q) when is_map(Map) ->
167167
TT =
168-
[if
169-
is_reference(V) ->
168+
[case extract_value_ref(V) of
169+
Ref when is_reference(Ref) ->
170170
argument_error(<<('Elixir.Kernel':inspect(Map, []))/binary, " contains a reference (",
171-
('Elixir.Kernel':inspect(V, []))/binary, ") and therefore it cannot be escaped ",
171+
('Elixir.Kernel':inspect(Ref, []))/binary, ") and therefore it cannot be escaped ",
172172
"(it must be defined within a function instead). ", (bad_escape_hint())/binary>>);
173-
true ->
173+
_ ->
174174
{do_quote(K, Q), do_quote(V, Q)}
175175
end || {K, V} <- lists:sort(maps:to_list(Map))],
176176
{'%{}', [], TT};
@@ -206,6 +206,17 @@ do_escape(Fun, _) when is_function(Fun) ->
206206
do_escape(Other, _) ->
207207
bad_escape(Other).
208208

209+
extract_value_ref(Ref) when is_reference(Ref) -> Ref;
210+
extract_value_ref(Tuple) when is_tuple(Tuple) -> extract_value_ref_from_tuple(Tuple, 1);
211+
extract_value_ref(_) -> nil.
212+
213+
extract_value_ref_from_tuple(Tuple, Index) when Index > tuple_size(Tuple) -> nil;
214+
extract_value_ref_from_tuple(Tuple, Index) ->
215+
case element(Index, Tuple) of
216+
Ref when is_reference(Ref) -> Ref;
217+
_ -> extract_value_ref_from_tuple(Tuple, Index + 1)
218+
end.
219+
209220
bad_escape(Arg) ->
210221
argument_error(<<"cannot escape ", ('Elixir.Kernel':inspect(Arg, []))/binary, ". ",
211222
(bad_escape_hint())/binary>>).

lib/elixir/test/elixir/macro_test.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ defmodule MacroTest do
143143

144144
test "inspects container when a reference cannot be escaped" do
145145
assert_raise ArgumentError, ~r"~r/foo/ contains a reference", fn ->
146-
Macro.escape(%{~r/foo/ | re_pattern: make_ref()})
146+
Macro.escape(%{~r/foo/ | re_pattern: {:re_pattern, 0, 0, 0, make_ref()}})
147147
end
148148
end
149149
end

0 commit comments

Comments
 (0)