diff options
author | José Valim <[email protected]> | 2015-10-19 16:55:24 +0200 |
---|---|---|
committer | José Valim <[email protected]> | 2015-10-19 16:58:52 +0200 |
commit | c0c2f6a204d83ee89cd179b0a6d5996e248539e5 (patch) | |
tree | 5f0172327edc4d23c71cbddb94d0bf86e6dc7d78 /lib/stdlib | |
parent | 98647fcc1632f60871adee20031e294e5d5b6eb0 (diff) | |
download | otp-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.erl | 2 | ||||
-rw-r--r-- | lib/stdlib/test/erl_eval_SUITE.erl | 10 |
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}), |