diff options
author | Björn-Egil Dahlberg <[email protected]> | 2014-04-04 12:00:07 +0200 |
---|---|---|
committer | Björn-Egil Dahlberg <[email protected]> | 2014-04-04 12:00:07 +0200 |
commit | 89eef897c6564c72d9717228a73959339e486bdb (patch) | |
tree | ebb39bfd3e9bbd3526b2996e36f1d57ee1f0b2c8 /lib/stdlib | |
parent | 76c73b9554a3d74b027bc2e1fdace7192b7a8de6 (diff) | |
parent | e26dbc750fdd207c852bf9006668c5771f465dcf (diff) | |
download | otp-89eef897c6564c72d9717228a73959339e486bdb.tar.gz otp-89eef897c6564c72d9717228a73959339e486bdb.tar.bz2 otp-89eef897c6564c72d9717228a73959339e486bdb.zip |
Merge branch 'egil/maps-fix-map-key-patterns'
* egil/maps-fix-map-key-patterns:
stdlib: Fix erl_id_trans example
stdlib: Deny map keys defined as #{ .. := .. } in patterns
compiler: Fix compiling map keys in patterns from core
compiler,stdlib: Fix Map literals as keys for Maps in patterns
Diffstat (limited to 'lib/stdlib')
-rw-r--r-- | lib/stdlib/examples/erl_id_trans.erl | 2 | ||||
-rw-r--r-- | lib/stdlib/src/erl_expand_records.erl | 6 | ||||
-rw-r--r-- | lib/stdlib/src/erl_lint.erl | 36 | ||||
-rw-r--r-- | lib/stdlib/test/erl_lint_SUITE.erl | 14 |
4 files changed, 37 insertions, 21 deletions
diff --git a/lib/stdlib/examples/erl_id_trans.erl b/lib/stdlib/examples/erl_id_trans.erl index 5fcb74310e..e71e26e51a 100644 --- a/lib/stdlib/examples/erl_id_trans.erl +++ b/lib/stdlib/examples/erl_id_trans.erl @@ -148,7 +148,7 @@ pattern({map,Line,Ps0}) -> Ps1 = pattern_list(Ps0), {map,Line,Ps1}; pattern({map_field_exact,Line,K,V}) -> - Ke = pattern(K), + Ke = expr(K), Ve = pattern(V), {map_field_exact,Line,Ke,Ve}; %%pattern({struct,Line,Tag,Ps0}) -> diff --git a/lib/stdlib/src/erl_expand_records.erl b/lib/stdlib/src/erl_expand_records.erl index f53c6e1278..57e768ba9d 100644 --- a/lib/stdlib/src/erl_expand_records.erl +++ b/lib/stdlib/src/erl_expand_records.erl @@ -135,10 +135,10 @@ pattern({tuple,Line,Ps}, St0) -> pattern({map,Line,Ps}, St0) -> {TPs,St1} = pattern_list(Ps, St0), {{map,Line,TPs},St1}; -pattern({map_field_exact,Line,Key0,V0}, St0) -> - {Key,St1} = pattern(Key0, St0), +pattern({map_field_exact,Line,K0,V0}, St0) -> + {K,St1} = expr(K0, St0), {V,St2} = pattern(V0, St1), - {{map_field_exact,Line,Key,V},St2}; + {{map_field_exact,Line,K,V},St2}; %%pattern({struct,Line,Tag,Ps}, St0) -> %% {TPs,TPsvs,St1} = pattern_list(Ps, St0), %% {{struct,Line,Tag,TPs},TPsvs,St1}; diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl index c4c94fbee4..7c064ce902 100644 --- a/lib/stdlib/src/erl_lint.erl +++ b/lib/stdlib/src/erl_lint.erl @@ -1407,7 +1407,7 @@ pattern({map,_Line,Ps}, Vt, Old, Bvt, St) -> ({map_field_assoc,L,_,_}, {Psvt,Bvt0,St0}) -> {Psvt,Bvt0,add_error(L, illegal_pattern, St0)}; ({map_field_exact,L,KP,VP}, {Psvt,Bvt0,St0}) -> - case is_valid_map_key(KP, St0) of + case is_valid_map_key(KP, pattern, St0) of true -> {Pvt,Bvt1,St1} = pattern(VP, Vt, Old, Bvt, St0), {vtmerge_pat(Pvt, Psvt),vtmerge_pat(Bvt0, Bvt1), St1}; @@ -2322,14 +2322,16 @@ is_valid_call(Call) -> %% check for value expression without variables is_valid_map_key(K,St) -> + is_valid_map_key(K,expr,St). +is_valid_map_key(K,Ctx,St) -> case expr(K,[],St) of {[],_} -> - is_valid_map_key_value(K); + is_valid_map_key_value(K,Ctx); {[Var|_],_} -> {false,variable,element(1,Var)} end. -is_valid_map_key_value(K) -> +is_valid_map_key_value(K,Ctx) -> case K of {char,_,_} -> true; {integer,_,_} -> true; @@ -2338,34 +2340,36 @@ is_valid_map_key_value(K) -> {nil,_} -> true; {atom,_,_} -> true; {cons,_,H,T} -> - is_valid_map_key_value(H) andalso - is_valid_map_key_value(T); + is_valid_map_key_value(H,Ctx) andalso + is_valid_map_key_value(T,Ctx); {tuple,_,Es} -> foldl(fun(E,B) -> - B andalso is_valid_map_key_value(E) + B andalso is_valid_map_key_value(E,Ctx) end,true,Es); {map,_,Arg,Ps} -> % only check for value expressions to be valid % invalid map expressions are later checked in % core and kernel - is_valid_map_key_value(Arg) andalso foldl(fun + is_valid_map_key_value(Arg,Ctx) andalso foldl(fun ({Tag,_,Ke,Ve},B) when Tag =:= map_field_assoc; - Tag =:= map_field_exact -> - B andalso is_valid_map_key_value(Ke) - andalso is_valid_map_key_value(Ve) + Tag =:= map_field_exact, Ctx =:= expr -> + B andalso is_valid_map_key_value(Ke,Ctx) + andalso is_valid_map_key_value(Ve,Ctx); + (_,_) -> false end,true,Ps); {map,_,Ps} -> foldl(fun ({Tag,_,Ke,Ve},B) when Tag =:= map_field_assoc; - Tag =:= map_field_exact -> - B andalso is_valid_map_key_value(Ke) - andalso is_valid_map_key_value(Ve) + Tag =:= map_field_exact, Ctx =:= expr -> + B andalso is_valid_map_key_value(Ke,Ctx) + andalso is_valid_map_key_value(Ve,Ctx); + (_,_) -> false end, true, Ps); {record,_,_,Fs} -> foldl(fun ({record_field,_,Ke,Ve},B) -> - B andalso is_valid_map_key_value(Ke) - andalso is_valid_map_key_value(Ve) + B andalso is_valid_map_key_value(Ke,Ctx) + andalso is_valid_map_key_value(Ve,Ctx) end,true,Fs); {bin,_,Es} -> % only check for value expressions to be valid @@ -2373,7 +2377,7 @@ is_valid_map_key_value(K) -> % core and kernel foldl(fun ({bin_element,_,E,_,_},B) -> - B andalso is_valid_map_key_value(E) + B andalso is_valid_map_key_value(E,Ctx) end,true,Es); _ -> false end. diff --git a/lib/stdlib/test/erl_lint_SUITE.erl b/lib/stdlib/test/erl_lint_SUITE.erl index bb14de333d..d9512c0ef4 100644 --- a/lib/stdlib/test/erl_lint_SUITE.erl +++ b/lib/stdlib/test/erl_lint_SUITE.erl @@ -3406,7 +3406,19 @@ maps(Config) -> {4,erl_lint,illegal_map_key}, {6,erl_lint,illegal_map_key}, {8,erl_lint,illegal_map_key}, - {10,erl_lint,illegal_map_key}],[]}}], + {10,erl_lint,illegal_map_key}],[]}}, + {errors_in_map_keys_pattern, + <<"t(#{ a := 2, + #{} := A, + #{ 3 => 33 } := hi, + #{ 3 := 33 } := hi, + #{ hi => 54, \"hello\" => 45 } := hi, + #{ V => 33 } := hi }) -> + A. + ">>, + [], + {errors,[{4,erl_lint,illegal_map_key}, + {6,erl_lint,{illegal_map_key_variable,'V'}}],[]}}], [] = run(Config, Ts), ok. |