aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2015-01-27 13:42:31 +0100
committerBjörn Gustavsson <[email protected]>2015-01-28 11:59:53 +0100
commit440c54f6a6b78015e8c8e0c7d16ad3cbb3d22147 (patch)
tree232502616859bd1c428c4f17cc867bc27c7faff0 /lib/compiler
parent4a3ad317ec6ebe02ad1ecc8a4132896c333ba742 (diff)
downloadotp-440c54f6a6b78015e8c8e0c7d16ad3cbb3d22147.tar.gz
otp-440c54f6a6b78015e8c8e0c7d16ad3cbb3d22147.tar.bz2
otp-440c54f6a6b78015e8c8e0c7d16ad3cbb3d22147.zip
core_pp: Correct printing of map literals
A map key in a pattern would be incorrectly pretty-printed. As an example, the pattern in: x() -> #{ #{ a => 3 } := 42 } = X. would be pretty-printed as: <~{~<~{~<'a',3>}~,42>}~ instead of: <~{~<~{::<'a',3>}~,42>}~ When this problem has been corrected, the workaround for it in cerl:ann_c_map/3 can be removed. The workaround was not harmless, as it would cause the following map update to incorrectly succeed: (#{})#{a:=1}
Diffstat (limited to 'lib/compiler')
-rw-r--r--lib/compiler/src/cerl.erl12
-rw-r--r--lib/compiler/src/core_pp.erl10
-rw-r--r--lib/compiler/test/map_SUITE.erl6
3 files changed, 14 insertions, 14 deletions
diff --git a/lib/compiler/src/cerl.erl b/lib/compiler/src/cerl.erl
index 96c8e02542..705c87539e 100644
--- a/lib/compiler/src/cerl.erl
+++ b/lib/compiler/src/cerl.erl
@@ -1617,18 +1617,6 @@ ann_c_map(As, Es) ->
-spec ann_c_map([term()], c_map() | c_literal(), [c_map_pair()]) -> c_map() | c_literal().
-ann_c_map(As,#c_literal{val=Mval}=M,Es) when is_map(Mval), map_size(Mval) =:= 0 ->
- Pairs = [[Ck,Cv]||#c_map_pair{key=Ck,val=Cv}<-Es],
- IsLit = lists:foldl(fun(Pair,Res) ->
- Res andalso is_lit_list(Pair)
- end, true, Pairs),
- Fun = fun(Pair) -> [K,V] = lit_list_vals(Pair), {K,V} end,
- case IsLit of
- false ->
- #c_map{arg=M, es=Es, anno=As };
- true ->
- #c_literal{anno=As, val=maps:from_list(lists:map(Fun, Pairs))}
- end;
ann_c_map(As,#c_literal{val=M},Es) when is_map(M) ->
fold_map_pairs(As,Es,M);
ann_c_map(As,M,Es) ->
diff --git a/lib/compiler/src/core_pp.erl b/lib/compiler/src/core_pp.erl
index 03801a9b6d..01922c3fdf 100644
--- a/lib/compiler/src/core_pp.erl
+++ b/lib/compiler/src/core_pp.erl
@@ -184,12 +184,12 @@ format_1(#c_map{arg=Var,es=Es}, Ctxt) ->
];
format_1(#c_map_pair{op=#c_literal{val=assoc},key=K,val=V}, Ctxt) ->
["::<",
- format_hseq([K,V], ",", add_indent(Ctxt, 1), fun format/2),
+ format_map_pair(K, V, Ctxt),
">"
];
format_1(#c_map_pair{op=#c_literal{val=exact},key=K,val=V}, Ctxt) ->
["~<",
- format_hseq([K,V], ",", add_indent(Ctxt, 1), fun format/2),
+ format_map_pair(K, V, Ctxt),
">"
];
format_1(#c_cons{hd=H,tl=T}, Ctxt) ->
@@ -448,6 +448,12 @@ format_list_tail(#c_cons{anno=[],hd=H,tl=T}, Ctxt) ->
format_list_tail(Tail, Ctxt) ->
["|",format(Tail, add_indent(Ctxt, 1)),"]"].
+format_map_pair(K, V, Ctxt0) ->
+ Ctxt1 = add_indent(Ctxt0, 1),
+ Txt = format(K, set_class(Ctxt1, expr)),
+ Ctxt2 = add_indent(Ctxt0, width(Txt, Ctxt1)),
+ [Txt,",",format(V, Ctxt2)].
+
indent(Ctxt) -> indent(Ctxt#ctxt.indent, Ctxt).
indent(N, _) when N =< 0 -> "";
diff --git a/lib/compiler/test/map_SUITE.erl b/lib/compiler/test/map_SUITE.erl
index dbac61765b..bc5ae803c6 100644
--- a/lib/compiler/test/map_SUITE.erl
+++ b/lib/compiler/test/map_SUITE.erl
@@ -319,6 +319,12 @@ t_update_exact(Config) when is_list(Config) ->
{'EXIT',{badarg,_}} = (catch M0#{42=>v1,42.0:=v2,42:=v3}),
{'EXIT',{badarg,_}} = (catch <<>>#{nonexisting:=val}),
{'EXIT',{badarg,_}} = (catch M0#{<<0:257>> := val}), %% limitation
+
+ %% A workaround for a bug allowed an empty map to be updated.
+ {'EXIT',{badarg,_}} = (catch (id(#{}))#{a:=1}),
+ {'EXIT',{badarg,_}} = (catch #{}#{a:=1}),
+ Empty = #{},
+ {'EXIT',{badarg,_}} = (catch Empty#{a:=1}),
ok.
t_update_values(Config) when is_list(Config) ->