aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src
diff options
context:
space:
mode:
authorBjörn-Egil Dahlberg <[email protected]>2016-11-28 11:04:02 +0100
committerBjörn-Egil Dahlberg <[email protected]>2016-11-28 11:04:02 +0100
commit4c60be1b45e3e18606f552d4cc6afc2eaad18576 (patch)
tree0a5524391ac8eb21ffd1d4ac2e79801a91d1e784 /lib/compiler/src
parent40e8a4d37d8505de57ce02c241da856564ee086d (diff)
parentfd6ba06462488da02a59ad8aa55819f0fa9ce83d (diff)
downloadotp-4c60be1b45e3e18606f552d4cc6afc2eaad18576.tar.gz
otp-4c60be1b45e3e18606f552d4cc6afc2eaad18576.tar.bz2
otp-4c60be1b45e3e18606f552d4cc6afc2eaad18576.zip
Merge branch 'egil/compiler/maps-warn-repeated-keys/OTP-14058'
* egil/compiler/maps-warn-repeated-keys/OTP-14058: compiler: Test repeated map key warnings compiler: Warn for repeated identical map keys
Diffstat (limited to 'lib/compiler/src')
-rw-r--r--lib/compiler/src/v3_core.erl32
1 files changed, 25 insertions, 7 deletions
diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl
index f40cf97f57..14cd41ae27 100644
--- a/lib/compiler/src/v3_core.erl
+++ b/lib/compiler/src/v3_core.erl
@@ -883,19 +883,33 @@ badmap_term(Map, #core{in_guard=false}) ->
c_tuple([#c_literal{val=badmap},Map]).
map_build_pairs(Map, Es0, Ann, St0) ->
- {Es,Pre,St1} = map_build_pairs_1(Es0, St0),
+ {Es,Pre,_,St1} = map_build_pairs_1(Es0, cerl_sets:new(), St0),
{ann_c_map(Ann, Map, Es),Pre,St1}.
-map_build_pairs_1([{Op0,L,K0,V0}|Es], St0) ->
+map_build_pairs_1([{Op0,L,K0,V0}|Es], Used0, St0) ->
{K,Pre0,St1} = safe(K0, St0),
{V,Pre1,St2} = safe(V0, St1),
- {Pairs,Pre2,St3} = map_build_pairs_1(Es, St2),
+ {Pairs,Pre2,Used1,St3} = map_build_pairs_1(Es, Used0, St2),
As = lineno_anno(L, St3),
Op = map_op(Op0),
+ {Used2,St4} = maybe_warn_repeated_keys(K, L, Used1, St3),
Pair = cerl:ann_c_map_pair(As, Op, K, V),
- {[Pair|Pairs],Pre0++Pre1++Pre2,St3};
-map_build_pairs_1([], St) ->
- {[],[],St}.
+ {[Pair|Pairs],Pre0++Pre1++Pre2,Used2,St4};
+map_build_pairs_1([], Used, St) ->
+ {[],[],Used,St}.
+
+maybe_warn_repeated_keys(Ck,Line,Used,St) ->
+ case cerl:is_literal(Ck) of
+ false -> {Used,St};
+ true ->
+ K = cerl:concrete(Ck),
+ case cerl_sets:is_element(K,Used) of
+ true ->
+ {Used, add_warning(Line, {map_key_repeated,K}, St)};
+ false ->
+ {cerl_sets:add_element(K,Used), St}
+ end
+ end.
map_op(map_field_assoc) -> #c_literal{val=assoc};
map_op(map_field_exact) -> #c_literal{val=exact}.
@@ -2603,7 +2617,11 @@ format_error(nomatch) ->
format_error(bad_binary) ->
"binary construction will fail because of a type mismatch";
format_error(badmap) ->
- "map construction will fail because of a type mismatch".
+ "map construction will fail because of a type mismatch";
+format_error({map_key_repeated,Key}) when is_atom(Key) ->
+ io_lib:format("key '~w' will be overridden in expression", [Key]);
+format_error({map_key_repeated,Key}) ->
+ io_lib:format("key ~p will be overridden in expression", [Key]).
add_warning(Anno, Term, #core{ws=Ws,file=[{file,File}]}=St) ->
case erl_anno:generated(Anno) of