diff options
author | Björn-Egil Dahlberg <[email protected]> | 2014-02-07 18:28:29 +0100 |
---|---|---|
committer | Björn-Egil Dahlberg <[email protected]> | 2014-02-07 18:28:29 +0100 |
commit | 67663e057a35dfee45bf802539738b8ef107bd32 (patch) | |
tree | a0bb369bfd343436f59630d31d5bf72ffc87c801 /lib | |
parent | 46cad6ef63c4b9adc7b9fd795e8484c03e73dce5 (diff) | |
download | otp-67663e057a35dfee45bf802539738b8ef107bd32.tar.gz otp-67663e057a35dfee45bf802539738b8ef107bd32.tar.bz2 otp-67663e057a35dfee45bf802539738b8ef107bd32.zip |
compiler: Fix sys_core_fold let optimization
Map variable was not covered and faulty optimization could occur.
Ex.
t() ->
M0 = id(#{ "a" => 1 }),
#{ "a" := _ } = M0,
M0#{ "a" := b }.
M0 was lost in let expression optimization.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/compiler/src/core_lib.erl | 4 | ||||
-rw-r--r-- | lib/compiler/test/map_SUITE.erl | 11 |
2 files changed, 13 insertions, 2 deletions
diff --git a/lib/compiler/src/core_lib.erl b/lib/compiler/src/core_lib.erl index f506901099..ed181e3baa 100644 --- a/lib/compiler/src/core_lib.erl +++ b/lib/compiler/src/core_lib.erl @@ -105,8 +105,8 @@ vu_expr(V, #c_cons{hd=H,tl=T}) -> vu_expr(V, H) orelse vu_expr(V, T); vu_expr(V, #c_tuple{es=Es}) -> vu_expr_list(V, Es); -vu_expr(V, #c_map{es=Es}) -> - vu_expr_list(V, Es); +vu_expr(V, #c_map{var=M,es=Es}) -> + vu_expr(V, M) orelse vu_expr_list(V, Es); vu_expr(V, #c_map_pair{key=Key,val=Val}) -> vu_expr_list(V, [Key,Val]); vu_expr(V, #c_binary{segments=Ss}) -> diff --git a/lib/compiler/test/map_SUITE.erl b/lib/compiler/test/map_SUITE.erl index dc880a7a9d..cad6ac6887 100644 --- a/lib/compiler/test/map_SUITE.erl +++ b/lib/compiler/test/map_SUITE.erl @@ -179,6 +179,17 @@ t_update_map_expressions(Config) when is_list(Config) -> #{ a :=42, b:=42, c:=42 } = (maps:from_list([{a,1},{b,2},{c,3}]))#{ a := 42, b := 42, c := 42 }, #{ "a" :=1, "b":=42, "c":=42 } = (maps:from_list([{"a",1},{"b",2}]))#{ "b" := 42, "c" => 42 }, + %% Test need to be in a fun. + %% This tests that let expr optimisation in sys_core_fold + %% covers maps correctly. + F = fun() -> + M0 = id(#{ "a" => [1,2,3] }), + #{ "a" := _ } = M0, + M0#{ "a" := b } + end, + + #{ "a" := b } = F(), + %% Error cases, FIXME: should be 'badmap'? {'EXIT',{badarg,_}} = (catch (id(<<>>))#{ a := 42, b => 2 }), {'EXIT',{badarg,_}} = (catch (id([]))#{ a := 42, b => 2 }), |