aboutsummaryrefslogtreecommitdiffstats
path: root/lib/stdlib
diff options
context:
space:
mode:
authorJosé Valim <[email protected]>2015-10-19 16:55:24 +0200
committerJosé Valim <[email protected]>2015-10-19 16:58:52 +0200
commitc0c2f6a204d83ee89cd179b0a6d5996e248539e5 (patch)
tree5f0172327edc4d23c71cbddb94d0bf86e6dc7d78 /lib/stdlib
parent98647fcc1632f60871adee20031e294e5d5b6eb0 (diff)
downloadotp-c0c2f6a204d83ee89cd179b0a6d5996e248539e5.tar.gz
otp-c0c2f6a204d83ee89cd179b0a6d5996e248539e5.tar.bz2
otp-c0c2f6a204d83ee89cd179b0a6d5996e248539e5.zip
Use full list of bindings when matching on map keys
Prior to this patch, the following code would not eval: X = key, (fun(#{X := value}) -> true end)(#{X => value}) That's because the key evaluation was using the new list of bindings introduced on every anonymous fun. Since keys only match on values defined prior to the pattern and do not introduce any new binding, we must use the full and original list of binding.
Diffstat (limited to 'lib/stdlib')
-rw-r--r--lib/stdlib/src/erl_eval.erl2
-rw-r--r--lib/stdlib/test/erl_eval_SUITE.erl10
2 files changed, 11 insertions, 1 deletions
diff --git a/lib/stdlib/src/erl_eval.erl b/lib/stdlib/src/erl_eval.erl
index ca3cc43b19..568eb1c852 100644
--- a/lib/stdlib/src/erl_eval.erl
+++ b/lib/stdlib/src/erl_eval.erl
@@ -1184,7 +1184,7 @@ match_tuple([], _, _, Bs, _BBs) ->
match_map([{map_field_exact, _, K, V}|Fs], Map, Bs0, BBs) ->
Vm = try
- {value, Ke, _} = expr(K, Bs0),
+ {value, Ke, _} = expr(K, BBs),
maps:get(Ke,Map)
catch error:_ ->
throw(nomatch)
diff --git a/lib/stdlib/test/erl_eval_SUITE.erl b/lib/stdlib/test/erl_eval_SUITE.erl
index b9c4ad0a46..50fc62a00e 100644
--- a/lib/stdlib/test/erl_eval_SUITE.erl
+++ b/lib/stdlib/test/erl_eval_SUITE.erl
@@ -1483,6 +1483,16 @@ eep43(Config) when is_list(Config) ->
" #{ K1 := 1, K2 := 2, K3 := 3, {2,2} := 4} = Map "
"end.",
#{ 1 => 1, <<42:301>> => 2, {3,<<42:301>>} => 3, {2,2} => 4}),
+ check(fun () ->
+ X = key,
+ (fun(#{X := value}) -> true end)(#{X => value})
+ end,
+ "begin "
+ " X = key, "
+ " (fun(#{X := value}) -> true end)(#{X => value}) "
+ "end.",
+ true),
+
error_check("[camembert]#{}.", {badmap,[camembert]}),
error_check("[camembert]#{nonexisting:=v}.", {badmap,[camembert]}),
error_check("#{} = 1.", {badmatch,1}),