Skip to content

Commit 6660e7e

Browse files
committed
Make Access syntax fail to compile for unsupported values
1 parent 5e15f2e commit 6660e7e

File tree

3 files changed

+32
-7
lines changed

3 files changed

+32
-7
lines changed

lib/elixir/src/elixir_exp.erl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ expand_remote(Receiver, DotMeta, Right, Meta, Args, E, EL) ->
516516
ok
517517
end,
518518
{EArgs, EA} = expand_args(Args, E),
519-
{elixir_rewrite:rewrite(Receiver, DotMeta, Right, Meta, EArgs),
519+
{elixir_rewrite:rewrite(Receiver, DotMeta, Right, Meta, EArgs, EA),
520520
elixir_env:mergev(EL, EA)}.
521521

522522
%% Lexical helpers

lib/elixir/src/elixir_rewrite.erl

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
-module(elixir_rewrite).
2-
-export([rewrite/5, inline/3]).
2+
-export([rewrite/6, inline/3]).
33
-include("elixir.hrl").
44

5+
-define(is_literal(Arg), (is_binary(Arg) orelse is_number(Arg) orelse is_atom(Arg))).
6+
57
%% Convenience variables
68

79
-define(atom, 'Elixir.Atom').
10+
-define(access, 'Elixir.Access').
811
-define(enum, 'Elixir.Enum').
912
-define(float, 'Elixir.Float').
1013
-define(io, 'Elixir.IO').
@@ -173,9 +176,17 @@ inline(_, _, _) -> false.
173176

174177
%% Complex rewrite rules
175178

176-
rewrite(?string_chars, _DotMeta, 'to_string', _Meta, [String]) when is_binary(String) ->
179+
rewrite(?access, _DotMeta, 'get', _Meta, [nil, Arg], _Env)
180+
when ?is_literal(Arg) orelse (is_atom(element(1, Arg)) andalso element(3, Arg) == nil) ->
181+
nil;
182+
rewrite(?access, _DotMeta, 'get', Meta, [Arg, _], Env)
183+
when ?is_literal(Arg) orelse element(1, Arg) == '{}' orelse element(1, Arg) == '<<>>' ->
184+
elixir_errors:compile_error(Meta, ?m(Env, file),
185+
"the Access syntax and calls to Access.get/2 are not available for the value: ~ts",
186+
['Elixir.Macro':to_string(Arg)]);
187+
rewrite(?string_chars, _DotMeta, 'to_string', _Meta, [String], _File) when is_binary(String) ->
177188
String;
178-
rewrite(?string_chars, DotMeta, 'to_string', Meta, [String]) ->
189+
rewrite(?string_chars, DotMeta, 'to_string', Meta, [String], _Env) ->
179190
Var = {'rewrite', Meta, 'Elixir'},
180191
Guard = {{'.', ?generated, [erlang, is_binary]}, ?generated, [Var]},
181192
Slow = remote(?string_chars, DotMeta, 'to_string', Meta, [Var]),
@@ -186,9 +197,9 @@ rewrite(?string_chars, DotMeta, 'to_string', Meta, [String]) ->
186197
{'->', ?generated, [[Var], Slow]}]
187198
}]]};
188199

189-
rewrite(?enum, DotMeta, 'reverse', Meta, [List]) when is_list(List) ->
200+
rewrite(?enum, DotMeta, 'reverse', Meta, [List], _Env) when is_list(List) ->
190201
remote(lists, DotMeta, 'reverse', Meta, [List]);
191-
rewrite(?enum, DotMeta, 'reverse', Meta, [List]) ->
202+
rewrite(?enum, DotMeta, 'reverse', Meta, [List], _Env) ->
192203
Var = {'rewrite', Meta, 'Elixir'},
193204
Guard = {{'.', ?generated, [erlang, is_list]}, ?generated, [Var]},
194205
Slow = remote(?enum, DotMeta, 'reverse', Meta, [Var]),
@@ -199,7 +210,7 @@ rewrite(?enum, DotMeta, 'reverse', Meta, [List]) ->
199210
{'->', ?generated, [[Var], Slow]}]
200211
}]]};
201212

202-
rewrite(Receiver, DotMeta, Right, Meta, Args) ->
213+
rewrite(Receiver, DotMeta, Right, Meta, Args, _Env) ->
203214
{EReceiver, ERight, EArgs} = rewrite(Receiver, Right, Args),
204215
remote(EReceiver, DotMeta, ERight, Meta, EArgs).
205216

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,20 @@ defmodule Kernel.ErrorsTest do
5353
'fn 1 end'
5454
end
5555

56+
test "invalid Access" do
57+
msg = fn(val) ->
58+
"nofile:1: the Access syntax and calls to Access.get/2" <>
59+
" are not available for the value: " <> val
60+
end
61+
62+
assert_compile_fail CompileError, msg.("1"), "1[:foo]"
63+
assert_compile_fail CompileError, msg.("1.1"), "1.1[:foo]"
64+
assert_compile_fail CompileError, msg.("{}"), "{}[:foo]"
65+
assert_compile_fail CompileError, msg.(":foo"), ":foo[:foo]"
66+
assert_compile_fail CompileError, msg.("\"\""), "\"\"[:foo]"
67+
assert_compile_fail CompileError, msg.("<<>>"), "<<>>[:foo]"
68+
end
69+
5670
test "kw missing space" do
5771
msg = "nofile:1: keyword argument must be followed by space after: foo:"
5872

0 commit comments

Comments
 (0)