From aa9834f86a1f2e96e5fcb058108d710d9f443ff3 Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Sat, 3 Nov 2012 17:53:23 +0100 Subject: Silence some wrong warnings triggered by inline_list_funcs Code like `lists:map(fun(X) -> X end, ?C10k), ok` triggers the following warning: no_file:none: Warning: a term is constructed, but never used --- lib/compiler/src/sys_core_fold.erl | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl index 18fba7962b..17397bef2e 100644 --- a/lib/compiler/src/sys_core_fold.erl +++ b/lib/compiler/src/sys_core_fold.erl @@ -756,6 +756,7 @@ call_1(#c_call{anno=Anno}, lists, map, [Arg1,Arg2], Sub) -> op=F, args=[X]}, body=#c_cons{hd=H, + anno=[compiler_generated], tl=#c_apply{anno=Anno, op=Loop, args=[Xs]}}}}, @@ -780,7 +781,7 @@ call_1(#c_call{anno=Anno}, lists, flatmap, [Arg1,Arg2], Sub) -> C1 = #c_clause{pats=[#c_cons{hd=X, tl=Xs}], guard=#c_literal{val=true}, body=#c_let{vars=[H], arg=#c_apply{anno=Anno, op=F, args=[X]}, - body=#c_call{anno=Anno, + body=#c_call{anno=[compiler_generated|Anno], module=#c_literal{val=erlang}, name=#c_literal{val='++'}, args=[H, @@ -807,7 +808,7 @@ call_1(#c_call{anno=Anno}, lists, filter, [Arg1,Arg2], Sub) -> B = #c_var{name='B'}, Err1 = #c_tuple{es=[#c_literal{val='case_clause'}, X]}, CC1 = #c_clause{pats=[#c_literal{val=true}], guard=#c_literal{val=true}, - body=#c_cons{hd=X, tl=Xs}}, + body=#c_cons{anno=[compiler_generated], hd=X, tl=Xs}}, CC2 = #c_clause{pats=[#c_literal{val=false}], guard=#c_literal{val=true}, body=Xs}, CC3 = #c_clause{pats=[X], guard=#c_literal{val=true}, @@ -901,7 +902,10 @@ call_1(#c_call{anno=Anno}, lists, mapfoldl, [Arg1,Arg2,Arg3], Sub) -> op=Loop, args=[Xs, Avar]}, #c_tuple{es=[Xs, Avar]}, - #c_tuple{es=[#c_cons{hd=X, tl=Xs}, Avar]}) + #c_tuple{anno=[compiler_generated], + es=[#c_cons{anno=[compiler_generated], + hd=X, tl=Xs}, + Avar]}) %%% Multiple-value version %%% #c_let{vars=[Xs,A], %%% %% The tuple here will be optimised @@ -912,7 +916,8 @@ call_1(#c_call{anno=Anno}, lists, mapfoldl, [Arg1,Arg2,Arg3], Sub) -> )}, C2 = #c_clause{pats=[#c_literal{val=[]}], guard=#c_literal{val=true}, %%% Tuple passing version - body=#c_tuple{es=[#c_literal{val=[]}, Avar]}}, + body=#c_tuple{anno=[compiler_generated], + es=[#c_literal{val=[]}, Avar]}}, %%% Multiple-value version %%% body=#c_values{es=[#c_literal{val=[]}, A]}}, Err = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]}, @@ -955,7 +960,9 @@ call_1(#c_call{anno=Anno}, lists, mapfoldr, [Arg1,Arg2,Arg3], Sub) -> #c_tuple{es=[Xs, Avar]}, Match(#c_apply{anno=Anno, op=F, args=[X, Avar]}, #c_tuple{es=[X, Avar]}, - #c_tuple{es=[#c_cons{hd=X, tl=Xs}, Avar]})) + #c_tuple{anno=[compiler_generated], + es=[#c_cons{anno=[compiler_generated], + hd=X, tl=Xs}, Avar]})) %%% Multiple-value version %%% body=#c_let{vars=[Xs,A], %%% %% The tuple will be optimised away @@ -967,7 +974,8 @@ call_1(#c_call{anno=Anno}, lists, mapfoldr, [Arg1,Arg2,Arg3], Sub) -> }, C2 = #c_clause{pats=[#c_literal{val=[]}], guard=#c_literal{val=true}, %%% Tuple passing version - body=#c_tuple{es=[#c_literal{val=[]}, Avar]}}, + body=#c_tuple{anno=[compiler_generated], + es=[#c_literal{val=[]}, Avar]}}, %%% Multiple-value version %%% body=#c_values{es=[#c_literal{val=[]}, A]}}, Err = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]}, -- cgit v1.2.3 From 98ee8e929c7e4015fab483a7eb112a94e777ea3b Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Sat, 3 Nov 2012 18:55:07 +0100 Subject: Document compiler option 'inline_list_funcs' --- lib/compiler/doc/src/compile.xml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'lib') diff --git a/lib/compiler/doc/src/compile.xml b/lib/compiler/doc/src/compile.xml index 27d750f929..ddaae2655d 100644 --- a/lib/compiler/doc/src/compile.xml +++ b/lib/compiler/doc/src/compile.xml @@ -815,6 +815,32 @@ pi() -> 3.1416. +
+ Inlining of list functions +

The compiler can also inline a variety of list manipulation functions + from the stdlib's lists module.

+ +

This feature must be explicitly enabled with a compiler option or a + -compile() attribute in the source module.

+ +

To enable inlining of list functions, use the inline_list_funcs + option.

+ +

The following functions are inlined:

+ + lists:all/2 + lists:any/2 + lists:foreach/2 + lists:map/2 + lists:flatmap/2 + lists:filter/2 + lists:foldl/3 + lists:foldr/3 + lists:mapfoldl/3 + lists:mapfoldr/3 + +
+
Parse Transformations -- cgit v1.2.3 From 2ca91b2f861a17a741ef0249dd11a319dc72660b Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Sun, 4 Nov 2012 17:24:15 +0100 Subject: Make inlined list functions fail with function_clause The function_clause errors produced by inline_list_funcs should properly be annotated with their function names to avoid kernel_v3 making them into case_clauses errors. See v3_kernel:translate_match_fail_1/4. --- lib/compiler/src/sys_core_fold.erl | 20 ++++++++++---------- lib/compiler/test/inline_SUITE.erl | 22 ++++++++++++++++++++++ 2 files changed, 32 insertions(+), 10 deletions(-) (limited to 'lib') diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl index 17397bef2e..8649ba8f01 100644 --- a/lib/compiler/src/sys_core_fold.erl +++ b/lib/compiler/src/sys_core_fold.erl @@ -690,7 +690,7 @@ call_1(#c_call{anno=Anno}, lists, all, [Arg1,Arg2], Sub) -> body=#c_literal{val=true}}, Err2 = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]}, C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true}, - body=match_fail(Anno, Err2)}, + body=match_fail([{function_name,{'lists^all',1}}|Anno], Err2)}, Fun = #c_fun{vars=[Xs], body=#c_case{arg=Xs, clauses=[C1, C2, C3]}}, L = #c_var{name='L'}, @@ -717,7 +717,7 @@ call_1(#c_call{anno=Anno}, lists, any, [Arg1,Arg2], Sub) -> body=#c_literal{val=false}}, Err2 = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]}, C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true}, - body=match_fail(Anno, Err2)}, + body=match_fail([{function_name,{'lists^any',1}}|Anno], Err2)}, Fun = #c_fun{vars=[Xs], body=#c_case{arg=Xs, clauses=[C1, C2, C3]}}, L = #c_var{name='L'}, @@ -737,7 +737,7 @@ call_1(#c_call{anno=Anno}, lists, foreach, [Arg1,Arg2], Sub) -> body=#c_literal{val=ok}}, Err = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]}, C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true}, - body=match_fail(Anno, Err)}, + body=match_fail([{function_name,{'lists^foreach',1}}|Anno], Err)}, Fun = #c_fun{vars=[Xs], body=#c_case{arg=Xs, clauses=[C1, C2, C3]}}, L = #c_var{name='L'}, @@ -764,7 +764,7 @@ call_1(#c_call{anno=Anno}, lists, map, [Arg1,Arg2], Sub) -> body=#c_literal{val=[]}}, Err = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]}, C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true}, - body=match_fail(Anno, Err)}, + body=match_fail([{function_name,{'lists^map',1}}|Anno], Err)}, Fun = #c_fun{vars=[Xs], body=#c_case{arg=Xs, clauses=[C1, C2, C3]}}, L = #c_var{name='L'}, @@ -792,7 +792,7 @@ call_1(#c_call{anno=Anno}, lists, flatmap, [Arg1,Arg2], Sub) -> body=#c_literal{val=[]}}, Err = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]}, C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true}, - body=match_fail(Anno, Err)}, + body=match_fail([{function_name,{'lists^flatmap',1}}|Anno], Err)}, Fun = #c_fun{vars=[Xs], body=#c_case{arg=Xs, clauses=[C1, C2, C3]}}, L = #c_var{name='L'}, @@ -826,7 +826,7 @@ call_1(#c_call{anno=Anno}, lists, filter, [Arg1,Arg2], Sub) -> body=#c_literal{val=[]}}, Err2 = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]}, C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true}, - body=match_fail(Anno, Err2)}, + body=match_fail([{function_name,{'lists^filter',1}}|Anno], Err2)}, Fun = #c_fun{vars=[Xs], body=#c_case{arg=Xs, clauses=[C1, C2, C3]}}, L = #c_var{name='L'}, @@ -849,7 +849,7 @@ call_1(#c_call{anno=Anno}, lists, foldl, [Arg1,Arg2,Arg3], Sub) -> C2 = #c_clause{pats=[#c_literal{val=[]}], guard=#c_literal{val=true}, body=A}, Err = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]}, C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true}, - body=match_fail(Anno, Err)}, + body=match_fail([{function_name,{'lists^foldl',2}}|Anno], Err)}, Fun = #c_fun{vars=[Xs, A], body=#c_case{arg=Xs, clauses=[C1, C2, C3]}}, L = #c_var{name='L'}, @@ -872,7 +872,7 @@ call_1(#c_call{anno=Anno}, lists, foldr, [Arg1,Arg2,Arg3], Sub) -> C2 = #c_clause{pats=[#c_literal{val=[]}], guard=#c_literal{val=true}, body=A}, Err = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]}, C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true}, - body=match_fail(Anno, Err)}, + body=match_fail([{function_name,{'lists^foldr',2}}|Anno], Err)}, Fun = #c_fun{vars=[Xs, A], body=#c_case{arg=Xs, clauses=[C1, C2, C3]}}, L = #c_var{name='L'}, @@ -922,7 +922,7 @@ call_1(#c_call{anno=Anno}, lists, mapfoldl, [Arg1,Arg2,Arg3], Sub) -> %%% body=#c_values{es=[#c_literal{val=[]}, A]}}, Err = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]}, C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true}, - body=match_fail(Anno, Err)}, + body=match_fail([{function_name,{'lists^mapfoldl',2}}|Anno], Err)}, Fun = #c_fun{vars=[Xs, Avar], body=#c_case{arg=Xs, clauses=[C1, C2, C3]}}, L = #c_var{name='L'}, @@ -980,7 +980,7 @@ call_1(#c_call{anno=Anno}, lists, mapfoldr, [Arg1,Arg2,Arg3], Sub) -> %%% body=#c_values{es=[#c_literal{val=[]}, A]}}, Err = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]}, C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true}, - body=match_fail(Anno, Err)}, + body=match_fail([{function_name,{'lists^mapfoldr',2}}|Anno], Err)}, Fun = #c_fun{vars=[Xs, Avar], body=#c_case{arg=Xs, clauses=[C1, C2, C3]}}, L = #c_var{name='L'}, diff --git a/lib/compiler/test/inline_SUITE.erl b/lib/compiler/test/inline_SUITE.erl index 2e17d3fde6..01bc9b34ad 100644 --- a/lib/compiler/test/inline_SUITE.erl +++ b/lib/compiler/test/inline_SUITE.erl @@ -255,6 +255,28 @@ lists(Config) when is_list(Config) -> %% Cleanup. erase(?MODULE), + + {'EXIT',{function_clause,_}} = + (catch lists:map(fun (X) -> X end, not_a_list)), + {'EXIT',{function_clause,_}} = + (catch lists:flatmap(fun (X) -> X end, not_a_list)), + {'EXIT',{function_clause,_}} = + (catch lists:foreach(fun (X) -> X end, not_a_list)), + {'EXIT',{function_clause,_}} = + (catch lists:filter(fun (_) -> true end, not_a_list)), + {'EXIT',{function_clause,_}} = + (catch lists:any(fun (_) -> false end, not_a_list)), + {'EXIT',{function_clause,_}} = + (catch lists:all(fun (_) -> true end, not_a_list)), + {'EXIT',{function_clause,_}} = + (catch lists:foldl(fun (X, Acc) -> {X,Acc} end, acc, not_a_list)), + {'EXIT',{function_clause,_}} = + (catch lists:foldr(fun (X, Acc) -> {X,Acc} end, acc, not_a_list)), + {'EXIT',{function_clause,_}} = + (catch lists:mapfoldl(fun (X, Acc) -> {X,Acc} end, acc, not_a_list)), + {'EXIT',{function_clause,_}} = + (catch lists:mapfoldr(fun (X, Acc) -> {X,Acc} end, acc, not_a_list)), + ok. my_apply(M, F, A, Init) -> -- cgit v1.2.3 From 572d66b1e4a5d5e519f89881a18bdf4f2745f62c Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Sun, 4 Nov 2012 19:20:29 +0100 Subject: Properly guard against badly-typed arguments when inlining The inlining code for inline_list_funcs silenced the function_clause error that should occur when calling lists:map(3.5, []). --- lib/compiler/src/sys_core_fold.erl | 52 ++++++++++++++++++++++++++++++-------- lib/compiler/test/inline_SUITE.erl | 13 ++++++++++ 2 files changed, 55 insertions(+), 10 deletions(-) (limited to 'lib') diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl index 8649ba8f01..a09d80ac3f 100644 --- a/lib/compiler/src/sys_core_fold.erl +++ b/lib/compiler/src/sys_core_fold.erl @@ -686,7 +686,10 @@ call_1(#c_call{anno=Anno}, lists, all, [Arg1,Arg2], Sub) -> C1 = #c_clause{pats=[#c_cons{hd=X, tl=Xs}], guard=#c_literal{val=true}, body=#c_case{arg=#c_apply{anno=Anno, op=F, args=[X]}, clauses = [CC1, CC2, CC3]}}, - C2 = #c_clause{pats=[#c_literal{val=[]}], guard=#c_literal{val=true}, + C2 = #c_clause{pats=[#c_literal{val=[]}], + guard=#c_call{module=#c_literal{val=erlang}, + name=#c_literal{val=is_function}, + args=[F, #c_literal{val=1}]}, body=#c_literal{val=true}}, Err2 = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]}, C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true}, @@ -713,7 +716,10 @@ call_1(#c_call{anno=Anno}, lists, any, [Arg1,Arg2], Sub) -> C1 = #c_clause{pats=[#c_cons{hd=X, tl=Xs}], guard=#c_literal{val=true}, body=#c_case{arg=#c_apply{anno=Anno, op=F, args=[X]}, clauses = [CC1, CC2, CC3]}}, - C2 = #c_clause{pats=[#c_literal{val=[]}], guard=#c_literal{val=true}, + C2 = #c_clause{pats=[#c_literal{val=[]}], + guard=#c_call{module=#c_literal{val=erlang}, + name=#c_literal{val=is_function}, + args=[F, #c_literal{val=1}]}, body=#c_literal{val=false}}, Err2 = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]}, C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true}, @@ -733,7 +739,10 @@ call_1(#c_call{anno=Anno}, lists, foreach, [Arg1,Arg2], Sub) -> C1 = #c_clause{pats=[#c_cons{hd=X, tl=Xs}], guard=#c_literal{val=true}, body=#c_seq{arg=#c_apply{anno=Anno, op=F, args=[X]}, body=#c_apply{anno=Anno, op=Loop, args=[Xs]}}}, - C2 = #c_clause{pats=[#c_literal{val=[]}], guard=#c_literal{val=true}, + C2 = #c_clause{pats=[#c_literal{val=[]}], + guard=#c_call{module=#c_literal{val=erlang}, + name=#c_literal{val=is_function}, + args=[F, #c_literal{val=1}]}, body=#c_literal{val=ok}}, Err = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]}, C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true}, @@ -760,7 +769,10 @@ call_1(#c_call{anno=Anno}, lists, map, [Arg1,Arg2], Sub) -> tl=#c_apply{anno=Anno, op=Loop, args=[Xs]}}}}, - C2 = #c_clause{pats=[#c_literal{val=[]}], guard=#c_literal{val=true}, + C2 = #c_clause{pats=[#c_literal{val=[]}], + guard=#c_call{module=#c_literal{val=erlang}, + name=#c_literal{val=is_function}, + args=[F, #c_literal{val=1}]}, body=#c_literal{val=[]}}, Err = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]}, C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true}, @@ -788,7 +800,10 @@ call_1(#c_call{anno=Anno}, lists, flatmap, [Arg1,Arg2], Sub) -> #c_apply{anno=Anno, op=Loop, args=[Xs]}]}}}, - C2 = #c_clause{pats=[#c_literal{val=[]}], guard=#c_literal{val=true}, + C2 = #c_clause{pats=[#c_literal{val=[]}], + guard=#c_call{module=#c_literal{val=erlang}, + name=#c_literal{val=is_function}, + args=[F, #c_literal{val=1}]}, body=#c_literal{val=[]}}, Err = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]}, C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true}, @@ -822,7 +837,10 @@ call_1(#c_call{anno=Anno}, lists, filter, [Arg1,Arg2], Sub) -> op=Loop, args=[Xs]}, body=Case}}}, - C2 = #c_clause{pats=[#c_literal{val=[]}], guard=#c_literal{val=true}, + C2 = #c_clause{pats=[#c_literal{val=[]}], + guard=#c_call{module=#c_literal{val=erlang}, + name=#c_literal{val=is_function}, + args=[F, #c_literal{val=1}]}, body=#c_literal{val=[]}}, Err2 = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]}, C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true}, @@ -846,7 +864,11 @@ call_1(#c_call{anno=Anno}, lists, foldl, [Arg1,Arg2,Arg3], Sub) -> args=[Xs, #c_apply{anno=Anno, op=F, args=[X, A]}]}}, - C2 = #c_clause{pats=[#c_literal{val=[]}], guard=#c_literal{val=true}, body=A}, + C2 = #c_clause{pats=[#c_literal{val=[]}], + guard=#c_call{module=#c_literal{val=erlang}, + name=#c_literal{val=is_function}, + args=[F, #c_literal{val=2}]}, + body=A}, Err = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]}, C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true}, body=match_fail([{function_name,{'lists^foldl',2}}|Anno], Err)}, @@ -869,7 +891,11 @@ call_1(#c_call{anno=Anno}, lists, foldr, [Arg1,Arg2,Arg3], Sub) -> args=[X, #c_apply{anno=Anno, op=Loop, args=[Xs, A]}]}}, - C2 = #c_clause{pats=[#c_literal{val=[]}], guard=#c_literal{val=true}, body=A}, + C2 = #c_clause{pats=[#c_literal{val=[]}], + guard=#c_call{module=#c_literal{val=erlang}, + name=#c_literal{val=is_function}, + args=[F, #c_literal{val=2}]}, + body=A}, Err = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]}, C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true}, body=match_fail([{function_name,{'lists^foldr',2}}|Anno], Err)}, @@ -914,7 +940,10 @@ call_1(#c_call{anno=Anno}, lists, mapfoldl, [Arg1,Arg2,Arg3], Sub) -> %%% body=#c_values{es=[#c_cons{hd=X, tl=Xs}, %%% A]}} )}, - C2 = #c_clause{pats=[#c_literal{val=[]}], guard=#c_literal{val=true}, + C2 = #c_clause{pats=[#c_literal{val=[]}], + guard=#c_call{module=#c_literal{val=erlang}, + name=#c_literal{val=is_function}, + args=[F, #c_literal{val=2}]}, %%% Tuple passing version body=#c_tuple{anno=[compiler_generated], es=[#c_literal{val=[]}, Avar]}}, @@ -972,7 +1001,10 @@ call_1(#c_call{anno=Anno}, lists, mapfoldr, [Arg1,Arg2,Arg3], Sub) -> %%% #c_values{es=[#c_cons{hd=X, tl=Xs}, %%% A]})} }, - C2 = #c_clause{pats=[#c_literal{val=[]}], guard=#c_literal{val=true}, + C2 = #c_clause{pats=[#c_literal{val=[]}], + guard=#c_call{module=#c_literal{val=erlang}, + name=#c_literal{val=is_function}, + args=[F, #c_literal{val=2}]}, %%% Tuple passing version body=#c_tuple{anno=[compiler_generated], es=[#c_literal{val=[]}, Avar]}}, diff --git a/lib/compiler/test/inline_SUITE.erl b/lib/compiler/test/inline_SUITE.erl index 01bc9b34ad..63180c3f95 100644 --- a/lib/compiler/test/inline_SUITE.erl +++ b/lib/compiler/test/inline_SUITE.erl @@ -277,6 +277,19 @@ lists(Config) when is_list(Config) -> {'EXIT',{function_clause,_}} = (catch lists:mapfoldr(fun (X, Acc) -> {X,Acc} end, acc, not_a_list)), + {'EXIT',{function_clause,_}} = (catch lists:map(not_a_function, [])), + {'EXIT',{function_clause,_}} = (catch lists:flatmap(not_a_function, [])), + {'EXIT',{function_clause,_}} = (catch lists:foreach(not_a_function, [])), + {'EXIT',{function_clause,_}} = (catch lists:filter(not_a_function, [])), + {'EXIT',{function_clause,_}} = (catch lists:any(not_a_function, [])), + {'EXIT',{function_clause,_}} = (catch lists:all(not_a_function, [])), + {'EXIT',{function_clause,_}} = (catch lists:foldl(not_a_function, acc, [])), + {'EXIT',{function_clause,_}} = (catch lists:foldr(not_a_function, acc, [])), + {'EXIT',{function_clause,_}} = + (catch lists:mapfoldl(not_a_function, acc, [])), + {'EXIT',{function_clause,_}} = + (catch lists:mapfoldr(not_a_function, acc, [])), + ok. my_apply(M, F, A, Init) -> -- cgit v1.2.3 From 7b0b3688ba8b921b8cc1eff39ed39a14c424d557 Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Mon, 5 Nov 2012 17:04:07 +0100 Subject: Raise a function_clause error with the right arguments when inlining The inlined lists functions raised an error with only the list instead of all their given arguments. --- lib/compiler/src/sys_core_fold.erl | 20 ++++++++-------- lib/compiler/test/inline_SUITE.erl | 48 ++++++++++++++++++++++---------------- 2 files changed, 38 insertions(+), 30 deletions(-) (limited to 'lib') diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl index a09d80ac3f..f17b0bd130 100644 --- a/lib/compiler/src/sys_core_fold.erl +++ b/lib/compiler/src/sys_core_fold.erl @@ -691,7 +691,7 @@ call_1(#c_call{anno=Anno}, lists, all, [Arg1,Arg2], Sub) -> name=#c_literal{val=is_function}, args=[F, #c_literal{val=1}]}, body=#c_literal{val=true}}, - Err2 = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]}, + Err2 = #c_tuple{es=[#c_literal{val='function_clause'}, F, Xs]}, C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true}, body=match_fail([{function_name,{'lists^all',1}}|Anno], Err2)}, Fun = #c_fun{vars=[Xs], @@ -721,7 +721,7 @@ call_1(#c_call{anno=Anno}, lists, any, [Arg1,Arg2], Sub) -> name=#c_literal{val=is_function}, args=[F, #c_literal{val=1}]}, body=#c_literal{val=false}}, - Err2 = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]}, + Err2 = #c_tuple{es=[#c_literal{val='function_clause'}, F, Xs]}, C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true}, body=match_fail([{function_name,{'lists^any',1}}|Anno], Err2)}, Fun = #c_fun{vars=[Xs], @@ -744,7 +744,7 @@ call_1(#c_call{anno=Anno}, lists, foreach, [Arg1,Arg2], Sub) -> name=#c_literal{val=is_function}, args=[F, #c_literal{val=1}]}, body=#c_literal{val=ok}}, - Err = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]}, + Err = #c_tuple{es=[#c_literal{val='function_clause'}, F, Xs]}, C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true}, body=match_fail([{function_name,{'lists^foreach',1}}|Anno], Err)}, Fun = #c_fun{vars=[Xs], @@ -774,7 +774,7 @@ call_1(#c_call{anno=Anno}, lists, map, [Arg1,Arg2], Sub) -> name=#c_literal{val=is_function}, args=[F, #c_literal{val=1}]}, body=#c_literal{val=[]}}, - Err = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]}, + Err = #c_tuple{es=[#c_literal{val='function_clause'}, F, Xs]}, C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true}, body=match_fail([{function_name,{'lists^map',1}}|Anno], Err)}, Fun = #c_fun{vars=[Xs], @@ -805,7 +805,7 @@ call_1(#c_call{anno=Anno}, lists, flatmap, [Arg1,Arg2], Sub) -> name=#c_literal{val=is_function}, args=[F, #c_literal{val=1}]}, body=#c_literal{val=[]}}, - Err = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]}, + Err = #c_tuple{es=[#c_literal{val='function_clause'}, F, Xs]}, C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true}, body=match_fail([{function_name,{'lists^flatmap',1}}|Anno], Err)}, Fun = #c_fun{vars=[Xs], @@ -842,7 +842,7 @@ call_1(#c_call{anno=Anno}, lists, filter, [Arg1,Arg2], Sub) -> name=#c_literal{val=is_function}, args=[F, #c_literal{val=1}]}, body=#c_literal{val=[]}}, - Err2 = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]}, + Err2 = #c_tuple{es=[#c_literal{val='function_clause'}, F, Xs]}, C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true}, body=match_fail([{function_name,{'lists^filter',1}}|Anno], Err2)}, Fun = #c_fun{vars=[Xs], @@ -869,7 +869,7 @@ call_1(#c_call{anno=Anno}, lists, foldl, [Arg1,Arg2,Arg3], Sub) -> name=#c_literal{val=is_function}, args=[F, #c_literal{val=2}]}, body=A}, - Err = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]}, + Err = #c_tuple{es=[#c_literal{val='function_clause'}, F, A, Xs]}, C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true}, body=match_fail([{function_name,{'lists^foldl',2}}|Anno], Err)}, Fun = #c_fun{vars=[Xs, A], @@ -896,7 +896,7 @@ call_1(#c_call{anno=Anno}, lists, foldr, [Arg1,Arg2,Arg3], Sub) -> name=#c_literal{val=is_function}, args=[F, #c_literal{val=2}]}, body=A}, - Err = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]}, + Err = #c_tuple{es=[#c_literal{val='function_clause'}, F, A, Xs]}, C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true}, body=match_fail([{function_name,{'lists^foldr',2}}|Anno], Err)}, Fun = #c_fun{vars=[Xs, A], @@ -949,7 +949,7 @@ call_1(#c_call{anno=Anno}, lists, mapfoldl, [Arg1,Arg2,Arg3], Sub) -> es=[#c_literal{val=[]}, Avar]}}, %%% Multiple-value version %%% body=#c_values{es=[#c_literal{val=[]}, A]}}, - Err = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]}, + Err = #c_tuple{es=[#c_literal{val='function_clause'}, F, Avar, Xs]}, C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true}, body=match_fail([{function_name,{'lists^mapfoldl',2}}|Anno], Err)}, Fun = #c_fun{vars=[Xs, Avar], @@ -1010,7 +1010,7 @@ call_1(#c_call{anno=Anno}, lists, mapfoldr, [Arg1,Arg2,Arg3], Sub) -> es=[#c_literal{val=[]}, Avar]}}, %%% Multiple-value version %%% body=#c_values{es=[#c_literal{val=[]}, A]}}, - Err = #c_tuple{es=[#c_literal{val='function_clause'}, Xs]}, + Err = #c_tuple{es=[#c_literal{val='function_clause'}, F, Avar, Xs]}, C3 = #c_clause{pats=[Xs], guard=#c_literal{val=true}, body=match_fail([{function_name,{'lists^mapfoldr',2}}|Anno], Err)}, Fun = #c_fun{vars=[Xs, Avar], diff --git a/lib/compiler/test/inline_SUITE.erl b/lib/compiler/test/inline_SUITE.erl index 63180c3f95..e7bb552edb 100644 --- a/lib/compiler/test/inline_SUITE.erl +++ b/lib/compiler/test/inline_SUITE.erl @@ -256,38 +256,46 @@ lists(Config) when is_list(Config) -> %% Cleanup. erase(?MODULE), - {'EXIT',{function_clause,_}} = + {'EXIT',{function_clause,[{?MODULE,_,[_,not_a_list],_}|_]}} = (catch lists:map(fun (X) -> X end, not_a_list)), - {'EXIT',{function_clause,_}} = + {'EXIT',{function_clause,[{?MODULE,_,[_,not_a_list],_}|_]}} = (catch lists:flatmap(fun (X) -> X end, not_a_list)), - {'EXIT',{function_clause,_}} = + {'EXIT',{function_clause,[{?MODULE,_,[_,not_a_list],_}|_]}} = (catch lists:foreach(fun (X) -> X end, not_a_list)), - {'EXIT',{function_clause,_}} = + {'EXIT',{function_clause,[{?MODULE,_,[_,not_a_list],_}|_]}} = (catch lists:filter(fun (_) -> true end, not_a_list)), - {'EXIT',{function_clause,_}} = + {'EXIT',{function_clause,[{?MODULE,_,[_,not_a_list],_}|_]}} = (catch lists:any(fun (_) -> false end, not_a_list)), - {'EXIT',{function_clause,_}} = + {'EXIT',{function_clause,[{?MODULE,_,[_,not_a_list],_}|_]}} = (catch lists:all(fun (_) -> true end, not_a_list)), - {'EXIT',{function_clause,_}} = + {'EXIT',{function_clause,[{?MODULE,_,[_,acc,not_a_list],_}|_]}} = (catch lists:foldl(fun (X, Acc) -> {X,Acc} end, acc, not_a_list)), - {'EXIT',{function_clause,_}} = + {'EXIT',{function_clause,[{?MODULE,_,[_,acc,not_a_list],_}|_]}} = (catch lists:foldr(fun (X, Acc) -> {X,Acc} end, acc, not_a_list)), - {'EXIT',{function_clause,_}} = + {'EXIT',{function_clause,[{?MODULE,_,[_,acc,not_a_list],_}|_]}} = (catch lists:mapfoldl(fun (X, Acc) -> {X,Acc} end, acc, not_a_list)), - {'EXIT',{function_clause,_}} = + {'EXIT',{function_clause,[{?MODULE,_,[_,acc,not_a_list],_}|_]}} = (catch lists:mapfoldr(fun (X, Acc) -> {X,Acc} end, acc, not_a_list)), - {'EXIT',{function_clause,_}} = (catch lists:map(not_a_function, [])), - {'EXIT',{function_clause,_}} = (catch lists:flatmap(not_a_function, [])), - {'EXIT',{function_clause,_}} = (catch lists:foreach(not_a_function, [])), - {'EXIT',{function_clause,_}} = (catch lists:filter(not_a_function, [])), - {'EXIT',{function_clause,_}} = (catch lists:any(not_a_function, [])), - {'EXIT',{function_clause,_}} = (catch lists:all(not_a_function, [])), - {'EXIT',{function_clause,_}} = (catch lists:foldl(not_a_function, acc, [])), - {'EXIT',{function_clause,_}} = (catch lists:foldr(not_a_function, acc, [])), - {'EXIT',{function_clause,_}} = + {'EXIT',{function_clause,[{?MODULE,_,[not_a_function,[]],_}|_]}} = + (catch lists:map(not_a_function, [])), + {'EXIT',{function_clause,[{?MODULE,_,[not_a_function,[]],_}|_]}} = + (catch lists:flatmap(not_a_function, [])), + {'EXIT',{function_clause,[{?MODULE,_,[not_a_function,[]],_}|_]}} = + (catch lists:foreach(not_a_function, [])), + {'EXIT',{function_clause,[{?MODULE,_,[not_a_function,[]],_}|_]}} = + (catch lists:filter(not_a_function, [])), + {'EXIT',{function_clause,[{?MODULE,_,[not_a_function,[]],_}|_]}} = + (catch lists:any(not_a_function, [])), + {'EXIT',{function_clause,[{?MODULE,_,[not_a_function,[]],_}|_]}} = + (catch lists:all(not_a_function, [])), + {'EXIT',{function_clause,[{?MODULE,_,[not_a_function,acc,[]],_}|_]}} = + (catch lists:foldl(not_a_function, acc, [])), + {'EXIT',{function_clause,[{?MODULE,_,[not_a_function,acc,[]],_}|_]}} = + (catch lists:foldr(not_a_function, acc, [])), + {'EXIT',{function_clause,[{?MODULE,_,[not_a_function,acc,[]],_}|_]}} = (catch lists:mapfoldl(not_a_function, acc, [])), - {'EXIT',{function_clause,_}} = + {'EXIT',{function_clause,[{?MODULE,_,[not_a_function,acc,[]],_}|_]}} = (catch lists:mapfoldr(not_a_function, acc, [])), ok. -- cgit v1.2.3