From a0988a638a92211ae0af6ec35ca99edfc05110aa Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Sat, 10 Nov 2012 21:32:31 +0100 Subject: Test named funs --- lib/compiler/test/fun_SUITE.erl | 13 ++++- lib/debugger/test/erl_eval_SUITE.erl | 26 +++++++++- lib/debugger/test/fun_SUITE.erl | 17 ++++++- lib/dialyzer/test/small_SUITE_data/results/eep37 | 0 lib/dialyzer/test/small_SUITE_data/src/eep37.erl | 15 ++++++ lib/stdlib/test/erl_eval_SUITE.erl | 27 ++++++++++- lib/stdlib/test/erl_lint_SUITE.erl | 60 ++++++++++++++++++++++-- lib/stdlib/test/erl_pp_SUITE.erl | 27 ++++++++++- lib/stdlib/test/ms_transform_SUITE.erl | 11 ++++- lib/stdlib/test/qlc_SUITE.erl | 14 +++++- lib/tools/test/cover_SUITE.erl | 18 ++++++- lib/tools/test/xref_SUITE.erl | 13 +++-- lib/tools/test/xref_SUITE_data/read/read.erl | 27 +++++------ 13 files changed, 230 insertions(+), 38 deletions(-) create mode 100644 lib/dialyzer/test/small_SUITE_data/results/eep37 create mode 100644 lib/dialyzer/test/small_SUITE_data/src/eep37.erl (limited to 'lib') diff --git a/lib/compiler/test/fun_SUITE.erl b/lib/compiler/test/fun_SUITE.erl index 6067ee8e06..e35692efd1 100644 --- a/lib/compiler/test/fun_SUITE.erl +++ b/lib/compiler/test/fun_SUITE.erl @@ -21,7 +21,7 @@ -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2, test1/1,overwritten_fun/1,otp_7202/1,bif_fun/1, - external/1]). + external/1,eep37/1]). %% Internal export. -export([call_me/1]). @@ -32,7 +32,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> test_lib:recompile(?MODULE), - [test1,overwritten_fun,otp_7202,bif_fun,external]. + [test1,overwritten_fun,otp_7202,bif_fun,external,eep37]. groups() -> []. @@ -197,5 +197,14 @@ external(Config) when is_list(Config) -> call_me(I) -> {ok,I}. +eep37(Config) when is_list(Config) -> + F = fun Fact(N) when N > 0 -> N * Fact(N - 1); Fact(0) -> 1 end, + Add = fun _(N) -> N + 1 end, + UnusedName = fun BlackAdder(N) -> N + 42 end, + 720 = F(6), + 10 = Add(9), + 50 = UnusedName(8), + ok. + id(I) -> I. diff --git a/lib/debugger/test/erl_eval_SUITE.erl b/lib/debugger/test/erl_eval_SUITE.erl index bb2669f450..be9312b68f 100644 --- a/lib/debugger/test/erl_eval_SUITE.erl +++ b/lib/debugger/test/erl_eval_SUITE.erl @@ -39,7 +39,8 @@ otp_8133/1, funs/1, try_catch/1, - eval_expr_5/1]). + eval_expr_5/1, + eep37/1]). %% %% Define to run outside of test server @@ -78,7 +79,7 @@ all() -> pattern_expr, match_bin, guard_3, guard_4, lc, simple_cases, unary_plus, apply_atom, otp_5269, otp_6539, otp_6543, otp_6787, otp_6977, otp_7550, - otp_8133, funs, try_catch, eval_expr_5]. + otp_8133, funs, try_catch, eval_expr_5, eep37]. groups() -> []. @@ -1323,6 +1324,27 @@ eval_expr_5(Config) when is_list(Config) -> ok end. +eep37(Config) when is_list(Config) -> + check(fun () -> (fun _(X) -> X end)(42) end, + "(fun _(X) -> X end)(42).", + 42), + check(fun () -> (fun _Id(X) -> X end)(42) end, + "(fun _Id(X) -> X end)(42).", 42), + check(fun () -> is_function((fun Self() -> Self end)(), 0) end, + "is_function((fun Self() -> Self end)(), 0).", + true), + check(fun () -> + F = fun Fact(N) when N > 0 -> + N * Fact(N - 1); + Fact(0) -> + 1 + end, + F(6) + end, + "(fun Fact(N) when N > 0 -> N * Fact(N - 1); Fact(0) -> 1 end)(6).", + 720), + ok. + %% Check the string in different contexts: as is; in fun; from compiled code. check(F, String, Result) -> check1(F, String, Result), diff --git a/lib/debugger/test/fun_SUITE.erl b/lib/debugger/test/fun_SUITE.erl index a06cdc7165..8425f973e6 100644 --- a/lib/debugger/test/fun_SUITE.erl +++ b/lib/debugger/test/fun_SUITE.erl @@ -24,7 +24,7 @@ init_per_testcase/2,end_per_testcase/2, init_per_suite/1,end_per_suite/1, good_call/1,bad_apply/1,bad_fun_call/1,badarity/1, - ext_badarity/1,otp_6061/1,external/1]). + ext_badarity/1,otp_6061/1,external/1,eep37/1]). %% Internal exports. -export([nothing/0,call_me/1]). @@ -48,7 +48,7 @@ end_per_group(_GroupName, Config) -> cases() -> [good_call, bad_apply, bad_fun_call, badarity, - ext_badarity, otp_6061, external]. + ext_badarity, otp_6061, external, eep37]. init_per_testcase(_Case, Config) -> test_lib:interpret(?MODULE), @@ -288,5 +288,18 @@ external(Config) when is_list(Config) -> call_me(I) -> {ok,I}. +eep37(Config) when is_list(Config) -> + F = fun Fact(N) when N > 0 -> N * Fact(N - 1); Fact(0) -> 1 end, + Add = fun _(N) -> N + 1 end, + UnusedName = fun BlackAdder(N) -> N + 42 end, + 720 = F(6), + 10 = Add(9), + 50 = UnusedName(8), + [1,1,2,6,24,120] = lists:map(F, lists:seq(0, 5)), + {'EXIT',{{badarity,_},_}} = (catch lists:map(fun G() -> G() end, [1])), + {'EXIT',{{badarity,_},_}} = (catch F()), + + ok. + id(I) -> I. diff --git a/lib/dialyzer/test/small_SUITE_data/results/eep37 b/lib/dialyzer/test/small_SUITE_data/results/eep37 new file mode 100644 index 0000000000..e69de29bb2 diff --git a/lib/dialyzer/test/small_SUITE_data/src/eep37.erl b/lib/dialyzer/test/small_SUITE_data/src/eep37.erl new file mode 100644 index 0000000000..2818688f95 --- /dev/null +++ b/lib/dialyzer/test/small_SUITE_data/src/eep37.erl @@ -0,0 +1,15 @@ +-module(eep37). + +-compile(export_all). + +-spec self() -> fun(() -> fun()). +self() -> + fun Self() -> Self end. + +-spec fact() -> fun((non_neg_integer()) -> non_neg_integer()). +fact() -> + fun Fact(N) when N > 0 -> + N * Fact(N - 1); + Fact(0) -> + 1 + end. diff --git a/lib/stdlib/test/erl_eval_SUITE.erl b/lib/stdlib/test/erl_eval_SUITE.erl index 7ceef727f1..c4b6b35e72 100644 --- a/lib/stdlib/test/erl_eval_SUITE.erl +++ b/lib/stdlib/test/erl_eval_SUITE.erl @@ -41,7 +41,8 @@ funs/1, try_catch/1, eval_expr_5/1, - zero_width/1]). + zero_width/1, + eep37/1]). %% %% Define to run outside of test server @@ -80,7 +81,8 @@ all() -> pattern_expr, match_bin, guard_3, guard_4, lc, simple_cases, unary_plus, apply_atom, otp_5269, otp_6539, otp_6543, otp_6787, otp_6977, otp_7550, - otp_8133, otp_10622, funs, try_catch, eval_expr_5, zero_width]. + otp_8133, otp_10622, funs, try_catch, eval_expr_5, zero_width, + eep37]. groups() -> []. @@ -1401,6 +1403,27 @@ zero_width(Config) when is_list(Config) -> "ok end.", ok), ok. +eep37(Config) when is_list(Config) -> + check(fun () -> (fun _(X) -> X end)(42) end, + "(fun _(X) -> X end)(42).", + 42), + check(fun () -> (fun _Id(X) -> X end)(42) end, + "(fun _Id(X) -> X end)(42).", 42), + check(fun () -> is_function((fun Self() -> Self end)(), 0) end, + "is_function((fun Self() -> Self end)(), 0).", + true), + check(fun () -> + F = fun Fact(N) when N > 0 -> + N * Fact(N - 1); + Fact(0) -> + 1 + end, + F(6) + end, + "(fun Fact(N) when N > 0 -> N * Fact(N - 1); Fact(0) -> 1 end)(6).", + 720), + ok. + %% Check the string in different contexts: as is; in fun; from compiled code. check(F, String, Result) -> check1(F, String, Result), diff --git a/lib/stdlib/test/erl_lint_SUITE.erl b/lib/stdlib/test/erl_lint_SUITE.erl index 6bf87adf14..a71d7f3018 100644 --- a/lib/stdlib/test/erl_lint_SUITE.erl +++ b/lib/stdlib/test/erl_lint_SUITE.erl @@ -575,7 +575,7 @@ unused_vars_warn_rec(Config) when is_list(Config) -> ok. unused_vars_warn_fun(doc) -> - "Warnings for unused variables in records."; + "Warnings for unused variables in funs."; unused_vars_warn_fun(suite) -> []; unused_vars_warn_fun(Config) when is_list(Config) -> Ts = [{fun1, @@ -643,7 +643,60 @@ unused_vars_warn_fun(Config) when is_list(Config) -> {22,erl_lint,{unused_var,'U'}}, {24,erl_lint,{unused_var,'U'}}, {26,erl_lint,{unused_var,'U'}}, - {26,erl_lint,{shadowed_var,'U','fun'}}]}} + {26,erl_lint,{shadowed_var,'U','fun'}}]}}, + {named_fun, + <<"u() -> + fun U() -> foo end, % U unused. + U; % U unbound. + u() -> + case foo of + true -> + U = 2; + false -> + true + end, + fun U() -> foo end, % U unused. + U; % U unsafe. + u() -> + case foo of + true -> + U = 2; + false -> + U = 3 + end, + fun U() -> foo end, % U shadowed. U unused. + U; + u() -> + case foo of + true -> + U = 2; % U unused. + false -> + U = 3 % U unused. + end, + fun U() -> foo end; % U shadowed. U unused. + u() -> + fun U(U) -> foo end; % U shadowed. U unused. + u() -> + fun U(1) -> U; U(U) -> foo end; % U shadowed. U unused. + u() -> + fun _(N) -> N + 1 end. % Cover handling of '_' name. + ">>, + [warn_unused_vars], + {error,[{3,erl_lint,{unbound_var,'U'}}, + {12,erl_lint,{unsafe_var,'U',{'case',5}}}], + [{2,erl_lint,{unused_var,'U'}}, + {11,erl_lint,{unused_var,'U'}}, + {20,erl_lint,{unused_var,'U'}}, + {20,erl_lint,{shadowed_var,'U','named fun'}}, + {25,erl_lint,{unused_var,'U'}}, + {27,erl_lint,{unused_var,'U'}}, + {29,erl_lint,{unused_var,'U'}}, + {29,erl_lint,{shadowed_var,'U','named fun'}}, + {31,erl_lint,{unused_var,'U'}}, + {31,erl_lint,{unused_var,'U'}}, + {31,erl_lint,{shadowed_var,'U','fun'}}, + {33,erl_lint,{unused_var,'U'}}, + {33,erl_lint,{shadowed_var,'U','fun'}}]}} ], ?line [] = run(Config, Ts), ok. @@ -2201,7 +2254,8 @@ otp_5878(Config) when is_list(Config) -> <<"-record(r1, {t = case foo of _ -> 3 end}). -record(r2, {a = case foo of A -> A; _ -> 3 end}). -record(r3, {a = case foo of A -> A end}). - t() -> {#r1{},#r2{},#r3{}}. + -record(r4, {a = fun _AllowedFunName() -> allowed end}). + t() -> {#r1{},#r2{},#r3{},#r4{}}. ">>, [warn_unused_record], {errors,[{2,erl_lint,{variable_in_record_def,'A'}}, diff --git a/lib/stdlib/test/erl_pp_SUITE.erl b/lib/stdlib/test/erl_pp_SUITE.erl index 70a9d70e5c..cc744ee76b 100644 --- a/lib/stdlib/test/erl_pp_SUITE.erl +++ b/lib/stdlib/test/erl_pp_SUITE.erl @@ -130,7 +130,27 @@ func(Config) when is_list(Config) -> true end)().">>}, {func_7, - <<"t(M, F, A) -> fun M:F/A.">>} + <<"t(M, F, A) -> fun M:F/A.">>}, + {func_8, + <<"-record(r1, {a,b}). + -record(r3, {a = fun Id(_) -> #r1{} end(1), b}). + + t() -> + fun Id(A) when record(A#r3.a, r1) -> 7 end(#r3{}). + ">>}, + {func_9, + <<"-record(r1, {a,b}). + -record(r3, {a = fun Id(_) -> #r1{} end(1), b}). + + t() -> + fsdfsdfjsdfjkljf:sdlfjdsfjlf( + fun Id(sdfsd) -> {sdkjsdf,sdfjsdkljfsdl,sdfkjdklf} end). + ">>}, + {func_10, + <<"t() -> + (fun True() -> + true + end)().">>} ], ?line compile(Config, Ts), ok. @@ -158,6 +178,7 @@ recs(Config) when is_list(Config) -> -record(r1, {a,b}). -record(r2, {a = #r1{},b,c=length([1,2,3])}). -record(r3, {a = fun(_) -> #r1{} end(1), b}). + -record(r4, {a = fun R1(_) -> #r1{} end(1), b}). t() -> foo = fun(A) when A#r1.a > A#r1.b -> foo end(#r1{b = 2}), @@ -741,6 +762,7 @@ neg_indent(Config) when is_list(Config) -> ?line ok = pp_expr(<<"{[a,b,c],[d,e|f]}">>), ?line ok = pp_expr(<<"f(a,b,c)">>), ?line ok = pp_expr(<<"fun() when a,b;c,d -> a end">>), + ?line ok = pp_expr(<<"fun A() when a,b;c,d -> a end">>), ?line ok = pp_expr(<<"<<34:32,17:32>>">>), ?line ok = pp_expr(<<"if a,b,c -> d; e,f,g -> h,i end">>), ?line ok = pp_expr(<<"if a -> d; c -> d end">>), @@ -763,6 +785,9 @@ neg_indent(Config) when is_list(Config) -> Fun2 = {'fun',2,{clauses,[{clause,2,[],[],[{atom,3,true}]}]}, {0,108059557,'-t/0-fun-0-'}}, ?line "fun() -> true end" = flat_expr(Fun2), + Fun3 = {named_fun,3,'True',[{clause,3,[],[],[{atom,3,true}]}], + {0,424242424,'-t/0-True-0-'}}, + ?line "fun True() -> true end" = flat_expr(Fun3), ok. diff --git a/lib/stdlib/test/ms_transform_SUITE.erl b/lib/stdlib/test/ms_transform_SUITE.erl index a17307b07b..4ec13ed472 100644 --- a/lib/stdlib/test/ms_transform_SUITE.erl +++ b/lib/stdlib/test/ms_transform_SUITE.erl @@ -40,6 +40,7 @@ -export([action_function/1]). -export([warnings/1]). -export([no_warnings/1]). +-export([eep37/1]). -export([init_per_testcase/2, end_per_testcase/2]). init_per_testcase(_Func, Config) -> @@ -57,7 +58,7 @@ all() -> record_index, multipass, bitsyntax, record_defaults, andalso_orelse, float_1_function, action_function, warnings, no_warnings, top_match, old_guards, autoimported, - semicolon]. + semicolon, eep37]. groups() -> []. @@ -806,6 +807,14 @@ action_function(Config) when is_list(Config) -> ok. +eep37(Config) when is_list(Config) -> + setup(Config), + [{'$1',[],['$1']}] = + compile_and_run(<<"F = fun _Ms() ->\n" + " ets:fun2ms(fun (X) -> X end)\n" + " end,\n" + "F()">>). + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/lib/stdlib/test/qlc_SUITE.erl b/lib/stdlib/test/qlc_SUITE.erl index 5f9244b479..2846657c09 100644 --- a/lib/stdlib/test/qlc_SUITE.erl +++ b/lib/stdlib/test/qlc_SUITE.erl @@ -76,7 +76,9 @@ manpage/1, - backward/1, forward/1]). + backward/1, forward/1, + + eep37/1]). %% Internal exports. -export([bad_table_throw/1, bad_table_exit/1, default_table/1, bad_table/1, @@ -132,7 +134,7 @@ groups() -> evaluator, string_to_handle, table, process_dies, sort, keysort, filesort, cache, cache_list, filter, info, nested_info, lookup1, lookup2, lookup_rec, indices, - pre_fun, skip_filters]}, + pre_fun, skip_filters, eep37]}, {table_impls, [], [ets, dets]}, {join, [], [join_option, join_filter, join_lookup, join_merge, @@ -7427,6 +7429,14 @@ forward(Config) when is_list(Config) -> ?line run(Config, Ts), ok. +eep37(Config) when is_list(Config) -> + Ts = [ + <<"H = (fun _Handle() -> qlc:q([X || X <- []]) end)(), + [] = qlc:eval(H)">> + ], + run(Config, Ts), + ok. + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% bad_table_throw(Tab) -> diff --git a/lib/tools/test/cover_SUITE.erl b/lib/tools/test/cover_SUITE.erl index 29b26c7a76..bd71218474 100644 --- a/lib/tools/test/cover_SUITE.erl +++ b/lib/tools/test/cover_SUITE.erl @@ -28,7 +28,7 @@ export_import/1, otp_5031/1, eif/1, otp_5305/1, otp_5418/1, otp_6115/1, otp_7095/1, otp_8188/1, otp_8270/1, otp_8273/1, otp_8340/1, - otp_10979_hanging_node/1, compile_beam_opts/1]). + otp_10979_hanging_node/1, compile_beam_opts/1, eep37/1]). -include_lib("test_server/include/test_server.hrl"). @@ -53,7 +53,7 @@ all() -> dont_reconnect_after_stop, stop_node_after_disconnect, export_import, otp_5031, eif, otp_5305, otp_5418, otp_6115, otp_7095, otp_8188, otp_8270, otp_8273, - otp_8340, otp_10979_hanging_node, compile_beam_opts]; + otp_8340, otp_10979_hanging_node, compile_beam_opts, eep37]; _pid -> {skip, "It looks like the test server is running " @@ -1382,6 +1382,20 @@ comprehension_8188(Cf) -> ok. +eep37(Config) when is_list(Config) -> + [{{t,1},1},{{t,2},1},{{t,4},6},{{t,6},1},{{t,8},1}] = + analyse_expr(<<"begin\n" % 1 + " F =\n" % 1 + " fun Fact(N) when N > 0 ->\n" + " N * Fact(N - 1);\n" % 6 + " Fact(0) ->\n" + " 1\n" % 1 + " end,\n" + " F(6)\n" % 1 + "end\n">>, + Config), + ok. + otp_10979_hanging_node(_Config) -> P1 = processes(), diff --git a/lib/tools/test/xref_SUITE.erl b/lib/tools/test/xref_SUITE.erl index 31b0b13b7b..3e9eaf259c 100644 --- a/lib/tools/test/xref_SUITE.erl +++ b/lib/tools/test/xref_SUITE.erl @@ -1047,7 +1047,7 @@ read_expected(Version) -> POS1 = 28, POS2 = POS1+10, POS3 = POS2+6, POS4 = POS3+6, POS5 = POS4+10, POS6 = POS5+5, POS7 = POS6+6, POS8 = POS7+6, POS9 = POS8+8, POS10 = POS9+10, POS11 = POS10+7, POS12 = POS11+8, POS13 = POS12+10, - POS14 = POS13+18, % POS15 = POS14+23, + POS14 = POS13+18, POS15 = POS14+23, FF = {read,funfuns,0}, U = [{POS1+5,{FF,{dist,'$F_EXPR',0}}}, @@ -1196,11 +1196,6 @@ read_expected(Version) -> {0,{FF,{modul,'$F_EXPR',179}}}] ++ O1; _ -> -% [{POS15+2,{{read,bi,0},{foo,t,0}}}, -% {POS15+3,{{read,bi,0},{bar,t,0}}}, -% {POS15+6,{{read,bi,0},{read,local,0}}}, -% {POS15+8,{{read,bi,0},{foo,t,0}}}, -% {POS15+10,{{read,bi,0},{bar,t,0}}}] ++ [{16,{FF,{read,'$F_EXPR',178}}}, {17,{FF,{modul,'$F_EXPR',179}}}] ++ @@ -1227,7 +1222,11 @@ read_expected(Version) -> _ -> [{POS13+16, {{read,bi,0},{erlang,'!',2}}}, {POS13+16, {{read,bi,0},{erlang,'-',1}}}, - {POS13+16, {{read,bi,0},{erlang,self,0}}}] + {POS13+16, {{read,bi,0},{erlang,self,0}}}, + {POS15+1, {{read,bi,0},{erlang,'>',2}}}, + {POS15+2, {{read,bi,0},{erlang,'-',2}}}, + {POS15+2, {{read,bi,0},{erlang,'*',2}}}, + {POS15+8, {{read,bi,0},{erlang,'/',2}}}] end ++ [{POS14+19, {{read,bi,0},{erlang,'+',2}}}, {POS14+21, {{read,bi,0},{erlang,'+',2}}}, diff --git a/lib/tools/test/xref_SUITE_data/read/read.erl b/lib/tools/test/xref_SUITE_data/read/read.erl index 19694c9e25..5f388194b0 100644 --- a/lib/tools/test/xref_SUITE_data/read/read.erl +++ b/lib/tools/test/xref_SUITE_data/read/read.erl @@ -156,20 +156,19 @@ bi() -> <> = Bin3, X = 9, <<(X+1):8>>, _Fyy = <>, - D + E + F. -%bi() -> -% %% POS15=POS14+13 -% try -% foo:t(), -% bar:t() -% of -% {v,1} -> -% local(); -% {v,2} -> -% foo:t() -% catch -% {'EXIT',_} -> bar:t() -% end. + D + E + F; +bi() -> + %% EEP37. POS15=POS14+23 + F = fun Fact(N) when N > 0 -> + N * Fact(N - 1); + Fact(0) -> + 1 + end, + F(6), + G = fun _(foo) -> bar; + _(X) -> X / 3 + end, + G(foo). local() -> true. -- cgit v1.2.3