diff options
author | Hans Bolinder <hasse@erlang.org> | 2021-02-01 07:17:32 +0100 |
---|---|---|
committer | Hans Bolinder <hasse@erlang.org> | 2021-02-01 07:17:32 +0100 |
commit | ee6a69bcef0dfdafe07906b939052d24e25be9c3 (patch) | |
tree | a778d0648b2b9fbbb3bc1eba374ce0d25a29a1e3 | |
parent | 2ac9e0744e867f791662a5f279e91f6a7bf67199 (diff) | |
parent | 370a2f1c940d305818eb6e415e874741382c22d9 (diff) | |
download | erlang-ee6a69bcef0dfdafe07906b939052d24e25be9c3.tar.gz |
Merge branch 'richcarl/columns/PR-2664/OTP-16824'
* richcarl/columns/PR-2664/OTP-16824: (56 commits)
Update primary bootstrap
erl_lint: Give a better column position for format warnings
erl_lint: Correct column number for unsized binary not at end
Include column numbers in compiler warnings
dialyzer: Improve column numbers in warnings
stdlib: Improve locations of annotations of abstract code
stdlib: Improve error locations in module erl_lint
stdlib: Improve error locations in module epp
stdlib: Improve error locations in module erl_parse
stdlib: Fix handling of annotations in erl_expand_records
erl_docgen: Correct handling of annotation of abstract code
syntax_tools: Generalize start line to be location
syntax_tools: Correct handling of annotations of abstract code
edoc: Correct handling of annotations of abstract code
tools: Substitute Anno for Line in xref_reader
tools: Substitute Anno for Line in cover
stdlib: Substitute Anno for Line in epp
stdlib: Substitute Anno for Line in erl_eval
stdlib: Substitute Anno for Line in erl_pp
stdlib: Substitute Anno for Line in eval_bits
...
378 files changed, 7473 insertions, 6357 deletions
diff --git a/bootstrap/lib/compiler/ebin/beam_kernel_to_ssa.beam b/bootstrap/lib/compiler/ebin/beam_kernel_to_ssa.beam Binary files differindex 0706fdbfec..2d33442b97 100644 --- a/bootstrap/lib/compiler/ebin/beam_kernel_to_ssa.beam +++ b/bootstrap/lib/compiler/ebin/beam_kernel_to_ssa.beam diff --git a/bootstrap/lib/compiler/ebin/beam_validator.beam b/bootstrap/lib/compiler/ebin/beam_validator.beam Binary files differindex 953da17fc7..5c0f87ae51 100644 --- a/bootstrap/lib/compiler/ebin/beam_validator.beam +++ b/bootstrap/lib/compiler/ebin/beam_validator.beam diff --git a/bootstrap/lib/compiler/ebin/compile.beam b/bootstrap/lib/compiler/ebin/compile.beam Binary files differindex 6ddcf90e3a..b784aa70a6 100644 --- a/bootstrap/lib/compiler/ebin/compile.beam +++ b/bootstrap/lib/compiler/ebin/compile.beam diff --git a/bootstrap/lib/compiler/ebin/core_parse.beam b/bootstrap/lib/compiler/ebin/core_parse.beam Binary files differindex 5f27e0b8d2..34dc7f5b46 100644 --- a/bootstrap/lib/compiler/ebin/core_parse.beam +++ b/bootstrap/lib/compiler/ebin/core_parse.beam diff --git a/bootstrap/lib/compiler/ebin/core_pp.beam b/bootstrap/lib/compiler/ebin/core_pp.beam Binary files differindex 127f6788e9..6c350e9446 100644 --- a/bootstrap/lib/compiler/ebin/core_pp.beam +++ b/bootstrap/lib/compiler/ebin/core_pp.beam diff --git a/bootstrap/lib/compiler/ebin/sys_core_fold.beam b/bootstrap/lib/compiler/ebin/sys_core_fold.beam Binary files differindex 12dd896002..00157fb6c7 100644 --- a/bootstrap/lib/compiler/ebin/sys_core_fold.beam +++ b/bootstrap/lib/compiler/ebin/sys_core_fold.beam diff --git a/bootstrap/lib/compiler/ebin/v3_core.beam b/bootstrap/lib/compiler/ebin/v3_core.beam Binary files differindex 1c3b5689a6..3cb616a81d 100644 --- a/bootstrap/lib/compiler/ebin/v3_core.beam +++ b/bootstrap/lib/compiler/ebin/v3_core.beam diff --git a/bootstrap/lib/compiler/ebin/v3_kernel.beam b/bootstrap/lib/compiler/ebin/v3_kernel.beam Binary files differindex e5aa99bca3..43414360fc 100644 --- a/bootstrap/lib/compiler/ebin/v3_kernel.beam +++ b/bootstrap/lib/compiler/ebin/v3_kernel.beam diff --git a/bootstrap/lib/compiler/ebin/v3_kernel_pp.beam b/bootstrap/lib/compiler/ebin/v3_kernel_pp.beam Binary files differindex 49503157bc..4527b8f59a 100644 --- a/bootstrap/lib/compiler/ebin/v3_kernel_pp.beam +++ b/bootstrap/lib/compiler/ebin/v3_kernel_pp.beam diff --git a/bootstrap/lib/stdlib/ebin/epp.beam b/bootstrap/lib/stdlib/ebin/epp.beam Binary files differindex bfae4816ae..bf37e8267f 100644 --- a/bootstrap/lib/stdlib/ebin/epp.beam +++ b/bootstrap/lib/stdlib/ebin/epp.beam diff --git a/bootstrap/lib/stdlib/ebin/erl_eval.beam b/bootstrap/lib/stdlib/ebin/erl_eval.beam Binary files differindex 2b02e261a6..60f90d6d69 100644 --- a/bootstrap/lib/stdlib/ebin/erl_eval.beam +++ b/bootstrap/lib/stdlib/ebin/erl_eval.beam diff --git a/bootstrap/lib/stdlib/ebin/erl_expand_records.beam b/bootstrap/lib/stdlib/ebin/erl_expand_records.beam Binary files differindex cba2040d12..f4659650e7 100644 --- a/bootstrap/lib/stdlib/ebin/erl_expand_records.beam +++ b/bootstrap/lib/stdlib/ebin/erl_expand_records.beam diff --git a/bootstrap/lib/stdlib/ebin/erl_lint.beam b/bootstrap/lib/stdlib/ebin/erl_lint.beam Binary files differindex 74f709d9aa..ab71a039d1 100644 --- a/bootstrap/lib/stdlib/ebin/erl_lint.beam +++ b/bootstrap/lib/stdlib/ebin/erl_lint.beam diff --git a/bootstrap/lib/stdlib/ebin/erl_parse.beam b/bootstrap/lib/stdlib/ebin/erl_parse.beam Binary files differindex a8855fdc89..27a61834d6 100644 --- a/bootstrap/lib/stdlib/ebin/erl_parse.beam +++ b/bootstrap/lib/stdlib/ebin/erl_parse.beam diff --git a/bootstrap/lib/stdlib/ebin/escript.beam b/bootstrap/lib/stdlib/ebin/escript.beam Binary files differindex c1e2ac905b..f4500ff85c 100644 --- a/bootstrap/lib/stdlib/ebin/escript.beam +++ b/bootstrap/lib/stdlib/ebin/escript.beam diff --git a/bootstrap/lib/stdlib/ebin/ms_transform.beam b/bootstrap/lib/stdlib/ebin/ms_transform.beam Binary files differindex cd71cf103f..87e2e64379 100644 --- a/bootstrap/lib/stdlib/ebin/ms_transform.beam +++ b/bootstrap/lib/stdlib/ebin/ms_transform.beam diff --git a/bootstrap/lib/stdlib/ebin/qlc.beam b/bootstrap/lib/stdlib/ebin/qlc.beam Binary files differindex fcdb29b57c..48caea4b17 100644 --- a/bootstrap/lib/stdlib/ebin/qlc.beam +++ b/bootstrap/lib/stdlib/ebin/qlc.beam diff --git a/bootstrap/lib/stdlib/ebin/qlc_pt.beam b/bootstrap/lib/stdlib/ebin/qlc_pt.beam Binary files differindex 68fb458930..066ead20ee 100644 --- a/bootstrap/lib/stdlib/ebin/qlc_pt.beam +++ b/bootstrap/lib/stdlib/ebin/qlc_pt.beam diff --git a/bootstrap/lib/stdlib/ebin/shell.beam b/bootstrap/lib/stdlib/ebin/shell.beam Binary files differindex b8880d8b8e..65aac7e12c 100644 --- a/bootstrap/lib/stdlib/ebin/shell.beam +++ b/bootstrap/lib/stdlib/ebin/shell.beam diff --git a/erts/test/erlc_SUITE.erl b/erts/test/erlc_SUITE.erl index c41d1ded74..3451039333 100644 --- a/erts/test/erlc_SUITE.erl +++ b/erts/test/erlc_SUITE.erl @@ -112,9 +112,9 @@ compile_yecc(Config) when is_list(Config) -> BadFile = filename:join(SrcDir, "yecc_test_bad.yrl"), run(Config, Cmd, BadFile, "-W0", - ["rootsymbol form is not a nonterminal\$", + ["Nonterminals is missing\$", + "rootsymbol form is not a nonterminal\$", "undefined nonterminal: form\$", - "Nonterminals is missing\$", "_ERROR_"]), exists(filename:join(OutDir, "yecc_test_ok.erl")), ok. @@ -357,10 +357,11 @@ make_dep_options(Config) -> %% since compiler is run on the erlang code a warning will be %% issued by the compiler, match that. - WarningRE = "/system_test/erlc_SUITE_data/src/erl_test_ok.erl:[0-9]+: " + WarningRE = + "/system_test/erlc_SUITE_data/src/erl_test_ok.erl:[0-9]+:[0-9]+: " "Warning: function foo/0 is unused$", ErrorRE = "/system_test/erlc_SUITE_data/src/erl_test_missing_header.erl:" - "[0-9]+: can't find include file \"missing.hrl\"$", + "[0-9]+:[0-9]+: can't find include file \"missing.hrl\"$", DepRE_MMD = insert_before("_OK_", WarningRE, DepRE), DepRETarget_MMD = insert_before("_OK_", WarningRE, DepRETarget), diff --git a/lib/compiler/doc/src/compile.xml b/lib/compiler/doc/src/compile.xml index 8329ed867c..467f01b9d8 100644 --- a/lib/compiler/doc/src/compile.xml +++ b/lib/compiler/doc/src/compile.xml @@ -355,6 +355,20 @@ module.beam: module.erl \ since R13B04.</p> </item> + <tag><c>error_location</c></tag> + <item> + <p>If the value of this flag is <c>line</c>, the location + <seeerl marker="#error_information"><c>ErrorLocation</c></seeerl> + of warnings and errors is a line number. If + the value is <c>column</c>, <c>ErrorLocation</c> includes + both a line number and a column number. + Default is <c>column</c>. This option is supported + since Erlang/OTP 24.0.</p> + <p>If the value of this flag is <c>column</c>, + <seeerl marker="#debug_info">debug information</seeerl> + includes column information.</p> + </item> + <tag><c>return</c></tag> <item> <p>A short form for both <c>return_errors</c> and @@ -783,7 +797,7 @@ module.beam: module.erl \ The filename is included here, as the compiler uses the Erlang pre-processor <c>epp</c>, which allows the code to be included in other files. It is therefore important to know to - <em>which</em> file the line number of an error or a warning refers. + <em>which</em> file the location of an error or a warning refers. </p> </desc> </func> @@ -810,7 +824,7 @@ module.beam: module.erl \ <v>ModuleName = module()</v> <v>BinaryOrCode = binary() | term()</v> <v>ErrRet = error | {error,Errors,Warnings}</v> - <v>Warnings = Errors = [{<seetype marker="kernel:file#filename">file:filename()</seetype>, [{<seetype marker="stdlib:erl_anno#line">erl_anno:line()</seetype> | 'none', module(), term()}]}]</v> + <v>Warnings = Errors = [{<seetype marker="kernel:file#filename">file:filename()</seetype>, [{<seetype marker="stdlib:erl_anno#location">erl_anno:location()</seetype> | 'none', module(), term()}]}]</v> </type> <desc> <p>Analogous to <c>file/1</c>, but takes a list of forms (in @@ -1003,6 +1017,10 @@ pi() -> 3.1416. <p>Parse transformations are used when a programmer wants to use Erlang syntax but with different semantics. The original Erlang code is then transformed into other Erlang code.</p> + + <p>See <seeerl marker="stdlib:erl_id_trans">erl_id_trans(3)</seeerl> + for an example and an explanation of the function + <c>parse_transform_info/0</c>.</p> </section> <section> @@ -1013,10 +1031,10 @@ pi() -> 3.1416. <c>ErrorInfo</c> structure, which is returned from all I/O modules. It has the following format:</p> <code> -{ErrorLine, Module, ErrorDescriptor}</code> +{ErrorLocation, Module, ErrorDescriptor}</code> - <p><c>ErrorLine</c> is the atom <c>none</c> if the error does - not correspond to a specific line, for example, if the source file does + <p><c>ErrorLocation</c> is the atom <c>none</c> if the error does + not correspond to a specific location, for example, if the source file does not exist.</p> <p>A string describing the error is obtained with the following diff --git a/lib/compiler/src/beam_kernel_to_ssa.erl b/lib/compiler/src/beam_kernel_to_ssa.erl index 7ba2d925e4..0c79f00d1f 100644 --- a/lib/compiler/src/beam_kernel_to_ssa.erl +++ b/lib/compiler/src/beam_kernel_to_ssa.erl @@ -1276,6 +1276,9 @@ new_label(#cg{lcount=Next}=St) -> line_anno([Line,{file,Name}]) when is_integer(Line) -> line_anno_1(Name, Line); +line_anno([{Line,Column},{file,Name}]) when is_integer(Line), + is_integer(Column) -> + line_anno_1(Name, Line); line_anno([_|_]=A) -> {Name,Line} = find_loc(A, no_file, 0), line_anno_1(Name, Line); @@ -1292,6 +1295,9 @@ line_anno_1(Name, Line) -> find_loc([Line|T], File, _) when is_integer(Line) -> find_loc(T, File, Line); +find_loc([{Line, Column}|T], File, _) when is_integer(Line), + is_integer(Column) -> + find_loc(T, File, Line); find_loc([{file,File}|T], _, Line) -> find_loc(T, File, Line); find_loc([_|T], File, Line) -> diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl index 233167b536..794ba7874e 100644 --- a/lib/compiler/src/beam_validator.erl +++ b/lib/compiler/src/beam_validator.erl @@ -57,7 +57,7 @@ validate({Mod,Exp,Attr,Fs,Lc}, Level) when is_atom(Mod), [] -> ok; Es0 -> - Es = [{?MODULE,E} || E <- Es0], + Es = [{1,?MODULE,E} || E <- Es0], {error,[{atom_to_list(Mod),Es}]} end. diff --git a/lib/compiler/src/compile.erl b/lib/compiler/src/compile.erl index 5ccaaf1714..4fec417c6e 100644 --- a/lib/compiler/src/compile.erl +++ b/lib/compiler/src/compile.erl @@ -375,7 +375,13 @@ internal({forms,Forms}, Opts0) -> Source = proplists:get_value(source, Opts0, ""), Opts1 = proplists:delete(source, Opts0), Compile = build_compile(Opts1), - internal_comp(Ps, Forms, Source, "", Compile); + NewForms = case with_columns(Opts0) of + true -> + Forms; + false -> + strip_columns(Forms) + end, + internal_comp(Ps, NewForms, Source, "", Compile); internal({file,File}, Opts) -> {Ext,Ps} = passes(file, Opts), Compile = build_compile(Opts), @@ -1007,18 +1013,32 @@ do_parse_module(DefEncoding, #compile{ifile=File,options=Opts,dir=Dir}=St) -> true -> filename:basename(SourceName0); false -> SourceName0 end, + StartLocation = case with_columns(Opts) of + true -> + {1,1}; + false -> + 1 + end, R = epp:parse_file(File, [{includes,[".",Dir|inc_paths(Opts)]}, {source_name, SourceName}, {macros,pre_defs(Opts)}, {default_encoding,DefEncoding}, + {location,StartLocation}, extra]), case R of {ok,Forms,Extra} -> Encoding = proplists:get_value(encoding, Extra), case find_invalid_unicode(Forms, File) of none -> - {ok,Forms,St#compile{encoding=Encoding}}; + Forms1 = + case with_columns(Opts ++ compile_options(Forms)) of + true -> + Forms; + false -> + strip_columns(Forms) + end, + {ok,Forms1,St#compile{encoding=Encoding}}; {invalid_unicode,_,_}=Ret -> case Encoding of none -> @@ -1032,6 +1052,9 @@ do_parse_module(DefEncoding, #compile{ifile=File,options=Opts,dir=Dir}=St) -> {error,St#compile{errors=St#compile.errors ++ Es}} end. +with_columns(Opts) -> + proplists:get_value(error_location, Opts, column) =:= column. + find_invalid_unicode([H|T], File0) -> case H of {attribute,_,file,{File,_}} -> @@ -1135,10 +1158,12 @@ foldl_transform([T|Ts], Code0, St) -> Es = [{St#compile.ifile,[{none,compile, {parse_transform,T,R}}]}], {error,St#compile{errors=St#compile.errors ++ Es}}; - {warning, Forms, Ws} -> + {warning, Forms0, Ws} -> + Forms = maybe_strip_columns(Forms0, T), foldl_transform(Ts, Forms, St#compile{warnings=St#compile.warnings ++ Ws}); - Forms -> + Forms0 -> + Forms = maybe_strip_columns(Forms0, T), foldl_transform(Ts, Forms, St) end; false -> @@ -1148,6 +1173,27 @@ foldl_transform([T|Ts], Code0, St) -> end; foldl_transform([], Code, St) -> {ok,Code,St}. +%%% It is possible--although unlikely--that parse transforms add +%%% columns to the abstract code, why this function is called for +%%% every parse transform. +maybe_strip_columns(Code, T) -> + case erlang:function_exported(T, parse_transform_info, 0) of + true -> + Info = T:parse_transform_info(), + case maps:get(error_location, Info, column) of + line -> + strip_columns(Code); + _ -> + Code + end; + false -> + Code + end. + +strip_columns(Code) -> + F = fun(A) -> erl_anno:set_location(erl_anno:line(A), A) end, + [erl_parse:map_anno(F, Form) || Form <- Code]. + get_core_transforms(Opts) -> [M || {core_transform,M} <- Opts]. core_transforms(Code, St) -> @@ -1729,18 +1775,13 @@ format_message(F, P, [{none,Mod,E}|Es]) -> M = {none,io_lib:format("~ts: ~s~ts\n", [F,P,Mod:format_error(E)])}, [M|format_message(F, P, Es)]; format_message(F, P, [{{Line,Column}=Loc,Mod,E}|Es]) -> - M = {{F,Loc},io_lib:format("~ts:~w:~w ~s~ts\n", + M = {{F,Loc},io_lib:format("~ts:~w:~w: ~s~ts\n", [F,Line,Column,P,Mod:format_error(E)])}, [M|format_message(F, P, Es)]; format_message(F, P, [{Line,Mod,E}|Es]) -> M = {{F,{Line,0}},io_lib:format("~ts:~w: ~s~ts\n", [F,Line,P,Mod:format_error(E)])}, [M|format_message(F, P, Es)]; -format_message(F, P, [{Mod,E}|Es]) -> - %% Not documented and not expected to be used any more, but - %% keep a while just in case. - M = {none,io_lib:format("~ts: ~s~ts\n", [F,P,Mod:format_error(E)])}, - [M|format_message(F, P, Es)]; format_message(_, _, []) -> []. %% list_errors(File, ErrorDescriptors) -> ok @@ -1754,11 +1795,6 @@ list_errors(F, [{{Line,Column},Mod,E}|Es]) -> list_errors(F, [{Line,Mod,E}|Es]) -> io:fwrite("~ts:~w: ~ts\n", [F,Line,Mod:format_error(E)]), list_errors(F, Es); -list_errors(F, [{Mod,E}|Es]) -> - %% Not documented and not expected to be used any more, but - %% keep a while just in case. - io:fwrite("~ts: ~ts\n", [F,Mod:format_error(E)]), - list_errors(F, Es); list_errors(_F, []) -> ok. %% erlfile(Dir, Base) -> ErlFile diff --git a/lib/compiler/src/core_pp.erl b/lib/compiler/src/core_pp.erl index 19fa11235c..ab92f3dfce 100644 --- a/lib/compiler/src/core_pp.erl +++ b/lib/compiler/src/core_pp.erl @@ -101,6 +101,8 @@ format_anno_list([H], Ctxt) -> strip_line([A | As]) when is_integer(A) -> strip_line(As); +strip_line([{A,C} | As]) when is_integer(A), is_integer(C) -> + strip_line(As); strip_line([{file,_File} | As]) -> strip_line(As); strip_line([A | As]) -> @@ -110,6 +112,8 @@ strip_line([]) -> get_line([L | _As]) when is_integer(L) -> L; +get_line([{L, _Column} | _As]) when is_integer(L) -> + L; get_line([_ | As]) -> get_line(As); get_line([]) -> diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl index 704bddc2ac..287280c18f 100644 --- a/lib/compiler/src/sys_core_fold.erl +++ b/lib/compiler/src/sys_core_fold.erl @@ -97,7 +97,8 @@ -record(sub, {v=[], %Variable substitutions s=sets:new([{version, 2}]) :: sets:set(), %Variables in scope t=#{} :: map(), %Types - in_guard=false}). %In guard or not. + in_guard=false, %In guard or not. + top=true}). %Not inside a term. -spec module(cerl:c_module(), [compile:option()]) -> {'ok', cerl:c_module(), [_]}. @@ -176,7 +177,7 @@ expr(#c_var{}=V, Ctxt, Sub) -> effect -> void(); value -> sub_get_var(V, Sub) end; -expr(#c_literal{val=Val}=L, Ctxt, _Sub) -> +expr(#c_literal{val=Val}=L, Ctxt, Sub) -> case Ctxt of effect -> case Val of @@ -188,35 +189,36 @@ expr(#c_literal{val=Val}=L, Ctxt, _Sub) -> void(); _ -> %% Warn and replace with void(). - add_warning(L, useless_building), + warn_useless_building(L, Sub), void() end; value -> L end; expr(#c_cons{anno=Anno,hd=H0,tl=T0}=Cons, Ctxt, Sub) -> - H1 = expr(H0, Ctxt, Sub), - T1 = expr(T0, Ctxt, Sub), + DeeperSub = descend(Cons, Sub), + H1 = expr(H0, Ctxt, DeeperSub), + T1 = expr(T0, Ctxt, DeeperSub), case Ctxt of effect -> - add_warning(Cons, useless_building), + warn_useless_building(Cons, Sub), make_effect_seq([H1,T1], Sub); value -> ann_c_cons(Anno, H1, T1) end; expr(#c_tuple{anno=Anno,es=Es0}=Tuple, Ctxt, Sub) -> - Es = expr_list(Es0, Ctxt, Sub), + Es = expr_list(Es0, Ctxt, descend(Tuple, Sub)), case Ctxt of effect -> - add_warning(Tuple, useless_building), + warn_useless_building(Tuple, Sub), make_effect_seq(Es, Sub); value -> ann_c_tuple(Anno, Es) end; expr(#c_map{anno=Anno,arg=V0,es=Es0}=Map, Ctxt, Sub) -> - Es = pair_list(Es0, Ctxt, Sub), + Es = pair_list(Es0, Ctxt, descend(Map, Sub)), case Ctxt of effect -> - add_warning(Map, useless_building), + warn_useless_building(Map, Sub), make_effect_seq(Es, Sub); value -> V = expr(V0, Ctxt, Sub), @@ -226,15 +228,15 @@ expr(#c_binary{segments=Ss}=Bin0, Ctxt, Sub) -> %% Warn for useless building, but always build the binary %% anyway to preserve a possible exception. case Ctxt of - effect -> add_warning(Bin0, useless_building); + effect -> warn_useless_building(Bin0, Sub); value -> ok end, Bin1 = Bin0#c_binary{segments=bitstr_list(Ss, Sub)}, Bin = bin_un_utf(Bin1), eval_binary(Bin); -expr(#c_fun{}=Fun, effect, _) -> +expr(#c_fun{}=Fun, effect, Sub) -> %% A fun is created, but not used. Warn, and replace with the void value. - add_warning(Fun, useless_building), + warn_useless_building(Fun, Sub), void(); expr(#c_fun{vars=Vs0,body=B0}=Fun, Ctxt0, Sub0) -> {Vs1,Sub1} = var_list(Vs0, Sub0), @@ -2712,6 +2714,63 @@ copy_type(_, _, Tdb) -> Tdb. void() -> #c_literal{val=ok}. +%%% +%%% Handling of the `useless_building` warning (building a term that +%%% is never used). +%%% +%%% Consider this code fragment: +%%% +%%% [ {ok,Term} ], +%%% ok +%%% +%%% The list that is ignored contains a tuple that is also ignored. +%%% While optimizing this code fragment, two warnings for useless +%%% building will be generated: one for the list and one for the tuple +%%% inside. Before the introduction of column numbers, those two warnings +%%% would be coalesced to one becuase they had the same line number. +%%% +%%% With column numbers, we will need a more sophisticated solution to +%%% avoid emitting annoying duplicate warnings. +%%% +%%% Note that if two separate terms are being built on the same line, we +%%% do expect to get two warnings: +%%% +%%% [ {ok,Term} ], [ {error,BadTerm} ], ok +%%% ^ ^ +%%% +%%% (The carets mark the expected columns for the warnings.) +%%% +%%% To handle those requirements, we will use the #sub{} record to keep +%%% track of whether we are at the top level or have descended into +%%% a sub expression. +%%% + +%% Note in the Sub record that we have are no longer at the top level. +descend(_Core, #sub{top=false}=Sub) -> + Sub; +descend(Core, #sub{top=true}=Sub) -> + case should_suppress_warning(Core) of + true -> + %% In a list comprehension being ignored such as: + %% + %% [{error,Z} || Z <- List], ok + %% + %% the warning for ignoring the cons cell should be + %% suppressed, but there should still be a warning for + %% ignoring the {error,Z} tuple. Therefore, pretend that + %% we are still at the top level. + Sub; + false -> + %% No longer at top level. Warnings for useless building + %% should now be suppressed. + Sub#sub{top=false} + end. + +warn_useless_building(Core, #sub{top=Top}) -> + case Top of + true -> add_warning(Core, useless_building); + false -> ok + end. %%% %%% Handling of warnings. @@ -2719,29 +2778,38 @@ void() -> #c_literal{val=ok}. init_warnings() -> put({?MODULE,warnings}, []). - add_warning(Core, Term) -> case should_suppress_warning(Core) of true -> ok; false -> Anno = cerl:get_ann(Core), - Line = get_line(Anno), + Location = get_location(Anno), File = get_file(Anno), Key = {?MODULE,warnings}, case get(Key) of - [{File,[{Line,?MODULE,Term}]}|_] -> + [{File,[{Location,?MODULE,Term}]}|_] -> ok; %We already have %an identical warning. Ws -> - put(Key, [{File,[{Line,?MODULE,Term}]}|Ws]) + put(Key, [{File,[{Location,?MODULE,Term}]}|Ws]) end end. get_line([Line|_]) when is_integer(Line) -> Line; +get_line([{Line, _Column} | _T]) when is_integer(Line) -> Line; get_line([_|T]) -> get_line(T); get_line([]) -> none. +get_location([Line|_]) when is_integer(Line) -> + Line; +get_location([{Line, Column} | _T]) when is_integer(Line), is_integer(Column) -> + {Line,Column}; +get_location([_|T]) -> + get_location(T); +get_location([]) -> + none. + get_file([{file,File}|_]) -> File; get_file([_|T]) -> get_file(T); get_file([]) -> "no_file". % should not happen diff --git a/lib/compiler/src/sys_pre_attributes.erl b/lib/compiler/src/sys_pre_attributes.erl index 67adae5acf..1b0fcd46af 100644 --- a/lib/compiler/src/sys_pre_attributes.erl +++ b/lib/compiler/src/sys_pre_attributes.erl @@ -114,7 +114,7 @@ pre_transform(S) -> pre_transform([H | T], Acc, S) -> case H of - {attribute, Line, Name, Val} -> + {attribute, Anno, Name, Val} -> case lists:keyfind(Name, 2, S#state.pre_ops) of false -> pre_transform(T, [H | Acc], S); @@ -123,7 +123,7 @@ pre_transform([H | T], Acc, S) -> report_warning("Replace attribute ~p: ~p -> ~p~n", [Name, Val, NewVal], S), - New = {attribute, Line, Name, NewVal}, + New = {attribute, Anno, Name, NewVal}, Pre = lists:keydelete(Name, 2, S#state.pre_ops), Post = lists:keydelete(Name, 2, S#state.post_ops), S2 = S#state{pre_ops = Pre, post_ops = Post}, @@ -158,9 +158,9 @@ post_transform(S) -> post_transform([H | T], Acc, S) -> case H of - {attribute, Line, module, _Val} = Attribute -> + {attribute, Anno, module, _Val} = Attribute -> Acc2 = lists:reverse([Attribute | Acc]), - Forms = Acc2 ++ attrs(S#state.post_ops, Line, S) ++ T, + Forms = Acc2 ++ attrs(S#state.post_ops, Anno, S) ++ T, S#state{forms = Forms, post_ops = []}; _Any -> post_transform(T, [H | Acc], S) @@ -168,12 +168,12 @@ post_transform([H | T], Acc, S) -> post_transform([], Acc, S) -> S#state{forms = lists:reverse(Acc)}. -attrs([{replace, Name, NewVal} | T], Line, S) -> +attrs([{replace, Name, NewVal} | T], Anno, S) -> report_verbose("Insert attribute ~p: ~p~n", [Name, NewVal], S), - [{attribute, Line, Name, NewVal} | attrs(T, Line, S)]; -attrs([{insert, Name, NewVal} | T], Line, S) -> + [{attribute, Anno, Name, NewVal} | attrs(T, Anno, S)]; +attrs([{insert, Name, NewVal} | T], Anno, S) -> report_verbose("Insert attribute ~p: ~p~n", [Name, NewVal], S), - [{attribute, Line, Name, NewVal} | attrs(T, Line, S)]; + [{attribute, Anno, Name, NewVal} | attrs(T, Anno, S)]; attrs([], _, _) -> []. diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl index d4ee6053ab..1b9e961514 100644 --- a/lib/compiler/src/v3_core.erl +++ b/lib/compiler/src/v3_core.erl @@ -947,20 +947,21 @@ map_build_pairs_1([{Op0,L,K0,V0}|Es], Used0, St0) -> {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), + {Used2,St4} = maybe_warn_repeated_keys(K, K0, Used1, St3), Pair = cerl:ann_c_map_pair(As, Op, K, V), {[Pair|Pairs],Pre0++Pre1++Pre2,Used2,St4}; map_build_pairs_1([], Used, St) -> {[],[],Used,St}. -maybe_warn_repeated_keys(Ck,Line,Used,St) -> +maybe_warn_repeated_keys(Ck, K0, Used, St) -> case cerl:is_literal(Ck) of false -> {Used,St}; true -> K = cerl:concrete(Ck), case sets:is_element(K,Used) of true -> - {Used, add_warning(Line, {map_key_repeated,K}, St)}; + Location = element(2, K0), + {Used, add_warning(Location, {map_key_repeated,K}, St)}; false -> {sets:add_element(K,Used), St} end @@ -3389,10 +3390,10 @@ full_anno(L, #core{wanted=true}=St) -> lineno_anno(L, St). lineno_anno(L, St) -> - Line = erl_anno:line(L), + Location = erl_anno:location(L), Generated = erl_anno:generated(L), CompilerGenerated = [compiler_generated || Generated], - [Line] ++ St#core.file ++ CompilerGenerated. + [Location] ++ St#core.file ++ CompilerGenerated. get_lineno_anno(Ce) -> case get_anno(Ce) of diff --git a/lib/compiler/src/v3_kernel.erl b/lib/compiler/src/v3_kernel.erl index eb04a2c916..40cf1c276c 100644 --- a/lib/compiler/src/v3_kernel.erl +++ b/lib/compiler/src/v3_kernel.erl @@ -338,7 +338,7 @@ expr(#c_call{anno=A,module=M0,name=F0,args=Cargs}, Sub, St0) -> error -> %% Invalid call (e.g. M:42/3). Issue a warning, and let %% the generated code use the old explict apply. - St = add_warning(get_line(A), bad_call, A, St0), + St = add_warning(get_location(A), bad_call, A, St0), Call = #c_call{anno=A, module=#c_literal{val=erlang}, name=#c_literal{val=apply}, @@ -1066,7 +1066,7 @@ maybe_add_warning(Ke, MatchAnno, St) -> St; false -> Anno = get_kanno(Ke), - Line = get_line(Anno), + Line = get_location(Anno), MatchLine = get_line(MatchAnno), Warn = case MatchLine of none -> nomatch_shadow; @@ -1074,8 +1074,18 @@ maybe_add_warning(Ke, MatchAnno, St) -> end, add_warning(Line, Warn, Anno, St) end. - + +get_location([Line|_]) when is_integer(Line) -> + Line; +get_location([{Line, Column} | _T]) when is_integer(Line), is_integer(Column) -> + {Line,Column}; +get_location([_|T]) -> + get_location(T); +get_location([]) -> + none. + get_line([Line|_]) when is_integer(Line) -> Line; +get_line([{Line, _Column} | _T]) when is_integer(Line) -> Line; get_line([_|T]) -> get_line(T); get_line([]) -> none. diff --git a/lib/compiler/src/v3_kernel_pp.erl b/lib/compiler/src/v3_kernel_pp.erl index f7479e6b15..5a4e6fa788 100644 --- a/lib/compiler/src/v3_kernel_pp.erl +++ b/lib/compiler/src/v3_kernel_pp.erl @@ -57,6 +57,8 @@ format(Node, Ctxt) -> format_1(Node, Ctxt); [L,{file,_}] when is_integer(L) -> format_1(Node, Ctxt); + [{L,C},{file,_}] when is_integer(L), is_integer(C) -> + format_1(Node, Ctxt); List -> format_anno(List, Ctxt, fun (Ctxt1) -> format_1(Node, Ctxt1) diff --git a/lib/compiler/test/beam_validator_SUITE.erl b/lib/compiler/test/beam_validator_SUITE.erl index 49731f9137..565a86be98 100644 --- a/lib/compiler/test/beam_validator_SUITE.erl +++ b/lib/compiler/test/beam_validator_SUITE.erl @@ -99,7 +99,7 @@ compiler_bug(Config) when is_list(Config) -> %% the beam_validator module. {error, [{"compiler_bug", - [{beam_validator,_}]}], + [{_Pos,beam_validator,_}]}], []} = compile:file(File, [from_asm,return_errors,time]), ok. @@ -892,7 +892,7 @@ do_val(Mod, Config) -> case compile:file(File, [from_asm,no_postopt,return_errors]) of {error,L,[]} -> [{Base,Errors0}] = L, - Errors = [E || {beam_validator,E} <- Errors0], + Errors = [E || {_Pos,beam_validator,E} <- Errors0], _ = [io:put_chars(beam_validator:format_error(E)) || E <- Errors], Errors; @@ -903,7 +903,7 @@ do_val(Mod, Config) -> beam_val(M) -> Name = atom_to_list(element(1, M)), {error,[{Name,Errors0}]} = beam_validator:validate(M, strong), - Errors = [E || {beam_validator,E} <- Errors0], + Errors = [E || {_Pos,beam_validator,E} <- Errors0], _ = [io:put_chars(beam_validator:format_error(E)) || E <- Errors], Errors. diff --git a/lib/compiler/test/compile_SUITE.erl b/lib/compiler/test/compile_SUITE.erl index 290ed87016..6af2d9b2b5 100644 --- a/lib/compiler/test/compile_SUITE.erl +++ b/lib/compiler/test/compile_SUITE.erl @@ -1240,9 +1240,11 @@ do_warnings_1([{Name,Ws}|T], F) -> end; do_warnings_1([], _) -> ok. -do_warnings_2([{Int,_,_}=W|T], Next, F) -> - if - is_integer(Int) -> +do_warnings_2([{Pos,_,_}=W|T], Next, F) -> + case Pos of + Line when is_integer(Line) -> + do_warnings_2(T, Next, F); + {Line,Col} when is_integer(Line), is_integer(Col) -> do_warnings_2(T, Next, F); true -> io:format("~s:\nMissing line number: ~p\n", @@ -1502,14 +1504,17 @@ debug_info_attribute(DataDir, Name, Opts) -> {ok,_,Bin} = compile:file(File, [binary | Opts]), {ok, {_, Attrs}} = beam_lib:chunks(Bin, [debug_info]), - [{debug_info,{debug_info_v1,erl_abstract_code, - {[{attribute,1,file,{_,1}}, - {attribute,1,module,debug_info}, - {attribute,2,compile,[debug_info]}, - {eof,2}], _}}}] = Attrs, + [{debug_info,{debug_info_v1,erl_abstract_code, {Forms, _}}}] = Attrs, + [{attribute,{1,1},file,{_,1}}, + {attribute,{1,2},module,debug_info}, + {attribute,{2,2},compile,[debug_info]}, + {eof,_}] = forms_to_terms(Forms), ok. +forms_to_terms(Forms) -> + [erl_parse:anno_to_term(Form) || Form <- Forms]. + %%% %%% Utilities. %%% diff --git a/lib/compiler/test/error_SUITE.erl b/lib/compiler/test/error_SUITE.erl index 9436ad5d53..388ecce4f9 100644 --- a/lib/compiler/test/error_SUITE.erl +++ b/lib/compiler/test/error_SUITE.erl @@ -23,7 +23,7 @@ -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2, head_mismatch_line/1,warnings_as_errors/1, bif_clashes/1, - transforms/1,maps_warnings/1,bad_utf8/1]). + transforms/1,maps_warnings/1,bad_utf8/1,bad_decls/1]). %% Used by transforms/1 test case. -export([parse_transform/2]). @@ -36,7 +36,7 @@ all() -> groups() -> [{p,test_lib:parallel(), [head_mismatch_line,warnings_as_errors,bif_clashes, - transforms,maps_warnings,bad_utf8]}]. + transforms,maps_warnings,bad_utf8,bad_decls]}]. init_per_suite(Config) -> test_lib:recompile(?MODULE), @@ -64,7 +64,7 @@ bif_clashes(Config) when is_list(Config) -> ">>, [return_warnings], {error, - [{4, erl_lint,{call_to_redefined_old_bif,{length,1}}}], []} }], + [{{4,18}, erl_lint,{call_to_redefined_old_bif,{length,1}}}], []} }], [] = run(Config, Ts), Ts1 = [{bif_clashes2, <<" @@ -75,7 +75,7 @@ bif_clashes(Config) when is_list(Config) -> ">>, [return_warnings], {error, - [{3, erl_lint,{redefine_old_bif_import,{length,1}}}], []} }], + [{{3,16}, erl_lint,{redefine_old_bif_import,{length,1}}}], []} }], [] = run(Config, Ts1), Ts00 = [{bif_clashes3, <<" @@ -112,7 +112,7 @@ bif_clashes(Config) when is_list(Config) -> ">>, [return_warnings], {warning, - [{4, erl_lint,{call_to_redefined_bif,{binary_part,3}}}]} }], + [{{4,18}, erl_lint,{call_to_redefined_bif,{binary_part,3}}}]} }], [] = run(Config, Ts000), Ts111 = [{bif_clashes6, <<" @@ -123,7 +123,7 @@ bif_clashes(Config) when is_list(Config) -> ">>, [return_warnings], {warning, - [{3, erl_lint,{redefine_bif_import,{binary_part,3}}}]} }], + [{{3,16}, erl_lint,{redefine_bif_import,{binary_part,3}}}]} }], [] = run(Config, Ts111), Ts2 = [{bif_clashes7, <<" @@ -137,7 +137,7 @@ bif_clashes(Config) when is_list(Config) -> ">>, [], {error, - [{7,erl_lint,{define_import,{length,1}}}], + [{{7,15},erl_lint,{define_import,{length,1}}}], []} }], [] = run2(Config, Ts2), Ts3 = [{bif_clashes8, @@ -151,7 +151,7 @@ bif_clashes(Config) when is_list(Config) -> ">>, [], {error, - [{4,erl_lint,{illegal_guard_local_call,{length,1}}}], + [{{4,25},erl_lint,{illegal_guard_local_call,{length,1}}}], []} }], [] = run2(Config, Ts3), Ts4 = [{bif_clashes9, @@ -164,7 +164,7 @@ bif_clashes(Config) when is_list(Config) -> ">>, [], {error, - [{5,erl_lint,{illegal_guard_local_call,{length,1}}}], + [{{5,25},erl_lint,{illegal_guard_local_call,{length,1}}}], []} }], [] = run2(Config, Ts4), @@ -176,7 +176,7 @@ bif_clashes(Config) when is_list(Config) -> %% Tests that a head mismatch is reported on the correct line (OTP-2125). head_mismatch_line(Config) when is_list(Config) -> [E|_] = get_compilation_errors(Config, "head_mismatch_line"), - {26, Mod, Reason} = E, + {{26,1}, Mod, Reason} = E, Mod:format_error(Reason), ok. @@ -202,7 +202,7 @@ warnings_as_errors(Config) when is_list(Config) -> [warnings_as_errors, export_all, {outdir, OutDir}], {error, [], - [{3,erl_lint,{unused_var,'A'}}]} }], + [{{3,18},erl_lint,{unused_var,'A'}}]} }], [] = run(Ts1, TestFile, write_beam), false = filelib:is_regular(BeamFile), @@ -214,7 +214,7 @@ warnings_as_errors(Config) when is_list(Config) -> ">>, [return_warnings, export_all, {outdir, OutDir}], {warning, - [{3,erl_lint,{unused_var,'A'}}]} }], + [{{3,18},erl_lint,{unused_var,'A'}}]} }], [] = run(Ts2, TestFile, write_beam), true = filelib:is_regular(BeamFile), @@ -270,7 +270,7 @@ maps_warnings(Config) when is_list(Config) -> id(I) -> I. ">>, [return], - {error,[{3,erl_lint,{unbound_var,'K'}}],[]}} + {error,[{{3,15},erl_lint,{unbound_var,'K'}}],[]}} ], [] = run2(Config, Ts1), ok. @@ -285,13 +285,102 @@ bad_utf8(Config) -> t() -> \"",246,"\". ">>, [], - {error,[{2,epp,cannot_parse}, - {2,file_io_server,invalid_unicode}], + {error,[{{2,15},epp,cannot_parse}, + {{2,15},file_io_server,invalid_unicode}], []} }], [] = run2(Config, Ts), ok. +bad_decls(Config) -> + Ts = [{bad_decls_1, + <<"\n-module({l}). + ">>, + [], + {error,[{{2,9},erl_parse,"bad " ++ ["module"] ++ " declaration"}], + []} + }, + {bad_decls_2, + <<"\n-module(l, m). + ">>, + [], + {error,[{{2,12},erl_parse,"bad variable list"}],[]} + }, + {bad_decls_3, + <<"\n-export([a/1], Y). + ">>, + [], + {error,[{{2,16},erl_parse,"bad " ++ ["export"] ++ " declaration"}], + []} + }, + {bad_decls_4, + <<"\n-import([a/1], Y). + ">>, + [], + {error,[{{2,16},erl_parse,"bad " ++ ["import"] ++ " declaration"}], + []} + }, + {bad_decls_5, + <<"\n-ugly({A,B}). + ">>, + [], + {error,[{{2,7},erl_parse,"bad attribute"}],[]} + }, + {bad_decls_6, + <<"\n-ugly(a, b). + ">>, + [], + {error,[{{2,10},erl_parse,"bad attribute"}],[]} + }, + {bad_decls_7, + <<"\n-export([A/1]). + ">>, + [], + {error,[{{2,10},erl_parse,"bad function name"}],[]} + }, + {bad_decls_8, + <<"\n-export([a/a]). + ">>, + [], + {error,[{{2,12},erl_parse,"bad function arity"}],[]} + }, + {bad_decls_9, + <<"\n-export([a/1, {3,4}]). + ">>, + [], + {error,[{{2,15},erl_parse,"bad Name/Arity"}],[]} + }, + {bad_decls_10, + <<"\n-record(A, {{bad,a}}). + ">>, + [], + {error,[{{2,9},erl_parse,"bad " ++ ["record"] ++ " declaration"}], + []} + }, + {bad_decls_11, + <<"\n-record(a, [a,b,c,d]). + ">>, + [], + {error,[{{2,12},erl_parse,"bad record declaration"}],[]} + }, + {bad_decls_12, + <<"\n-record(a). + ">>, + [], + {error,[{{2,9},erl_parse,"bad " ++ ["record"] ++ " declaration"}], + []} + } + ], + [] = run2(Config, Ts), + + {error,{{1,4},erl_parse,"bad term"}} = parse_string("1, 2 + 4."), + {error,{{1,1},erl_parse,"bad term"}} = parse_string("34 + begin 34 end."), + ok. + +parse_string(S) -> + {ok,Ts,_} = erl_scan:string(S, {1, 1}), + erl_parse:parse_term(Ts). + run(Config, Tests) -> File = test_filename(Config), @@ -343,7 +432,7 @@ test_filename(Conf) -> run_test(Test0, File, Warnings, WriteBeam) -> ModName = filename:rootname(filename:basename(File), ".erl"), Mod = list_to_atom(ModName), - Test = ["-module(",ModName,"). ",Test0], + Test = iolist_to_binary(["-module(",ModName,"). ",Test0]), Opts = case WriteBeam of dont_write_beam -> [binary,return_errors|Warnings]; @@ -359,6 +448,7 @@ run_test(Test0, File, Warnings, WriteBeam) -> io:format("~p\n", [Opts]), Res = case compile:file(File, Opts) of {ok,Mod,_,[{_File,Ws}]} -> + print_diagnostics(Ws, Test), {warning,Ws}; {ok,Mod,_,[]} -> []; @@ -367,15 +457,42 @@ run_test(Test0, File, Warnings, WriteBeam) -> {ok,Mod,[]} -> []; {error,[{XFile,Es}],Ws} = _ZZ when is_list(XFile) -> + print_diagnostics(Es, Test), {error,Es,Ws}; {error,[{XFile,Es1},{XFile,Es2}],Ws} = _ZZ when is_list(XFile) -> - {error,Es1++Es2,Ws}; + Es = Es1 ++ Es2, + print_diagnostics(Es, Test), + {error,Es,Ws}; {error,Es,[{_File,Ws}]} = _ZZ-> + print_diagnostics(Es ++ Ws, Test), {error,Es,Ws} end, file:delete(File), Res. +print_diagnostics(Warnings, Source) -> + case binary:match(Source, <<"-file(">>) of + nomatch -> + Lines = binary:split(Source, <<"\n">>, [global]), + Cs = [print_diagnostic(W, Lines) || W <- Warnings], + io:put_chars(Cs); + _ -> + %% There are probably fake line numbers greater than + %% the number of actual lines. + ok + end. + +print_diagnostic({{LineNum,Column},Mod,Data}, Lines) -> + Line0 = lists:nth(LineNum, Lines), + <<Line1:(Column-1)/binary,_/binary>> = Line0, + Spaces = re:replace(Line1, <<"[^\t]">>, <<" ">>, [global]), + CaretLine = [Spaces,"^"], + [io_lib:format("~p:~p: ~ts\n", [LineNum,Column,Mod:format_error(Data)]), + Line0, "\n", + CaretLine, "\n\n"]; +print_diagnostic(_, _) -> + []. + fail() -> ct:fail(failed). diff --git a/lib/compiler/test/warnings_SUITE.erl b/lib/compiler/test/warnings_SUITE.erl index 46672c3a88..877329bd42 100644 --- a/lib/compiler/test/warnings_SUITE.erl +++ b/lib/compiler/test/warnings_SUITE.erl @@ -97,11 +97,11 @@ pattern(Config) when is_list(Config) -> foo(X) -> a = {nisse,b} = X. ">>, - [warn_unused_vars], - {warnings, - [{2,v3_core,nomatch}, - {6,v3_core,nomatch}, - {11,v3_core,nomatch} ] }}], + [warn_unused_vars], + {warnings, + [{{2,15},v3_core,nomatch}, + {{6,20},v3_core,nomatch}, + {{11,20},v3_core,nomatch} ] }}], [] = run(Config, Ts), ok. @@ -111,21 +111,21 @@ pattern2(Config) when is_list(Config) -> %% v3_kernel should generate some of the warnings. Source = <<"f(A) -> ok; f(B) -> error. - t(A, B, C) -> - case {A,B,C} of - {a,B} -> ok; - {_,B} -> ok - end. + t(A, B, C) -> + case {A,B,C} of + {a,B} -> ok; + {_,B} -> ok + end. ">>, %% Test warnings from sys_core_fold. Ts = [{pattern2, Source, [nowarn_unused_vars], - {warnings,[{2,sys_core_fold,{nomatch_shadow,1,{f,1}}}, - {4,sys_core_fold,no_clause_match}, - {5,sys_core_fold,nomatch_clause_type}, - {6,sys_core_fold,nomatch_clause_type}]}}], + {warnings,[{{2,15},sys_core_fold,{nomatch_shadow,1,{f,1}}}, + {{4,15},sys_core_fold,no_clause_match}, + {{5,17},sys_core_fold,nomatch_clause_type}, + {{6,17},sys_core_fold,nomatch_clause_type}]}}], [] = run(Config, Ts), %% Disable Core Erlang optimizations. v3_kernel should produce @@ -134,7 +134,7 @@ pattern2(Config) when is_list(Config) -> Source, [nowarn_unused_vars,no_copt], {warnings, - [{2,v3_kernel,{nomatch_shadow,1}}]}}], + [{{2,15},v3_kernel,{nomatch_shadow,1}}]}}], [] = run(Config, Ts2), ok. @@ -144,13 +144,13 @@ pattern3(Config) when is_list(Config) -> Ts = [{pattern3, <<" - f({A,_}) -> {ok,A}; - f([_|_]=B) -> {ok,B}; - f({urk,nisse}) -> urka_glurka. + f({A,_}) -> {ok,A}; + f([_|_]=B) -> {ok,B}; + f({urk,nisse}) -> urka_glurka. ">>, [nowarn_unused_vars], {warnings, - [{4,v3_kernel,{nomatch_shadow,2}}]}}], + [{{4,13},v3_kernel,{nomatch_shadow,2}}]}}], [] = run(Config, Ts), ok. @@ -205,12 +205,12 @@ pattern4(Config) when is_list(Config) -> ">>, [nowarn_unused_vars], {warnings, - [{9,sys_core_fold,no_clause_match}, - {11,sys_core_fold,nomatch_shadow}, - {15,sys_core_fold,nomatch_shadow}, - {18,sys_core_fold,no_clause_match}, - {23,sys_core_fold,no_clause_match}, - {33,sys_core_fold,no_clause_match} + [{{9,16},sys_core_fold,no_clause_match}, + {{11,18},sys_core_fold,nomatch_shadow}, + {{15,18},sys_core_fold,nomatch_shadow}, + {{18,16},sys_core_fold,no_clause_match}, + {{23,16},sys_core_fold,no_clause_match}, + {{33,16},sys_core_fold,no_clause_match} ]}}], [] = run(Config, Ts), @@ -234,14 +234,14 @@ guard(Config) when is_list(Config) -> ">>, [nowarn_unused_vars], {warnings, - [{2,sys_core_fold,no_clause_match}, - {2,sys_core_fold,nomatch_guard}, - {2,sys_core_fold,{eval_failure,badarg}}, - {4,sys_core_fold,no_clause_match}, - {4,sys_core_fold,nomatch_guard}, - {6,sys_core_fold,no_clause_match}, - {6,sys_core_fold,nomatch_guard}, - {6,sys_core_fold,{eval_failure,badarg}} + [{{2,15},sys_core_fold,no_clause_match}, + {{2,15},sys_core_fold,nomatch_guard}, + {{2,28},sys_core_fold,{eval_failure,badarg}}, + {{4,15},sys_core_fold,no_clause_match}, + {{4,15},sys_core_fold,nomatch_guard}, + {{6,15},sys_core_fold,no_clause_match}, + {{6,15},sys_core_fold,nomatch_guard}, + {{6,26},sys_core_fold,{eval_failure,badarg}} ]}}], [] = run(Config, Ts), @@ -252,14 +252,14 @@ bad_arith(Config) when is_list(Config) -> <<"f() -> if a + 3 > 3 -> ok; - true -> error + true -> error end. g(A) -> if is_integer(A), a + 3 > 3 -> ok; a + 3 > 42, is_integer(A) -> ok; - true -> error + true -> error end. h(A) -> @@ -267,14 +267,14 @@ bad_arith(Config) when is_list(Config) -> ">>, [], {warnings, - [{3,sys_core_fold,nomatch_guard}, - {3,sys_core_fold,{eval_failure,badarith}}, - {9,sys_core_fold,nomatch_guard}, - {9,sys_core_fold,{eval_failure,badarith}}, - {9,sys_core_fold,{no_effect,{erlang,is_integer,1}}}, - {10,sys_core_fold,nomatch_guard}, - {10,sys_core_fold,{eval_failure,badarith}}, - {15,sys_core_fold,{eval_failure,badarith}} + [{{3,19},sys_core_fold,nomatch_guard}, + {{3,21},sys_core_fold,{eval_failure,badarith}}, + {{9,19},sys_core_fold,nomatch_guard}, + {{9,19},sys_core_fold,{no_effect,{erlang,is_integer,1}}}, + {{9,36},sys_core_fold,{eval_failure,badarith}}, + {{10,19},sys_core_fold,nomatch_guard}, + {{10,21},sys_core_fold,{eval_failure,badarith}}, + {{15,19},sys_core_fold,{eval_failure,badarith}} ] }}], [] = run(Config, Ts), ok. @@ -296,18 +296,18 @@ bool_cases(Config) when is_list(Config) -> Other -> {error,not_bool} end. - h(Bool) -> - case not Bool of - maybe -> strange; - false -> ok; - true -> error - end. + h(Bool) -> + case not Bool of + maybe -> strange; + false -> ok; + true -> error + end. ">>, - [nowarn_unused_vars], - {warnings, - [{6,sys_core_fold,nomatch_shadow}, - {13,sys_core_fold,nomatch_shadow}, - {18,sys_core_fold,nomatch_clause_type} ]} }], + [nowarn_unused_vars], + {warnings, + [{{6,18},sys_core_fold,nomatch_shadow}, + {{13,18},sys_core_fold,nomatch_shadow}, + {{18,18},sys_core_fold,nomatch_clause_type} ]} }], [] = run(Config, Ts), ok. @@ -320,13 +320,13 @@ bad_apply(Config) when is_list(Config) -> t(4) -> []:start(); t(5) -> erlang:[](). ">>, - [], - {warnings, - [{2,v3_kernel,bad_call}, - {3,v3_kernel,bad_call}, - {4,v3_kernel,bad_call}, - {5,v3_kernel,bad_call}, - {6,v3_kernel,bad_call}]}}], + [], + {warnings, + [{{2,22},v3_kernel,bad_call}, + {{3,22},v3_kernel,bad_call}, + {{4,22},v3_kernel,bad_call}, + {{5,22},v3_kernel,bad_call}, + {{6,22},v3_kernel,bad_call}]}}], [] = run(Config, Ts), %% Also verify that the generated code generates the correct error. @@ -352,108 +352,63 @@ files(Config) when is_list(Config) -> ">>, [], {warnings, - [{"file1",[{17,sys_core_fold,{eval_failure,badarith}}]}, - {"file2",[{10,sys_core_fold,{eval_failure,badarith}}]}]}}], + [{"file1",[{{17,20},sys_core_fold,{eval_failure,badarith}}]}, + {"file2",[{{10,20},sys_core_fold,{eval_failure,badarith}}]}]}}], [] = run(Config, Ts), ok. %% Test warnings for term construction and BIF calls in effect context. effect(Config) when is_list(Config) -> - Ts = [{effect, - <<" - t(X) -> - case X of - warn_lc -> - [is_integer(Z) || Z <- [1,2,3]]; - warn_lc_2 -> - [{error,Z} || Z <- [1,2,3]]; - warn_lc_3 -> - [{error,abs(Z)} || Z <- [1,2,3]]; - no_warn_lc -> - [put(last_integer, Z) || Z <- [1,2,3]]; %no warning - unused_tuple_literal -> - {a,b,c}; - unused_list_literal -> - [1,2,3,4]; - unused_integer -> - 42; - unused_arith -> - X*X; - nested -> - [{ok,node(),?MODULE:foo(),self(),[time(),date()],time()}, - is_integer(X)]; - unused_bit_syntax -> - <<X:8>>; - unused_fun -> - fun() -> {ok,X} end; - unused_named_fun -> - fun F(0) -> 1; - F(N) -> N*F(N-1) - end; - unused_atom -> - ignore; %no warning - unused_nil -> - []; %no warning - comp_op -> - X =:= 2; - cookie -> - erlang:get_cookie(); - result_ignore -> - _ = list_to_integer(X); - warn_lc_4 -> - %% No warning because of assignment to _. - [_ = abs(Z) || Z <- [1,2,3]] - end, - ok. - - %% No warnings should be generated in the following functions. + Ts = [{no_warnings, + %% No warnings should be generated in the following functions. + <<" m1(X, Sz) -> if - Sz =:= 0 -> X = 0; - true -> ok + Sz =:= 0 -> X = 0; + true -> ok end, ok. m2(X, Sz) -> if - Sz =:= 0 -> X = {a,Sz}; - true -> ok + Sz =:= 0 -> X = {a,Sz}; + true -> ok end, ok. m3(X, Sz) -> if - Sz =:= 0 -> X = [a,Sz]; - true -> ok + Sz =:= 0 -> X = [a,Sz]; + true -> ok end, ok. m4(X, Sz, Var) -> if - Sz =:= 0 -> X = Var; - true -> ok + Sz =:= 0 -> X = Var; + true -> ok end, ok. m5(X, Sz) -> if - Sz =:= 0 -> X = {a,b,c}; - true -> ok + Sz =:= 0 -> X = {a,b,c}; + true -> ok end, ok. m6(X, Sz) -> if - Sz =:= 0 -> X = {a,Sz,[1,2,3]}; - true -> ok + Sz =:= 0 -> X = {a,Sz,[1,2,3]}; + true -> ok end, ok. m7(X, Sz) -> if - Sz =:= 0 -> X = {a,Sz,[1,2,3],abs(Sz)}; - true -> ok + Sz =:= 0 -> X = {a,Sz,[1,2,3],abs(Sz)}; + true -> ok end, ok. @@ -473,34 +428,103 @@ effect(Config) when is_list(Config) -> CurrentConfig = {id(camel_phase3),id(sms)}, case CurrentConfig of {apa, bepa} -> ok; - _ -> ok - end + _ -> ok + end end, ok. id(I) -> I. ">>, - [], - {warnings,[{5,sys_core_fold,{no_effect,{erlang,is_integer,1}}}, - {7,sys_core_fold,useless_building}, - {9,sys_core_fold,result_ignored}, - {9,sys_core_fold,useless_building}, - {13,sys_core_fold,useless_building}, - {15,sys_core_fold,useless_building}, - {17,sys_core_fold,useless_building}, - {19,sys_core_fold,result_ignored}, - {21,sys_core_fold,useless_building}, - {21,sys_core_fold,{no_effect,{erlang,date,0}}}, - {21,sys_core_fold,{no_effect,{erlang,node,0}}}, - {21,sys_core_fold,{no_effect,{erlang,self,0}}}, - {21,sys_core_fold,{no_effect,{erlang,time,0}}}, - {22,sys_core_fold,useless_building}, - {22,sys_core_fold,{no_effect,{erlang,is_integer,1}}}, - {24,sys_core_fold,useless_building}, - {26,sys_core_fold,useless_building}, - {28,sys_core_fold,useless_building}, - {36,sys_core_fold,{no_effect,{erlang,'=:=',2}}}, - {38,sys_core_fold,{no_effect,{erlang,get_cookie,0}}}]}}], + [],[]}, + + {basic, + <<" + t(X) -> + case X of + warn_lc -> + [is_integer(Z) || Z <- [1,2,3]]; + warn_lc_2 -> + [{error,Z} || Z <- [1,2,3]]; + warn_lc_3 -> + [{error,abs(Z)} || Z <- [1,2,3]]; + no_warn_lc -> + [put(last_integer, Z) || Z <- [1,2,3]]; %no warning + unused_tuple_literal -> + {a,b,c}; + unused_list_literal -> + [1,2,3,4]; + unused_integer -> + 42; + unused_arith -> + X*X + end, + ok. + ">>, + [], + {warnings,[{{5,22},sys_core_fold,{no_effect,{erlang,is_integer,1}}}, + {{7,22},sys_core_fold,useless_building}, + {{9,22},sys_core_fold,useless_building}, + {{9,29},sys_core_fold,result_ignored}, + {{13,21},sys_core_fold,useless_building}, + {{15,21},sys_core_fold,useless_building}, + {{17,21},sys_core_fold,useless_building}, + {{19,22},sys_core_fold,result_ignored}]}}, + + {nested, + <<" + t(X) -> + case X of + nested -> + [{ok,node(),module:foo(),self(),[time(),date()],time()}, + is_integer(X)]; + unused_bit_syntax -> + <<X:8>>; + unused_fun -> + fun() -> {ok,X} end; + unused_named_fun -> + fun F(0) -> 1; + F(N) -> N*F(N-1) + end; + unused_atom -> + ignore; %no warning + unused_nil -> + []; %no warning + comp_op -> + X =:= 2; + cookie -> + erlang:get_cookie(); + result_ignore -> + _ = list_to_integer(X); + warn_lc_4 -> + %% No warning because of assignment to _. + [_ = abs(Z) || Z <- [1,2,3]] + end, + ok. + ">>, + [], + {warnings,[{{5,21},sys_core_fold,useless_building}, + {{5,26},sys_core_fold,{no_effect,{erlang,node,0}}}, + {{5,46},sys_core_fold,{no_effect,{erlang,self,0}}}, + {{5,54},sys_core_fold,{no_effect,{erlang,time,0}}}, + {{5,61},sys_core_fold,{no_effect,{erlang,date,0}}}, + {{5,69},sys_core_fold,{no_effect,{erlang,time,0}}}, + {{6,22},sys_core_fold,{no_effect,{erlang,is_integer,1}}}, + {{8,21},sys_core_fold,useless_building}, + {{10,21},sys_core_fold,useless_building}, + {{12,21},sys_core_fold,useless_building}, + {{20,23},sys_core_fold,{no_effect,{erlang,'=:=',2}}}, + {{22,21},sys_core_fold,{no_effect,{erlang,get_cookie,0}}}]}}, + + {seq, + <<" + t(T) -> + [ {a,b,T} ], [ {x,y,T} ], + ok. + ">>, + [], + {warnings,[{{3,16},sys_core_fold,useless_building}, + {{3,30},sys_core_fold,useless_building}]}} + ], [] = run(Config, Ts), ok. @@ -508,9 +532,9 @@ bin_opt_info(Config) when is_list(Config) -> Code = <<" t1(Bin) -> case Bin of - _ when byte_size(Bin) > 20 -> erlang:error(too_long); + _ when byte_size(Bin) > 20 -> erlang:error(too_long); <<_,T/binary>> -> t1(T); - <<>> -> ok + <<>> -> ok end. %% We use a tail in a BIF instruction, remote call, function @@ -533,17 +557,17 @@ bin_opt_info(Config) when is_list(Config) -> %% to run. {warnings, [{5,beam_ssa_bsm,{unsuitable_call, - {{b_local,{b_literal,t1},1}, - {used_before_match, - {b_set,_,_,{bif,byte_size},[_]}}}}}, + {{b_local,{b_literal,t1},1}, + {used_before_match, + {b_set,_,_,{bif,byte_size},[_]}}}}}, {5,beam_ssa_bsm,{binary_created,_,_}}, {11,beam_ssa_bsm,{binary_created,_,_}}, %% A =< B -> T {13,beam_ssa_bsm,context_reused}, %% A > B -> t2(T); {16,beam_ssa_bsm,{binary_created,_,_}}, %% when byte_size(T) < 4 -> {19,beam_ssa_bsm,{remote_call, - {b_remote, - {b_literal,erlang}, - {b_literal,split_binary},2}}}, + {b_remote, + {b_literal,erlang}, + {b_literal,split_binary},2}}}, {19,beam_ssa_bsm,{binary_created,_,_}} %% split_binary(T, 4) ]} = Ws, @@ -563,9 +587,9 @@ bin_construction(Config) when is_list(Config) -> Bin = <<1,2,3,7:4>>, <<Bin/binary>>. ">>, - [], - {warnings,[{4,sys_core_fold,embedded_binary_size}, - {8,sys_core_fold,{embedded_unit,8,28}}]}}], + [], + {warnings,[{{4,18},sys_core_fold,embedded_binary_size}, + {{8,18},sys_core_fold,{embedded_unit,8,28}}]}}], [] = run(Config, Ts), ok. @@ -595,17 +619,17 @@ maps(Config) when is_list(Config) -> end. ">>, [], - {warnings,[{3,sys_core_fold,no_clause_match}, - {9,sys_core_fold,nomatch_clause_type}]}}, + {warnings,[{{3,18},sys_core_fold,no_clause_match}, + {{9,22},sys_core_fold,nomatch_clause_type}]}}, {bad_map_src1, <<" t() -> - M = {a,[]}, - {'EXIT',{badarg,_}} = (catch(M#{ a => 1 })), - ok. + M = {a,[]}, + {'EXIT',{badarg,_}} = (catch(M#{ a => 1 })), + ok. ">>, [], - {warnings,[{4,sys_core_fold,{eval_failure,badmap}}]}}, + {warnings,[{{4,48},sys_core_fold,{eval_failure,badmap}}]}}, {bad_map_src2, <<" t() -> @@ -619,11 +643,11 @@ maps(Config) when is_list(Config) -> {bad_map_src3, <<" t() -> - {'EXIT',{badarg,_}} = (catch <<>>#{ a := 1}), - ok. + {'EXIT',{badarg,_}} = (catch <<>>#{ a := 1}), + ok. ">>, [], - {warnings,[{3,sys_core_fold,{eval_failure,badmap}}]}}, + {warnings,[{{3,51},sys_core_fold,{eval_failure,badmap}}]}}, {ok_map_literal_key, <<" t() -> @@ -672,15 +696,15 @@ maps(Config) when is_list(Config) -> M#{<<\"a\">>=>1, <<\"b\">>=> 2, <<\"a\">>:=3}. ">>, [], - {warnings,[{3,v3_core,{map_key_repeated,a}}, - {8,v3_core,{map_key_repeated,a}}, - {11,v3_core,{map_key_repeated,a}}, - {14,v3_core,{map_key_repeated,"a"}}, - {17,v3_core,{map_key_repeated,"a"}}, - {20,v3_core,{map_key_repeated,"a"}}, - {23,v3_core,{map_key_repeated,"a"}}, - {28,v3_core,{map_key_repeated,"a"}}, - {31,v3_core,{map_key_repeated,<<"a">>}}]}}, + {warnings,[{{3,20},v3_core,{map_key_repeated,a}}, + {{8,21},v3_core,{map_key_repeated,a}}, + {{11,21},v3_core,{map_key_repeated,a}}, + {{14,20},v3_core,{map_key_repeated,"a"}}, + {{17,21},v3_core,{map_key_repeated,"a"}}, + {{20,21},v3_core,{map_key_repeated,"a"}}, + {{23,20},v3_core,{map_key_repeated,"a"}}, + {{28,21},v3_core,{map_key_repeated,"a"}}, + {{31,21},v3_core,{map_key_repeated,<<"a">>}}]}}, {repeated_keys2, <<" foo4(K) -> @@ -733,15 +757,15 @@ maps(Config) when is_list(Config) -> M1#{#{<<\"a\">>=>1}:=3,K=>2}. ">>, [], - {warnings,[{3,v3_core,{map_key_repeated,"a"}}, - {6,v3_core,{map_key_repeated,a}}, - {9,v3_core,{map_key_repeated,<<"a">>}}, - {14,v3_core,{map_key_repeated,{"a",1}}}, - {17,v3_core,{map_key_repeated,{"a",<<"b">>}}}, - {21,v3_core,{map_key_repeated,{<<"a">>,1}}}, - {25,v3_core,{map_key_repeated,#{"a" => 1}}}, - {28,v3_core,{map_key_repeated,#{"a" => <<"b">>}}}, - {32,v3_core,{map_key_repeated,#{<<"a">> => 1}}}]}} + {warnings,[{{3,20},v3_core,{map_key_repeated,"a"}}, + {{6,21},v3_core,{map_key_repeated,a}}, + {{9,21},v3_core,{map_key_repeated,<<"a">>}}, + {{14,20},v3_core,{map_key_repeated,{"a",1}}}, + {{17,21},v3_core,{map_key_repeated,{"a",<<"b">>}}}, + {{21,21},v3_core,{map_key_repeated,{<<"a">>,1}}}, + {{25,20},v3_core,{map_key_repeated,#{"a" => 1}}}, + {{28,21},v3_core,{map_key_repeated,#{"a" => <<"b">>}}}, + {{32,21},v3_core,{map_key_repeated,#{<<"a">> => 1}}}]}} ], run(Config, Ts), ok. @@ -770,7 +794,7 @@ redundant_boolean_clauses(Config) when is_list(Config) -> end. ">>, [], - {warnings,[{5,sys_core_fold,nomatch_shadow}]}}], + {warnings,[{{5,22},sys_core_fold,nomatch_shadow}]}}], run(Config, Ts), ok. @@ -782,13 +806,13 @@ latin1_fallback(Conf) when is_list(Conf) -> %% Test that the compiler fall backs to latin-1 with %% a warning if a file has no encoding and does not %% contain correct UTF-8 sequences. - <<"%% Bj",246,"rn + <<"\n%% Bj",246,"rn t(_) -> \"",246,"\"; t(x) -> ok. ">>, - [], - {warnings,[{1,compile,reparsing_invalid_unicode}, - {3,sys_core_fold,{nomatch_shadow,2,{t,1}}}]}}], + [], + {warnings,[{{2,1},compile,reparsing_invalid_unicode}, + {{4,15},sys_core_fold,{nomatch_shadow,3,{t,1}}}]}}], [] = run(Conf, Ts1), Ts2 = [{latin1_fallback2, @@ -800,7 +824,7 @@ latin1_fallback(Conf) when is_list(Conf) -> -include(\"include_me.hrl\"). ">>, [], - {warnings,[{1,compile,reparsing_invalid_unicode}]} + {warnings,[{{1,1},compile,reparsing_invalid_unicode}]} }], [] = run(Conf, Ts2), @@ -814,38 +838,39 @@ latin1_fallback(Conf) when is_list(Conf) -> -endif. ">>, [], - {warnings,[{2,compile,reparsing_invalid_unicode}]}}], + {warnings,[{{2,24},compile,reparsing_invalid_unicode}]}}], [] = run(Conf, Ts3), ok. underscore(Config) when is_list(Config) -> %% The code template. - S0 = <<"f(A) -> + S0 = <<" + f(A) -> _VAR1 = <<A>>, _VAR2 = {ok,A}, _VAR3 = [A], ok. - g(A) -> + g(A) -> _VAR1 = A/0, _VAR2 = date(), - ok. + ok. h() -> _VAR1 = fun() -> ok end, - ok. + ok. i(A) -> _VAR1 = #{A=>42}, - ok. + ok. ">>, %% Define all possible warnings. - Warnings = [{2,sys_core_fold,useless_building}, - {3,sys_core_fold,useless_building}, - {4,sys_core_fold,useless_building}, - {7,sys_core_fold,result_ignored}, - {8,sys_core_fold,{no_effect,{erlang,date,0}}}, - {11,sys_core_fold,useless_building}, - {14,sys_core_fold,useless_building}], + Warnings = [{{3,23},sys_core_fold,useless_building}, + {{4,23},sys_core_fold,useless_building}, + {{5,23},sys_core_fold,useless_building}, + {{8,24},sys_core_fold,result_ignored}, + {{9,23},sys_core_fold,{no_effect,{erlang,date,0}}}, + {{12,24},sys_core_fold,useless_building}, + {{15,24},sys_core_fold,useless_building}], %% Compile the unmodified template. Assigning to variable that @@ -861,7 +886,7 @@ underscore(Config) when is_list(Config) -> [] = run(Config, Ts1), %% Make sure that we get warnings if we remove "_VAR<digit> = ". - S2 = re:replace(S0, "_VAR\\d+ = ", "", [global]), + S2 = re:replace(S0, "_VAR\\d = ", " ", [global]), io:format("~s\n", [S2]), Ts2 = [{underscore2,S2,[],{warnings,Warnings}}], [] = run(Config, Ts2), @@ -869,7 +894,7 @@ underscore(Config) when is_list(Config) -> %% We should also get warnings if we assign to a variables that don't %% begin with underscore (as well as warnings for unused variables from %% erl_lint). - S3 = re:replace(S0, "_(?=VAR\\d+)", "", [global]), + S3 = re:replace(S0, "_(?=VAR\\d+)", " ", [global]), io:format("~s\n", [S3]), Ts3 = [{underscore2,S3,[],{warnings,Warnings}}], [] = run(Config, Ts3), @@ -913,7 +938,8 @@ no_warnings(Config) when is_list(Config) -> bit_syntax(Config) -> Ts = [{?FUNCTION_NAME, - <<"a(<<-1>>) -> ok; + <<" + a(<<-1>>) -> ok; a(<<1023>>) -> ok; a(<<777/signed>>) -> ok; a(<<a/binary>>) -> ok; @@ -932,25 +958,25 @@ bit_syntax(Config) -> end. ">>, [], - {warnings,[{1,sys_core_fold,no_clause_match}, - {1,sys_core_fold,{nomatch_bit_syntax_unsigned,-1}}, - {2,sys_core_fold,{nomatch_bit_syntax_truncated, - unsigned,1023,8}}, - {3,sys_core_fold,{nomatch_bit_syntax_truncated, - signed,777,8}}, - {4,sys_core_fold,{nomatch_bit_syntax_type,a,binary}}, - {5,sys_core_fold,{nomatch_bit_syntax_type,a,integer}}, - {6,sys_core_fold,{nomatch_bit_syntax_type,a,float}}, - {7,sys_core_fold,{nomatch_bit_syntax_type,a,utf8}}, - {8,sys_core_fold,{nomatch_bit_syntax_type,a,utf16}}, - {9,sys_core_fold,{nomatch_bit_syntax_type,a,utf32}}, - {10,sys_core_fold,{nomatch_bit_syntax_type,a,utf32}}, - {11,sys_core_fold,no_clause_match}, - {11,sys_core_fold,{nomatch_bit_syntax_size,bad}}, - {14,sys_core_fold,{nomatch_bit_syntax_unsigned,-42}}, - {16,sys_core_fold,{nomatch_bit_syntax_type,42,binary}} - ]} - }], + {warnings,[{{2,15},sys_core_fold,no_clause_match}, + {{2,19},sys_core_fold,{nomatch_bit_syntax_unsigned,-1}}, + {{3,19},sys_core_fold,{nomatch_bit_syntax_truncated, + unsigned,1023,8}}, + {{4,19},sys_core_fold,{nomatch_bit_syntax_truncated, + signed,777,8}}, + {{5,19},sys_core_fold,{nomatch_bit_syntax_type,a,binary}}, + {{6,19},sys_core_fold,{nomatch_bit_syntax_type,a,integer}}, + {{7,19},sys_core_fold,{nomatch_bit_syntax_type,a,float}}, + {{8,19},sys_core_fold,{nomatch_bit_syntax_type,a,utf8}}, + {{9,19},sys_core_fold,{nomatch_bit_syntax_type,a,utf16}}, + {{10,19},sys_core_fold,{nomatch_bit_syntax_type,a,utf32}}, + {{11,19},sys_core_fold,{nomatch_bit_syntax_type,a,utf32}}, + {{12,37},sys_core_fold,{nomatch_bit_syntax_size,bad}}, + {{12,45},sys_core_fold,no_clause_match}, + {{15,21},sys_core_fold,{nomatch_bit_syntax_unsigned,-42}}, + {{17,21},sys_core_fold,{nomatch_bit_syntax_type,42,binary}} + ]} + }], run(Config, Ts), ok. @@ -1053,8 +1079,33 @@ recv_opt_info(Config) when is_list(Config) -> %%% End of test cases. %%% -run(Config, Tests) -> +run(Config, Tests0) -> + do_run(Config, Tests0), + + %% Now test without column numbers. + Tests = [lines_only(T) || T <- Tests0], + do_run(Config, Tests). + +lines_only({Name,Test,Opts,{warnings,Result0}}) -> + Result1 = lists:map(fun lines_only_1/1, Result0), + Result = {warnings,lists:usort(Result1)}, + {Name,Test,[{error_location,line}|Opts],Result}; +lines_only(NoWarnings) -> NoWarnings. + +lines_only_1({File,Es0}) when is_list(Es0) -> + Es = [lines_only_1(E) || E <- Es0], + {File,Es}; +lines_only_1({Loc,Mod,Error}) -> + case Loc of + {Line,_Col} -> + {Line,Mod,Error}; + Line when is_integer(Line) -> + {Line,Mod,Error} + end. + +do_run(Config, Tests) -> F = fun({N,P,Ws,E}, BadL) -> + io:format("### ~s\n", [N]), case catch run_test(Config, P, Ws) of E -> BadL; @@ -1069,15 +1120,16 @@ run(Config, Tests) -> %% Compiles a test module and returns the list of errors and warnings. run_test(Conf, Test0, Warnings) -> - Module = "warnings_"++test_lib:uniq(), + Module = "warnings" ++ test_lib:uniq(), Filename = Module ++ ".erl", DataDir = ?privdir, - Test = ["-module(", Module, "). ", Test0], + Test1 = ["-module(", Module, "). -file( \"", Filename, "\", 1). ", Test0], + Test = iolist_to_binary(Test1), File = filename:join(DataDir, Filename), Opts = [binary,export_all,return|Warnings], ok = file:write_file(File, Test), - %% Compile once just to print all warnings. + %% Compile once just to print all warnings (and cover more code). compile:file(File, [binary,export_all,report|Warnings]), %% Test result of compilation. @@ -1091,12 +1143,33 @@ run_test(Conf, Test0, Warnings) -> Mod =/= erl_lint]} || {F,Ws} <- Ws0], case WsL of - [{_File,Ws}] -> {warnings, Ws}; - _ -> list_to_tuple([warnings, WsL]) + [{_File,Ws}] -> + print_warnings(Ws, Test), + {warnings, Ws}; + _ -> + list_to_tuple([warnings, WsL]) end end, file:delete(File), Res. +print_warnings(Warnings, Source) -> + Lines = binary:split(Source, <<"\n">>, [global]), + Cs = [print_warning(W, Lines) || W <- Warnings], + io:put_chars(Cs), + ok. + +print_warning({{LineNum,Column},Mod,Data}, Lines) -> + Line0 = lists:nth(LineNum, Lines), + <<Line1:(Column-1)/binary,_/binary>> = Line0, + Spaces = re:replace(Line1, <<"[^\t]">>, <<" ">>, [global]), + CaretLine = [Spaces,"^"], + [io_lib:format("~p:~p: ~ts\n", + [LineNum,Column,Mod:format_error(Data)]), + Line0, "\n", + CaretLine, "\n\n"]; +print_warning(_, _) -> + []. + fail() -> ct:fail(failed). diff --git a/lib/dialyzer/src/cerl_prettypr.erl b/lib/dialyzer/src/cerl_prettypr.erl index 46193276d4..d5032bae9e 100644 --- a/lib/dialyzer/src/cerl_prettypr.erl +++ b/lib/dialyzer/src/cerl_prettypr.erl @@ -895,6 +895,8 @@ tidy_float_2([]) -> []. get_line([L | _As]) when is_integer(L) -> L; +get_line([{L, _Column} | _As]) when is_integer(L) -> + L; get_line([_ | As]) -> get_line(As); get_line([]) -> diff --git a/lib/dialyzer/src/dialyzer.erl b/lib/dialyzer/src/dialyzer.erl index c1bc5ff597..938ecf1a97 100644 --- a/lib/dialyzer/src/dialyzer.erl +++ b/lib/dialyzer/src/dialyzer.erl @@ -285,17 +285,21 @@ format_warning(W) -> format_warning(RawWarning, FOpt) when is_atom(FOpt) -> format_warning(RawWarning, [{filename_opt, FOpt}]); -format_warning({Tag, {File, Line, _MFA}, Msg}, Opts) -> - format_warning({Tag, {File, Line}, Msg}, Opts); -format_warning({_Tag, {File, Line}, Msg}, Opts) when is_list(File), - is_integer(Line) -> +format_warning({Tag, {File, Location, _MFA}, Msg}, Opts) -> + format_warning({Tag, {File, Location}, Msg}, Opts); +format_warning({_Tag, {File, Location}, Msg}, Opts) when is_list(File) -> F = case proplists:get_value(filename_opt, Opts, basename) of fullpath -> File; basename -> filename:basename(File) end, Indent = proplists:get_value(indent_opt, Opts, ?INDENT_OPT), String = message_to_string(Msg, Indent), - lists:flatten(io_lib:format("~ts:~w: ~ts", [F, Line, String])). + lists:flatten(io_lib:format("~ts:~s: ~ts", [F, pos(Location), String])). + +pos({Line, Column}) when is_integer(Line), is_integer(Column) -> + io_lib:format("~w:~w", [Line, Column]); +pos(Line) when is_integer(Line) -> + io_lib:format("~w", [Line]). %%----------------------------------------------------------------------------- %% Message classification and pretty-printing below. Messages appear in @@ -408,11 +412,12 @@ message_to_string({contract_supertype, [M, F, _A, Contract, Sig]}, I) -> io_lib:format("Type specification ~ts" " is a supertype of the success typing: ~ts\n", [con(M, F, Contract, I), con(M, F, Sig, I)]); -message_to_string({contract_range, [Contract, M, F, ArgStrings, Line, CRet]}, - I) -> +message_to_string({contract_range, [Contract, M, F, ArgStrings, + Location, CRet]}, I) -> io_lib:format("The contract ~ts cannot be right because the inferred" - " return for ~tw~ts on line ~w is ~ts\n", - [con(M, F, Contract, I), F, a(ArgStrings, I), Line, t(CRet, I)]); + " return for ~tw~ts on position ~s is ~ts\n", + [con(M, F, Contract, I), F, a(ArgStrings, I), + pos(Location), t(CRet, I)]); message_to_string({invalid_contract, [M, F, A, Sig]}, I) -> io_lib:format("Invalid type specification for function ~w:~tw/~w." " The success typing is ~ts\n", [M, F, A, sig(Sig, I)]); diff --git a/lib/dialyzer/src/dialyzer.hrl b/lib/dialyzer/src/dialyzer.hrl index e1821f10eb..7776aa103b 100644 --- a/lib/dialyzer/src/dialyzer.hrl +++ b/lib/dialyzer/src/dialyzer.hrl @@ -77,8 +77,8 @@ %% This is the representation of each warning as they will be returned %% to dialyzer's callers %% --type file_line() :: {file:filename(), non_neg_integer()}. --type dial_warning() :: {dial_warn_tag(), file_line(), {atom(), [term()]}}. +-type file_location() :: {file:filename(), erl_anno:location()}. +-type dial_warning() :: {dial_warn_tag(), file_location(), {atom(), [term()]}}. %% %% This is the representation of each warning before suppressions have @@ -86,7 +86,7 @@ %% -type m_or_mfa() :: module() % warnings not associated with any function | mfa(). --type warning_info() :: {file:filename(), non_neg_integer(), m_or_mfa()}. +-type warning_info() :: {file:filename(), erl_anno:location(), m_or_mfa()}. -type raw_warning() :: {dial_warn_tag(), warning_info(), {atom(), [term()]}}. %% diff --git a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl index 9993c68fed..ed71018fe4 100644 --- a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl +++ b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl @@ -580,7 +580,7 @@ filter_warnings(Warnings, Codeserver) -> is_ok_fun({_F, _L, Module}, _Codeserver) when is_atom(Module) -> true; -is_ok_fun({_Filename, _Line, {_M, _F, _A} = MFA}, Codeserver) -> +is_ok_fun({_Filename, _Loc, {_M, _F, _A} = MFA}, Codeserver) -> not dialyzer_utils:is_suppressed_fun(MFA, Codeserver). is_ok_tag(Tag, {_F, _L, MorMFA}, Codeserver) -> @@ -620,14 +620,14 @@ format_bad_calls([{{_, _, _}, {_, module_info, A}}|Left], CodeServer, Acc) format_bad_calls([{FromMFA, {M, F, A} = To}|Left], CodeServer, Acc) -> {_Var, FunCode} = dialyzer_codeserver:lookup_mfa_code(FromMFA, CodeServer), Msg = {call_to_missing, [M, F, A]}, - {File, Line} = find_call_file_and_line(FromMFA, FunCode, To, CodeServer), - WarningInfo = {File, Line, FromMFA}, + {File, Loc} = find_call_file_and_location(FromMFA, FunCode, To, CodeServer), + WarningInfo = {File, Loc, FromMFA}, NewAcc = [{?WARN_CALLGRAPH, WarningInfo, Msg}|Acc], format_bad_calls(Left, CodeServer, NewAcc); format_bad_calls([], _CodeServer, Acc) -> Acc. -find_call_file_and_line({Module, _, _}, Tree, MFA, CodeServer) -> +find_call_file_and_location({Module, _, _}, Tree, MFA, CodeServer) -> Fun = fun(SubTree, Acc) -> case cerl:is_c_call(SubTree) of @@ -640,7 +640,9 @@ find_call_file_and_line({Module, _, _}, Tree, MFA, CodeServer) -> case {cerl:concrete(M), cerl:concrete(F), A} of MFA -> Ann = cerl:get_ann(SubTree), - [{get_file(CodeServer, Module, Ann), get_line(Ann)}|Acc]; + File = get_file(CodeServer, Module, Ann), + Location = get_location(SubTree), + [{File, Location}|Acc]; {erlang, make_fun, 3} -> [CA1, CA2, CA3] = cerl:call_args(SubTree), case @@ -657,7 +659,7 @@ find_call_file_and_line({Module, _, _}, Tree, MFA, CodeServer) -> MFA -> Ann = cerl:get_ann(SubTree), [{get_file(CodeServer, Module, Ann), - get_line(Ann)}|Acc]; + get_location(SubTree)}|Acc]; _ -> Acc end; @@ -673,9 +675,8 @@ find_call_file_and_line({Module, _, _}, Tree, MFA, CodeServer) -> end, hd(cerl_trees:fold(Fun, [], Tree)). -get_line([Line|_]) when is_integer(Line) -> Line; -get_line([_|Tail]) -> get_line(Tail); -get_line([]) -> -1. +get_location(Tree) -> + dialyzer_utils:get_location(Tree, -1). get_file(Codeserver, Module, [{file, FakeFile}|_]) -> dialyzer_codeserver:translate_fake_file(Codeserver, Module, FakeFile); diff --git a/lib/dialyzer/src/dialyzer_behaviours.erl b/lib/dialyzer/src/dialyzer_behaviours.erl index d380ab2a50..4be84502a1 100644 --- a/lib/dialyzer/src/dialyzer_behaviours.erl +++ b/lib/dialyzer/src/dialyzer_behaviours.erl @@ -65,14 +65,14 @@ check_callbacks(Module, Attrs, Records, Plt, Codeserver) -> %%-------------------------------------------------------------------- get_behaviours(Attrs) -> - BehaviourListsAndLine = + BehaviourListsAndLocation = [{cerl:concrete(L2), hd(cerl:get_ann(L2))} || {L1, L2} <- Attrs, cerl:is_literal(L1), cerl:is_literal(L2), cerl:concrete(L1) =:= 'behaviour' orelse cerl:concrete(L1) =:= 'behavior'], - Behaviours = lists:append([Behs || {Behs,_} <- BehaviourListsAndLine]), - BehLines = [{B,L} || {L1,L} <- BehaviourListsAndLine, B <- L1], - {Behaviours, BehLines}. + Behaviours = lists:append([Behs || {Behs,_} <- BehaviourListsAndLocation]), + BehLocations = [{B,L} || {L1,L} <- BehaviourListsAndLocation, B <- L1], + {Behaviours, BehLocations}. get_warnings(Module, Behaviours, State) -> get_warnings(Module, Behaviours, State, []). @@ -96,7 +96,7 @@ check_all_callbacks(Module, Behaviour, [Cb|Rest], #state{plt = Plt, codeserver = Codeserver, records = Records} = State, Acc) -> {{Behaviour, Function, Arity}, - {{_BehFile, _BehLine}, Callback, Xtra}} = Cb, + {{_BehFile, _BehLocation}, Callback, Xtra}} = Cb, CbMFA = {Module, Function, Arity}, CbReturnType = dialyzer_contracts:get_contract_return(Callback), CbArgTypes = dialyzer_contracts:get_contract_args(Callback), @@ -135,7 +135,7 @@ check_all_callbacks(Module, Behaviour, [Cb|Rest], Acc2 = case dialyzer_codeserver:lookup_mfa_contract(CbMFA, Codeserver) of 'error' -> Acc1; - {ok, {{File, Line}, Contract, _Xtra}} -> + {ok, {{File, Location}, Contract, _Xtra}} -> Acc10 = Acc1, SpecReturnType0 = dialyzer_contracts:get_contract_return(Contract), SpecArgTypes0 = dialyzer_contracts:get_contract_args(Contract), @@ -148,7 +148,7 @@ check_all_callbacks(Module, Behaviour, [Cb|Rest], false -> ExtraType = erl_types:t_subtract(SpecReturnType, CbReturnType), [{callback_spec_type_mismatch, - [File, Line, Behaviour, Function, Arity, + [File, Location, Behaviour, Function, Arity, erl_types:t_to_string(ExtraType, Records), erl_types:t_to_string(CbReturnType, Records)]}|Acc10] end, @@ -156,7 +156,7 @@ check_all_callbacks(Module, Behaviour, [Cb|Rest], erl_types:t_inf_lists(SpecArgTypes, CbArgTypes)) of false -> Acc11; true -> - find_mismatching_args({spec, File, Line}, SpecArgTypes, + find_mismatching_args({spec, File, Location}, SpecArgTypes, CbArgTypes, Behaviour, Function, Arity, Records, 1, Acc11) end @@ -180,8 +180,8 @@ find_mismatching_args(Kind, [Type|Rest], [CbType|CbRest], Behaviour, NewAcc = [case Kind of type -> {callback_arg_type_mismatch, Info}; - {spec, File, Line} -> - {callback_spec_arg_type_mismatch, [File, Line | Info]} + {spec, File, Location} -> + {callback_spec_arg_type_mismatch, [File, Location | Info]} end | Acc], find_mismatching_args(Kind, Rest, CbRest, Behaviour, Function, Arity, Records, N+1, NewAcc) @@ -190,29 +190,28 @@ find_mismatching_args(Kind, [Type|Rest], [CbType|CbRest], Behaviour, add_tag_warning_info(Module, {Tag, [B|_R]} = Warn, State) when Tag =:= callback_missing; Tag =:= callback_info_missing -> - {B, Line} = lists:keyfind(B, 1, State#state.behlines), + {B, Location} = lists:keyfind(B, 1, State#state.behlines), Category = case Tag of callback_missing -> ?WARN_BEHAVIOUR; callback_info_missing -> ?WARN_UNDEFINED_CALLBACK end, - {Category, {State#state.filename, Line, Module}, Warn}; -add_tag_warning_info(Module, {Tag, [File, Line|R]}, _State) + {Category, {State#state.filename, Location, Module}, Warn}; +add_tag_warning_info(Module, {Tag, [File, Location|R]}, _State) when Tag =:= callback_spec_type_mismatch; Tag =:= callback_spec_arg_type_mismatch -> - {?WARN_BEHAVIOUR, {File, Line, Module}, {Tag, R}}; + {?WARN_BEHAVIOUR, {File, Location, Module}, {Tag, R}}; add_tag_warning_info(Module, {_Tag, [_B, Fun, Arity|_R]} = Warn, State) -> {_A, FunCode} = dialyzer_codeserver:lookup_mfa_code({Module, Fun, Arity}, State#state.codeserver), Anns = cerl:get_ann(FunCode), File = get_file(State#state.codeserver, Module, Anns), - WarningInfo = {File, get_line(Anns), {Module, Fun, Arity}}, + WarningInfo = {File, get_location(FunCode), {Module, Fun, Arity}}, {?WARN_BEHAVIOUR, WarningInfo, Warn}. -get_line([Line|_]) when is_integer(Line) -> Line; -get_line([_|Tail]) -> get_line(Tail); -get_line([]) -> -1. +get_location(Tree) -> + dialyzer_utils:get_location(Tree, -1). get_file(Codeserver, Module, [{file, FakeFile}|_]) -> dialyzer_codeserver:translate_fake_file(Codeserver, Module, FakeFile); diff --git a/lib/dialyzer/src/dialyzer_cl.erl b/lib/dialyzer/src/dialyzer_cl.erl index 5e680062fb..15696fb3b6 100644 --- a/lib/dialyzer/src/dialyzer_cl.erl +++ b/lib/dialyzer/src/dialyzer_cl.erl @@ -637,15 +637,15 @@ unknown_warnings(State = #cl_state{legal_warnings = LegalWarnings}) -> unknown_types(State); false -> [] end, - WarningInfo = {_Filename = "", _Line = 0, _MorMFA = ''}, + WarningInfo = {_Filename = "", _Location = 0, _MorMFA = ''}, [{?WARN_UNKNOWN, WarningInfo, W} || W <- Unknown]. unknown_functions(#cl_state{external_calls = Calls}) -> [{unknown_function, MFA} || MFA <- Calls]. set_warning_id(Warnings) -> - lists:map(fun({Tag, {File, Line, _MorMFA}, Msg}) -> - {Tag, {File, Line}, Msg} + lists:map(fun({Tag, {File, Location, _MorMFA}, Msg}) -> + {Tag, {File, Location}, Msg} end, Warnings). print_ext_calls(#cl_state{report_mode = quiet}) -> @@ -735,7 +735,7 @@ print_warnings(#cl_state{output = Output, -spec process_warnings([raw_warning()]) -> [raw_warning()]. process_warnings(Warnings) -> - Warnings1 = lists:keysort(2, Warnings), %% Sort on file/line (and m/mfa..) + Warnings1 = lists:keysort(2, Warnings), %% Sort on file/location (and m/mfa..) remove_duplicate_warnings(Warnings1, []). remove_duplicate_warnings([Duplicate, Duplicate|Left], Acc) -> diff --git a/lib/dialyzer/src/dialyzer_codeserver.erl b/lib/dialyzer/src/dialyzer_codeserver.erl index c4e3c322e5..3fbfacc38c 100644 --- a/lib/dialyzer/src/dialyzer_codeserver.erl +++ b/lib/dialyzer/src/dialyzer_codeserver.erl @@ -317,10 +317,10 @@ finalize_records(#codeserver{temp_records = TmpRecords, true = ets:delete(TmpRecords), Fun = fun({Mod, Map}) -> MFun = - fun({record, _}, {FileLine, ArityFields}) -> - {FileLine, lists:map(ArFun, ArityFields)}; - (_, {{M, FileLine, Abs, Args}, Type}) -> - {{M, FileLine, erl_parse:map_anno(AFun, Abs), Args}, Type} + fun({record, _}, {FileLocation, ArityFields}) -> + {FileLocation, lists:map(ArFun, ArityFields)}; + (_, {{M, FileLocation, Abs, Args}, Type}) -> + {{M, FileLocation, erl_parse:map_anno(AFun, Abs), Args}, Type} end, {Mod, maps:map(MFun, Map)} end, diff --git a/lib/dialyzer/src/dialyzer_contracts.erl b/lib/dialyzer/src/dialyzer_contracts.erl index e041c43cc1..cd9a4c16ce 100644 --- a/lib/dialyzer/src/dialyzer_contracts.erl +++ b/lib/dialyzer/src/dialyzer_contracts.erl @@ -37,7 +37,7 @@ %% Types used in other parts of the system below %%----------------------------------------------------------------------- --type file_contract() :: {file_line(), #contract{}, Extra :: [_]}. +-type file_contract() :: {file_location(), #contract{}, Extra :: [_]}. -type plt_contracts() :: orddict:orddict(mfa(), #contract{}). @@ -448,8 +448,8 @@ contracts_without_fun(Contracts, AllFuns0, Callgraph) -> [warn_spec_missing_fun(MFA, Contracts) || MFA <- ErrorContractMFAs]. warn_spec_missing_fun({M, F, A} = MFA, Contracts) -> - {{File, Line}, _Contract, _Xtra} = maps:get(MFA, Contracts), - WarningInfo = {File, Line, MFA}, + {{File, Location}, _Contract, _Xtra} = maps:get(MFA, Contracts), + WarningInfo = {File, Location, MFA}, {?WARN_CONTRACT_SYNTAX, WarningInfo, {spec_missing_fun, [M, F, A]}}. %% This treats the "when" constraints. It will be extended, we hope. @@ -478,23 +478,23 @@ insert_constraints([], Map) -> Map. -type spec_data() :: {TypeSpec :: [_], Xtra:: [_]}. --spec store_tmp_contract(module(), mfa(), file_line(), spec_data(), +-spec store_tmp_contract(module(), mfa(), file_location(), spec_data(), contracts(), types()) -> contracts(). -store_tmp_contract(Module, MFA, FileLine, {TypeSpec, Xtra}, SpecMap, +store_tmp_contract(Module, MFA, FileLocation, {TypeSpec, Xtra}, SpecMap, RecordsDict) -> %% io:format("contract from form: ~tp\n", [TypeSpec]), - TmpContract = contract_from_form(TypeSpec, Module, MFA, RecordsDict, FileLine), + TmpContract = contract_from_form(TypeSpec, Module, MFA, RecordsDict, FileLocation), %% io:format("contract: ~tp\n", [TmpContract]), - maps:put(MFA, {FileLine, TmpContract, Xtra}, SpecMap). + maps:put(MFA, {FileLocation, TmpContract, Xtra}, SpecMap). -contract_from_form(Forms, Module, MFA, RecDict, FileLine) -> +contract_from_form(Forms, Module, MFA, RecDict, FileLocation) -> {CFuns, Forms1} = - contract_from_form(Forms, Module, MFA, RecDict, FileLine, [], []), + contract_from_form(Forms, Module, MFA, RecDict, FileLocation, [], []), #tmp_contract{contract_funs = CFuns, forms = Forms1}. contract_from_form([{type, _, 'fun', [_, _]} = Form | Left], Module, MFA, - RecDict, FileLine, TypeAcc, FormAcc) -> + RecDict, FileLocation, TypeAcc, FormAcc) -> TypeFun = fun(ExpTypes, RecordTable, Cache) -> {NewType, NewCache} = @@ -503,9 +503,9 @@ contract_from_form([{type, _, 'fun', [_, _]} = Form | Left], Module, MFA, Cache) catch throw:{error, Msg} -> - {File, Line} = FileLine, - NewMsg = io_lib:format("~ts:~p: ~ts", [filename:basename(File), - Line, Msg]), + {File, Location} = FileLocation, + NewMsg = io_lib:format("~ts:~s: ~ts", [filename:basename(File), + pos(Location), Msg]), throw({error, NewMsg}) end, NewTypeNoVars = erl_types:subst_all_vars_to_any(NewType), @@ -513,11 +513,11 @@ contract_from_form([{type, _, 'fun', [_, _]} = Form | Left], Module, MFA, end, NewTypeAcc = [TypeFun | TypeAcc], NewFormAcc = [{Form, []} | FormAcc], - contract_from_form(Left, Module, MFA, RecDict, FileLine, NewTypeAcc, + contract_from_form(Left, Module, MFA, RecDict, FileLocation, NewTypeAcc, NewFormAcc); -contract_from_form([{type, _L1, bounded_fun, - [{type, _L2, 'fun', [_, _]} = Form, Constr]}| Left], - Module, MFA, RecDict, FileLine, TypeAcc, FormAcc) -> +contract_from_form([{type, _Anno1, bounded_fun, + [{type, _Anno2, 'fun', [_, _]} = Form, Constr]}| Left], + Module, MFA, RecDict, FileLocation, TypeAcc, FormAcc) -> TypeFun = fun(ExpTypes, RecordTable, Cache) -> {Constr1, VarTable, Cache1} = @@ -531,11 +531,16 @@ contract_from_form([{type, _L1, bounded_fun, end, NewTypeAcc = [TypeFun | TypeAcc], NewFormAcc = [{Form, Constr} | FormAcc], - contract_from_form(Left, Module, MFA, RecDict, FileLine, NewTypeAcc, + contract_from_form(Left, Module, MFA, RecDict, FileLocation, NewTypeAcc, NewFormAcc); -contract_from_form([], _Mod, _MFA, _RecDict, _FileLine, TypeAcc, FormAcc) -> +contract_from_form([], _Mod, _MFA, _RecDict, _FileLocation, TypeAcc, FormAcc) -> {lists:reverse(TypeAcc), lists:reverse(FormAcc)}. +pos({Line, Column}) when is_integer(Line), is_integer(Column) -> + io_lib:format("~w:~w", [Line, Column]); +pos(Line) when is_integer(Line) -> + io_lib:format("~w", [Line]). + process_constraints(Constrs, Module, MFA, RecDict, ExpTypes, RecordTable, Cache) -> {Init0, NewCache} = initialize_constraints(Constrs, Module, MFA, RecDict, @@ -697,7 +702,7 @@ remove_uses(Var, Use, [Constr|Constrs]) -> end, [NewConstr|remove_uses(Var, Use, Constrs)]. -remove_use({var, L, V}, V) -> {var, L, '_'}; +remove_use({var, Anno, V}, V) -> {var, Anno, '_'}; remove_use(T, V) when is_tuple(T) -> list_to_tuple(remove_use(tuple_to_list(T), V)); remove_use([E|Es], V) -> @@ -742,7 +747,7 @@ get_invalid_contract_warnings_modules([Mod|Mods], CodeServer, Plt, Acc) -> get_invalid_contract_warnings_modules([], _CodeServer, _Plt, Acc) -> Acc. -get_invalid_contract_warnings_funs([{MFA, {FileLine, Contract, _Xtra}}|Left], +get_invalid_contract_warnings_funs([{MFA, {FileLocation, Contract, _Xtra}}|Left], Plt, RecDict, Opaques, Acc) -> case dialyzer_plt:lookup(Plt, MFA) of none -> @@ -752,8 +757,8 @@ get_invalid_contract_warnings_funs([{MFA, {FileLine, Contract, _Xtra}}|Left], Sig = erl_types:t_fun(Args, Ret), {M, _F, _A} = MFA, %% io:format("MFA ~tp~n", [MFA]), - {File, Line} = FileLine, - WarningInfo = {File, Line, MFA}, + {File, Location} = FileLocation, + WarningInfo = {File, Location, MFA}, NewAcc = case check_contract(Contract, Sig, Opaques) of {error, invalid_contract} -> diff --git a/lib/dialyzer/src/dialyzer_dataflow.erl b/lib/dialyzer/src/dialyzer_dataflow.erl index 2f25da2a37..f0ecd89a8b 100644 --- a/lib/dialyzer/src/dialyzer_dataflow.erl +++ b/lib/dialyzer/src/dialyzer_dataflow.erl @@ -434,8 +434,9 @@ handle_apply(Tree, Map, State) -> [ArgNs, format_args(Args, ArgTypes, State), format_type(OpType, State)]}, + ArgTree = select_arg(ArgNs, Args, Tree), State3 = state__add_warning(State2, ?WARN_FAILING_CALL, - Tree, Msg), + ArgTree, Msg), {State3, enter_type(Op, OpType1, Map2), t_none()}; false -> Map3 = enter_type_lists(Args, NewArgs, Map2), @@ -554,9 +555,9 @@ handle_apply_or_call([{TypeOfApply, {Fun, Sig, Contr, LocalRet}}|Left], true -> Ann = cerl:get_ann(Tree), File = get_file(Ann, State), - Line = abs(get_line(Ann)), + Location = get_location(Tree), dialyzer_races:store_race_call(Fun, ArgTypes, Args, - {File, Line}, State); + {File, Location}, State); false -> State end, FailedConj = any_none([RetWithoutLocal|NewArgTypes]), @@ -599,8 +600,21 @@ handle_apply_or_call([{TypeOfApply, {Fun, Sig, Contr, LocalRet}}|Left], {call_without_opaque, _} -> ?WARN_OPAQUE; {opaque_type_test, _} -> ?WARN_OPAQUE end, + LocTree = case Msg of + {call, [_M, _F, _ASs, ANs | _]} -> + select_arg(ANs, Args, Tree); + {apply, [_ASs, ANs | _]} -> + select_arg(ANs, Args, Tree); + {call_with_opaque, [_M, _F, _ASs, ANs, _EAs_]} -> + select_arg(ANs, Args, Tree); + {call_without_opaque, + [_M, _F, _ASs, [{N, _T, _TS} | _]]} -> + select_arg([N], Args, Tree); + {opaque_type_test, _} -> + Tree + end, Frc = {erlang, is_record, 3} =:= state__lookup_name(Fun, State), - state__add_warning(State1, WarnType, Tree, Msg, Frc) + state__add_warning(State1, WarnType, LocTree, Msg, Frc) end; false -> State1 end, @@ -942,12 +956,12 @@ handle_call(Tree, Map, State) -> format_args(Args, As, State1), MS, format_type(t_module(), State1), format_type(MType0, State1)]}, - state__add_warning(State1, ?WARN_FAILING_CALL, Tree, Msg); + state__add_warning(State1, ?WARN_FAILING_CALL, M, Msg); false -> Msg = {opaque_call, [MS, format_cerl(F), format_args(Args, As, State1), MS, format_type(MType0, State1)]}, - state__add_warning(State1, ?WARN_FAILING_CALL, Tree, Msg) + state__add_warning(State1, ?WARN_FAILING_CALL, M, Msg) end; FOpaque -> FS = format_cerl(F), @@ -957,12 +971,12 @@ handle_call(Tree, Map, State) -> format_args(Args, As, State1), FS, format_type(t_atom(), State1), format_type(FType0, State1)]}, - state__add_warning(State1, ?WARN_FAILING_CALL, Tree, Msg); + state__add_warning(State1, ?WARN_FAILING_CALL, F, Msg); false -> Msg = {opaque_call, [format_cerl(M), FS, format_args(Args, As, State1), FS, format_type(FType0, State1)]}, - state__add_warning(State1, ?WARN_FAILING_CALL, Tree, Msg) + state__add_warning(State1, ?WARN_FAILING_CALL, F, Msg) end; true -> State1 end, @@ -1246,10 +1260,12 @@ handle_tuple(Tree, Map, State) -> case t_is_none(InfTupleType) of true -> RecC = format_type(TupleType, State1), - FieldDiffs = format_field_diffs(TupleType, State1), + {FieldPosList, FieldDiffs} = + format_field_diffs(TupleType, State1), Msg = {record_constr, [RecC, FieldDiffs]}, + LocTree = lists:nth(hd(FieldPosList), Left), State2 = state__add_warning(State1, ?WARN_MATCHING, - Tree, Msg), + LocTree, Msg), {State2, Map1, t_none()}; false -> case bind_pat_vars(Elements, t_tuple_args(RecType), @@ -1258,8 +1274,9 @@ handle_tuple(Tree, Map, State) -> Msg = {record_constr, [TagVal, format_patterns(ErrorPat), format_type(ErrorType, State1)]}, + LocTree = hd(ErrorPat), State2 = state__add_warning(State1, ?WARN_MATCHING, - Tree, Msg), + LocTree, Msg), {State2, Map1, t_none()}; {error, opaque, ErrorPat, ErrorType, OpaqueType} -> OpaqueStr = format_type(OpaqueType, State1), @@ -1269,8 +1286,9 @@ handle_tuple(Tree, Map, State) -> " declared to be of type " ++ format_type(ErrorType, State1), OpaqueStr, OpaqueStr]}, + LocTree = hd(ErrorPat), State2 = state__add_warning(State1, ?WARN_OPAQUE, - Tree, Msg), + LocTree, Msg), {State2, Map1, t_none()}; {error, record, ErrorPat, ErrorType, _} -> Msg = {record_match, @@ -2643,7 +2661,12 @@ signal_guard_failure(Eval, Guard, ArgTypes, Tag, State) -> [F, format_args(Args, ArgTypes, State)] end, Msg = {Kind, FArgs}, - throw({Tag, {Guard, Msg}}). + LocTree = + case XInfo of + [] -> Guard; + [Ns1] -> select_arg(Ns1, Args, Guard) + end, + throw({Tag, {LocTree, Msg}}). is_infix_op({erlang, '=:=', 2}) -> true; is_infix_op({erlang, '==', 2}) -> true; @@ -3128,7 +3151,7 @@ state__add_warning(#state{warnings = Warnings, warning_mode = true} = State, case Force of true -> WarningInfo = {get_file(Ann, State), - abs(get_line(Ann)), + get_location(Tree), State#state.curr_fun}, Warn = {Tag, WarningInfo, Msg}, ?debug("MSG ~ts\n", [dialyzer:format_warning(Warn)]), @@ -3138,7 +3161,7 @@ state__add_warning(#state{warnings = Warnings, warning_mode = true} = State, true -> State; false -> WarningInfo = {get_file(Ann, State), - get_line(Ann), + get_location(Tree), State#state.curr_fun}, Warn = {Tag, WarningInfo, Msg}, case Tag of @@ -3627,9 +3650,18 @@ add_work(New, {List, Rev, Set} = Work) -> %%% =========================================================================== get_line([Line|_]) when is_integer(Line) -> Line; +get_line([{Line, _Column} | _Tail]) when is_integer(Line) -> Line; get_line([_|Tail]) -> get_line(Tail); get_line([]) -> -1. +get_location(Tree) -> + dialyzer_utils:get_location(Tree, 1). + +select_arg([], _Args, Tree) -> + Tree; +select_arg([ArgN | _], Args, _Tree) -> + lists:nth(ArgN, Args). + get_file([], _State) -> []; get_file([{file, FakeFile}|_], State) -> state__translate_file(FakeFile, State); @@ -3686,7 +3718,8 @@ format_arg(Arg) -> format_type(Type, #state{records = R}) -> t_to_string(Type, R). --spec format_field_diffs(type(), state()) -> string(). +-spec format_field_diffs(type(), state()) -> + {[FieldPos :: pos_integer()], string()}. format_field_diffs(RecConstruction, #state{records = R}) -> erl_types:record_field_diffs_to_string(RecConstruction, R). diff --git a/lib/dialyzer/src/dialyzer_races.erl b/lib/dialyzer/src/dialyzer_races.erl index 7602faa21d..adefc16f99 100644 --- a/lib/dialyzer/src/dialyzer_races.erl +++ b/lib/dialyzer/src/dialyzer_races.erl @@ -105,7 +105,7 @@ arg_types :: [erl_types:erl_type()], vars :: [core_vars()], state :: dialyzer_dataflow:state(), - file_line :: file_line(), + file_loc :: file_location(), var_map :: dict:dict() | 'undefined'}). -record(fun_call, {caller :: dialyzer_callgraph:mfa_or_funlbl(), callee :: dialyzer_callgraph:mfa_or_funlbl(), @@ -128,7 +128,7 @@ args :: args(), arg_types :: [erl_types:erl_type()], vars :: [core_vars()], - file_line :: file_line(), + file_loc :: file_location(), index :: non_neg_integer(), fun_mfa :: dialyzer_callgraph:mfa_or_funlbl(), fun_label :: label()}). @@ -161,10 +161,10 @@ -spec store_race_call(dialyzer_callgraph:mfa_or_funlbl(), [erl_types:erl_type()], [core_vars()], - file_line(), dialyzer_dataflow:state()) -> + file_location(), dialyzer_dataflow:state()) -> dialyzer_dataflow:state(). -store_race_call(Fun, ArgTypes, Args, FileLine, State) -> +store_race_call(Fun, ArgTypes, Args, FileLocation, State) -> Races = dialyzer_dataflow:state__get_races(State), CurrFun = Races#races.curr_fun, CurrFunLabel = Races#races.curr_fun_label, @@ -184,7 +184,7 @@ store_race_call(Fun, ArgTypes, Args, FileLine, State) -> VarArgs = format_args(Args, ArgTypes, CleanState, register), RaceFun = #race_fun{mfa = Fun, args = VarArgs, arg_types = ArgTypes, vars = Args, - file_line = FileLine, index = RaceListSize, + file_loc = FileLocation, index = RaceListSize, fun_mfa = CurrFun, fun_label = CurrFunLabel}, {[#warn_call{call_name = register, args = VarArgs}| RaceList], RaceListSize + 1, [RaceFun|RaceTags], no_t}; @@ -192,7 +192,7 @@ store_race_call(Fun, ArgTypes, Args, FileLine, State) -> VarArgs = format_args(Args, ArgTypes, CleanState, unregister), RaceFun = #race_fun{mfa = Fun, args = VarArgs, arg_types = ArgTypes, vars = Args, - file_line = FileLine, index = RaceListSize, + file_loc = FileLocation, index = RaceListSize, fun_mfa = CurrFun, fun_label = CurrFunLabel}, {[#warn_call{call_name = unregister, args = VarArgs}| RaceList], RaceListSize + 1, [RaceFun|RaceTags], no_t}; @@ -200,13 +200,13 @@ store_race_call(Fun, ArgTypes, Args, FileLine, State) -> VarArgs = format_args(Args, ArgTypes, CleanState, whereis), {[#dep_call{call_name = whereis, args = VarArgs, arg_types = ArgTypes, vars = Args, - state = CleanState, file_line = FileLine}| + state = CleanState, file_loc = FileLocation}| RaceList], RaceListSize + 1, RaceTags, no_t}; {ets, insert, 2} -> VarArgs = format_args(Args, ArgTypes, CleanState, ets_insert), RaceFun = #race_fun{mfa = Fun, args = VarArgs, arg_types = ArgTypes, vars = Args, - file_line = FileLine, index = RaceListSize, + file_loc = FileLocation, index = RaceListSize, fun_mfa = CurrFun, fun_label = CurrFunLabel}, {[#warn_call{call_name = ets_insert, args = VarArgs}| RaceList], RaceListSize + 1, [RaceFun|RaceTags], no_t}; @@ -214,7 +214,7 @@ store_race_call(Fun, ArgTypes, Args, FileLine, State) -> VarArgs = format_args(Args, ArgTypes, CleanState, ets_lookup), {[#dep_call{call_name = ets_lookup, args = VarArgs, arg_types = ArgTypes, vars = Args, - state = CleanState, file_line = FileLine}| + state = CleanState, file_loc = FileLocation}| RaceList], RaceListSize + 1, RaceTags, no_t}; {ets, new, 2} -> VarArgs = format_args(Args, ArgTypes, CleanState, ets_new), @@ -240,7 +240,7 @@ store_race_call(Fun, ArgTypes, Args, FileLine, State) -> end, {[#dep_call{call_name = mnesia_dirty_read, args = VarArgs, arg_types = ArgTypes, vars = Args, - state = CleanState, file_line = FileLine}|RaceList], + state = CleanState, file_loc = FileLocation}|RaceList], RaceListSize + 1, RaceTags, no_t}; {mnesia, dirty_write, A} when A =:= 1 orelse A =:= 2 -> VarArgs = @@ -252,7 +252,7 @@ store_race_call(Fun, ArgTypes, Args, FileLine, State) -> end, RaceFun = #race_fun{mfa = Fun, args = VarArgs, arg_types = ArgTypes, vars = Args, - file_line = FileLine, index = RaceListSize, + file_loc = FileLocation, index = RaceListSize, fun_mfa = CurrFun, fun_label = CurrFunLabel}, {[#warn_call{call_name = mnesia_dirty_write, args = VarArgs}|RaceList], @@ -286,7 +286,7 @@ race(State) -> [] -> State; [#race_fun{mfa = Fun, args = VarArgs, arg_types = ArgTypes, - vars = Args, file_line = FileLine, + vars = Args, file_loc = FileLocation, index = Index, fun_mfa = CurrFun, fun_label = CurrFunLabel}|T] -> Callgraph = dialyzer_dataflow:state__get_callgraph(State), @@ -308,9 +308,9 @@ race(State) -> DepList = fixup_race_list(RaceWarnTag, VarArgs, State1), {State2, RaceWarn} = get_race_warn(Fun, Args, ArgTypes, DepList, State), - {File, Line} = FileLine, + {File, Location} = FileLocation, CurrMFA = dialyzer_dataflow:state__find_function(CurrFun, State), - WarningInfo = {File, Line, CurrMFA}, + WarningInfo = {File, Location, CurrMFA}, race( state__add_race_warning( state__renew_race_tags(T, State2), RaceWarn, RaceWarnTag, @@ -1254,9 +1254,9 @@ cleanup_dep_calls(DepList) -> case DepList of [] -> []; [#dep_call{call_name = CallName, arg_types = ArgTypes, - vars = Vars, state = State, file_line = FileLine}|T] -> + vars = Vars, state = State, file_loc = FileLocation}|T] -> [#dep_call{call_name = CallName, arg_types = ArgTypes, - vars = Vars, state = State, file_line = FileLine}| + vars = Vars, state = State, file_loc = FileLocation}| cleanup_dep_calls(T)] end. @@ -2353,7 +2353,7 @@ get_reason(DependencyList, Reason) -> case DependencyList of [] -> ""; [#dep_call{call_name = Call, arg_types = ArgTypes, vars = Args, - state = State, file_line = {File, Line}}|T] -> + state = State, file_loc = {File, Location}}|T] -> R = Reason ++ case Call of @@ -2365,7 +2365,7 @@ get_reason(DependencyList, Reason) -> " call in " ++ filename:basename(File) ++ " on line " ++ - lists:flatten(io_lib:write(Line)), + lists:flatten(io_lib:write(Location)), case T of [] -> R; _ -> get_reason(T, R ++ ", ") diff --git a/lib/dialyzer/src/dialyzer_succ_typings.erl b/lib/dialyzer/src/dialyzer_succ_typings.erl index 48115bb683..c53ea15ae1 100644 --- a/lib/dialyzer/src/dialyzer_succ_typings.erl +++ b/lib/dialyzer/src/dialyzer_succ_typings.erl @@ -385,7 +385,7 @@ prepare_decoration(FunTypes, Callgraph, Codeserver) -> case dialyzer_callgraph:lookup_name(Label, Callgraph) of {ok, MFA} -> case dialyzer_codeserver:lookup_mfa_contract(MFA, Codeserver) of - {ok, {_FileLine, Contract, _Xtra}} -> + {ok, {_FileLocation, Contract, _Xtra}} -> [{LabelType, {MFA, Contract}}|Acc]; error -> [{LabelType, no}|Acc] end; diff --git a/lib/dialyzer/src/dialyzer_utils.erl b/lib/dialyzer/src/dialyzer_utils.erl index f679f146cc..0cf6427f8d 100644 --- a/lib/dialyzer/src/dialyzer_utils.erl +++ b/lib/dialyzer/src/dialyzer_utils.erl @@ -39,6 +39,7 @@ sets_filter/2, src_compiler_opts/0, refold_pattern/1, + get_location/2, ets_tab2list/1, ets_move/2, parallelism/0, @@ -58,15 +59,15 @@ print_types(RecDict) -> print_types1([], _) -> ok; print_types1([{type, _Name, _NArgs} = Key|T], RecDict) -> - {ok, {{_Mod, _FileLine, _Form, _Args}, Type}} = dict:find(Key, RecDict), + {ok, {{_Mod, _FileLocation, _Form, _Args}, Type}} = dict:find(Key, RecDict), io:format("\n~tw: ~tw\n", [Key, Type]), print_types1(T, RecDict); print_types1([{opaque, _Name, _NArgs} = Key|T], RecDict) -> - {ok, {{_Mod, _FileLine, _Form, _Args}, Type}} = dict:find(Key, RecDict), + {ok, {{_Mod, _FileLocation, _Form, _Args}, Type}} = dict:find(Key, RecDict), io:format("\n~tw: ~tw\n", [Key, Type]), print_types1(T, RecDict); print_types1([{record, _Name} = Key|T], RecDict) -> - {ok, {_FileLine, [{_Arity, _Fields} = AF]}} = dict:find(Key, RecDict), + {ok, {_FileLocation, [{_Arity, _Fields} = AF]}} = dict:find(Key, RecDict), io:format("~tw: ~tw\n\n", [Key, AF]), print_types1(T, RecDict). -define(debug(D_), print_types(D_)). @@ -141,35 +142,35 @@ get_record_and_type_info(Core) -> Tuples = core_to_attr_tuples(Core), get_record_and_type_info(Tuples, Module, maps:new(), "nofile"). -get_record_and_type_info([{record, Line, [{Name, Fields0}]}|Left], +get_record_and_type_info([{record, Location, [{Name, Fields0}]}|Left], Module, RecDict, File) -> {ok, Fields} = get_record_fields(Fields0, RecDict), Arity = length(Fields), - FN = {File, Line}, + FN = {File, Location}, NewRecDict = maps:put({record, Name}, {FN, [{Arity,Fields}]}, RecDict), get_record_and_type_info(Left, Module, NewRecDict, File); -get_record_and_type_info([{type, Line, [{{record, Name}, Fields0, []}]} +get_record_and_type_info([{type, Location, [{{record, Name}, Fields0, []}]} |Left], Module, RecDict, File) -> %% This overrides the original record declaration. {ok, Fields} = get_record_fields(Fields0, RecDict), Arity = length(Fields), - FN = {File, Line}, + FN = {File, Location}, NewRecDict = maps:put({record, Name}, {FN, [{Arity, Fields}]}, RecDict), get_record_and_type_info(Left, Module, NewRecDict, File); -get_record_and_type_info([{Attr, Line, [{Name, TypeForm}]}|Left], +get_record_and_type_info([{Attr, Location, [{Name, TypeForm}]}|Left], Module, RecDict, File) when Attr =:= 'type'; Attr =:= 'opaque' -> - FN = {File, Line}, + FN = {File, Location}, try add_new_type(Attr, Name, TypeForm, [], Module, FN, RecDict) of NewRecDict -> get_record_and_type_info(Left, Module, NewRecDict, File) catch throw:{error, _} = Error -> Error end; -get_record_and_type_info([{Attr, Line, [{Name, TypeForm, Args}]}|Left], +get_record_and_type_info([{Attr, Location, [{Name, TypeForm, Args}]}|Left], Module, RecDict, File) when Attr =:= 'type'; Attr =:= 'opaque' -> - FN = {File, Line}, + FN = {File, Location}, try add_new_type(Attr, Name, TypeForm, Args, Module, FN, RecDict) of NewRecDict -> get_record_and_type_info(Left, Module, NewRecDict, File) @@ -212,15 +213,15 @@ get_record_fields([{typed_record_field, OrdRecField, TypeForm}|Left], RecDict, Acc) -> Name = case OrdRecField of - {record_field, _Line, Name0} -> erl_parse:normalise(Name0); - {record_field, _Line, Name0, _Init} -> erl_parse:normalise(Name0) + {record_field, _Location, Name0} -> erl_parse:normalise(Name0); + {record_field, _Location, Name0, _Init} -> erl_parse:normalise(Name0) end, get_record_fields(Left, RecDict, [{Name, TypeForm}|Acc]); -get_record_fields([{record_field, _Line, Name}|Left], RecDict, Acc) -> +get_record_fields([{record_field, _Location, Name}|Left], RecDict, Acc) -> A = erl_anno:set_generated(true, erl_anno:new(1)), NewAcc = [{erl_parse:normalise(Name), {var, A, '_'}}|Acc], get_record_fields(Left, RecDict, NewAcc); -get_record_fields([{record_field, _Line, Name, _Init}|Left], RecDict, Acc) -> +get_record_fields([{record_field, _Location, Name, _Init}|Left], RecDict, Acc) -> A = erl_anno:set_generated(true, erl_anno:new(1)), NewAcc = [{erl_parse:normalise(Name), {var, A, '_'}}|Acc], get_record_fields(Left, RecDict, NewAcc); @@ -260,15 +261,15 @@ process_record_remote_types(CServer) -> end, C4, Fields), {{Arity, Fields1}, C7} end, - {FileLine, Fields} = Value, + {FileLocation, Fields} = Value, {FieldsList, C3} = lists:mapfoldl(FieldFun, C2, orddict:to_list(Fields)), - {{Key, {FileLine, orddict:from_list(FieldsList)}}, C3}; + {{Key, {FileLocation, orddict:from_list(FieldsList)}}, C3}; {_TypeOrOpaque, Name, NArgs} -> %% Make sure warnings about unknown types are output %% also for types unused by specs. MTA = {Module, Name, NArgs}, - {{_Module, _FileLine, Form, _ArgNames}, _Type} = Value, + {{_Module, _FileLocation, Form, _ArgNames}, _Type} = Value, check_remote(Form, ExpTypes, MTA, RecordTable), {{Key, Value}, C2} end @@ -302,7 +303,7 @@ process_opaque_types(AllModules, CServer, TempExpTypes) -> fun({Key, Value}, C2) -> case Key of {opaque, Name, NArgs} -> - {{_Module, _FileLine, Form, _ArgNames}=F, _Type} = Value, + {{_Module, _FileLocation, Form, _ArgNames}=F, _Type} = Value, Site = {type, {Module, Name, NArgs}}, {Type, C3} = erl_types:t_from_form(Form, TempExpTypes, Site, @@ -345,14 +346,14 @@ check_record_fields(AllModules, CServer, TempExpTypes) -> CheckForm(Field, Site, C4) end, C3, Fields) end, - {FileLine, Fields} = Value, + {FileLocation, Fields} = Value, Fun = fun() -> lists:foldl(FieldFun, C2, Fields) end, - msg_with_position(Fun, FileLine); + msg_with_position(Fun, FileLocation); {_OpaqueOrType, Name, NArgs} -> Site = {type, {Module, Name, NArgs}}, - {{_Module, FileLine, Form, _ArgNames}, _Type} = Value, + {{_Module, FileLocation, Form, _ArgNames}, _Type} = Value, Fun = fun() -> CheckForm(Form, Site, C2) end, - msg_with_position(Fun, FileLine) + msg_with_position(Fun, FileLocation) end end, C0 = erl_types:cache__new(), @@ -360,13 +361,13 @@ check_record_fields(AllModules, CServer, TempExpTypes) -> end, lists:foreach(CheckFun, AllModules). -msg_with_position(Fun, FileLine) -> +msg_with_position(Fun, FileLocation) -> try Fun() catch throw:{error, Msg} -> - {File, Line} = FileLine, + {File, Location} = FileLocation, BaseName = filename:basename(File), - NewMsg = io_lib:format("~ts:~p: ~ts", [BaseName, Line, Msg]), + NewMsg = io_lib:format("~ts:~s: ~ts", [BaseName, pos(Location), Msg]), throw({error, NewMsg}) end. @@ -485,12 +486,13 @@ get_spec_info([], SpecMap, CallbackMap, {ok, SpecMap, CallbackMap}. core_to_attr_tuples(Core) -> - [{cerl:concrete(Key), get_core_line(cerl:get_ann(Key)), cerl:concrete(Value)} || + [{cerl:concrete(Key), get_core_location(cerl:get_ann(Key)), cerl:concrete(Value)} || {Key, Value} <- cerl:module_attrs(Core)]. -get_core_line([L | _As]) when is_integer(L) -> L; -get_core_line([_ | As]) -> get_core_line(As); -get_core_line([]) -> undefined. +get_core_location([L | _As]) when is_integer(L) -> L; +get_core_location([{L, C} | _As]) when is_integer(L), is_integer(C) -> {L, C}; +get_core_location([_ | As]) -> get_core_location(As); +get_core_location([]) -> undefined. -spec get_fun_meta_info(module(), cerl:c_module(), [dial_warn_tag()]) -> dialyzer_codeserver:fun_meta_info() | {'error', string()}. @@ -551,12 +553,12 @@ get_func_suppressions(M, Core, Functions) -> AttrFile = collect_attribute(Core, dialyzer), TagsFAs = check_fa_list(AttrFile, '*', Functions), %% Check the options: - Fun = fun({{[nowarn_function], _L, _File}, _FA}) -> ok; + Fun = fun({{[nowarn_function], _Loc, _File}, _FA}) -> ok; ({OptLFile, _FA}) -> _ = get_options1([OptLFile], ordsets:new()) end, lists:foreach(Fun, TagsFAs), - [{{M, F, A}, W} || {{Warnings, _L, _File}, {F, A}} <- TagsFAs, W <- Warnings]. + [{{M, F, A}, W} || {{Warnings, _Loc, _File}, {F, A}} <- TagsFAs, W <- Warnings]. -spec get_options(cerl:c_module(), [dial_warn_tag()]) -> ordsets:ordset(dial_warn_tag()). @@ -565,21 +567,21 @@ get_options(Core, LegalWarnings) -> AttrFile = collect_attribute(Core, dialyzer), get_options1(AttrFile, LegalWarnings). -get_options1([{Args, L, File}|Left], Warnings) -> +get_options1([{Args, Loc, File}|Left], Warnings) -> Opts = [O || O <- Args, is_atom(O)], try dialyzer_options:build_warnings(Opts, Warnings) of NewWarnings -> get_options1(Left, NewWarnings) catch throw:{dialyzer_options_error, Msg} -> - Msg1 = flat_format(" ~ts:~w: ~ts", [File, L, Msg]), + Msg1 = flat_format(" ~ts:~s: ~ts", [File, pos(Loc), Msg]), throw({error, Msg1}) end; get_options1([], Warnings) -> Warnings. -type collected_attribute() :: - {Args :: [term()], erl_anno:line(), file:filename()}. + {Args :: [term()], erl_anno:location(), file:filename()}. collect_attribute(Core, Tag) -> collect_attribute(cerl:module_attrs(Core), Tag, "nofile"). @@ -587,7 +589,7 @@ collect_attribute(Core, Tag) -> collect_attribute([{Key, Value}|T], Tag, File) -> case cerl:concrete(Key) of Tag -> - [{cerl:concrete(Value), get_core_line(cerl:get_ann(Key)), File} | + [{cerl:concrete(Value), get_core_location(cerl:get_ann(Key)), File} | collect_attribute(T, Tag, File)]; file -> [{IncludeFile, _}] = cerl:concrete(Value), @@ -659,12 +661,17 @@ src_compiler_opts() -> format_errors([{Mod, Errors}|Left]) -> FormatedError = - [io_lib:format("~ts:~w: ~ts\n", [Mod, Line, M:format_error(Desc)]) - || {Line, M, Desc} <- Errors], + [io_lib:format("~ts:~s: ~ts\n", [Mod, pos(Location), M:format_error(Desc)]) + || {Location, M, Desc} <- Errors], [lists:flatten(FormatedError) | format_errors(Left)]; format_errors([]) -> []. +pos({Line,Col}) -> + io_lib:format("~w:~w", [Line,Col]); +pos(Line) -> + io_lib:format("~w", [Line]). + -spec format_sig(erl_types:erl_type()) -> string(). format_sig(Type) -> @@ -695,8 +702,8 @@ check_fa_list(AttrFile, Tag, Functions) -> FuncTab = gb_sets:from_list(Functions), check_fa_list1(AttrFile, Tag, FuncTab). -check_fa_list1([{Args, L, File}|Left], Tag, Funcs) -> - TermsL = [{{[Tag0], L, File}, Term} || +check_fa_list1([{Args, Loc, File}|Left], Tag, Funcs) -> + TermsL = [{{[Tag0], Loc, File}, Term} || {Tags, Terms0} <- Args, Tag0 <- lists:flatten([Tags]), Tag =:= '*' orelse Tag =:= Tag0, @@ -704,15 +711,15 @@ check_fa_list1([{Args, L, File}|Left], Tag, Funcs) -> case lists:dropwhile(fun({_, T}) -> is_fa(T) end, TermsL) of [] -> ok; [{_, Bad}|_] -> - Msg1 = flat_format(" Bad function ~tw in line ~ts:~w", - [Bad, File, L]), + Msg1 = flat_format(" Bad function ~tw at location ~ts:~s", + [Bad, File, pos(Loc)]), throw({error, Msg1}) end, case lists:dropwhile(fun({_, FA}) -> is_known(FA, Funcs) end, TermsL) of [] -> ok; [{_, {F, A}}|_] -> - Msg2 = flat_format(" Unknown function ~tw/~w in line ~ts:~w", - [F, A, File, L]), + Msg2 = flat_format(" Unknown function ~tw/~w at location ~ts:~s", + [F, A, File, pos(Loc)]), throw({error, Msg2}) end, TermsL ++ check_fa_list1(Left, Tag, Funcs); @@ -965,6 +972,46 @@ label(Tree) -> Label = -erlang:unique_integer([positive]), cerl:set_ann(Tree, [{label, Label}]). +-spec get_location(cerl:cerl(), -1 | erl_anno:location()) -> + erl_anno:location(). + +%% Get the location of Tree, if Tree is a leaf, or the location of the +%% leftmost subtree of Tree, if Tree is not a leaf. If there is no +%% location to be found in Tree, Default is returned. +get_location(Tree, Default) -> + case get_all_locations(Tree) of + [] -> + Default; + Locations -> + LF = fun({_L,_C}=Loc) -> Loc; + (Line) -> {Line, 1} + end, + F = fun(Loc1, Loc2) -> LF(Loc1) =< LF(Loc2) end, + [Location|_] = lists:sort(F, Locations), + Location + end. + +get_all_locations(Tree) -> + SubTrees = lists:append(cerl:subtrees(Tree)), + case maybe_get_location(cerl:get_ann(Tree)) of + no -> + []; + Location -> + [Location] + end + ++ + lists:append([get_all_locations(T) || T <- SubTrees]). + +maybe_get_location([Line|_]) when is_integer(Line) -> + Line; +maybe_get_location([{Line, Column}|_Tail]) when is_integer(Line), + is_integer(Column) -> + {Line, Column}; +maybe_get_location([_|Tail]) -> + maybe_get_location(Tail); +maybe_get_location([]) -> + no. + %%------------------------------------------------------------------------------ -spec ets_tab2list(ets:tid()) -> list(). diff --git a/lib/dialyzer/src/erl_types.erl b/lib/dialyzer/src/erl_types.erl index 9526a2a10d..d84b1a5138 100644 --- a/lib/dialyzer/src/erl_types.erl +++ b/lib/dialyzer/src/erl_types.erl @@ -766,7 +766,7 @@ t_opaque_from_records(RecMap) -> end, RecMap), OpaqueTypeMap = maps:map(fun({opaque, Name, _Arity}, - {{Module, _FileLine, _Form, ArgNames}, _Type}) -> + {{Module, _FileLocation, _Form, ArgNames}, _Type}) -> %% Args = args_to_types(ArgNames), %% List = lists:zip(ArgNames, Args), %% TmpVarTab = maps:to_list(List), @@ -4426,26 +4426,28 @@ record_fields_to_string([F|Fs], [{FName, _Abstr, DefType}|FDefs], record_fields_to_string([], [], _RecDict, Acc) -> lists:reverse(Acc). --spec record_field_diffs_to_string(erl_type(), type_table()) -> string(). +-spec record_field_diffs_to_string(erl_type(), type_table()) -> + {[FieldPos :: pos_integer()], string()}. record_field_diffs_to_string(?tuple([_|Fs], Arity, Tag), RecDict) -> [TagAtom] = atom_vals(Tag), {ok, FieldNames} = lookup_record(TagAtom, Arity-1, RecDict), %% io:format("RecCElems = ~p\nRecTypes = ~p\n", [Fs, FieldNames]), - FieldDiffs = field_diffs(Fs, FieldNames, RecDict, []), - flat_join(FieldDiffs, " and "). + Diffs = field_diffs(Fs, FieldNames, 1, RecDict, []), + {FNs, FieldDiffs} = lists:unzip(Diffs), + {FNs, flat_join(FieldDiffs, " and ")}. -field_diffs([F|Fs], [{FName, _Abstr, DefType}|FDefs], RecDict, Acc) -> +field_diffs([F|Fs], [{FName, _Abstr, DefType}|FDefs], Pos, RecDict, Acc) -> %% Don't care about opacity for now. NewAcc = case not t_is_none(t_inf(F, DefType)) of true -> Acc; false -> Str = atom_to_string(FName) ++ "::" ++ t_to_string(DefType, RecDict), - [Str|Acc] + [{Pos,Str}|Acc] end, - field_diffs(Fs, FDefs, RecDict, NewAcc); -field_diffs([], [], _, Acc) -> + field_diffs(Fs, FDefs, Pos + 1, RecDict, NewAcc); +field_diffs([], [], _, _, Acc) -> lists:reverse(Acc). comma_sequence(Types, RecDict) -> @@ -4610,93 +4612,93 @@ from_form_loop(Form, State, D, Limit, C, T0) -> from_form(_, _S, D, L, C) when D =< 0 ; L =< 0 -> {t_any(), L, C}; -from_form({var, _L, '_'}, _S, _D, L, C) -> +from_form({var, _Anno, '_'}, _S, _D, L, C) -> {t_any(), L, C}; -from_form({var, _L, Name}, S, _D, L, C) -> +from_form({var, _Anno, Name}, S, _D, L, C) -> V = S#from_form.vtab, case maps:find(Name, V) of error -> {t_var(Name), L, C}; {ok, Val} -> {Val, L, C} end; -from_form({ann_type, _L, [_Var, Type]}, S, D, L, C) -> +from_form({ann_type, _Anno, [_Var, Type]}, S, D, L, C) -> from_form(Type, S, D, L, C); -from_form({paren_type, _L, [Type]}, S, D, L, C) -> +from_form({paren_type, _Anno, [Type]}, S, D, L, C) -> from_form(Type, S, D, L, C); -from_form({remote_type, _L, [{atom, _, Module}, {atom, _, Type}, Args]}, +from_form({remote_type, _Anno, [{atom, _, Module}, {atom, _, Type}, Args]}, S, D, L, C) -> remote_from_form(Module, Type, Args, S, D, L, C); -from_form({atom, _L, Atom}, _S, _D, L, C) -> +from_form({atom, _Anno, Atom}, _S, _D, L, C) -> {t_atom(Atom), L, C}; -from_form({integer, _L, Int}, _S, _D, L, C) -> +from_form({integer, _Anno, Int}, _S, _D, L, C) -> {t_integer(Int), L, C}; -from_form({char, _L, Char}, _S, _D, L, C) -> +from_form({char, _Anno, Char}, _S, _D, L, C) -> {t_integer(Char), L, C}; -from_form({op, _L, _Op, _Arg} = Op, _S, _D, L, C) -> +from_form({op, _Anno, _Op, _Arg} = Op, _S, _D, L, C) -> case erl_eval:partial_eval(Op) of {integer, _, Val} -> {t_integer(Val), L, C}; _ -> throw({error, io_lib:format("Unable to evaluate type ~w\n", [Op])}) end; -from_form({op, _L, _Op, _Arg1, _Arg2} = Op, _S, _D, L, C) -> +from_form({op, _Anno, _Op, _Arg1, _Arg2} = Op, _S, _D, L, C) -> case erl_eval:partial_eval(Op) of {integer, _, Val} -> {t_integer(Val), L, C}; _ -> throw({error, io_lib:format("Unable to evaluate type ~w\n", [Op])}) end; -from_form({type, _L, any, []}, _S, _D, L, C) -> +from_form({type, _Anno, any, []}, _S, _D, L, C) -> {t_any(), L, C}; -from_form({type, _L, arity, []}, _S, _D, L, C) -> +from_form({type, _Anno, arity, []}, _S, _D, L, C) -> {t_arity(), L, C}; -from_form({type, _L, atom, []}, _S, _D, L, C) -> +from_form({type, _Anno, atom, []}, _S, _D, L, C) -> {t_atom(), L, C}; -from_form({type, _L, binary, []}, _S, _D, L, C) -> +from_form({type, _Anno, binary, []}, _S, _D, L, C) -> {t_binary(), L, C}; -from_form({type, _L, binary, [Base, Unit]} = Type, _S, _D, L, C) -> +from_form({type, _Anno, binary, [Base, Unit]} = Type, _S, _D, L, C) -> case {erl_eval:partial_eval(Base), erl_eval:partial_eval(Unit)} of {{integer, _, B}, {integer, _, U}} when B >= 0, U >= 0 -> {t_bitstr(U, B), L, C}; _ -> throw({error, io_lib:format("Unable to evaluate type ~w\n", [Type])}) end; -from_form({type, _L, bitstring, []}, _S, _D, L, C) -> +from_form({type, _Anno, bitstring, []}, _S, _D, L, C) -> {t_bitstr(), L, C}; -from_form({type, _L, bool, []}, _S, _D, L, C) -> +from_form({type, _Anno, bool, []}, _S, _D, L, C) -> {t_boolean(), L, C}; % XXX: Temporarily -from_form({type, _L, boolean, []}, _S, _D, L, C) -> +from_form({type, _Anno, boolean, []}, _S, _D, L, C) -> {t_boolean(), L, C}; -from_form({type, _L, byte, []}, _S, _D, L, C) -> +from_form({type, _Anno, byte, []}, _S, _D, L, C) -> {t_byte(), L, C}; -from_form({type, _L, char, []}, _S, _D, L, C) -> +from_form({type, _Anno, char, []}, _S, _D, L, C) -> {t_char(), L, C}; -from_form({type, _L, float, []}, _S, _D, L, C) -> +from_form({type, _Anno, float, []}, _S, _D, L, C) -> {t_float(), L, C}; -from_form({type, _L, function, []}, _S, _D, L, C) -> +from_form({type, _Anno, function, []}, _S, _D, L, C) -> {t_fun(), L, C}; -from_form({type, _L, 'fun', []}, _S, _D, L, C) -> +from_form({type, _Anno, 'fun', []}, _S, _D, L, C) -> {t_fun(), L, C}; -from_form({type, _L, 'fun', [{type, _, any}, Range]}, S, D, L, C) -> +from_form({type, _Anno, 'fun', [{type, _, any}, Range]}, S, D, L, C) -> {T, L1, C1} = from_form(Range, S, D - 1, L - 1, C), {t_fun(T), L1, C1}; -from_form({type, _L, 'fun', [{type, _, product, Domain}, Range]}, +from_form({type, _Anno, 'fun', [{type, _, product, Domain}, Range]}, S, D, L, C) -> {Dom1, L1, C1} = list_from_form(Domain, S, D, L, C), {Ran1, L2, C2} = from_form(Range, S, D, L1, C1), {t_fun(Dom1, Ran1), L2, C2}; -from_form({type, _L, identifier, []}, _S, _D, L, C) -> +from_form({type, _Anno, identifier, []}, _S, _D, L, C) -> {t_identifier(), L, C}; -from_form({type, _L, integer, []}, _S, _D, L, C) -> +from_form({type, _Anno, integer, []}, _S, _D, L, C) -> {t_integer(), L, C}; -from_form({type, _L, iodata, []}, _S, _D, L, C) -> +from_form({type, _Anno, iodata, []}, _S, _D, L, C) -> {t_iodata(), L, C}; -from_form({type, _L, iolist, []}, _S, _D, L, C) -> +from_form({type, _Anno, iolist, []}, _S, _D, L, C) -> {t_iolist(), L, C}; -from_form({type, _L, list, []}, _S, _D, L, C) -> +from_form({type, _Anno, list, []}, _S, _D, L, C) -> {t_list(), L, C}; -from_form({type, _L, list, [Type]}, S, D, L, C) -> +from_form({type, _Anno, list, [Type]}, S, D, L, C) -> {T, L1, C1} = from_form(Type, S, D - 1, L - 1, C), {t_list(T), L1, C1}; -from_form({type, _L, map, any}, S, D, L, C) -> +from_form({type, _Anno, map, any}, S, D, L, C) -> builtin_type(map, t_map(), S, D, L, C); -from_form({type, _L, map, List}, S, D0, L, C) -> +from_form({type, _Anno, map, List}, S, D0, L, C) -> {Pairs1, L5, C5} = fun PairsFromForm(_, L1, C1) when L1 =< 0 -> {[{?any,?opt,?any}], L1, C1}; PairsFromForm([], L1, C1) -> {[], L1, C1}; @@ -4716,88 +4718,88 @@ from_form({type, _L, map, List}, S, D0, L, C) -> {t_map(Pairs, DefK, DefV), L5, C5} catch none -> {t_none(), L5, C5} end; -from_form({type, _L, mfa, []}, _S, _D, L, C) -> +from_form({type, _Anno, mfa, []}, _S, _D, L, C) -> {t_mfa(), L, C}; -from_form({type, _L, module, []}, _S, _D, L, C) -> +from_form({type, _Anno, module, []}, _S, _D, L, C) -> {t_module(), L, C}; -from_form({type, _L, nil, []}, _S, _D, L, C) -> +from_form({type, _Anno, nil, []}, _S, _D, L, C) -> {t_nil(), L, C}; -from_form({type, _L, neg_integer, []}, _S, _D, L, C) -> +from_form({type, _Anno, neg_integer, []}, _S, _D, L, C) -> {t_neg_integer(), L, C}; -from_form({type, _L, non_neg_integer, []}, _S, _D, L, C) -> +from_form({type, _Anno, non_neg_integer, []}, _S, _D, L, C) -> {t_non_neg_integer(), L, C}; -from_form({type, _L, no_return, []}, _S, _D, L, C) -> +from_form({type, _Anno, no_return, []}, _S, _D, L, C) -> {t_unit(), L, C}; -from_form({type, _L, node, []}, _S, _D, L, C) -> +from_form({type, _Anno, node, []}, _S, _D, L, C) -> {t_node(), L, C}; -from_form({type, _L, none, []}, _S, _D, L, C) -> +from_form({type, _Anno, none, []}, _S, _D, L, C) -> {t_none(), L, C}; -from_form({type, _L, nonempty_list, []}, _S, _D, L, C) -> +from_form({type, _Anno, nonempty_list, []}, _S, _D, L, C) -> {t_nonempty_list(), L, C}; -from_form({type, _L, nonempty_list, [Type]}, S, D, L, C) -> +from_form({type, _Anno, nonempty_list, [Type]}, S, D, L, C) -> {T, L1, C1} = from_form(Type, S, D, L - 1, C), {t_nonempty_list(T), L1, C1}; -from_form({type, _L, nonempty_improper_list, [Cont, Term]}, S, D, L, C) -> +from_form({type, _Anno, nonempty_improper_list, [Cont, Term]}, S, D, L, C) -> {T1, L1, C1} = from_form(Cont, S, D, L - 1, C), {T2, L2, C2} = from_form(Term, S, D, L1, C1), {t_cons(T1, T2), L2, C2}; -from_form({type, _L, nonempty_maybe_improper_list, []}, _S, _D, L, C) -> +from_form({type, _Anno, nonempty_maybe_improper_list, []}, _S, _D, L, C) -> {t_cons(?any, ?any), L, C}; -from_form({type, _L, nonempty_maybe_improper_list, [Cont, Term]}, +from_form({type, _Anno, nonempty_maybe_improper_list, [Cont, Term]}, S, D, L, C) -> {T1, L1, C1} = from_form(Cont, S, D, L - 1, C), {T2, L2, C2} = from_form(Term, S, D, L1, C1), {t_cons(T1, T2), L2, C2}; -from_form({type, _L, nonempty_string, []}, _S, _D, L, C) -> +from_form({type, _Anno, nonempty_string, []}, _S, _D, L, C) -> {t_nonempty_string(), L, C}; -from_form({type, _L, number, []}, _S, _D, L, C) -> +from_form({type, _Anno, number, []}, _S, _D, L, C) -> {t_number(), L, C}; -from_form({type, _L, pid, []}, _S, _D, L, C) -> +from_form({type, _Anno, pid, []}, _S, _D, L, C) -> {t_pid(), L, C}; -from_form({type, _L, port, []}, _S, _D, L, C) -> +from_form({type, _Anno, port, []}, _S, _D, L, C) -> {t_port(), L, C}; -from_form({type, _L, pos_integer, []}, _S, _D, L, C) -> +from_form({type, _Anno, pos_integer, []}, _S, _D, L, C) -> {t_pos_integer(), L, C}; -from_form({type, _L, maybe_improper_list, []}, _S, _D, L, C) -> +from_form({type, _Anno, maybe_improper_list, []}, _S, _D, L, C) -> {t_maybe_improper_list(), L, C}; -from_form({type, _L, maybe_improper_list, [Content, Termination]}, +from_form({type, _Anno, maybe_improper_list, [Content, Termination]}, S, D, L, C) -> {T1, L1, C1} = from_form(Content, S, D, L - 1, C), {T2, L2, C2} = from_form(Termination, S, D, L1, C1), {t_maybe_improper_list(T1, T2), L2, C2}; -from_form({type, _L, product, Elements}, S, D, L, C) -> +from_form({type, _Anno, product, Elements}, S, D, L, C) -> {Lst, L1, C1} = list_from_form(Elements, S, D - 1, L, C), {t_product(Lst), L1, C1}; -from_form({type, _L, range, [From, To]} = Type, _S, _D, L, C) -> +from_form({type, _Anno, range, [From, To]} = Type, _S, _D, L, C) -> case {erl_eval:partial_eval(From), erl_eval:partial_eval(To)} of {{integer, _, FromVal}, {integer, _, ToVal}} -> {t_from_range(FromVal, ToVal), L, C}; _ -> throw({error, io_lib:format("Unable to evaluate type ~w\n", [Type])}) end; -from_form({type, _L, record, [Name|Fields]}, S, D, L, C) -> +from_form({type, _Anno, record, [Name|Fields]}, S, D, L, C) -> record_from_form(Name, Fields, S, D, L, C); -from_form({type, _L, reference, []}, _S, _D, L, C) -> +from_form({type, _Anno, reference, []}, _S, _D, L, C) -> {t_reference(), L, C}; -from_form({type, _L, string, []}, _S, _D, L, C) -> +from_form({type, _Anno, string, []}, _S, _D, L, C) -> {t_string(), L, C}; -from_form({type, _L, term, []}, _S, _D, L, C) -> +from_form({type, _Anno, term, []}, _S, _D, L, C) -> {t_any(), L, C}; -from_form({type, _L, timeout, []}, _S, _D, L, C) -> +from_form({type, _Anno, timeout, []}, _S, _D, L, C) -> {t_timeout(), L, C}; -from_form({type, _L, tuple, any}, _S, _D, L, C) -> +from_form({type, _Anno, tuple, any}, _S, _D, L, C) -> {t_tuple(), L, C}; -from_form({type, _L, tuple, Args}, S, D, L, C) -> +from_form({type, _Anno, tuple, Args}, S, D, L, C) -> {Lst, L1, C1} = list_from_form(Args, S, D - 1, L, C), {t_tuple(Lst), L1, C1}; -from_form({type, _L, union, Args}, S, D, L, C) -> +from_form({type, _Anno, union, Args}, S, D, L, C) -> {Lst, L1, C1} = list_from_form(Args, S, D, L, C), {t_sup(Lst), L1, C1}; -from_form({user_type, _L, Name, Args}, S, D, L, C) -> +from_form({user_type, _Anno, Name, Args}, S, D, L, C) -> type_from_form(Name, Args, S, D, L, C); -from_form({type, _L, Name, Args}, S, D, L, C) -> +from_form({type, _Anno, Name, Args}, S, D, L, C) -> %% Compatibility: modules compiled before Erlang/OTP 18.0. type_from_form(Name, Args, S, D, L, C); -from_form({opaque, _L, Name, {Mod, Args, Rep}}, _S, _D, L, C) -> +from_form({opaque, _Anno, Name, {Mod, Args, Rep}}, _S, _D, L, C) -> %% XXX. To be removed. {t_opaque(Mod, Name, Args, Rep), L, C}. @@ -4909,7 +4911,7 @@ remote_from_form1(RemMod, Name, Args, ArgsLen, RemDict, RemType, TypeNames, {_, {_, _}} when element(1, Site) =:= check -> {_ArgTypes, L1, C1} = list_from_form(Args, S, D, L, C), {t_any(), L1, C1}; - {Tag, {{Mod, _FileLine, Form, ArgNames}, Type}} -> + {Tag, {{Mod, _FileLocation, Form, ArgNames}, Type}} -> NewTypeNames = [RemType|TypeNames], S1 = S#from_form{tnames = NewTypeNames}, {ArgTypes, L1, C1} = list_from_form(Args, S1, D, L, C), @@ -5168,30 +5170,30 @@ t_check_record_fields(Form, ExpTypes, Site, RecDict, VarTable, Cache) -> %% If there is something wrong with parse_form() %% throw({error, io_lib:chars()} is called. -check_record_fields({var, _L, _}, _S, C) -> C; -check_record_fields({ann_type, _L, [_Var, Type]}, S, C) -> +check_record_fields({var, _Anno, _}, _S, C) -> C; +check_record_fields({ann_type, _Anno, [_Var, Type]}, S, C) -> check_record_fields(Type, S, C); -check_record_fields({paren_type, _L, [Type]}, S, C) -> +check_record_fields({paren_type, _Anno, [Type]}, S, C) -> check_record_fields(Type, S, C); -check_record_fields({remote_type, _L, [{atom, _, _}, {atom, _, _}, Args]}, +check_record_fields({remote_type, _Anno, [{atom, _, _}, {atom, _, _}, Args]}, S, C) -> list_check_record_fields(Args, S, C); -check_record_fields({atom, _L, _}, _S, C) -> C; -check_record_fields({integer, _L, _}, _S, C) -> C; -check_record_fields({char, _L, _}, _S, C) -> C; -check_record_fields({op, _L, _Op, _Arg}, _S, C) -> C; -check_record_fields({op, _L, _Op, _Arg1, _Arg2}, _S, C) -> C; -check_record_fields({type, _L, tuple, any}, _S, C) -> C; -check_record_fields({type, _L, map, any}, _S, C) -> C; -check_record_fields({type, _L, binary, [_Base, _Unit]}, _S, C) -> C; -check_record_fields({type, _L, 'fun', [{type, _, any}, Range]}, S, C) -> +check_record_fields({atom, _Anno, _}, _S, C) -> C; +check_record_fields({integer, _Anno, _}, _S, C) -> C; +check_record_fields({char, _Anno, _}, _S, C) -> C; +check_record_fields({op, _Anno, _Op, _Arg}, _S, C) -> C; +check_record_fields({op, _Anno, _Op, _Arg1, _Arg2}, _S, C) -> C; +check_record_fields({type, _Anno, tuple, any}, _S, C) -> C; +check_record_fields({type, _Anno, map, any}, _S, C) -> C; +check_record_fields({type, _Anno, binary, [_Base, _Unit]}, _S, C) -> C; +check_record_fields({type, _Anno, 'fun', [{type, _, any}, Range]}, S, C) -> check_record_fields(Range, S, C); -check_record_fields({type, _L, range, [_From, _To]}, _S, C) -> C; -check_record_fields({type, _L, record, [Name|Fields]}, S, C) -> +check_record_fields({type, _Anno, range, [_From, _To]}, _S, C) -> C; +check_record_fields({type, _Anno, record, [Name|Fields]}, S, C) -> check_record(Name, Fields, S, C); -check_record_fields({type, _L, _, Args}, S, C) -> +check_record_fields({type, _Anno, _, Args}, S, C) -> list_check_record_fields(Args, S, C); -check_record_fields({user_type, _L, _Name, Args}, S, C) -> +check_record_fields({user_type, _Anno, _Name, Args}, S, C) -> list_check_record_fields(Args, S, C). check_record({atom, _, Name}, ModFields, S, C) -> @@ -5276,32 +5278,32 @@ t_var_names([]) -> -spec t_form_to_string(parse_form()) -> string(). -t_form_to_string({var, _L, '_'}) -> "_"; -t_form_to_string({var, _L, Name}) -> atom_to_list(Name); -t_form_to_string({atom, _L, Atom}) -> +t_form_to_string({var, _Anno, '_'}) -> "_"; +t_form_to_string({var, _Anno, Name}) -> atom_to_list(Name); +t_form_to_string({atom, _Anno, Atom}) -> io_lib:write_string(atom_to_list(Atom), $'); % To quote or not to quote... ' -t_form_to_string({integer, _L, Int}) -> integer_to_list(Int); -t_form_to_string({char, _L, Char}) -> integer_to_list(Char); -t_form_to_string({op, _L, _Op, _Arg} = Op) -> +t_form_to_string({integer, _Anno, Int}) -> integer_to_list(Int); +t_form_to_string({char, _Anno, Char}) -> integer_to_list(Char); +t_form_to_string({op, _Anno, _Op, _Arg} = Op) -> case erl_eval:partial_eval(Op) of {integer, _, _} = Int -> t_form_to_string(Int); _ -> io_lib:format("Badly formed type ~w", [Op]) end; -t_form_to_string({op, _L, _Op, _Arg1, _Arg2} = Op) -> +t_form_to_string({op, _Anno, _Op, _Arg1, _Arg2} = Op) -> case erl_eval:partial_eval(Op) of {integer, _, _} = Int -> t_form_to_string(Int); _ -> io_lib:format("Badly formed type ~w", [Op]) end; -t_form_to_string({ann_type, _L, [Var, Type]}) -> +t_form_to_string({ann_type, _Anno, [Var, Type]}) -> t_form_to_string(Var) ++ "::" ++ t_form_to_string(Type); -t_form_to_string({paren_type, _L, [Type]}) -> +t_form_to_string({paren_type, _Anno, [Type]}) -> flat_format("(~ts)", [t_form_to_string(Type)]); -t_form_to_string({remote_type, _L, [{atom, _, Mod}, {atom, _, Name}, Args]}) -> +t_form_to_string({remote_type, _Anno, [{atom, _, Mod}, {atom, _, Name}, Args]}) -> ArgString = "(" ++ flat_join(t_form_to_string_list(Args), ",") ++ ")", flat_format("~w:~tw", [Mod, Name]) ++ ArgString; -t_form_to_string({type, _L, arity, []}) -> "arity()"; -t_form_to_string({type, _L, binary, []}) -> "binary()"; -t_form_to_string({type, _L, binary, [Base, Unit]} = Type) -> +t_form_to_string({type, _Anno, arity, []}) -> "arity()"; +t_form_to_string({type, _Anno, binary, []}) -> "binary()"; +t_form_to_string({type, _Anno, binary, [Base, Unit]} = Type) -> case {erl_eval:partial_eval(Base), erl_eval:partial_eval(Unit)} of {{integer, _, B}, {integer, _, U}} -> %% the following mirrors the clauses of t_to_string/2 @@ -5315,51 +5317,51 @@ t_form_to_string({type, _L, binary, [Base, Unit]} = Type) -> end; _ -> io_lib:format("Badly formed bitstr type ~w", [Type]) end; -t_form_to_string({type, _L, bitstring, []}) -> "bitstring()"; -t_form_to_string({type, _L, 'fun', []}) -> "fun()"; -t_form_to_string({type, _L, 'fun', [{type, _, any}, Range]}) -> +t_form_to_string({type, _Anno, bitstring, []}) -> "bitstring()"; +t_form_to_string({type, _Anno, 'fun', []}) -> "fun()"; +t_form_to_string({type, _Anno, 'fun', [{type, _, any}, Range]}) -> "fun(...) -> " ++ t_form_to_string(Range); -t_form_to_string({type, _L, 'fun', [{type, _, product, Domain}, Range]}) -> +t_form_to_string({type, _Anno, 'fun', [{type, _, product, Domain}, Range]}) -> "fun((" ++ flat_join(t_form_to_string_list(Domain), ",") ++ ") -> " ++ t_form_to_string(Range) ++ ")"; -t_form_to_string({type, _L, iodata, []}) -> "iodata()"; -t_form_to_string({type, _L, iolist, []}) -> "iolist()"; -t_form_to_string({type, _L, list, [Type]}) -> +t_form_to_string({type, _Anno, iodata, []}) -> "iodata()"; +t_form_to_string({type, _Anno, iolist, []}) -> "iolist()"; +t_form_to_string({type, _Anno, list, [Type]}) -> "[" ++ t_form_to_string(Type) ++ "]"; -t_form_to_string({type, _L, map, any}) -> "map()"; -t_form_to_string({type, _L, map, Args}) -> +t_form_to_string({type, _Anno, map, any}) -> "map()"; +t_form_to_string({type, _Anno, map, Args}) -> "#{" ++ flat_join(t_form_to_string_list(Args), ",") ++ "}"; -t_form_to_string({type, _L, map_field_assoc, [Key, Val]}) -> +t_form_to_string({type, _Anno, map_field_assoc, [Key, Val]}) -> t_form_to_string(Key) ++ "=>" ++ t_form_to_string(Val); -t_form_to_string({type, _L, map_field_exact, [Key, Val]}) -> +t_form_to_string({type, _Anno, map_field_exact, [Key, Val]}) -> t_form_to_string(Key) ++ ":=" ++ t_form_to_string(Val); -t_form_to_string({type, _L, mfa, []}) -> "mfa()"; -t_form_to_string({type, _L, module, []}) -> "module()"; -t_form_to_string({type, _L, node, []}) -> "node()"; -t_form_to_string({type, _L, nonempty_list, [Type]}) -> +t_form_to_string({type, _Anno, mfa, []}) -> "mfa()"; +t_form_to_string({type, _Anno, module, []}) -> "module()"; +t_form_to_string({type, _Anno, node, []}) -> "node()"; +t_form_to_string({type, _Anno, nonempty_list, [Type]}) -> "[" ++ t_form_to_string(Type) ++ ",...]"; -t_form_to_string({type, _L, nonempty_string, []}) -> "nonempty_string()"; -t_form_to_string({type, _L, product, Elements}) -> +t_form_to_string({type, _Anno, nonempty_string, []}) -> "nonempty_string()"; +t_form_to_string({type, _Anno, product, Elements}) -> "<" ++ flat_join(t_form_to_string_list(Elements), ",") ++ ">"; -t_form_to_string({type, _L, range, [From, To]} = Type) -> +t_form_to_string({type, _Anno, range, [From, To]} = Type) -> case {erl_eval:partial_eval(From), erl_eval:partial_eval(To)} of {{integer, _, FromVal}, {integer, _, ToVal}} -> flat_format("~w..~w", [FromVal, ToVal]); _ -> flat_format("Badly formed type ~w",[Type]) end; -t_form_to_string({type, _L, record, [{atom, _, Name}]}) -> +t_form_to_string({type, _Anno, record, [{atom, _, Name}]}) -> flat_format("#~tw{}", [Name]); -t_form_to_string({type, _L, record, [{atom, _, Name}|Fields]}) -> +t_form_to_string({type, _Anno, record, [{atom, _, Name}|Fields]}) -> FieldString = flat_join(t_form_to_string_list(Fields), ","), flat_format("#~tw{~ts}", [Name, FieldString]); -t_form_to_string({type, _L, field_type, [{atom, _, Name}, Type]}) -> +t_form_to_string({type, _Anno, field_type, [{atom, _, Name}, Type]}) -> flat_format("~tw::~ts", [Name, t_form_to_string(Type)]); -t_form_to_string({type, _L, term, []}) -> "term()"; -t_form_to_string({type, _L, timeout, []}) -> "timeout()"; -t_form_to_string({type, _L, tuple, any}) -> "tuple()"; -t_form_to_string({type, _L, tuple, Args}) -> +t_form_to_string({type, _Anno, term, []}) -> "term()"; +t_form_to_string({type, _Anno, timeout, []}) -> "timeout()"; +t_form_to_string({type, _Anno, tuple, any}) -> "tuple()"; +t_form_to_string({type, _Anno, tuple, Args}) -> "{" ++ flat_join(t_form_to_string_list(Args), ",") ++ "}"; -t_form_to_string({type, _L, union, Args}) -> +t_form_to_string({type, _Anno, union, Args}) -> flat_join(lists:map(fun(Arg) -> case Arg of {ann_type, _AL, _} -> @@ -5369,7 +5371,7 @@ t_form_to_string({type, _L, union, Args}) -> end end, Args), " | "); -t_form_to_string({type, _L, Name, []} = T) -> +t_form_to_string({type, _Anno, Name, []} = T) -> try M = mod, Site = {type, {M,Name,0}}, @@ -5384,12 +5386,12 @@ t_form_to_string({type, _L, Name, []} = T) -> t_to_string(T1) catch throw:{error, _} -> atom_to_string(Name) ++ "()" end; -t_form_to_string({user_type, _L, Name, List}) -> +t_form_to_string({user_type, _Anno, Name, List}) -> flat_format("~tw(~ts)", [Name, flat_join(t_form_to_string_list(List), ",")]); -t_form_to_string({type, L, Name, List}) -> +t_form_to_string({type, Anno, Name, List}) -> %% Compatibility: modules compiled before Erlang/OTP 18.0. - t_form_to_string({user_type, L, Name, List}). + t_form_to_string({user_type, Anno, Name, List}). t_form_to_string_list(List) -> t_form_to_string_list(List, []). @@ -5454,9 +5456,9 @@ lookup_module_types(Module, CodeTable, Cache) -> lookup_record(Tag, Table) when is_atom(Tag) -> case maps:find({record, Tag}, Table) of - {ok, {_FileLine, [{_Arity, Fields}]}} -> + {ok, {_FileLocation, [{_Arity, Fields}]}} -> {ok, Fields}; - {ok, {_FileLine, List}} when is_list(List) -> + {ok, {_FileLocation, List}} when is_list(List) -> %% This will have to do, since we do not know which record we %% are looking for. error; @@ -5469,8 +5471,8 @@ lookup_record(Tag, Table) when is_atom(Tag) -> lookup_record(Tag, Arity, Table) when is_atom(Tag) -> case maps:find({record, Tag}, Table) of - {ok, {_FileLine, [{Arity, Fields}]}} -> {ok, Fields}; - {ok, {_FileLine, OrdDict}} -> orddict:find(Arity, OrdDict); + {ok, {_FileLocation, [{Arity, Fields}]}} -> {ok, Fields}; + {ok, {_FileLocation, OrdDict}} -> orddict:find(Arity, OrdDict); error -> error end. diff --git a/lib/dialyzer/src/typer.erl b/lib/dialyzer/src/typer.erl index 5a1b8619c9..69a622db2d 100644 --- a/lib/dialyzer/src/typer.erl +++ b/lib/dialyzer/src/typer.erl @@ -937,8 +937,9 @@ analyze_one_function({Var, FunBody} = Function, Acc) -> dialyzerObj = NewDialyzerObj}. get_line([Line|_]) when is_integer(Line) -> Line; -get_line([_|T]) -> get_line(T); -get_line([]) -> none. +get_line([{Line, _Column} | _Tail]) when is_integer(Line) -> Line; +get_line([_|Tail]) -> get_line(Tail); +get_line([]) -> -1. get_file([{file,File}|_]) -> File; get_file([_|T]) -> get_file(T); diff --git a/lib/dialyzer/test/abstract_SUITE.erl b/lib/dialyzer/test/abstract_SUITE.erl index 37fb39cf27..9962148b09 100644 --- a/lib/dialyzer/test/abstract_SUITE.erl +++ b/lib/dialyzer/test/abstract_SUITE.erl @@ -67,10 +67,11 @@ generated_case(Config) when is_list(Config) -> [{call,7,{remote,7,{var,7,'Arg'},{atom,7,fn}},[]}]}]}]}]}], Config, [], []), %% With Arg set to [] so neither clause matches - [{warn_return_no_exit,{_,3},_}, + [W = {warn_return_no_exit,{_,3},_}, {warn_matching,{_,6},_}, {warn_failing_call,{_,7},_}] = - test([{attribute,1,module,foo}, + test([{attribute,1,file, {"fileName.erl",1}}, + {attribute,1,module,foo}, {attribute,2,export,[{bar,0}]}, {function,3,bar,0, [{clause,3,[],[], @@ -81,6 +82,9 @@ generated_case(Config) when is_list(Config) -> {clause,[{location,7},{generated,true}],[{var,7,'_'}],[], [{call,7,{remote,7,{var,7,'Arg'},{atom,7,fn}},[]}]}]}]}]}], Config, [], []), + %% Location is a line (no column): + "fileName.erl:3: Function bar/0 has no local return\n" = + dialyzer:format_warning(W), ok. test(Prog0, Config, COpts, DOpts) -> diff --git a/lib/dialyzer/test/behaviour_SUITE_data/results/callbacks_and_specs b/lib/dialyzer/test/behaviour_SUITE_data/results/callbacks_and_specs index 843d26ee59..d1bfc7295c 100644 --- a/lib/dialyzer/test/behaviour_SUITE_data/results/callbacks_and_specs +++ b/lib/dialyzer/test/behaviour_SUITE_data/results/callbacks_and_specs @@ -1,5 +1,5 @@ -my_callbacks_wrong.erl:26: The return type #state{parent::pid(),status::'closed' | 'init' | 'open',subscribe::[{pid(),integer()}],counter::integer()} in the specification of callback_init/1 is not a subtype of {'ok',_}, which is the expected return type for the callback of the my_behaviour behaviour -my_callbacks_wrong.erl:28: The inferred return type of callback_init/1 (#state{parent::pid(),status::'init',subscribe::[],counter::1}) has nothing in common with {'ok',_}, which is the expected return type for the callback of the my_behaviour behaviour -my_callbacks_wrong.erl:30: The return type {'reply',#state{parent::pid(),status::'closed' | 'init' | 'open',subscribe::[{pid(),integer()}],counter::integer()}} in the specification of callback_cast/3 is not a subtype of {'noreply',_}, which is the expected return type for the callback of the my_behaviour behaviour -my_callbacks_wrong.erl:39: The specified type for the 2nd argument of callback_call/3 (atom()) is not a supertype of pid(), which is expected type for this argument in the callback of the my_behaviour behaviour +my_callbacks_wrong.erl:26:2: The return type #state{parent::pid(),status::'closed' | 'init' | 'open',subscribe::[{pid(),integer()}],counter::integer()} in the specification of callback_init/1 is not a subtype of {'ok',_}, which is the expected return type for the callback of the my_behaviour behaviour +my_callbacks_wrong.erl:28:1: The inferred return type of callback_init/1 (#state{parent::pid(),status::'init',subscribe::[],counter::1}) has nothing in common with {'ok',_}, which is the expected return type for the callback of the my_behaviour behaviour +my_callbacks_wrong.erl:30:2: The return type {'reply',#state{parent::pid(),status::'closed' | 'init' | 'open',subscribe::[{pid(),integer()}],counter::integer()}} in the specification of callback_cast/3 is not a subtype of {'noreply',_}, which is the expected return type for the callback of the my_behaviour behaviour +my_callbacks_wrong.erl:39:2: The specified type for the 2nd argument of callback_call/3 (atom()) is not a supertype of pid(), which is expected type for this argument in the callback of the my_behaviour behaviour diff --git a/lib/dialyzer/test/behaviour_SUITE_data/results/gen_event_incorrect_return b/lib/dialyzer/test/behaviour_SUITE_data/results/gen_event_incorrect_return index c3ebee05da..d7edce5d97 100644 --- a/lib/dialyzer/test/behaviour_SUITE_data/results/gen_event_incorrect_return +++ b/lib/dialyzer/test/behaviour_SUITE_data/results/gen_event_incorrect_return @@ -1,2 +1,2 @@ -gen_event_incorrect_return.erl:16: The inferred return type of init/1 ('error') has nothing in common with {'error',_} | {'ok',_} | {'ok',_,'hibernate'}, which is the expected return type for the callback of the gen_event behaviour +gen_event_incorrect_return.erl:16:1: The inferred return type of init/1 ('error') has nothing in common with {'error',_} | {'ok',_} | {'ok',_,'hibernate'}, which is the expected return type for the callback of the gen_event behaviour diff --git a/lib/dialyzer/test/behaviour_SUITE_data/results/gen_server_incorrect_args b/lib/dialyzer/test/behaviour_SUITE_data/results/gen_server_incorrect_args index 1be0ce0d8c..69c2186481 100644 --- a/lib/dialyzer/test/behaviour_SUITE_data/results/gen_server_incorrect_args +++ b/lib/dialyzer/test/behaviour_SUITE_data/results/gen_server_incorrect_args @@ -1,5 +1,5 @@ -gen_server_incorrect_args.erl:3: Undefined callback function handle_cast/2 (behaviour gen_server) -gen_server_incorrect_args.erl:3: Undefined callback function init/1 (behaviour gen_server) -gen_server_incorrect_args.erl:7: The inferred return type of handle_call/3 ({'no'} | {'ok'}) has nothing in common with {'noreply',_} | {'noreply',_,'hibernate' | 'infinity' | non_neg_integer() | {'continue',_}} | {'reply',_,_} | {'stop',_,_} | {'reply',_,_,'hibernate' | 'infinity' | non_neg_integer() | {'continue',_}} | {'stop',_,_,_}, which is the expected return type for the callback of the gen_server behaviour -gen_server_incorrect_args.erl:7: The inferred type for the 2nd argument of handle_call/3 ('boo' | 'foo') is not a supertype of {pid(),_}, which is expected type for this argument in the callback of the gen_server behaviour +gen_server_incorrect_args.erl:3:2: Undefined callback function handle_cast/2 (behaviour gen_server) +gen_server_incorrect_args.erl:3:2: Undefined callback function init/1 (behaviour gen_server) +gen_server_incorrect_args.erl:7:1: The inferred return type of handle_call/3 ({'no'} | {'ok'}) has nothing in common with {'noreply',_} | {'noreply',_,'hibernate' | 'infinity' | non_neg_integer() | {'continue',_}} | {'reply',_,_} | {'stop',_,_} | {'reply',_,_,'hibernate' | 'infinity' | non_neg_integer() | {'continue',_}} | {'stop',_,_,_}, which is the expected return type for the callback of the gen_server behaviour +gen_server_incorrect_args.erl:7:1: The inferred type for the 2nd argument of handle_call/3 ('boo' | 'foo') is not a supertype of {pid(),_}, which is expected type for this argument in the callback of the gen_server behaviour diff --git a/lib/dialyzer/test/behaviour_SUITE_data/results/gen_server_missing_callbacks b/lib/dialyzer/test/behaviour_SUITE_data/results/gen_server_missing_callbacks index 188f7822fa..50841d84cc 100644 --- a/lib/dialyzer/test/behaviour_SUITE_data/results/gen_server_missing_callbacks +++ b/lib/dialyzer/test/behaviour_SUITE_data/results/gen_server_missing_callbacks @@ -1,2 +1,2 @@ -gen_server_missing_callbacks.erl:3: Undefined callback function handle_cast/2 (behaviour gen_server) +gen_server_missing_callbacks.erl:3:2: Undefined callback function handle_cast/2 (behaviour gen_server) diff --git a/lib/dialyzer/test/behaviour_SUITE_data/results/sample_behaviour b/lib/dialyzer/test/behaviour_SUITE_data/results/sample_behaviour index 68adf4cfa0..ab69a698c5 100644 --- a/lib/dialyzer/test/behaviour_SUITE_data/results/sample_behaviour +++ b/lib/dialyzer/test/behaviour_SUITE_data/results/sample_behaviour @@ -1,9 +1,9 @@ -sample_callback_wrong.erl:16: The inferred return type of sample_callback_2/0 (42) has nothing in common with atom(), which is the expected return type for the callback of the sample_behaviour behaviour -sample_callback_wrong.erl:17: The inferred return type of sample_callback_3/0 ('fair') has nothing in common with 'fail' | {'ok',1..255}, which is the expected return type for the callback of the sample_behaviour behaviour -sample_callback_wrong.erl:18: The inferred return type of sample_callback_4/1 ('fail') has nothing in common with 'ok', which is the expected return type for the callback of the sample_behaviour behaviour -sample_callback_wrong.erl:20: The inferred return type of sample_callback_5/1 (string()) has nothing in common with 'fail' | 'ok', which is the expected return type for the callback of the sample_behaviour behaviour -sample_callback_wrong.erl:20: The inferred type for the 1st argument of sample_callback_5/1 (atom()) is not a supertype of 1..255, which is expected type for this argument in the callback of the sample_behaviour behaviour -sample_callback_wrong.erl:22: The inferred return type of sample_callback_6/3 ({'okk',number()}) has nothing in common with 'fail' | {'ok',1..255}, which is the expected return type for the callback of the sample_behaviour behaviour -sample_callback_wrong.erl:22: The inferred type for the 3rd argument of sample_callback_6/3 (atom()) is not a supertype of string(), which is expected type for this argument in the callback of the sample_behaviour behaviour -sample_callback_wrong.erl:4: Undefined callback function sample_callback_1/0 (behaviour sample_behaviour) +sample_callback_wrong.erl:16:1: The inferred return type of sample_callback_2/0 (42) has nothing in common with atom(), which is the expected return type for the callback of the sample_behaviour behaviour +sample_callback_wrong.erl:17:1: The inferred return type of sample_callback_3/0 ('fair') has nothing in common with 'fail' | {'ok',1..255}, which is the expected return type for the callback of the sample_behaviour behaviour +sample_callback_wrong.erl:18:1: The inferred return type of sample_callback_4/1 ('fail') has nothing in common with 'ok', which is the expected return type for the callback of the sample_behaviour behaviour +sample_callback_wrong.erl:20:1: The inferred return type of sample_callback_5/1 (string()) has nothing in common with 'fail' | 'ok', which is the expected return type for the callback of the sample_behaviour behaviour +sample_callback_wrong.erl:20:1: The inferred type for the 1st argument of sample_callback_5/1 (atom()) is not a supertype of 1..255, which is expected type for this argument in the callback of the sample_behaviour behaviour +sample_callback_wrong.erl:22:1: The inferred return type of sample_callback_6/3 ({'okk',number()}) has nothing in common with 'fail' | {'ok',1..255}, which is the expected return type for the callback of the sample_behaviour behaviour +sample_callback_wrong.erl:22:1: The inferred type for the 3rd argument of sample_callback_6/3 (atom()) is not a supertype of string(), which is expected type for this argument in the callback of the sample_behaviour behaviour +sample_callback_wrong.erl:4:2: Undefined callback function sample_callback_1/0 (behaviour sample_behaviour) diff --git a/lib/dialyzer/test/behaviour_SUITE_data/results/sample_behaviour_old b/lib/dialyzer/test/behaviour_SUITE_data/results/sample_behaviour_old index 67aa872984..6d8145a8ca 100644 --- a/lib/dialyzer/test/behaviour_SUITE_data/results/sample_behaviour_old +++ b/lib/dialyzer/test/behaviour_SUITE_data/results/sample_behaviour_old @@ -1,4 +1,4 @@ -incorrect_args_callback.erl:12: The inferred type for the 2nd argument of bar/2 ('yes') is not a supertype of [any()], which is expected type for this argument in the callback of the correct_behaviour behaviour -incorrect_return_callback.erl:9: The inferred return type of foo/0 ('error') has nothing in common with 'no' | 'yes', which is the expected return type for the callback of the correct_behaviour behaviour -missing_callback.erl:5: Undefined callback function foo/0 (behaviour correct_behaviour) +incorrect_args_callback.erl:12:1: The inferred type for the 2nd argument of bar/2 ('yes') is not a supertype of [any()], which is expected type for this argument in the callback of the correct_behaviour behaviour +incorrect_return_callback.erl:9:1: The inferred return type of foo/0 ('error') has nothing in common with 'no' | 'yes', which is the expected return type for the callback of the correct_behaviour behaviour +missing_callback.erl:5:2: Undefined callback function foo/0 (behaviour correct_behaviour) diff --git a/lib/dialyzer/test/behaviour_SUITE_data/results/supervisor_incorrect_return b/lib/dialyzer/test/behaviour_SUITE_data/results/supervisor_incorrect_return index 5a063a12b8..b396f37929 100644 --- a/lib/dialyzer/test/behaviour_SUITE_data/results/supervisor_incorrect_return +++ b/lib/dialyzer/test/behaviour_SUITE_data/results/supervisor_incorrect_return @@ -1,2 +1,2 @@ -supervisor_incorrect_return.erl:14: The inferred return type of init/1 ({'ok',{{'one_against_one',0,1},[{_,_,_,_,_,_},...]}}) has nothing in common with 'ignore' | {'ok',{{'one_for_all',non_neg_integer(),pos_integer()} | {'one_for_one',non_neg_integer(),pos_integer()} | {'rest_for_one',non_neg_integer(),pos_integer()} | {'simple_one_for_one',non_neg_integer(),pos_integer()} | #{'intensity'=>non_neg_integer(), 'period'=>pos_integer(), 'strategy'=>'one_for_all' | 'one_for_one' | 'rest_for_one' | 'simple_one_for_one'},[{_,{atom(),atom(),'undefined' | [any()]},'permanent' | 'temporary' | 'transient','brutal_kill' | 'infinity' | non_neg_integer(),'supervisor' | 'worker','dynamic' | [atom()]} | #{'id':=_, 'start':={atom(),atom(),'undefined' | [any()]}, 'modules'=>'dynamic' | [atom()], 'restart'=>'permanent' | 'temporary' | 'transient', 'shutdown'=>'brutal_kill' | 'infinity' | non_neg_integer(), 'type'=>'supervisor' | 'worker'}]}}, which is the expected return type for the callback of the supervisor behaviour +supervisor_incorrect_return.erl:14:1: The inferred return type of init/1 ({'ok',{{'one_against_one',0,1},[{_,_,_,_,_,_},...]}}) has nothing in common with 'ignore' | {'ok',{{'one_for_all',non_neg_integer(),pos_integer()} | {'one_for_one',non_neg_integer(),pos_integer()} | {'rest_for_one',non_neg_integer(),pos_integer()} | {'simple_one_for_one',non_neg_integer(),pos_integer()} | #{'intensity'=>non_neg_integer(), 'period'=>pos_integer(), 'strategy'=>'one_for_all' | 'one_for_one' | 'rest_for_one' | 'simple_one_for_one'},[{_,{atom(),atom(),'undefined' | [any()]},'permanent' | 'temporary' | 'transient','brutal_kill' | 'infinity' | non_neg_integer(),'supervisor' | 'worker','dynamic' | [atom()]} | #{'id':=_, 'start':={atom(),atom(),'undefined' | [any()]}, 'modules'=>'dynamic' | [atom()], 'restart'=>'permanent' | 'temporary' | 'transient', 'shutdown'=>'brutal_kill' | 'infinity' | non_neg_integer(), 'type'=>'supervisor' | 'worker'}]}}, which is the expected return type for the callback of the supervisor behaviour diff --git a/lib/dialyzer/test/behaviour_SUITE_data/results/undefined_callbacks b/lib/dialyzer/test/behaviour_SUITE_data/results/undefined_callbacks index 7147ffc750..f89b3042c5 100644 --- a/lib/dialyzer/test/behaviour_SUITE_data/results/undefined_callbacks +++ b/lib/dialyzer/test/behaviour_SUITE_data/results/undefined_callbacks @@ -1,2 +1,2 @@ -undefined_beh_callback.erl:5: Callback info about the undefined_behaviour behaviour is not available +undefined_beh_callback.erl:5:2: Callback info about the undefined_behaviour behaviour is not available diff --git a/lib/dialyzer/test/behaviour_SUITE_data/results/vars_in_beh_spec b/lib/dialyzer/test/behaviour_SUITE_data/results/vars_in_beh_spec index f313c24420..3cf2565c3c 100644 --- a/lib/dialyzer/test/behaviour_SUITE_data/results/vars_in_beh_spec +++ b/lib/dialyzer/test/behaviour_SUITE_data/results/vars_in_beh_spec @@ -1,4 +1,4 @@ -vars_in_beh_spec.erl:3: Undefined callback function handle_call/3 (behaviour gen_server) -vars_in_beh_spec.erl:3: Undefined callback function handle_cast/2 (behaviour gen_server) -vars_in_beh_spec.erl:3: Undefined callback function init/1 (behaviour gen_server) +vars_in_beh_spec.erl:3:2: Undefined callback function handle_call/3 (behaviour gen_server) +vars_in_beh_spec.erl:3:2: Undefined callback function handle_cast/2 (behaviour gen_server) +vars_in_beh_spec.erl:3:2: Undefined callback function init/1 (behaviour gen_server) diff --git a/lib/dialyzer/test/callgraph_SUITE_data/results/test_missing_functions b/lib/dialyzer/test/callgraph_SUITE_data/results/test_missing_functions index 4150bdb7c0..7a0c69ce30 100644 --- a/lib/dialyzer/test/callgraph_SUITE_data/results/test_missing_functions +++ b/lib/dialyzer/test/callgraph_SUITE_data/results/test_missing_functions @@ -1,3 +1,3 @@ -t1.erl:16: Call to missing or unexported function t2:t2/1 -t2.erl:13: Call to missing or unexported function t1:t3/1 +t1.erl:16:3: Call to missing or unexported function t2:t2/1 +t2.erl:13:3: Call to missing or unexported function t1:t3/1 diff --git a/lib/dialyzer/test/indent2_SUITE_data/results/arr b/lib/dialyzer/test/indent2_SUITE_data/results/arr index 77e67f0cab..c1ce887a3e 100644 --- a/lib/dialyzer/test/indent2_SUITE_data/results/arr +++ b/lib/dialyzer/test/indent2_SUITE_data/results/arr @@ -1,15 +1,15 @@ -arr.erl:14: Type specification arr:test2 +arr.erl:14:2: Type specification arr:test2 (array:array(T), non_neg_integer(), T) -> array:array(T) is a supertype of the success typing: arr:test2 (array:array(_), pos_integer(), _) -> array:array(_) -arr.erl:24: Type specification arr:test4 +arr.erl:24:2: Type specification arr:test4 (array:array(T), non_neg_integer(), _) -> array:array(T) is a supertype of the success typing: arr:test4 (array:array(_), pos_integer(), _) -> array:array(_) -arr.erl:29: Type specification arr:test5 +arr.erl:29:2: Type specification arr:test5 (array:array(T), non_neg_integer(), T) -> array:array(T) is a supertype of the success typing: arr:test5 (array:array(_), non_neg_integer(), integer()) -> array:array(_) -arr.erl:37: Type specification arr:test6 +arr.erl:37:2: Type specification arr:test6 (array:array(integer()), non_neg_integer(), integer()) -> array:array(any()) is not equal to the success typing: arr:test6 (array:array(_), non_neg_integer(), _) -> array:array(_) diff --git a/lib/dialyzer/test/indent2_SUITE_data/results/iodata b/lib/dialyzer/test/indent2_SUITE_data/results/iodata index d95551d330..88e1b9b34c 100644 --- a/lib/dialyzer/test/indent2_SUITE_data/results/iodata +++ b/lib/dialyzer/test/indent2_SUITE_data/results/iodata @@ -1,5 +1,5 @@ -iodata.erl:7: The specification for iodata:encode/2 states that the function might also return +iodata.erl:7:2: The specification for iodata:encode/2 states that the function might also return binary() but the inferred return is nonempty_maybe_improper_list(<<_:8, _:_*8>> | nonempty_maybe_improper_list(<<_:8, @@ -15,7 +15,7 @@ iodata.erl:7: The specification for iodata:encode/2 states that the function mig integer(), <<_:8, _:_*8>> | []) | integer() -iodata.erl:7: The success typing for iodata:encode/2 implies that the function might also return +iodata.erl:7:2: The success typing for iodata:encode/2 implies that the function might also return integer() but the specification return is binary() | maybe_improper_list(binary() | diff --git a/lib/dialyzer/test/indent2_SUITE_data/results/remote b/lib/dialyzer/test/indent2_SUITE_data/results/remote index 6decec6c6a..a31cedeeea 100644 --- a/lib/dialyzer/test/indent2_SUITE_data/results/remote +++ b/lib/dialyzer/test/indent2_SUITE_data/results/remote @@ -1,25 +1,25 @@ -remotes1.erl:17: The specification for remotes1:foo5/1 states that the function might also return +remotes1.erl:17:2: The specification for remotes1:foo5/1 states that the function might also return 'ko' but the inferred return is 'ok' -remotes1.erl:20: Type specification remotes1:foo6 +remotes1.erl:20:2: Type specification remotes1:foo6 ('ok' | 'ko') -> 'ok' is a supertype of the success typing: remotes1:foo6 ('ok') -> 'ok' -remotes1.erl:25: The specification for remotes1:foo7/1 states that the function might also return +remotes1.erl:25:2: The specification for remotes1:foo7/1 states that the function might also return 'ko' but the inferred return is 'ok' -remotes1.erl:28: Type specification remotes1:foo8 +remotes1.erl:28:2: Type specification remotes1:foo8 (local_type_42()) -> 'ok' is a supertype of the success typing: remotes1:foo8 ('ok') -> 'ok' -remotes1.erl:33: The specification for remotes1:foo9/1 states that the function might also return +remotes1.erl:33:2: The specification for remotes1:foo9/1 states that the function might also return 'ko' but the inferred return is 'ok' -remotes1.erl:36: Type specification remotes1:foo10 +remotes1.erl:36:2: Type specification remotes1:foo10 (local_and_known_remote_type_42()) -> 'ok' is a supertype of the success typing: remotes1:foo10 ('ok') -> 'ok' -remotes1.erl:49: Type specification remotes1:foo13 +remotes1.erl:49:2: Type specification remotes1:foo13 ('ok') -> local_and_unknown_remote_type_42() is a supertype of the success typing: remotes1:foo13 ('ok') -> 'ok' -remotes1.erl:52: Type specification remotes1:foo14 +remotes1.erl:52:2: Type specification remotes1:foo14 (local_and_unknown_remote_type_42()) -> 'ok' is a supertype of the success typing: remotes1:foo14 ('ok') -> 'ok' diff --git a/lib/dialyzer/test/indent_SUITE_data/results/abs b/lib/dialyzer/test/indent_SUITE_data/results/abs index ac663a4e80..46a41825fb 100644 --- a/lib/dialyzer/test/indent_SUITE_data/results/abs +++ b/lib/dialyzer/test/indent_SUITE_data/results/abs @@ -1,13 +1,13 @@ -abs.erl:16: The pattern +abs.erl:16:5: The pattern 'true' can never match the type 'false' -abs.erl:27: The pattern +abs.erl:27:5: The pattern 'true' can never match the type 'false' -abs.erl:37: The pattern +abs.erl:37:5: The pattern 'true' can never match the type 'false' -abs.erl:49: The pattern +abs.erl:49:5: The pattern 'true' can never match the type 'false' diff --git a/lib/dialyzer/test/indent_SUITE_data/results/app_call b/lib/dialyzer/test/indent_SUITE_data/results/app_call index 729587b5c6..7c245075fb 100644 --- a/lib/dialyzer/test/indent_SUITE_data/results/app_call +++ b/lib/dialyzer/test/indent_SUITE_data/results/app_call @@ -1,9 +1,9 @@ -app_call.erl:6: The call M:'foo' +app_call.erl:6:3: The call M:'foo' () requires that M is of type atom() not 42 -app_call.erl:9: The call 'mod':F +app_call.erl:9:7: The call 'mod':F () requires that F is of type atom() not {'gazonk', []} diff --git a/lib/dialyzer/test/indent_SUITE_data/results/blame_contract_range b/lib/dialyzer/test/indent_SUITE_data/results/blame_contract_range index 287d23d91f..97b1125483 100644 --- a/lib/dialyzer/test/indent_SUITE_data/results/blame_contract_range +++ b/lib/dialyzer/test/indent_SUITE_data/results/blame_contract_range @@ -1,8 +1,8 @@ -blame_contract_range.erl:14: The contract blame_contract_range:bar +blame_contract_range.erl:14:2: The contract blame_contract_range:bar (atom()) -> 'a' cannot be right because the inferred return for bar - ('b') on line 12 is + ('b') on position 12:3 is 'b' -blame_contract_range.erl:15: The pattern +blame_contract_range.erl:15:1: The pattern 'a' can never match the type 'b' diff --git a/lib/dialyzer/test/indent_SUITE_data/results/bs_fail_constr b/lib/dialyzer/test/indent_SUITE_data/results/bs_fail_constr index 86f1329bf3..40a5866376 100644 --- a/lib/dialyzer/test/indent_SUITE_data/results/bs_fail_constr +++ b/lib/dialyzer/test/indent_SUITE_data/results/bs_fail_constr @@ -1,9 +1,9 @@ -bs_fail_constr.erl:12: Binary construction will fail since the size field S in segment 42:S has type +bs_fail_constr.erl:12:8: Binary construction will fail since the size field S in segment 42:S has type neg_integer() -bs_fail_constr.erl:15: Binary construction will fail since the value field V in segment V/utf32 has type +bs_fail_constr.erl:15:5: Binary construction will fail since the value field V in segment V/utf32 has type float() -bs_fail_constr.erl:6: Binary construction will fail since the value field V in segment V has type +bs_fail_constr.erl:6:5: Binary construction will fail since the value field V in segment V has type float() -bs_fail_constr.erl:9: Binary construction will fail since the value field V in segment V/binary has type +bs_fail_constr.erl:9:5: Binary construction will fail since the value field V in segment V/binary has type atom() diff --git a/lib/dialyzer/test/indent_SUITE_data/results/callbacks_and_specs b/lib/dialyzer/test/indent_SUITE_data/results/callbacks_and_specs index dd9d3397d2..0d513775a1 100644 --- a/lib/dialyzer/test/indent_SUITE_data/results/callbacks_and_specs +++ b/lib/dialyzer/test/indent_SUITE_data/results/callbacks_and_specs @@ -1,23 +1,23 @@ -my_callbacks_wrong.erl:26: The return type +my_callbacks_wrong.erl:26:2: The return type #state{parent :: pid(), status :: 'closed' | 'init' | 'open', subscribe :: [{pid(), integer()}], counter :: integer()} in the specification of callback_init/1 is not a subtype of {'ok', _}, which is the expected return type for the callback of the my_behaviour behaviour -my_callbacks_wrong.erl:28: The inferred return type of callback_init/1 +my_callbacks_wrong.erl:28:1: The inferred return type of callback_init/1 (#state{parent :: pid(), status :: 'init', subscribe :: [], counter :: 1}) has nothing in common with {'ok', _}, which is the expected return type for the callback of the my_behaviour behaviour -my_callbacks_wrong.erl:30: The return type +my_callbacks_wrong.erl:30:2: The return type {'reply', #state{parent :: pid(), status :: 'closed' | 'init' | 'open', subscribe :: [{pid(), integer()}], counter :: integer()}} in the specification of callback_cast/3 is not a subtype of {'noreply', _}, which is the expected return type for the callback of the my_behaviour behaviour -my_callbacks_wrong.erl:39: The specified type for the 2nd argument of callback_call/3 ( +my_callbacks_wrong.erl:39:2: The specified type for the 2nd argument of callback_call/3 ( atom()) is not a supertype of pid(), which is expected type for this argument in the callback of the my_behaviour behaviour diff --git a/lib/dialyzer/test/indent_SUITE_data/results/contract3 b/lib/dialyzer/test/indent_SUITE_data/results/contract3 index 6e111f87d9..b290f232a2 100644 --- a/lib/dialyzer/test/indent_SUITE_data/results/contract3 +++ b/lib/dialyzer/test/indent_SUITE_data/results/contract3 @@ -1,3 +1,3 @@ -contract3.erl:17: Overloaded contract for contract3:t1/1 has overlapping domains; such contracts are currently unsupported and are simply ignored -contract3.erl:29: Overloaded contract for contract3:t3/3 has overlapping domains; such contracts are currently unsupported and are simply ignored +contract3.erl:17:2: Overloaded contract for contract3:t1/1 has overlapping domains; such contracts are currently unsupported and are simply ignored +contract3.erl:29:2: Overloaded contract for contract3:t3/3 has overlapping domains; such contracts are currently unsupported and are simply ignored diff --git a/lib/dialyzer/test/indent_SUITE_data/results/contracts_with_subtypes b/lib/dialyzer/test/indent_SUITE_data/results/contracts_with_subtypes index 737959a49d..039e5e23f6 100644 --- a/lib/dialyzer/test/indent_SUITE_data/results/contracts_with_subtypes +++ b/lib/dialyzer/test/indent_SUITE_data/results/contracts_with_subtypes @@ -1,88 +1,88 @@ -contracts_with_subtypes.erl:106: The call contracts_with_subtypes:rec_arg +contracts_with_subtypes.erl:106:18: The call contracts_with_subtypes:rec_arg ({'a', 'b'}) breaks the contract (Arg) -> 'ok' when Arg :: {'a', A} | {'b', B}, A :: 'a' | {'b', B}, B :: 'b' | {'a', A} -contracts_with_subtypes.erl:107: The call contracts_with_subtypes:rec_arg +contracts_with_subtypes.erl:107:18: The call contracts_with_subtypes:rec_arg ({'b', 'a'}) breaks the contract (Arg) -> 'ok' when Arg :: {'a', A} | {'b', B}, A :: 'a' | {'b', B}, B :: 'b' | {'a', A} -contracts_with_subtypes.erl:109: The call contracts_with_subtypes:rec_arg +contracts_with_subtypes.erl:109:19: The call contracts_with_subtypes:rec_arg ({'b', {'a', 'b'}}) breaks the contract (Arg) -> 'ok' when Arg :: {'a', A} | {'b', B}, A :: 'a' | {'b', B}, B :: 'b' | {'a', A} -contracts_with_subtypes.erl:135: The call contracts_with_subtypes:rec2 +contracts_with_subtypes.erl:135:15: The call contracts_with_subtypes:rec2 ({'a', 'b'}) breaks the contract (Arg) -> 'ok' when Arg :: ab() -contracts_with_subtypes.erl:136: The call contracts_with_subtypes:rec2 +contracts_with_subtypes.erl:136:15: The call contracts_with_subtypes:rec2 ({'b', 'a'}) breaks the contract (Arg) -> 'ok' when Arg :: ab() -contracts_with_subtypes.erl:137: The call contracts_with_subtypes:rec2 +contracts_with_subtypes.erl:137:16: The call contracts_with_subtypes:rec2 ({'a', {'b', 'a'}}) breaks the contract (Arg) -> 'ok' when Arg :: ab() -contracts_with_subtypes.erl:138: The call contracts_with_subtypes:rec2 +contracts_with_subtypes.erl:138:16: The call contracts_with_subtypes:rec2 ({'b', {'a', 'b'}}) breaks the contract (Arg) -> 'ok' when Arg :: ab() -contracts_with_subtypes.erl:139: The call contracts_with_subtypes:rec2 +contracts_with_subtypes.erl:139:17: The call contracts_with_subtypes:rec2 ({'a', {'b', {'a', 'b'}}}) breaks the contract (Arg) -> 'ok' when Arg :: ab() -contracts_with_subtypes.erl:140: The call contracts_with_subtypes:rec2 +contracts_with_subtypes.erl:140:17: The call contracts_with_subtypes:rec2 ({'b', {'a', {'b', 'a'}}}) breaks the contract (Arg) -> 'ok' when Arg :: ab() -contracts_with_subtypes.erl:141: The call contracts_with_subtypes:rec2 +contracts_with_subtypes.erl:141:18: The call contracts_with_subtypes:rec2 ({'a', {'b', {'a', {'b', 'a'}}}}) breaks the contract (Arg) -> 'ok' when Arg :: ab() -contracts_with_subtypes.erl:142: The call contracts_with_subtypes:rec2 +contracts_with_subtypes.erl:142:18: The call contracts_with_subtypes:rec2 ({'b', {'a', {'b', {'a', 'b'}}}}) breaks the contract (Arg) -> 'ok' when Arg :: ab() -contracts_with_subtypes.erl:175: The pattern +contracts_with_subtypes.erl:175:3: The pattern 1 can never match the type string() -contracts_with_subtypes.erl:178: The pattern +contracts_with_subtypes.erl:178:2: The pattern 'alpha' can never match the type {'ok', _} | {'ok', _, string()} -contracts_with_subtypes.erl:180: The pattern +contracts_with_subtypes.erl:180:2: The pattern 42 can never match the type {'ok', _} | {'ok', _, string()} -contracts_with_subtypes.erl:196: The pattern +contracts_with_subtypes.erl:196:2: The pattern 'alpha' can never match the type {'ok', _} -contracts_with_subtypes.erl:198: The pattern +contracts_with_subtypes.erl:198:2: The pattern 42 can never match the type {'ok', _} -contracts_with_subtypes.erl:216: The pattern +contracts_with_subtypes.erl:216:2: The pattern 'alpha' can never match the type {'ok', _} -contracts_with_subtypes.erl:218: The pattern +contracts_with_subtypes.erl:218:2: The pattern 42 can never match the type {'ok', _} -contracts_with_subtypes.erl:235: The pattern +contracts_with_subtypes.erl:235:3: The pattern 1 can never match the type string() -contracts_with_subtypes.erl:238: The pattern +contracts_with_subtypes.erl:238:2: The pattern {'ok', _} can never match the type {'ok', _, string()} -contracts_with_subtypes.erl:239: The pattern +contracts_with_subtypes.erl:239:2: The pattern 'alpha' can never match the type {'ok', _, string()} -contracts_with_subtypes.erl:23: Invalid type specification for function contracts_with_subtypes:extract2/0. The success typing is +contracts_with_subtypes.erl:23:2: Invalid type specification for function contracts_with_subtypes:extract2/0. The success typing is () -> 'something' -contracts_with_subtypes.erl:240: The pattern +contracts_with_subtypes.erl:240:2: The pattern {'ok', 42} can never match the type {'ok', _, string()} -contracts_with_subtypes.erl:241: The pattern +contracts_with_subtypes.erl:241:2: The pattern 42 can never match the type {'ok', _, string()} -contracts_with_subtypes.erl:268: The call contracts_with_subtypes:flat_ets_new +contracts_with_subtypes.erl:268:18: The call contracts_with_subtypes:flat_ets_new (12, []) breaks the contract (Name, Options) -> atom() @@ -99,7 +99,7 @@ contracts_with_subtypes.erl:268: The call contracts_with_subtypes:flat_ets_new {'write_concurrency', boolean()} | {'read_concurrency', boolean()} | 'compressed' -contracts_with_subtypes.erl:295: The call contracts_with_subtypes:factored_ets_new +contracts_with_subtypes.erl:295:22: The call contracts_with_subtypes:factored_ets_new (12, []) breaks the contract (Name, Options) -> atom() @@ -120,23 +120,23 @@ contracts_with_subtypes.erl:295: The call contracts_with_subtypes:factored_ets_n 'compressed', Pos :: pos_integer(), HeirData :: term() -contracts_with_subtypes.erl:77: The call contracts_with_subtypes:foo1 +contracts_with_subtypes.erl:77:16: The call contracts_with_subtypes:foo1 (5) breaks the contract (Arg1) -> Res when Arg1 :: atom(), Res :: atom() -contracts_with_subtypes.erl:78: The call contracts_with_subtypes:foo2 +contracts_with_subtypes.erl:78:16: The call contracts_with_subtypes:foo2 (5) breaks the contract (Arg1) -> Res when Arg1 :: Arg2, Arg2 :: atom(), Res :: atom() -contracts_with_subtypes.erl:79: The call contracts_with_subtypes:foo3 +contracts_with_subtypes.erl:79:16: The call contracts_with_subtypes:foo3 (5) breaks the contract (Arg1) -> Res when Arg2 :: atom(), Arg1 :: Arg2, Res :: atom() -contracts_with_subtypes.erl:7: Invalid type specification for function contracts_with_subtypes:extract/0. The success typing is +contracts_with_subtypes.erl:7:2: Invalid type specification for function contracts_with_subtypes:extract/0. The success typing is () -> 'something' -contracts_with_subtypes.erl:80: The call contracts_with_subtypes:foo4 +contracts_with_subtypes.erl:80:16: The call contracts_with_subtypes:foo4 (5) breaks the contract (Type) -> Type when Type :: atom() -contracts_with_subtypes.erl:81: The call contracts_with_subtypes:foo5 +contracts_with_subtypes.erl:81:16: The call contracts_with_subtypes:foo5 (5) breaks the contract (Type :: atom()) -> Type :: atom() -contracts_with_subtypes.erl:82: The call contracts_with_subtypes:foo6 +contracts_with_subtypes.erl:82:16: The call contracts_with_subtypes:foo6 (5) breaks the contract (Type) -> Type when Type :: atom() diff --git a/lib/dialyzer/test/indent_SUITE_data/results/dict_use b/lib/dialyzer/test/indent_SUITE_data/results/dict_use index c6863d057e..4039223eec 100644 --- a/lib/dialyzer/test/indent_SUITE_data/results/dict_use +++ b/lib/dialyzer/test/indent_SUITE_data/results/dict_use @@ -1,43 +1,43 @@ -dict_use.erl:41: The attempt to match a term of type +dict_use.erl:41:3: The attempt to match a term of type dict:dict(_, _) against the pattern 'gazonk' breaks the opacity of the term -dict_use.erl:45: The attempt to match a term of type +dict_use.erl:45:5: The attempt to match a term of type dict:dict(_, _) against the pattern [] breaks the opacity of the term -dict_use.erl:46: The attempt to match a term of type +dict_use.erl:46:5: The attempt to match a term of type dict:dict(_, _) against the pattern 42 breaks the opacity of the term -dict_use.erl:51: The attempt to match a term of type +dict_use.erl:51:5: The attempt to match a term of type dict:dict(_, _) against the pattern [] breaks the opacity of the term -dict_use.erl:52: The attempt to match a term of type +dict_use.erl:52:5: The attempt to match a term of type dict:dict(_, _) against the pattern 42 breaks the opacity of the term -dict_use.erl:58: Attempt to test for equality between a term of type +dict_use.erl:58:3: Attempt to test for equality between a term of type maybe_improper_list() and a term of opaque type dict:dict(_, _) -dict_use.erl:60: Attempt to test for inequality between a term of type +dict_use.erl:60:3: Attempt to test for inequality between a term of type atom() and a term of opaque type dict:dict(_, _) -dict_use.erl:64: Guard test length +dict_use.erl:64:19: Guard test length (D :: dict:dict(_, _)) breaks the opacity of its argument -dict_use.erl:65: Guard test is_atom +dict_use.erl:65:20: Guard test is_atom (D :: dict:dict(_, _)) breaks the opacity of its argument -dict_use.erl:66: Guard test is_list +dict_use.erl:66:20: Guard test is_list (D :: dict:dict(_, _)) breaks the opacity of its argument -dict_use.erl:70: The type test is_list +dict_use.erl:70:3: The type test is_list (dict:dict(_, _)) breaks the opacity of the term dict:dict(_, _) -dict_use.erl:73: The call dict:fetch +dict_use.erl:73:19: The call dict:fetch ('foo', [1, 2, 3]) does not have an opaque term of type dict:dict(_, _) as 2nd argument -dict_use.erl:76: The call dict:merge +dict_use.erl:76:19: The call dict:merge (Fun :: any(), 42, [1, 2]) does not have opaque terms as 2nd and 3rd arguments -dict_use.erl:79: The call dict:store +dict_use.erl:80:7: The call dict:store (42, 'elli', {'dict', 0, 16, 16, 8, 80, 48, diff --git a/lib/dialyzer/test/indent_SUITE_data/results/fun_app b/lib/dialyzer/test/indent_SUITE_data/results/fun_app index d4a3caf749..d26111e755 100644 --- a/lib/dialyzer/test/indent_SUITE_data/results/fun_app +++ b/lib/dialyzer/test/indent_SUITE_data/results/fun_app @@ -1,7 +1,7 @@ -fun_app.erl:37: Fun application will fail since F :: +fun_app.erl:37:23: Fun application will fail since F :: fun((_, _, _) -> 'ok' | 'true') is not a function of arity 1 -fun_app.erl:38: Fun application will fail since F :: +fun_app.erl:38:24: Fun application will fail since F :: fun((_, _, _) -> 'ok' | 'true') is not a function of arity 2 -fun_app.erl:40: Fun application will fail since F :: +fun_app.erl:40:28: Fun application will fail since F :: fun((_, _, _) -> 'ok' | 'true') is not a function of arity 4 diff --git a/lib/dialyzer/test/indent_SUITE_data/results/fun_app_args b/lib/dialyzer/test/indent_SUITE_data/results/fun_app_args index ac1bbb62b8..2d523d013b 100644 --- a/lib/dialyzer/test/indent_SUITE_data/results/fun_app_args +++ b/lib/dialyzer/test/indent_SUITE_data/results/fun_app_args @@ -1,5 +1,5 @@ -fun_app_args.erl:12: Fun application with arguments +fun_app_args.erl:12:19: Fun application with arguments ('b', []) will fail since the function has type 'c' | fun(('a', []) -> any()), which differs in the 1st argument diff --git a/lib/dialyzer/test/indent_SUITE_data/results/guard_update b/lib/dialyzer/test/indent_SUITE_data/results/guard_update index bd0e8cd5dd..fad87fa4d3 100644 --- a/lib/dialyzer/test/indent_SUITE_data/results/guard_update +++ b/lib/dialyzer/test/indent_SUITE_data/results/guard_update @@ -1,6 +1,6 @@ -guard_update.erl:6: The call guard_update:f +guard_update.erl:6:7: The call guard_update:f (#{'a' => 2}) will never return since it differs in the 1st argument from the success typing arguments: (#{'b' := _, _ => _}) -guard_update.erl:8: Clause guard cannot succeed. The variable M was matched against the type +guard_update.erl:8:1: Clause guard cannot succeed. The variable M was matched against the type #{'a' := 2} diff --git a/lib/dialyzer/test/indent_SUITE_data/results/guard_warnings b/lib/dialyzer/test/indent_SUITE_data/results/guard_warnings index a6cb54ff9c..a9ce4eeba1 100644 --- a/lib/dialyzer/test/indent_SUITE_data/results/guard_warnings +++ b/lib/dialyzer/test/indent_SUITE_data/results/guard_warnings @@ -1,134 +1,134 @@ -guard_warnings.erl:100: Guard test not +guard_warnings.erl:100:45: Guard test not ('true') can never succeed -guard_warnings.erl:102: Guard test +guard_warnings.erl:102:34: Guard test X :: 'true' =:= 'false' can never succeed -guard_warnings.erl:104: Guard test +guard_warnings.erl:104:33: Guard test X :: 'true' == 'false' can never succeed -guard_warnings.erl:106: Guard test +guard_warnings.erl:106:52: Guard test X :: 'true' =/= 'true' can never succeed -guard_warnings.erl:12: Guard test +guard_warnings.erl:12:1: Guard test X :: 'true' =:= 'false' can never succeed -guard_warnings.erl:14: Guard test +guard_warnings.erl:14:1: Guard test X :: 'false' =:= 'true' can never succeed -guard_warnings.erl:16: Guard test not +guard_warnings.erl:16:22: Guard test not (X :: 'true') can never succeed -guard_warnings.erl:18: Guard test and +guard_warnings.erl:18:16: Guard test and ('true', X :: none()) can never succeed -guard_warnings.erl:20: Guard test not +guard_warnings.erl:20:22: Guard test not (X :: 'true') can never succeed -guard_warnings.erl:22: Guard test and +guard_warnings.erl:22:16: Guard test and ('true', X :: none()) can never succeed -guard_warnings.erl:28: Guard test not(not +guard_warnings.erl:28:21: Guard test not(not (X :: 'false')) can never succeed -guard_warnings.erl:30: Guard test not(or +guard_warnings.erl:30:17: Guard test not(or ('false', X :: none())) can never succeed -guard_warnings.erl:32: Guard test not(not +guard_warnings.erl:32:22: Guard test not(not (X :: 'false')) can never succeed -guard_warnings.erl:34: Guard test not(or +guard_warnings.erl:34:17: Guard test not(or ('false', X :: none())) can never succeed -guard_warnings.erl:36: Guard test and +guard_warnings.erl:36:18: Guard test and ('true', 'false') can never succeed -guard_warnings.erl:38: Guard test and +guard_warnings.erl:38:16: Guard test and ('false', any()) can never succeed -guard_warnings.erl:40: Guard test and +guard_warnings.erl:40:17: Guard test and (X :: 'true', 'false') can never succeed -guard_warnings.erl:42: Guard test and +guard_warnings.erl:42:17: Guard test and ('false', X :: any()) can never succeed -guard_warnings.erl:44: Guard test and +guard_warnings.erl:44:17: Guard test and (X :: 'true', 'false') can never succeed -guard_warnings.erl:46: Guard test and +guard_warnings.erl:46:17: Guard test and ('false', X :: any()) can never succeed -guard_warnings.erl:48: Guard test not(or +guard_warnings.erl:48:21: Guard test not(or ('true', any())) can never succeed -guard_warnings.erl:50: Guard test not(or +guard_warnings.erl:50:23: Guard test not(or ('false', 'true')) can never succeed -guard_warnings.erl:52: Guard test not(or +guard_warnings.erl:52:17: Guard test not(or ('true', X :: any())) can never succeed -guard_warnings.erl:54: Guard test not(or +guard_warnings.erl:54:17: Guard test not(or (X :: 'false', 'true')) can never succeed -guard_warnings.erl:56: Guard test not(or +guard_warnings.erl:56:17: Guard test not(or ('true', X :: any())) can never succeed -guard_warnings.erl:58: Guard test not(or +guard_warnings.erl:58:17: Guard test not(or (X :: 'false', 'true')) can never succeed -guard_warnings.erl:60: Guard test and +guard_warnings.erl:60:17: Guard test and ('false', any()) can never succeed -guard_warnings.erl:62: Guard test and +guard_warnings.erl:62:19: Guard test and ('true', 'false') can never succeed -guard_warnings.erl:64: Guard test and +guard_warnings.erl:64:17: Guard test and ('false', X :: any()) can never succeed -guard_warnings.erl:66: Guard test and +guard_warnings.erl:66:17: Guard test and (X :: 'true', 'false') can never succeed -guard_warnings.erl:68: Guard test and +guard_warnings.erl:68:17: Guard test and ('false', X :: any()) can never succeed -guard_warnings.erl:70: Guard test and +guard_warnings.erl:70:17: Guard test and (X :: 'true', 'false') can never succeed -guard_warnings.erl:72: Guard test and +guard_warnings.erl:72:15: Guard test and ('false', 'false') can never succeed -guard_warnings.erl:74: Guard test and +guard_warnings.erl:74:16: Guard test and ('false', 'false') can never succeed -guard_warnings.erl:76: Guard test not(and +guard_warnings.erl:76:20: Guard test not(and ('true', 'true')) can never succeed -guard_warnings.erl:78: Guard test and +guard_warnings.erl:78:16: Guard test and ('false', 'false') can never succeed -guard_warnings.erl:80: Guard test not(and +guard_warnings.erl:80:20: Guard test not(and ('true', 'true')) can never succeed -guard_warnings.erl:82: Guard test or +guard_warnings.erl:82:15: Guard test or ('false', 'false') can never succeed -guard_warnings.erl:84: Guard test or +guard_warnings.erl:84:16: Guard test or ('false', 'false') can never succeed -guard_warnings.erl:86: Guard test or +guard_warnings.erl:86:20: Guard test or ('false', 'false') can never succeed -guard_warnings.erl:88: Guard test or +guard_warnings.erl:88:16: Guard test or ('false', 'false') can never succeed -guard_warnings.erl:90: Guard test or +guard_warnings.erl:90:20: Guard test or ('false', 'false') can never succeed -guard_warnings.erl:92: Guard test +guard_warnings.erl:92:15: Guard test 'true' =:= 'false' can never succeed -guard_warnings.erl:94: Guard test +guard_warnings.erl:94:15: Guard test 'true' == 'false' can never succeed -guard_warnings.erl:96: Guard test +guard_warnings.erl:96:20: Guard test 'true' =:= 'false' can never succeed -guard_warnings.erl:98: Guard test not( +guard_warnings.erl:98:20: Guard test not( 'true' == 'true') can never succeed diff --git a/lib/dialyzer/test/indent_SUITE_data/results/map_galore b/lib/dialyzer/test/indent_SUITE_data/results/map_galore index 1b63e28ace..13a39d80cd 100644 --- a/lib/dialyzer/test/indent_SUITE_data/results/map_galore +++ b/lib/dialyzer/test/indent_SUITE_data/results/map_galore @@ -1,12 +1,12 @@ -map_galore.erl:1000: A key of type +map_galore.erl:1000:51: A key of type 42 cannot exist in a map of type #{1 := 'a', 2 := 'b', 4 := 'd', 5 := 'e', float() => 'c' | 'v'} -map_galore.erl:1080: A key of type +map_galore.erl:1080:52: A key of type 'nonexisting' cannot exist in a map of type #{10 := 'a0', 11 := 'a1', @@ -88,7 +88,7 @@ map_galore.erl:1080: A key of type 100 | 101, ...]} => atom() | [1..255, ...]} -map_galore.erl:1082: A key of type +map_galore.erl:1082:51: A key of type 42 cannot exist in a map of type #{10 := 'a0', 11 := 'a1', @@ -170,7 +170,7 @@ map_galore.erl:1082: A key of type 100 | 101, ...]} => atom() | [1..255, ...]} -map_galore.erl:1140: The call map_galore:map_guard_sequence_1 +map_galore.erl:1140:61: The call map_galore:map_guard_sequence_1 (#{seq => 6, val => "e"}) will never return since it differs in the 1st argument from the success typing arguments: (#{'seq' := 1 | 2 | 3 | 4 | 5, 'val' := [97 | 98 | 99 | 100 | 101, ...], @@ -247,7 +247,7 @@ map_galore.erl:1140: The call map_galore:map_guard_sequence_1 39 => [any(), ...], <<_:16>> | [any(), ...] | {_} => [any(), ...]} => atom() | [1..255, ...]}) -map_galore.erl:1141: The call map_galore:map_guard_sequence_2 +map_galore.erl:1141:61: The call map_galore:map_guard_sequence_2 (#{'b' => 5}) will never return since it differs in the 1st argument from the success typing arguments: (#{'a' := 'gg' | 'kk' | 'sc' | 3 | 4, 'b' => 'other' | 3 | 4 | 5, @@ -325,7 +325,7 @@ map_galore.erl:1141: The call map_galore:map_guard_sequence_2 39 => [any(), ...], <<_:16>> | [any(), ...] | {_} => [any(), ...]} => atom() | [1..255, ...]}) -map_galore.erl:1209: The call map_galore:map_guard_sequence_1 +map_galore.erl:1209:63: The call map_galore:map_guard_sequence_1 (#{'seq' := 6, 'val' := [101, ...], 10 := 'a0', @@ -483,7 +483,7 @@ map_galore.erl:1209: The call map_galore:map_guard_sequence_1 39 => [any(), ...], <<_:16>> | [any(), ...] | {_} => [any(), ...]} => atom() | [1..255, ...]}) -map_galore.erl:1210: The call map_galore:map_guard_sequence_2 +map_galore.erl:1210:63: The call map_galore:map_guard_sequence_2 (#{'b' := 5, 10 := 'a0', 11 := 'a1', @@ -641,7 +641,7 @@ map_galore.erl:1210: The call map_galore:map_guard_sequence_2 39 => [any(), ...], <<_:16>> | [any(), ...] | {_} => [any(), ...]} => atom() | [1..255, ...]}) -map_galore.erl:1418: Fun application with arguments +map_galore.erl:1418:84: Fun application with arguments (#{'s' => 'none', 'v' => 'none'}) will never return since it differs in the 1st argument from the success typing arguments: (#{'s' := 'l' | 't' | 'v', 'v' := @@ -649,65 +649,65 @@ map_galore.erl:1418: Fun application with arguments <<_:16>> | [<<_:16>>, ...] | {<<_:16>>, <<_:16>>}}) -map_galore.erl:1491: The test +map_galore.erl:1491:13: The test #{} =:= #{'a' := 1} can never evaluate to 'true' -map_galore.erl:1492: The test +map_galore.erl:1492:13: The test #{'a' := 1} =:= #{} can never evaluate to 'true' -map_galore.erl:1495: The test +map_galore.erl:1495:13: The test #{'a' := 1} =:= #{'a' := 2} can never evaluate to 'true' -map_galore.erl:1496: The test +map_galore.erl:1496:13: The test #{'a' := 2} =:= #{'a' := 1} can never evaluate to 'true' -map_galore.erl:1497: The test +map_galore.erl:1497:13: The test #{'a' := 2, 'b' := 1} =:= #{'a' := 1, 'b' := 3} can never evaluate to 'true' -map_galore.erl:1498: The test +map_galore.erl:1498:13: The test #{'a' := 1, 'b' := 1} =:= #{'a' := 1, 'b' := 3} can never evaluate to 'true' -map_galore.erl:1762: The call maps:get +map_galore.erl:1762:9: The call maps:get ({1, 1}, #{{1, float()} => [101 | 108 | 112 | 116 | 117, ...]}) will never return since the success typing arguments are (any(), map()) -map_galore.erl:1763: The call maps:get +map_galore.erl:1763:55: The call maps:get ('a', #{}) will never return since the success typing arguments are (any(), map()) -map_galore.erl:1765: The call maps:get +map_galore.erl:1765:9: The call maps:get ('a', #{'b' => 1, 'c' => 2}) will never return since the success typing arguments are (any(), map()) -map_galore.erl:186: The pattern +map_galore.erl:186:41: The pattern #{'x' := 2} can never match the type #{'x' := 3} -map_galore.erl:187: The pattern +map_galore.erl:187:41: The pattern #{'x' := 3} can never match the type {'a', 'b', 'c'} -map_galore.erl:188: The pattern +map_galore.erl:188:41: The pattern #{'x' := 3} can never match the type #{'y' := 3} -map_galore.erl:189: The pattern +map_galore.erl:189:41: The pattern #{'x' := 3} can never match the type #{'x' := [101 | 104 | 114 | 116, ...]} -map_galore.erl:2280: Cons will produce an improper list since its 2nd argument is +map_galore.erl:2280:50: Cons will produce an improper list since its 2nd argument is {'b', 'a'} -map_galore.erl:2280: The call maps:from_list +map_galore.erl:2280:50: The call maps:from_list ([{'a', 'b'} | {'b', 'a'}]) will never return since it differs in the 1st argument from the success typing arguments: ([{_, _}]) -map_galore.erl:2281: The call maps:from_list +map_galore.erl:2281:50: The call maps:from_list ('a') will never return since it differs in the 1st argument from the success typing arguments: ([{_, _}]) -map_galore.erl:2282: The call maps:from_list +map_galore.erl:2282:50: The call maps:from_list (42) will never return since it differs in the 1st argument from the success typing arguments: ([{_, _}]) -map_galore.erl:997: A key of type +map_galore.erl:997:55: A key of type 'nonexisting' cannot exist in a map of type #{} -map_galore.erl:998: A key of type +map_galore.erl:998:52: A key of type 'nonexisting' cannot exist in a map of type #{1 := 'a', 2 := 'b', 4 := 'd', 5 := 'e', float() => 'c'} diff --git a/lib/dialyzer/test/indent_SUITE_data/results/order b/lib/dialyzer/test/indent_SUITE_data/results/order index 5b0030d7b1..e676717420 100644 --- a/lib/dialyzer/test/indent_SUITE_data/results/order +++ b/lib/dialyzer/test/indent_SUITE_data/results/order @@ -1,23 +1,23 @@ -order.erl:14: Guard test is_integer +order.erl:14:11: Guard test is_integer (Int :: 'b') can never succeed -order.erl:16: The variable _Else can never match since previous clauses completely covered the type +order.erl:16:2: The variable _Else can never match since previous clauses completely covered the type 'b' -order.erl:21: Guard test is_integer +order.erl:21:11: Guard test is_integer (Int :: 'b') can never succeed -order.erl:23: The variable _Else can never match since previous clauses completely covered the type +order.erl:23:2: The variable _Else can never match since previous clauses completely covered the type 'b' -order.erl:30: The variable _Else can never match since previous clauses completely covered the type +order.erl:30:2: The variable _Else can never match since previous clauses completely covered the type 'b' | 1 -order.erl:36: The variable Atom can never match since previous clauses completely covered the type +order.erl:36:2: The variable Atom can never match since previous clauses completely covered the type 1 -order.erl:37: The variable _Else can never match since previous clauses completely covered the type +order.erl:37:2: The variable _Else can never match since previous clauses completely covered the type 1 -order.erl:42: Guard test is_integer +order.erl:42:11: Guard test is_integer (Int :: 'b') can never succeed -order.erl:44: The variable _Else can never match since previous clauses completely covered the type +order.erl:44:2: The variable _Else can never match since previous clauses completely covered the type 'b' -order.erl:7: Guard test is_integer +order.erl:7:11: Guard test is_integer (Int :: 'b') can never succeed -order.erl:9: The variable _Else can never match since previous clauses completely covered the type +order.erl:9:2: The variable _Else can never match since previous clauses completely covered the type 'b' diff --git a/lib/dialyzer/test/indent_SUITE_data/results/queue_use b/lib/dialyzer/test/indent_SUITE_data/results/queue_use index b6604e5320..77afde07c4 100644 --- a/lib/dialyzer/test/indent_SUITE_data/results/queue_use +++ b/lib/dialyzer/test/indent_SUITE_data/results/queue_use @@ -1,34 +1,34 @@ -queue_use.erl:18: The call queue:is_empty +queue_use.erl:18:20: The call queue:is_empty ({[], []}) does not have an opaque term of type queue:queue(_) as 1st argument -queue_use.erl:22: The call queue:in +queue_use.erl:22:18: The call queue:in (42, Q0 :: {[], []}) does not have an opaque term of type queue:queue(_) as 2nd argument -queue_use.erl:27: The attempt to match a term of type +queue_use.erl:27:5: The attempt to match a term of type queue:queue(_) against the pattern {"*", Q2} breaks the opacity of the term -queue_use.erl:33: Attempt to test for equality between a term of type +queue_use.erl:33:5: Attempt to test for equality between a term of type {[42, ...], []} and a term of opaque type queue:queue(_) -queue_use.erl:36: The attempt to match a term of type +queue_use.erl:36:5: The attempt to match a term of type queue:queue(_) against the pattern {F, _R} breaks the opacity of the term -queue_use.erl:40: The call queue:out +queue_use.erl:40:35: The call queue:out ({"*", []}) does not have an opaque term of type queue:queue(_) as 1st argument -queue_use.erl:51: The call queue_use:is_in_queue +queue_use.erl:51:25: The call queue_use:is_in_queue (E :: 42, DB :: #db{p :: [], q :: queue:queue(_)}) contains an opaque term as 2nd argument when terms of different types are expected in these positions -queue_use.erl:56: The attempt to match a term of type +queue_use.erl:56:1: The attempt to match a term of type #db{p :: [], q :: queue:queue(_)} against the pattern {'db', _, {L1, L2}} breaks the opacity of queue:queue(_) -queue_use.erl:62: The call queue_use:tuple_queue +queue_use.erl:62:17: The call queue_use:tuple_queue ({42, 'gazonk'}) does not have a term of type {_, queue:queue(_)} (with opaque subterms) as 1st argument -queue_use.erl:65: The call queue:in +queue_use.erl:65:17: The call queue:in (F :: 42, Q :: 'gazonk') does not have an opaque term of type queue:queue(_) as 2nd argument diff --git a/lib/dialyzer/test/indent_SUITE_data/results/rec b/lib/dialyzer/test/indent_SUITE_data/results/rec index 5938b18be0..7bd512073d 100644 --- a/lib/dialyzer/test/indent_SUITE_data/results/rec +++ b/lib/dialyzer/test/indent_SUITE_data/results/rec @@ -1,15 +1,15 @@ -rec_use.erl:17: The attempt to match a term of type +rec_use.erl:17:2: The attempt to match a term of type rec_adt:rec() against the pattern {'rec', _, 42} breaks the opacity of the term -rec_use.erl:18: Guard test tuple_size +rec_use.erl:18:20: Guard test tuple_size (R :: rec_adt:rec()) breaks the opacity of its argument -rec_use.erl:23: The call rec_adt:get_a +rec_use.erl:23:19: The call rec_adt:get_a (R :: tuple()) does not have an opaque term of type rec_adt:rec() as 1st argument -rec_use.erl:27: Attempt to test for equality between a term of type +rec_use.erl:27:5: Attempt to test for equality between a term of type {'rec', 'gazonk', 42} and a term of opaque type rec_adt:rec() -rec_use.erl:30: The call erlang:tuple_size +rec_use.erl:30:16: The call erlang:tuple_size (rec_adt:rec()) contains an opaque term as 1st argument when a structured term of type tuple() is expected diff --git a/lib/dialyzer/test/indent_SUITE_data/results/record_construct b/lib/dialyzer/test/indent_SUITE_data/results/record_construct index a1268de690..f772773d92 100644 --- a/lib/dialyzer/test/indent_SUITE_data/results/record_construct +++ b/lib/dialyzer/test/indent_SUITE_data/results/record_construct @@ -1,11 +1,11 @@ -record_construct.erl:16: Record construction +record_construct.erl:16:3: Record construction #r_opa{b :: gb_sets:set(_), c :: 42, e :: 'false'} violates the declared type of field c :: boolean() -record_construct.erl:21: Record construction +record_construct.erl:21:3: Record construction #r_rem{a :: 'gazonk'} violates the declared type of field a :: string() -record_construct.erl:7: Record construction +record_construct.erl:7:3: Record construction #r_loc{a :: 'gazonk', b :: 42} violates the declared type of field a :: integer() and b :: atom() diff --git a/lib/dialyzer/test/indent_SUITE_data/results/record_creation_diffs b/lib/dialyzer/test/indent_SUITE_data/results/record_creation_diffs index 9b5f9489db..39ff8b943f 100644 --- a/lib/dialyzer/test/indent_SUITE_data/results/record_creation_diffs +++ b/lib/dialyzer/test/indent_SUITE_data/results/record_creation_diffs @@ -1,4 +1,4 @@ -record_creation_diffs.erl:11: Record construction +record_creation_diffs.erl:11:41: Record construction #bar{some_list :: {'this', 'is', 'a', 'tuple'}} violates the declared type of field some_list :: [any()] diff --git a/lib/dialyzer/test/indent_SUITE_data/results/record_match b/lib/dialyzer/test/indent_SUITE_data/results/record_match index 4738a4b0c9..69739a11d6 100644 --- a/lib/dialyzer/test/indent_SUITE_data/results/record_match +++ b/lib/dialyzer/test/indent_SUITE_data/results/record_match @@ -1,4 +1,4 @@ -record_match.erl:17: Matching of pattern +record_match.erl:17:5: Matching of pattern {'b_literal', 'undefined'} tagged with a record name violates the declared type of #b_local{} | #b_remote{} diff --git a/lib/dialyzer/test/indent_SUITE_data/results/record_pat b/lib/dialyzer/test/indent_SUITE_data/results/record_pat index cf9247d5a8..d68b18ded3 100644 --- a/lib/dialyzer/test/indent_SUITE_data/results/record_pat +++ b/lib/dialyzer/test/indent_SUITE_data/results/record_pat @@ -1,4 +1,4 @@ -record_pat.erl:14: Matching of pattern +record_pat.erl:14:1: Matching of pattern {'foo', 'baz'} tagged with a record name violates the declared type of #foo{bar :: integer()} diff --git a/lib/dialyzer/test/indent_SUITE_data/results/record_send_test b/lib/dialyzer/test/indent_SUITE_data/results/record_send_test index 998394bbd0..23f5ad09d6 100644 --- a/lib/dialyzer/test/indent_SUITE_data/results/record_send_test +++ b/lib/dialyzer/test/indent_SUITE_data/results/record_send_test @@ -1,5 +1,5 @@ -record_send_test.erl:30: The call erlang:'!' +record_send_test.erl:30:7: The call erlang:'!' (Rec1 :: #rec1{a :: 'a', b :: 'b', c :: 'c'}, 'hello_again') will never return since it differs in the 1st argument from the success typing arguments: (atom() | pid() | port() | reference() | {atom(), atom()}, diff --git a/lib/dialyzer/test/indent_SUITE_data/results/record_test b/lib/dialyzer/test/indent_SUITE_data/results/record_test index 1574459578..d9c2de548b 100644 --- a/lib/dialyzer/test/indent_SUITE_data/results/record_test +++ b/lib/dialyzer/test/indent_SUITE_data/results/record_test @@ -1,6 +1,6 @@ -record_test.erl:19: Matching of pattern +record_test.erl:19:5: Matching of pattern {'foo', _} tagged with a record name violates the declared type of 'foo' -record_test.erl:21: The variable _ can never match since previous clauses completely covered the type +record_test.erl:21:5: The variable _ can never match since previous clauses completely covered the type 'foo' diff --git a/lib/dialyzer/test/indent_SUITE_data/results/record_update b/lib/dialyzer/test/indent_SUITE_data/results/record_update index 6e4124552e..997b3ecb96 100644 --- a/lib/dialyzer/test/indent_SUITE_data/results/record_update +++ b/lib/dialyzer/test/indent_SUITE_data/results/record_update @@ -1,3 +1,3 @@ -record_update.erl:7: Invalid type specification for function record_update:quux/2. The success typing is +record_update.erl:7:2: Invalid type specification for function record_update:quux/2. The success typing is (#foo{bar :: atom()}, atom()) -> #foo{bar :: atom()} diff --git a/lib/dialyzer/test/indent_SUITE_data/results/sample_behaviour b/lib/dialyzer/test/indent_SUITE_data/results/sample_behaviour index f0e41d024a..e7ae7505f6 100644 --- a/lib/dialyzer/test/indent_SUITE_data/results/sample_behaviour +++ b/lib/dialyzer/test/indent_SUITE_data/results/sample_behaviour @@ -1,23 +1,23 @@ -sample_callback_wrong.erl:16: The inferred return type of sample_callback_2/0 +sample_callback_wrong.erl:16:1: The inferred return type of sample_callback_2/0 (42) has nothing in common with atom(), which is the expected return type for the callback of the sample_behaviour behaviour -sample_callback_wrong.erl:17: The inferred return type of sample_callback_3/0 +sample_callback_wrong.erl:17:1: The inferred return type of sample_callback_3/0 ('fair') has nothing in common with 'fail' | {'ok', 1..255}, which is the expected return type for the callback of the sample_behaviour behaviour -sample_callback_wrong.erl:18: The inferred return type of sample_callback_4/1 +sample_callback_wrong.erl:18:1: The inferred return type of sample_callback_4/1 ('fail') has nothing in common with 'ok', which is the expected return type for the callback of the sample_behaviour behaviour -sample_callback_wrong.erl:20: The inferred return type of sample_callback_5/1 +sample_callback_wrong.erl:20:1: The inferred return type of sample_callback_5/1 (string()) has nothing in common with 'fail' | 'ok', which is the expected return type for the callback of the sample_behaviour behaviour -sample_callback_wrong.erl:20: The inferred type for the 1st argument of sample_callback_5/1 ( +sample_callback_wrong.erl:20:1: The inferred type for the 1st argument of sample_callback_5/1 ( atom()) is not a supertype of 1..255, which is expected type for this argument in the callback of the sample_behaviour behaviour -sample_callback_wrong.erl:22: The inferred return type of sample_callback_6/3 +sample_callback_wrong.erl:22:1: The inferred return type of sample_callback_6/3 ({'okk', number()}) has nothing in common with 'fail' | {'ok', 1..255}, which is the expected return type for the callback of the sample_behaviour behaviour -sample_callback_wrong.erl:22: The inferred type for the 3rd argument of sample_callback_6/3 ( +sample_callback_wrong.erl:22:1: The inferred type for the 3rd argument of sample_callback_6/3 ( atom()) is not a supertype of string(), which is expected type for this argument in the callback of the sample_behaviour behaviour -sample_callback_wrong.erl:4: Undefined callback function sample_callback_1/0 (behaviour sample_behaviour) +sample_callback_wrong.erl:4:2: Undefined callback function sample_callback_1/0 (behaviour sample_behaviour) diff --git a/lib/dialyzer/test/indent_SUITE_data/results/simple b/lib/dialyzer/test/indent_SUITE_data/results/simple index bafe334405..f33392d5bc 100644 --- a/lib/dialyzer/test/indent_SUITE_data/results/simple +++ b/lib/dialyzer/test/indent_SUITE_data/results/simple @@ -1,288 +1,288 @@ -exact_api.erl:17: The call exact_api:set_type +exact_api.erl:17:14: The call exact_api:set_type (A :: #digraph{vtab :: 'notable', etab :: 'notable', ntab :: 'notable', cyclic :: 'true'}) does not have an opaque term of type digraph:graph() as 1st argument -exact_api.erl:23: The call digraph:delete +exact_api.erl:23:20: The call digraph:delete (G :: #digraph{vtab :: 'notable', etab :: 'notable', ntab :: 'notable', cyclic :: 'true'}) does not have an opaque term of type digraph:graph() as 1st argument -exact_api.erl:55: The attempt to match a term of type +exact_api.erl:55:5: The attempt to match a term of type exact_adt:exact_adt() against the pattern {'exact_adt'} breaks the opacity of the term -exact_api.erl:59: The call exact_adt:exact_adt_set_type2 +exact_api.erl:59:39: The call exact_adt:exact_adt_set_type2 (A :: #exact_adt{}) does not have an opaque term of type exact_adt:exact_adt() as 1st argument -is_rec.erl:10: The call erlang:is_record +is_rec.erl:10:5: The call erlang:is_record (simple1_adt:d1(), 'r', 2) contains an opaque term as 1st argument when terms of different types are expected in these positions -is_rec.erl:15: The call erlang:is_record +is_rec.erl:15:15: The call erlang:is_record (A :: simple1_adt:d1(), 'r', I :: 1 | 2 | 3) contains an opaque term as 1st argument when terms of different types are expected in these positions -is_rec.erl:19: Guard test is_record +is_rec.erl:19:18: Guard test is_record (A :: simple1_adt:d1(), 'r', 2) breaks the opacity of its argument -is_rec.erl:23: Guard test is_record +is_rec.erl:23:18: Guard test is_record ({simple1_adt:d1(), 1}, 'r', 2) breaks the opacity of its argument -is_rec.erl:41: The call erlang:is_record +is_rec.erl:41:15: The call erlang:is_record (A :: simple1_adt:d1(), R :: 'a') contains an opaque term as 1st argument when terms of different types are expected in these positions -is_rec.erl:45: The call erlang:is_record +is_rec.erl:45:18: The call erlang:is_record (A :: simple1_adt:d1(), A :: simple1_adt:d1(), 1) contains an opaque term as 2nd argument when terms of different types are expected in these positions -is_rec.erl:49: The call erlang:is_record +is_rec.erl:49:15: The call erlang:is_record (A :: simple1_adt:d1(), any(), 1) contains an opaque term as 1st argument when terms of different types are expected in these positions -is_rec.erl:53: The call erlang:is_record +is_rec.erl:53:18: The call erlang:is_record (A :: simple1_adt:d1(), A :: simple1_adt:d1(), any()) contains an opaque term as 2nd argument when terms of different types are expected in these positions -is_rec.erl:57: Guard test is_record +is_rec.erl:57:18: Guard test is_record (A :: simple1_adt:d1(), 'r', 2) breaks the opacity of its argument -is_rec.erl:61: The record +is_rec.erl:61:8: The record #r{f1 :: simple1_adt:d1()} violates the declared type for #r{} -is_rec.erl:65: The call erlang:is_record +is_rec.erl:65:5: The call erlang:is_record ({simple1_adt:d1(), 1}, 'r', 2) contains an opaque term as 1st argument when terms of different types are expected in these positions -rec_api.erl:104: Matching of pattern +rec_api.erl:104:5: Matching of pattern {'r2', 10} tagged with a record name violates the declared type of #r2{f1 :: 10} -rec_api.erl:113: The attempt to match a term of type +rec_api.erl:113:5: The attempt to match a term of type #r3{f1 :: queue:queue(_)} against the pattern {'r3', 'a'} breaks the opacity of queue:queue(_) -rec_api.erl:118: Record construction +rec_api.erl:118:18: Record construction #r3{f1 :: 10} violates the declared type of field f1 :: queue:queue(_) -rec_api.erl:123: The attempt to match a term of type +rec_api.erl:123:5: The attempt to match a term of type #r3{f1 :: 10} against the pattern {'r3', 10} breaks the opacity of queue:queue(_) -rec_api.erl:24: Record construction +rec_api.erl:24:18: Record construction #r1{f1 :: 10} violates the declared type of field f1 :: rec_api:a() -rec_api.erl:29: Matching of pattern +rec_api.erl:29:5: Matching of pattern {'r1', 10} tagged with a record name violates the declared type of #r1{f1 :: 10} -rec_api.erl:33: The attempt to match a term of type +rec_api.erl:33:5: The attempt to match a term of type rec_adt:r1() against the pattern {'r1', 'a'} breaks the opacity of the term -rec_api.erl:35: Invalid type specification for function rec_api:adt_t1/1. The success typing is +rec_api.erl:35:2: Invalid type specification for function rec_api:adt_t1/1. The success typing is (#r1{f1 :: 'a'}) -> #r1{f1 :: 'a'} -rec_api.erl:40: The specification for rec_api:adt_r1/0 has an opaque subtype +rec_api.erl:40:2: The specification for rec_api:adt_r1/0 has an opaque subtype rec_adt:r1() which is violated by the success typing () -> #r1{f1 :: 'a'} -rec_api.erl:85: The attempt to match a term of type +rec_api.erl:85:13: The attempt to match a term of type rec_adt:f() against the record field 'f' declared to be of type rec_api:f() breaks the opacity of the term -rec_api.erl:99: Record construction +rec_api.erl:99:18: Record construction #r2{f1 :: 10} violates the declared type of field f1 :: rec_api:a() -simple1_api.erl:113: The test +simple1_api.erl:113:5: The test simple1_api:d1() =:= simple1_api:d2() can never evaluate to 'true' -simple1_api.erl:118: Guard test +simple1_api.erl:118:5: Guard test simple1_api:d2() =:= A :: simple1_api:d1() can never succeed -simple1_api.erl:142: Attempt to test for equality between a term of type +simple1_api.erl:142:5: Attempt to test for equality between a term of type simple1_adt:o2() and a term of opaque type simple1_adt:o1() -simple1_api.erl:148: Guard test +simple1_api.erl:148:5: Guard test simple1_adt:o2() =:= A :: simple1_adt:o1() contains opaque terms as 1st and 2nd arguments -simple1_api.erl:154: Attempt to test for inequality between a term of type +simple1_api.erl:154:5: Attempt to test for inequality between a term of type simple1_adt:o2() and a term of opaque type simple1_adt:o1() -simple1_api.erl:160: Attempt to test for inequality between a term of type +simple1_api.erl:160:5: Attempt to test for inequality between a term of type simple1_adt:o2() and a term of opaque type simple1_adt:o1() -simple1_api.erl:165: Attempt to test for equality between a term of type +simple1_api.erl:165:5: Attempt to test for equality between a term of type simple1_adt:c2() and a term of opaque type simple1_adt:c1() -simple1_api.erl:181: Guard test +simple1_api.erl:181:8: Guard test A :: simple1_adt:d1() =< B :: simple1_adt:d2() contains opaque terms as 1st and 2nd arguments -simple1_api.erl:185: Guard test +simple1_api.erl:185:13: Guard test 'a' =< B :: simple1_adt:d2() contains an opaque term as 2nd argument -simple1_api.erl:189: Guard test +simple1_api.erl:189:8: Guard test A :: simple1_adt:d1() =< 'd' contains an opaque term as 1st argument -simple1_api.erl:197: The type test is_integer +simple1_api.erl:197:5: The type test is_integer (A :: simple1_adt:d1()) breaks the opacity of the term A:: simple1_adt:d1() -simple1_api.erl:221: Guard test +simple1_api.erl:221:8: Guard test A :: simple1_api:i1() > 3 can never succeed -simple1_api.erl:225: Guard test +simple1_api.erl:225:8: Guard test A :: simple1_adt:i1() > 3 contains an opaque term as 1st argument -simple1_api.erl:233: Guard test +simple1_api.erl:233:8: Guard test A :: simple1_adt:i1() < 3 contains an opaque term as 1st argument -simple1_api.erl:239: Guard test +simple1_api.erl:239:8: Guard test A :: 1 > 3 can never succeed -simple1_api.erl:243: Guard test +simple1_api.erl:243:8: Guard test A :: 1 > 3 can never succeed -simple1_api.erl:257: Guard test is_function +simple1_api.erl:257:8: Guard test is_function (T :: simple1_api:o1()) can never succeed -simple1_api.erl:265: Guard test is_function +simple1_api.erl:265:20: Guard test is_function (T :: simple1_adt:o1()) breaks the opacity of its argument -simple1_api.erl:269: The type test is_function +simple1_api.erl:269:5: The type test is_function (T :: simple1_adt:o1()) breaks the opacity of the term T:: simple1_adt:o1() -simple1_api.erl:274: Guard test is_function +simple1_api.erl:274:8: Guard test is_function (T :: simple1_api:o1(), A :: simple1_api:i1()) can never succeed -simple1_api.erl:284: Guard test is_function +simple1_api.erl:284:20: Guard test is_function (T :: simple1_adt:o1(), A :: simple1_adt:i1()) breaks the opacity of its argument -simple1_api.erl:289: The type test is_function +simple1_api.erl:289:5: The type test is_function (T :: simple1_adt:o1(), A :: simple1_adt:i1()) breaks the opacity of the term T:: simple1_adt:o1() -simple1_api.erl:294: The call erlang:is_function +simple1_api.erl:294:20: The call erlang:is_function (T :: simple1_api:o1(), A :: simple1_adt:i1()) contains an opaque term as 2nd argument when terms of different types are expected in these positions -simple1_api.erl:300: The type test is_function +simple1_api.erl:300:5: The type test is_function (T :: simple1_adt:o1(), A :: simple1_api:i1()) breaks the opacity of the term T:: simple1_adt:o1() -simple1_api.erl:306: Guard test +simple1_api.erl:306:8: Guard test B :: simple1_api:b2() =:= 'true' can never succeed -simple1_api.erl:315: Guard test +simple1_api.erl:315:8: Guard test A :: simple1_api:b1() =:= 'false' can never succeed -simple1_api.erl:319: Guard test not(and +simple1_api.erl:319:16: Guard test not(and ('true', 'true')) can never succeed -simple1_api.erl:337: Clause guard cannot succeed. -simple1_api.erl:342: Guard test +simple1_api.erl:337:8: Clause guard cannot succeed. +simple1_api.erl:342:8: Guard test B :: simple1_adt:b2() =:= 'true' contains an opaque term as 1st argument -simple1_api.erl:347: Guard test +simple1_api.erl:347:8: Guard test A :: simple1_adt:b1() =:= 'true' contains an opaque term as 1st argument -simple1_api.erl:355: Invalid type specification for function simple1_api:bool_adt_t6/1. The success typing is +simple1_api.erl:355:2: Invalid type specification for function simple1_api:bool_adt_t6/1. The success typing is ('true') -> 1 -simple1_api.erl:365: Clause guard cannot succeed. -simple1_api.erl:368: Invalid type specification for function simple1_api:bool_adt_t8/2. The success typing is +simple1_api.erl:365:8: Clause guard cannot succeed. +simple1_api.erl:368:2: Invalid type specification for function simple1_api:bool_adt_t8/2. The success typing is (boolean(), boolean()) -> 1 -simple1_api.erl:378: Clause guard cannot succeed. -simple1_api.erl:381: Invalid type specification for function simple1_api:bool_adt_t9/2. The success typing is +simple1_api.erl:378:8: Clause guard cannot succeed. +simple1_api.erl:381:2: Invalid type specification for function simple1_api:bool_adt_t9/2. The success typing is ('false', 'false') -> 1 -simple1_api.erl:407: The size +simple1_api.erl:407:12: The size simple1_adt:i1() breaks the opacity of A -simple1_api.erl:418: The attempt to match a term of type +simple1_api.erl:418:9: The attempt to match a term of type non_neg_integer() against the variable A breaks the opacity of simple1_adt:i1() -simple1_api.erl:425: The attempt to match a term of type +simple1_api.erl:425:9: The attempt to match a term of type non_neg_integer() against the variable B breaks the opacity of simple1_adt:i1() -simple1_api.erl:432: The pattern +simple1_api.erl:432:9: The pattern <<_:B>> can never match the type any() -simple1_api.erl:448: The attempt to match a term of type +simple1_api.erl:448:9: The attempt to match a term of type non_neg_integer() against the variable Sz breaks the opacity of simple1_adt:i1() -simple1_api.erl:460: The attempt to match a term of type +simple1_api.erl:460:9: The attempt to match a term of type simple1_adt:bit1() against the pattern <<_/binary>> breaks the opacity of the term -simple1_api.erl:478: The call 'foo':A +simple1_api.erl:478:9: The call 'foo':A (A :: simple1_adt:a()) breaks the opacity of the term A :: simple1_adt:a() -simple1_api.erl:486: The call A:'foo' +simple1_api.erl:486:5: The call A:'foo' (A :: simple1_adt:a()) breaks the opacity of the term A :: simple1_adt:a() -simple1_api.erl:499: The call 'foo':A +simple1_api.erl:499:9: The call 'foo':A (A :: simple1_api:i()) requires that A is of type atom() not simple1_api:i() -simple1_api.erl:503: The call 'foo':A +simple1_api.erl:503:9: The call 'foo':A (A :: simple1_adt:i()) requires that A is of type atom() not simple1_adt:i() -simple1_api.erl:507: The call A:'foo' +simple1_api.erl:507:5: The call A:'foo' (A :: simple1_api:i()) requires that A is of type atom() not simple1_api:i() -simple1_api.erl:511: The call A:'foo' +simple1_api.erl:511:5: The call A:'foo' (A :: simple1_adt:i()) requires that A is of type atom() not simple1_adt:i() -simple1_api.erl:519: Guard test +simple1_api.erl:519:9: Guard test A :: simple1_adt:d2() == B :: simple1_adt:d1() contains opaque terms as 1st and 2nd arguments -simple1_api.erl:534: Guard test +simple1_api.erl:534:9: Guard test A :: simple1_adt:d1() >= 3 contains an opaque term as 1st argument -simple1_api.erl:536: Guard test +simple1_api.erl:536:9: Guard test A :: simple1_adt:d1() == 3 contains an opaque term as 1st argument -simple1_api.erl:538: Guard test +simple1_api.erl:538:9: Guard test A :: simple1_adt:d1() =:= 3 contains an opaque term as 1st argument -simple1_api.erl:548: The call erlang:'<' +simple1_api.erl:548:5: The call erlang:'<' (A :: simple1_adt:d1(), 3) contains an opaque term as 1st argument when terms of different types are expected in these positions -simple1_api.erl:558: The call erlang:'=<' +simple1_api.erl:558:5: The call erlang:'=<' (A :: simple1_adt:d1(), B :: simple1_adt:d2()) contains opaque terms as 1st and 2nd arguments when terms of different types are expected in these positions -simple1_api.erl:565: Guard test +simple1_api.erl:565:17: Guard test {digraph:graph(), 3} > {digraph:graph(), atom() | ets:tid()} contains an opaque term as 2nd argument -simple1_api.erl:91: The specification for simple1_api:tup/0 has an opaque subtype +simple1_api.erl:91:2: The specification for simple1_api:tup/0 has an opaque subtype simple1_adt:tuple1() which is violated by the success typing () -> {'a', 'b'} -simple2_api.erl:100: The call lists:flatten +simple2_api.erl:100:19: The call lists:flatten (A :: simple1_adt:tuple1()) contains an opaque term as 1st argument when a structured term of type [any()] is expected -simple2_api.erl:116: The call lists:flatten +simple2_api.erl:116:19: The call lists:flatten ({simple1_adt:tuple1()}) will never return since it differs in the 1st argument from the success typing arguments: ([any()]) -simple2_api.erl:121: Guard test +simple2_api.erl:121:16: Guard test {simple1_adt:d1(), 3} > {simple1_adt:d1(), simple1_adt:tuple1()} contains an opaque term as 2nd argument -simple2_api.erl:125: The call erlang:tuple_to_list +simple2_api.erl:125:19: The call erlang:tuple_to_list (B :: simple1_adt:tuple1()) contains an opaque term as 1st argument when a structured term of type tuple() is expected -simple2_api.erl:31: The call erlang:'!' +simple2_api.erl:31:5: The call erlang:'!' (A :: simple1_adt:d1(), 'foo') contains an opaque term as 1st argument when terms of different types are expected in these positions -simple2_api.erl:35: The call erlang:send +simple2_api.erl:35:17: The call erlang:send (A :: simple1_adt:d1(), 'foo') contains an opaque term as 1st argument when terms of different types are expected in these positions -simple2_api.erl:51: The call erlang:'<' +simple2_api.erl:51:5: The call erlang:'<' (A :: simple1_adt:d1(), 3) contains an opaque term as 1st argument when terms of different types are expected in these positions -simple2_api.erl:59: The call lists:keysearch +simple2_api.erl:59:24: The call lists:keysearch (1, A :: simple1_adt:d1(), []) contains an opaque term as 2nd argument when terms of different types are expected in these positions -simple2_api.erl:67: The call lists:keysearch +simple2_api.erl:67:29: The call lists:keysearch ('key', 1, A :: simple1_adt:tuple1()) contains an opaque term as 3rd argument when terms of different types are expected in these positions -simple2_api.erl:96: The call lists:keyreplace +simple2_api.erl:96:37: The call lists:keyreplace ('a', 1, [{1, 2}], diff --git a/lib/dialyzer/test/indent_SUITE_data/results/suppress_request b/lib/dialyzer/test/indent_SUITE_data/results/suppress_request index c08f1798c1..94ab0948da 100644 --- a/lib/dialyzer/test/indent_SUITE_data/results/suppress_request +++ b/lib/dialyzer/test/indent_SUITE_data/results/suppress_request @@ -1,11 +1,11 @@ -suppress_request.erl:21: Expression produces a value of type +suppress_request.erl:21:5: Expression produces a value of type {'a', 'b'}, but this value is unmatched -suppress_request.erl:25: Expression produces a value of type +suppress_request.erl:25:5: Expression produces a value of type {'a', 'b'}, but this value is unmatched -suppress_request.erl:39: Guard test +suppress_request.erl:39:5: Guard test 2 =:= A :: fun((none()) -> no_return()) can never succeed -suppress_request.erl:7: Type specification suppress_request:test1 +suppress_request.erl:7:2: Type specification suppress_request:test1 ('a' | 'b') -> 'ok' is a subtype of the success typing: suppress_request:test1 ('a' | 'b' | 'c') -> 'ok' diff --git a/lib/dialyzer/test/indent_SUITE_data/results/trec b/lib/dialyzer/test/indent_SUITE_data/results/trec index f19f728750..83a188327f 100644 --- a/lib/dialyzer/test/indent_SUITE_data/results/trec +++ b/lib/dialyzer/test/indent_SUITE_data/results/trec @@ -1,10 +1,10 @@ -trec.erl:29: The call trec:mk_foo_loc +trec.erl:29:15: The call trec:mk_foo_loc (42, any()) will never return since it differs in the 1st argument from the success typing arguments: ('undefined', atom()) -trec.erl:32: Record construction violates the declared type for #foo{} since variable A cannot be of type +trec.erl:32:22: Record construction violates the declared type for #foo{} since variable A cannot be of type atom() -trec.erl:39: Record construction violates the declared type for #foo{} since variable A cannot be of type +trec.erl:39:22: Record construction violates the declared type for #foo{} since variable A cannot be of type atom() diff --git a/lib/dialyzer/test/indent_SUITE_data/results/whereis_control_flow1 b/lib/dialyzer/test/indent_SUITE_data/results/whereis_control_flow1 index 0e733fced6..1154cada8a 100644 --- a/lib/dialyzer/test/indent_SUITE_data/results/whereis_control_flow1 +++ b/lib/dialyzer/test/indent_SUITE_data/results/whereis_control_flow1 @@ -1,4 +1,4 @@ -whereis_control_flow1.erl:13: The call erlang:register +whereis_control_flow1.erl:13:18: The call erlang:register (AnAtom :: atom(), - Pid :: pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_control_flow1.erl on line 8 + Pid :: pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_control_flow1.erl on line {8,8} diff --git a/lib/dialyzer/test/map_SUITE_data/results/bad_argument b/lib/dialyzer/test/map_SUITE_data/results/bad_argument index af61a89638..c82b665915 100644 --- a/lib/dialyzer/test/map_SUITE_data/results/bad_argument +++ b/lib/dialyzer/test/map_SUITE_data/results/bad_argument @@ -1,5 +1,5 @@ -bad_argument.erl:14: Function t3/0 has no local return -bad_argument.erl:15: Guard test is_map('not_a_map') can never succeed -bad_argument.erl:5: Function t/0 has no local return -bad_argument.erl:6: A key of type 'b' cannot exist in a map of type #{'a':='q'} +bad_argument.erl:14:1: Function t3/0 has no local return +bad_argument.erl:15:6: Guard test is_map('not_a_map') can never succeed +bad_argument.erl:5:1: Function t/0 has no local return +bad_argument.erl:6:23: A key of type 'b' cannot exist in a map of type #{'a':='q'} diff --git a/lib/dialyzer/test/map_SUITE_data/results/contract b/lib/dialyzer/test/map_SUITE_data/results/contract index 620ec8e6b1..8a5112def8 100644 --- a/lib/dialyzer/test/map_SUITE_data/results/contract +++ b/lib/dialyzer/test/map_SUITE_data/results/contract @@ -1,7 +1,7 @@ -contract.erl:10: Function t2/0 has no local return -contract.erl:10: The call missing:f(#{'a'=>1, 'c'=>4}) breaks the contract (#{'a':=1,'b'=>2,'c'=>3}) -> 'ok' -contract.erl:12: Function t3/0 has no local return -contract.erl:12: The call missing:f(#{'a'=>1, 'b'=>2, 'e'=>3}) breaks the contract (#{'a':=1,'b'=>2,'c'=>3}) -> 'ok' -contract.erl:8: Function t1/0 has no local return -contract.erl:8: The call missing:f(#{'b'=>2}) breaks the contract (#{'a':=1,'b'=>2,'c'=>3}) -> 'ok' +contract.erl:10:11: The call missing:f(#{'a'=>1, 'c'=>4}) breaks the contract (#{'a':=1,'b'=>2,'c'=>3}) -> 'ok' +contract.erl:10:1: Function t2/0 has no local return +contract.erl:12:11: The call missing:f(#{'a'=>1, 'b'=>2, 'e'=>3}) breaks the contract (#{'a':=1,'b'=>2,'c'=>3}) -> 'ok' +contract.erl:12:1: Function t3/0 has no local return +contract.erl:8:11: The call missing:f(#{'b'=>2}) breaks the contract (#{'a':=1,'b'=>2,'c'=>3}) -> 'ok' +contract.erl:8:1: Function t1/0 has no local return diff --git a/lib/dialyzer/test/map_SUITE_data/results/contract_violation b/lib/dialyzer/test/map_SUITE_data/results/contract_violation index 958321618f..d0dd42a900 100644 --- a/lib/dialyzer/test/map_SUITE_data/results/contract_violation +++ b/lib/dialyzer/test/map_SUITE_data/results/contract_violation @@ -1,3 +1,3 @@ -contract_violation.erl:12: The pattern #{I:=Loc} can never match the type #{} -contract_violation.erl:16: Invalid type specification for function contract_violation:beam_disasm_lines/2. The success typing is ('none' | <<_:32,_:_*8>>,_) -> #{pos_integer()=>{'location',_,_}} +contract_violation.erl:12:2: The pattern #{I:=Loc} can never match the type #{} +contract_violation.erl:16:2: Invalid type specification for function contract_violation:beam_disasm_lines/2. The success typing is ('none' | <<_:32,_:_*8>>,_) -> #{pos_integer()=>{'location',_,_}} diff --git a/lib/dialyzer/test/map_SUITE_data/results/exact b/lib/dialyzer/test/map_SUITE_data/results/exact index ea00e61330..115a2cbe1c 100644 --- a/lib/dialyzer/test/map_SUITE_data/results/exact +++ b/lib/dialyzer/test/map_SUITE_data/results/exact @@ -1,3 +1,3 @@ -exact.erl:15: Function t2/1 has no local return -exact.erl:19: The variable _ can never match since previous clauses completely covered the type #{'a':=_, _=>_} +exact.erl:15:1: Function t2/1 has no local return +exact.erl:19:2: The variable _ can never match since previous clauses completely covered the type #{'a':=_, _=>_} diff --git a/lib/dialyzer/test/map_SUITE_data/results/guard_update b/lib/dialyzer/test/map_SUITE_data/results/guard_update index f6de2158fc..c22bd28cb0 100644 --- a/lib/dialyzer/test/map_SUITE_data/results/guard_update +++ b/lib/dialyzer/test/map_SUITE_data/results/guard_update @@ -1,5 +1,5 @@ -guard_update.erl:5: Function t/0 has no local return -guard_update.erl:6: The call guard_update:f(#{'a'=>2}) will never return since it differs in the 1st argument from the success typing arguments: (#{'b':=_, _=>_}) -guard_update.erl:8: Clause guard cannot succeed. The variable M was matched against the type #{'a':=2} -guard_update.erl:8: Function f/1 has no local return +guard_update.erl:5:1: Function t/0 has no local return +guard_update.erl:6:7: The call guard_update:f(#{'a'=>2}) will never return since it differs in the 1st argument from the success typing arguments: (#{'b':=_, _=>_}) +guard_update.erl:8:1: Clause guard cannot succeed. The variable M was matched against the type #{'a':=2} +guard_update.erl:8:1: Function f/1 has no local return diff --git a/lib/dialyzer/test/map_SUITE_data/results/initial_dataflow b/lib/dialyzer/test/map_SUITE_data/results/initial_dataflow index 69144f9208..b12b214218 100644 --- a/lib/dialyzer/test/map_SUITE_data/results/initial_dataflow +++ b/lib/dialyzer/test/map_SUITE_data/results/initial_dataflow @@ -1,4 +1,4 @@ -initial_dataflow.erl:11: The variable Q can never match since previous clauses completely covered the type #{} -initial_dataflow.erl:5: Function test/0 has no local return -initial_dataflow.erl:6: The pattern 'false' can never match the type 'true' +initial_dataflow.erl:11:1: The variable Q can never match since previous clauses completely covered the type #{} +initial_dataflow.erl:5:1: Function test/0 has no local return +initial_dataflow.erl:6:5: The pattern 'false' can never match the type 'true' diff --git a/lib/dialyzer/test/map_SUITE_data/results/is_map_guard b/lib/dialyzer/test/map_SUITE_data/results/is_map_guard index 6ab464d865..6a106a5fd1 100644 --- a/lib/dialyzer/test/map_SUITE_data/results/is_map_guard +++ b/lib/dialyzer/test/map_SUITE_data/results/is_map_guard @@ -1,5 +1,5 @@ -is_map_guard.erl:13: Function t2/0 has no local return -is_map_guard.erl:15: The call is_map_guard:explicit('still_not_map') will never return since it differs in the 1st argument from the success typing arguments: (map()) -is_map_guard.erl:6: Function t1/0 has no local return -is_map_guard.erl:8: The call is_map_guard:implicit('not_a_map') will never return since it differs in the 1st argument from the success typing arguments: (map()) +is_map_guard.erl:13:1: Function t2/0 has no local return +is_map_guard.erl:15:14: The call is_map_guard:explicit('still_not_map') will never return since it differs in the 1st argument from the success typing arguments: (map()) +is_map_guard.erl:6:1: Function t1/0 has no local return +is_map_guard.erl:8:14: The call is_map_guard:implicit('not_a_map') will never return since it differs in the 1st argument from the success typing arguments: (map()) diff --git a/lib/dialyzer/test/map_SUITE_data/results/loop b/lib/dialyzer/test/map_SUITE_data/results/loop index 2e956a5709..aaa8a676e8 100644 --- a/lib/dialyzer/test/map_SUITE_data/results/loop +++ b/lib/dialyzer/test/map_SUITE_data/results/loop @@ -1,4 +1,4 @@ -loop.erl:63: The call loop:start_timer(#loop{state::'idle' | 'waiting',queues::#{'category1'=>#queue{limit::non_neg_integer(),buffer::[any()]}, 'category2'=>#queue{limit::non_neg_integer(),buffer::[any()]}},counters::#{'counter1':=10, 2:=10}}) does not have a term of type #loop{state::'idle' | 'waiting',timer::timer:tref(),queues::#{'category1'=>#queue{limit::non_neg_integer(),buffer::[any()]}, 'category2'=>#queue{limit::non_neg_integer(),buffer::[any()]}},counters::#{'counter1'=>non_neg_integer(), 2=>non_neg_integer()}} (with opaque subterms) as 1st argument -loop.erl:67: Function wait/1 has no local return -loop.erl:85: Record construction #loop{state::'idle' | 'waiting',timer::{'error',_} | {'ok',timer:tref()},queues::#{'category1'=>#queue{limit::non_neg_integer(),buffer::[any()]}, 'category2'=>#queue{limit::non_neg_integer(),buffer::[any()]}},counters::#{'counter1'=>non_neg_integer(), 2=>non_neg_integer()}} violates the declared type of field timer::'undefined' | timer:tref() +loop.erl:63:27: The call loop:start_timer(#loop{state::'idle' | 'waiting',queues::#{'category1'=>#queue{limit::non_neg_integer(),buffer::[any()]}, 'category2'=>#queue{limit::non_neg_integer(),buffer::[any()]}},counters::#{'counter1':=10, 2:=10}}) does not have a term of type #loop{state::'idle' | 'waiting',timer::timer:tref(),queues::#{'category1'=>#queue{limit::non_neg_integer(),buffer::[any()]}, 'category2'=>#queue{limit::non_neg_integer(),buffer::[any()]}},counters::#{'counter1'=>non_neg_integer(), 2=>non_neg_integer()}} (with opaque subterms) as 1st argument +loop.erl:67:1: Function wait/1 has no local return +loop.erl:85:24: Record construction #loop{state::'idle' | 'waiting',timer::{'error',_} | {'ok',timer:tref()},queues::#{'category1'=>#queue{limit::non_neg_integer(),buffer::[any()]}, 'category2'=>#queue{limit::non_neg_integer(),buffer::[any()]}},counters::#{'counter1'=>non_neg_integer(), 2=>non_neg_integer()}} violates the declared type of field timer::'undefined' | timer:tref() diff --git a/lib/dialyzer/test/map_SUITE_data/results/map_anon_fun b/lib/dialyzer/test/map_SUITE_data/results/map_anon_fun index cfca5b1407..59a64ad047 100644 --- a/lib/dialyzer/test/map_SUITE_data/results/map_anon_fun +++ b/lib/dialyzer/test/map_SUITE_data/results/map_anon_fun @@ -1,2 +1,2 @@ -map_anon_fun.erl:4: Function g/1 will never be called +map_anon_fun.erl:4:1: Function g/1 will never be called diff --git a/lib/dialyzer/test/map_SUITE_data/results/map_galore b/lib/dialyzer/test/map_SUITE_data/results/map_galore index 6d1f4ff2bf..25cfe920d8 100644 --- a/lib/dialyzer/test/map_SUITE_data/results/map_galore +++ b/lib/dialyzer/test/map_SUITE_data/results/map_galore @@ -1,28 +1,28 @@ -map_galore.erl:1000: A key of type 42 cannot exist in a map of type #{1:='a', 2:='b', 4:='d', 5:='e', float()=>'c' | 'v'} -map_galore.erl:1080: A key of type 'nonexisting' cannot exist in a map of type #{10:='a0', 11:='a1', 12:='a2', 13:='a3', 14:='a4', 15:='a5', 16:='a6', 17:='a7', 18:='a8', 19:='a9', 20:='b0', 21:='b1', 22:='b2', 23:='b3', 24:='b4', 25:='b5', 26:='b6', 27:='b7', 28:='b8', 29:='b9', 30:=[48 | 99,...], 31:=[49 | 99,...], 32:=[50 | 99,...], 33:=[51 | 99,...], 34:=[52 | 99,...], 35:=[53 | 99,...], 36:=[54 | 99,...], 37:=[55 | 99,...], 38:=[56 | 99,...], 39:=[57 | 99,...], <<_:16>> | [48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...] | float() | {[[48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...],...]} | #{'k16'=>'a6', 'k26'=>'b6', 'k36'=>[54 | 99,...], 'map'=>'key', 'one'=>'small', 'second'=>'small', 'third'=>'small', 10=>'a0', 11=>'a1', 12=>'a2', 13=>'a3', 14=>'a4', 15=>'a5', 16=>'a6', 17=>'a7', 18=>'a8', 19=>'a9', 20=>'b0', 21=>'b1', 22=>'b2', 23=>'b3', 24=>'b4', 25=>'b5', 26=>'b6', 27=>'b7', 28=>'b8', 29=>'b9', 30=>[48 | 99,...], 31=>[49 | 99,...], 32=>[50 | 99,...], 33=>[51 | 99,...], 34=>[52 | 99,...], 35=>[53 | 99,...], 36=>[54 | 99,...], 37=>[55 | 99,...], 38=>[56 | 99,...], 39=>[57 | 99,...], <<_:16>> | [48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...] | {[[48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...],...]}=>[48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 100 | 101,...]}=>atom() | [1..255,...]} -map_galore.erl:1082: A key of type 42 cannot exist in a map of type #{10:='a0', 11:='a1', 12:='a2', 13:='a3', 14:='a4', 15:='a5', 16:='a6', 17:='a7', 18:='a8', 19:='a9', 20:='b0', 21:='b1', 22:='b2', 23:='b3', 24:='b4', 25:='b5', 26:='b6', 27:='b7', 28:='b8', 29:='b9', 30:=[48 | 99,...], 31:=[49 | 99,...], 32:=[50 | 99,...], 33:=[51 | 99,...], 34:=[52 | 99,...], 35:=[53 | 99,...], 36:=[54 | 99,...], 37:=[55 | 99,...], 38:=[56 | 99,...], 39:=[57 | 99,...], <<_:16>> | [48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...] | float() | {[[48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...],...]} | #{'k16'=>'a6', 'k26'=>'b6', 'k36'=>[54 | 99,...], 'map'=>'key', 'one'=>'small', 'second'=>'small', 'third'=>'small', 10=>'a0', 11=>'a1', 12=>'a2', 13=>'a3', 14=>'a4', 15=>'a5', 16=>'a6', 17=>'a7', 18=>'a8', 19=>'a9', 20=>'b0', 21=>'b1', 22=>'b2', 23=>'b3', 24=>'b4', 25=>'b5', 26=>'b6', 27=>'b7', 28=>'b8', 29=>'b9', 30=>[48 | 99,...], 31=>[49 | 99,...], 32=>[50 | 99,...], 33=>[51 | 99,...], 34=>[52 | 99,...], 35=>[53 | 99,...], 36=>[54 | 99,...], 37=>[55 | 99,...], 38=>[56 | 99,...], 39=>[57 | 99,...], <<_:16>> | [48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...] | {[[48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...],...]}=>[48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 100 | 101,...]}=>atom() | [1..255,...]} -map_galore.erl:1140: The call map_galore:map_guard_sequence_1(#{'seq'=>6, 'val'=>"e"}) will never return since it differs in the 1st argument from the success typing arguments: (#{'seq':=1 | 2 | 3 | 4 | 5, 'val':=[97 | 98 | 99 | 100 | 101,...], 10=>'a0', 11=>'a1', 12=>'a2', 13=>'a3', 14=>'a4', 15=>'a5', 16=>'a6', 17=>'a7', 18=>'a8', 19=>'a9', 20=>'b0', 21=>'b1', 22=>'b2', 23=>'b3', 24=>'b4', 25=>'b5', 26=>'b6', 27=>'b7', 28=>'b8', 29=>'b9', 30=>[48 | 99,...], 31=>[49 | 99,...], 32=>[50 | 99,...], 33=>[51 | 99,...], 34=>[52 | 99,...], 35=>[53 | 99,...], 36=>[54 | 99,...], 37=>[55 | 99,...], 38=>[56 | 99,...], 39=>[57 | 99,...], <<_:16>> | [48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...] | float() | {[any(),...]} | #{'k16'=>'a6', 'k26'=>'b6', 'k36'=>[any(),...], 'map'=>'key', 'one'=>'small', 'second'=>'small', 'third'=>'small', 10=>'a0', 11=>'a1', 12=>'a2', 13=>'a3', 14=>'a4', 15=>'a5', 16=>'a6', 17=>'a7', 18=>'a8', 19=>'a9', 20=>'b0', 21=>'b1', 22=>'b2', 23=>'b3', 24=>'b4', 25=>'b5', 26=>'b6', 27=>'b7', 28=>'b8', 29=>'b9', 30=>[any(),...], 31=>[any(),...], 32=>[any(),...], 33=>[any(),...], 34=>[any(),...], 35=>[any(),...], 36=>[any(),...], 37=>[any(),...], 38=>[any(),...], 39=>[any(),...], <<_:16>> | [any(),...] | {_}=>[any(),...]}=>atom() | [1..255,...]}) -map_galore.erl:1141: The call map_galore:map_guard_sequence_2(#{'b'=>5}) will never return since it differs in the 1st argument from the success typing arguments: (#{'a':='gg' | 'kk' | 'sc' | 3 | 4, 'b'=>'other' | 3 | 4 | 5, 'c'=>'sc2', 10=>'a0', 11=>'a1', 12=>'a2', 13=>'a3', 14=>'a4', 15=>'a5', 16=>'a6', 17=>'a7', 18=>'a8', 19=>'a9', 20=>'b0', 21=>'b1', 22=>'b2', 23=>'b3', 24=>'b4', 25=>'b5', 26=>'b6', 27=>'b7', 28=>'b8', 29=>'b9', 30=>[48 | 99,...], 31=>[49 | 99,...], 32=>[50 | 99,...], 33=>[51 | 99,...], 34=>[52 | 99,...], 35=>[53 | 99,...], 36=>[54 | 99,...], 37=>[55 | 99,...], 38=>[56 | 99,...], 39=>[57 | 99,...], <<_:16>> | [48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...] | float() | {[any(),...]} | #{'k16'=>'a6', 'k26'=>'b6', 'k36'=>[any(),...], 'map'=>'key', 'one'=>'small', 'second'=>'small', 'third'=>'small', 10=>'a0', 11=>'a1', 12=>'a2', 13=>'a3', 14=>'a4', 15=>'a5', 16=>'a6', 17=>'a7', 18=>'a8', 19=>'a9', 20=>'b0', 21=>'b1', 22=>'b2', 23=>'b3', 24=>'b4', 25=>'b5', 26=>'b6', 27=>'b7', 28=>'b8', 29=>'b9', 30=>[any(),...], 31=>[any(),...], 32=>[any(),...], 33=>[any(),...], 34=>[any(),...], 35=>[any(),...], 36=>[any(),...], 37=>[any(),...], 38=>[any(),...], 39=>[any(),...], <<_:16>> | [any(),...] | {_}=>[any(),...]}=>atom() | [1..255,...]}) -map_galore.erl:1209: The call map_galore:map_guard_sequence_1(#{'seq':=6, 'val':=[101,...], 10:='a0', 11:='a1', 12:='a2', 13:='a3', 14:='a4', 15:='a5', 16:='a6', 17:='a7', 18:='a8', 19:='a9', 20:='b0', 21:='b1', 22:='b2', 23:='b3', 24:='b4', 25:='b5', 26:='b6', 27:='b7', 28:='b8', 29:='b9', 30:=[48 | 99,...], 31:=[49 | 99,...], 32:=[50 | 99,...], 33:=[51 | 99,...], 34:=[52 | 99,...], 35:=[53 | 99,...], 36:=[54 | 99,...], 37:=[55 | 99,...], 38:=[56 | 99,...], 39:=[57 | 99,...], <<_:16>> | [48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...] | float() | {[[48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...] | 3,...]} | #{'k16'=>'a6', 'k26'=>'b6', 'k36'=>[54 | 99,...], 'map'=>'key', 'one'=>'small', 'second'=>'small', 'third'=>'small', 10=>'a0', 11=>'a1', 12=>'a2', 13=>'a3', 14=>'a4', 15=>'a5', 16=>'a6', 17=>'a7', 18=>'a8', 19=>'a9', 20=>'b0', 21=>'b1', 22=>'b2', 23=>'b3', 24=>'b4', 25=>'b5', 26=>'b6', 27=>'b7', 28=>'b8', 29=>'b9', 30=>[48 | 99,...], 31=>[49 | 99,...], 32=>[50 | 99,...], 33=>[51 | 99,...], 34=>[52 | 99,...], 35=>[53 | 99,...], 36=>[54 | 99,...], 37=>[55 | 99,...], 38=>[56 | 99,...], 39=>[57 | 99,...], <<_:16>> | [48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...] | {[[48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...],...]}=>[48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 100 | 101,...]}=>atom() | [1..255,...]}) will never return since it differs in the 1st argument from the success typing arguments: (#{'seq':=1 | 2 | 3 | 4 | 5, 'val':=[97 | 98 | 99 | 100 | 101,...], 10=>'a0', 11=>'a1', 12=>'a2', 13=>'a3', 14=>'a4', 15=>'a5', 16=>'a6', 17=>'a7', 18=>'a8', 19=>'a9', 20=>'b0', 21=>'b1', 22=>'b2', 23=>'b3', 24=>'b4', 25=>'b5', 26=>'b6', 27=>'b7', 28=>'b8', 29=>'b9', 30=>[48 | 99,...], 31=>[49 | 99,...], 32=>[50 | 99,...], 33=>[51 | 99,...], 34=>[52 | 99,...], 35=>[53 | 99,...], 36=>[54 | 99,...], 37=>[55 | 99,...], 38=>[56 | 99,...], 39=>[57 | 99,...], <<_:16>> | [48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...] | float() | {[any(),...]} | #{'k16'=>'a6', 'k26'=>'b6', 'k36'=>[any(),...], 'map'=>'key', 'one'=>'small', 'second'=>'small', 'third'=>'small', 10=>'a0', 11=>'a1', 12=>'a2', 13=>'a3', 14=>'a4', 15=>'a5', 16=>'a6', 17=>'a7', 18=>'a8', 19=>'a9', 20=>'b0', 21=>'b1', 22=>'b2', 23=>'b3', 24=>'b4', 25=>'b5', 26=>'b6', 27=>'b7', 28=>'b8', 29=>'b9', 30=>[any(),...], 31=>[any(),...], 32=>[any(),...], 33=>[any(),...], 34=>[any(),...], 35=>[any(),...], 36=>[any(),...], 37=>[any(),...], 38=>[any(),...], 39=>[any(),...], <<_:16>> | [any(),...] | {_}=>[any(),...]}=>atom() | [1..255,...]}) -map_galore.erl:1210: The call map_galore:map_guard_sequence_2(#{'b':=5, 10:='a0', 11:='a1', 12:='a2', 13:='a3', 14:='a4', 15:='a5', 16:='a6', 17:='a7', 18:='a8', 19:='a9', 20:='b0', 21:='b1', 22:='b2', 23:='b3', 24:='b4', 25:='b5', 26:='b6', 27:='b7', 28:='b8', 29:='b9', 30:=[48 | 99,...], 31:=[49 | 99,...], 32:=[50 | 99,...], 33:=[51 | 99,...], 34:=[52 | 99,...], 35:=[53 | 99,...], 36:=[54 | 99,...], 37:=[55 | 99,...], 38:=[56 | 99,...], 39:=[57 | 99,...], <<_:16>> | [48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...] | float() | {[[48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...] | 3,...]} | #{'k16'=>'a6', 'k26'=>'b6', 'k36'=>[54 | 99,...], 'map'=>'key', 'one'=>'small', 'second'=>'small', 'third'=>'small', 10=>'a0', 11=>'a1', 12=>'a2', 13=>'a3', 14=>'a4', 15=>'a5', 16=>'a6', 17=>'a7', 18=>'a8', 19=>'a9', 20=>'b0', 21=>'b1', 22=>'b2', 23=>'b3', 24=>'b4', 25=>'b5', 26=>'b6', 27=>'b7', 28=>'b8', 29=>'b9', 30=>[48 | 99,...], 31=>[49 | 99,...], 32=>[50 | 99,...], 33=>[51 | 99,...], 34=>[52 | 99,...], 35=>[53 | 99,...], 36=>[54 | 99,...], 37=>[55 | 99,...], 38=>[56 | 99,...], 39=>[57 | 99,...], <<_:16>> | [48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...] | {[[48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...],...]}=>[48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 100 | 101,...]}=>atom() | [1..255,...]}) will never return since it differs in the 1st argument from the success typing arguments: (#{'a':='gg' | 'kk' | 'sc' | 3 | 4, 'b'=>'other' | 3 | 4 | 5, 'c'=>'sc2', 10=>'a0', 11=>'a1', 12=>'a2', 13=>'a3', 14=>'a4', 15=>'a5', 16=>'a6', 17=>'a7', 18=>'a8', 19=>'a9', 20=>'b0', 21=>'b1', 22=>'b2', 23=>'b3', 24=>'b4', 25=>'b5', 26=>'b6', 27=>'b7', 28=>'b8', 29=>'b9', 30=>[48 | 99,...], 31=>[49 | 99,...], 32=>[50 | 99,...], 33=>[51 | 99,...], 34=>[52 | 99,...], 35=>[53 | 99,...], 36=>[54 | 99,...], 37=>[55 | 99,...], 38=>[56 | 99,...], 39=>[57 | 99,...], <<_:16>> | [48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...] | float() | {[any(),...]} | #{'k16'=>'a6', 'k26'=>'b6', 'k36'=>[any(),...], 'map'=>'key', 'one'=>'small', 'second'=>'small', 'third'=>'small', 10=>'a0', 11=>'a1', 12=>'a2', 13=>'a3', 14=>'a4', 15=>'a5', 16=>'a6', 17=>'a7', 18=>'a8', 19=>'a9', 20=>'b0', 21=>'b1', 22=>'b2', 23=>'b3', 24=>'b4', 25=>'b5', 26=>'b6', 27=>'b7', 28=>'b8', 29=>'b9', 30=>[any(),...], 31=>[any(),...], 32=>[any(),...], 33=>[any(),...], 34=>[any(),...], 35=>[any(),...], 36=>[any(),...], 37=>[any(),...], 38=>[any(),...], 39=>[any(),...], <<_:16>> | [any(),...] | {_}=>[any(),...]}=>atom() | [1..255,...]}) -map_galore.erl:1418: Fun application with arguments (#{'s'=>'none', 'v'=>'none'}) will never return since it differs in the 1st argument from the success typing arguments: (#{'s':='l' | 't' | 'v', 'v':='none' | <<_:16>> | [<<_:16>>,...] | {<<_:16>>,<<_:16>>}}) -map_galore.erl:1491: The test #{} =:= #{'a':=1} can never evaluate to 'true' -map_galore.erl:1492: The test #{'a':=1} =:= #{} can never evaluate to 'true' -map_galore.erl:1495: The test #{'a':=1} =:= #{'a':=2} can never evaluate to 'true' -map_galore.erl:1496: The test #{'a':=2} =:= #{'a':=1} can never evaluate to 'true' -map_galore.erl:1497: The test #{'a':=2, 'b':=1} =:= #{'a':=1, 'b':=3} can never evaluate to 'true' -map_galore.erl:1498: The test #{'a':=1, 'b':=1} =:= #{'a':=1, 'b':=3} can never evaluate to 'true' -map_galore.erl:1762: The call maps:get({1, 1},#{{1,float()}=>[101 | 108 | 112 | 116 | 117,...]}) will never return since the success typing arguments are (any(),map()) -map_galore.erl:1763: The call maps:get('a',#{}) will never return since the success typing arguments are (any(),map()) -map_galore.erl:1765: The call maps:get('a',#{'b'=>1, 'c'=>2}) will never return since the success typing arguments are (any(),map()) -map_galore.erl:186: The pattern #{'x':=2} can never match the type #{'x':=3} -map_galore.erl:187: The pattern #{'x':=3} can never match the type {'a','b','c'} -map_galore.erl:188: The pattern #{'x':=3} can never match the type #{'y':=3} -map_galore.erl:189: The pattern #{'x':=3} can never match the type #{'x':=[101 | 104 | 114 | 116,...]} -map_galore.erl:2280: Cons will produce an improper list since its 2nd argument is {'b','a'} -map_galore.erl:2280: The call maps:from_list([{'a', 'b'} | {'b', 'a'}]) will never return since it differs in the 1st argument from the success typing arguments: ([{_,_}]) -map_galore.erl:2281: The call maps:from_list('a') will never return since it differs in the 1st argument from the success typing arguments: ([{_,_}]) -map_galore.erl:2282: The call maps:from_list(42) will never return since it differs in the 1st argument from the success typing arguments: ([{_,_}]) -map_galore.erl:997: A key of type 'nonexisting' cannot exist in a map of type #{} -map_galore.erl:998: A key of type 'nonexisting' cannot exist in a map of type #{1:='a', 2:='b', 4:='d', 5:='e', float()=>'c'} +map_galore.erl:1000:51: A key of type 42 cannot exist in a map of type #{1:='a', 2:='b', 4:='d', 5:='e', float()=>'c' | 'v'} +map_galore.erl:1080:52: A key of type 'nonexisting' cannot exist in a map of type #{10:='a0', 11:='a1', 12:='a2', 13:='a3', 14:='a4', 15:='a5', 16:='a6', 17:='a7', 18:='a8', 19:='a9', 20:='b0', 21:='b1', 22:='b2', 23:='b3', 24:='b4', 25:='b5', 26:='b6', 27:='b7', 28:='b8', 29:='b9', 30:=[48 | 99,...], 31:=[49 | 99,...], 32:=[50 | 99,...], 33:=[51 | 99,...], 34:=[52 | 99,...], 35:=[53 | 99,...], 36:=[54 | 99,...], 37:=[55 | 99,...], 38:=[56 | 99,...], 39:=[57 | 99,...], <<_:16>> | [48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...] | float() | {[[48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...],...]} | #{'k16'=>'a6', 'k26'=>'b6', 'k36'=>[54 | 99,...], 'map'=>'key', 'one'=>'small', 'second'=>'small', 'third'=>'small', 10=>'a0', 11=>'a1', 12=>'a2', 13=>'a3', 14=>'a4', 15=>'a5', 16=>'a6', 17=>'a7', 18=>'a8', 19=>'a9', 20=>'b0', 21=>'b1', 22=>'b2', 23=>'b3', 24=>'b4', 25=>'b5', 26=>'b6', 27=>'b7', 28=>'b8', 29=>'b9', 30=>[48 | 99,...], 31=>[49 | 99,...], 32=>[50 | 99,...], 33=>[51 | 99,...], 34=>[52 | 99,...], 35=>[53 | 99,...], 36=>[54 | 99,...], 37=>[55 | 99,...], 38=>[56 | 99,...], 39=>[57 | 99,...], <<_:16>> | [48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...] | {[[48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...],...]}=>[48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 100 | 101,...]}=>atom() | [1..255,...]} +map_galore.erl:1082:51: A key of type 42 cannot exist in a map of type #{10:='a0', 11:='a1', 12:='a2', 13:='a3', 14:='a4', 15:='a5', 16:='a6', 17:='a7', 18:='a8', 19:='a9', 20:='b0', 21:='b1', 22:='b2', 23:='b3', 24:='b4', 25:='b5', 26:='b6', 27:='b7', 28:='b8', 29:='b9', 30:=[48 | 99,...], 31:=[49 | 99,...], 32:=[50 | 99,...], 33:=[51 | 99,...], 34:=[52 | 99,...], 35:=[53 | 99,...], 36:=[54 | 99,...], 37:=[55 | 99,...], 38:=[56 | 99,...], 39:=[57 | 99,...], <<_:16>> | [48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...] | float() | {[[48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...],...]} | #{'k16'=>'a6', 'k26'=>'b6', 'k36'=>[54 | 99,...], 'map'=>'key', 'one'=>'small', 'second'=>'small', 'third'=>'small', 10=>'a0', 11=>'a1', 12=>'a2', 13=>'a3', 14=>'a4', 15=>'a5', 16=>'a6', 17=>'a7', 18=>'a8', 19=>'a9', 20=>'b0', 21=>'b1', 22=>'b2', 23=>'b3', 24=>'b4', 25=>'b5', 26=>'b6', 27=>'b7', 28=>'b8', 29=>'b9', 30=>[48 | 99,...], 31=>[49 | 99,...], 32=>[50 | 99,...], 33=>[51 | 99,...], 34=>[52 | 99,...], 35=>[53 | 99,...], 36=>[54 | 99,...], 37=>[55 | 99,...], 38=>[56 | 99,...], 39=>[57 | 99,...], <<_:16>> | [48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...] | {[[48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...],...]}=>[48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 100 | 101,...]}=>atom() | [1..255,...]} +map_galore.erl:1140:61: The call map_galore:map_guard_sequence_1(#{'seq'=>6, 'val'=>"e"}) will never return since it differs in the 1st argument from the success typing arguments: (#{'seq':=1 | 2 | 3 | 4 | 5, 'val':=[97 | 98 | 99 | 100 | 101,...], 10=>'a0', 11=>'a1', 12=>'a2', 13=>'a3', 14=>'a4', 15=>'a5', 16=>'a6', 17=>'a7', 18=>'a8', 19=>'a9', 20=>'b0', 21=>'b1', 22=>'b2', 23=>'b3', 24=>'b4', 25=>'b5', 26=>'b6', 27=>'b7', 28=>'b8', 29=>'b9', 30=>[48 | 99,...], 31=>[49 | 99,...], 32=>[50 | 99,...], 33=>[51 | 99,...], 34=>[52 | 99,...], 35=>[53 | 99,...], 36=>[54 | 99,...], 37=>[55 | 99,...], 38=>[56 | 99,...], 39=>[57 | 99,...], <<_:16>> | [48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...] | float() | {[any(),...]} | #{'k16'=>'a6', 'k26'=>'b6', 'k36'=>[any(),...], 'map'=>'key', 'one'=>'small', 'second'=>'small', 'third'=>'small', 10=>'a0', 11=>'a1', 12=>'a2', 13=>'a3', 14=>'a4', 15=>'a5', 16=>'a6', 17=>'a7', 18=>'a8', 19=>'a9', 20=>'b0', 21=>'b1', 22=>'b2', 23=>'b3', 24=>'b4', 25=>'b5', 26=>'b6', 27=>'b7', 28=>'b8', 29=>'b9', 30=>[any(),...], 31=>[any(),...], 32=>[any(),...], 33=>[any(),...], 34=>[any(),...], 35=>[any(),...], 36=>[any(),...], 37=>[any(),...], 38=>[any(),...], 39=>[any(),...], <<_:16>> | [any(),...] | {_}=>[any(),...]}=>atom() | [1..255,...]}) +map_galore.erl:1141:61: The call map_galore:map_guard_sequence_2(#{'b'=>5}) will never return since it differs in the 1st argument from the success typing arguments: (#{'a':='gg' | 'kk' | 'sc' | 3 | 4, 'b'=>'other' | 3 | 4 | 5, 'c'=>'sc2', 10=>'a0', 11=>'a1', 12=>'a2', 13=>'a3', 14=>'a4', 15=>'a5', 16=>'a6', 17=>'a7', 18=>'a8', 19=>'a9', 20=>'b0', 21=>'b1', 22=>'b2', 23=>'b3', 24=>'b4', 25=>'b5', 26=>'b6', 27=>'b7', 28=>'b8', 29=>'b9', 30=>[48 | 99,...], 31=>[49 | 99,...], 32=>[50 | 99,...], 33=>[51 | 99,...], 34=>[52 | 99,...], 35=>[53 | 99,...], 36=>[54 | 99,...], 37=>[55 | 99,...], 38=>[56 | 99,...], 39=>[57 | 99,...], <<_:16>> | [48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...] | float() | {[any(),...]} | #{'k16'=>'a6', 'k26'=>'b6', 'k36'=>[any(),...], 'map'=>'key', 'one'=>'small', 'second'=>'small', 'third'=>'small', 10=>'a0', 11=>'a1', 12=>'a2', 13=>'a3', 14=>'a4', 15=>'a5', 16=>'a6', 17=>'a7', 18=>'a8', 19=>'a9', 20=>'b0', 21=>'b1', 22=>'b2', 23=>'b3', 24=>'b4', 25=>'b5', 26=>'b6', 27=>'b7', 28=>'b8', 29=>'b9', 30=>[any(),...], 31=>[any(),...], 32=>[any(),...], 33=>[any(),...], 34=>[any(),...], 35=>[any(),...], 36=>[any(),...], 37=>[any(),...], 38=>[any(),...], 39=>[any(),...], <<_:16>> | [any(),...] | {_}=>[any(),...]}=>atom() | [1..255,...]}) +map_galore.erl:1209:63: The call map_galore:map_guard_sequence_1(#{'seq':=6, 'val':=[101,...], 10:='a0', 11:='a1', 12:='a2', 13:='a3', 14:='a4', 15:='a5', 16:='a6', 17:='a7', 18:='a8', 19:='a9', 20:='b0', 21:='b1', 22:='b2', 23:='b3', 24:='b4', 25:='b5', 26:='b6', 27:='b7', 28:='b8', 29:='b9', 30:=[48 | 99,...], 31:=[49 | 99,...], 32:=[50 | 99,...], 33:=[51 | 99,...], 34:=[52 | 99,...], 35:=[53 | 99,...], 36:=[54 | 99,...], 37:=[55 | 99,...], 38:=[56 | 99,...], 39:=[57 | 99,...], <<_:16>> | [48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...] | float() | {[[48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...] | 3,...]} | #{'k16'=>'a6', 'k26'=>'b6', 'k36'=>[54 | 99,...], 'map'=>'key', 'one'=>'small', 'second'=>'small', 'third'=>'small', 10=>'a0', 11=>'a1', 12=>'a2', 13=>'a3', 14=>'a4', 15=>'a5', 16=>'a6', 17=>'a7', 18=>'a8', 19=>'a9', 20=>'b0', 21=>'b1', 22=>'b2', 23=>'b3', 24=>'b4', 25=>'b5', 26=>'b6', 27=>'b7', 28=>'b8', 29=>'b9', 30=>[48 | 99,...], 31=>[49 | 99,...], 32=>[50 | 99,...], 33=>[51 | 99,...], 34=>[52 | 99,...], 35=>[53 | 99,...], 36=>[54 | 99,...], 37=>[55 | 99,...], 38=>[56 | 99,...], 39=>[57 | 99,...], <<_:16>> | [48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...] | {[[48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...],...]}=>[48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 100 | 101,...]}=>atom() | [1..255,...]}) will never return since it differs in the 1st argument from the success typing arguments: (#{'seq':=1 | 2 | 3 | 4 | 5, 'val':=[97 | 98 | 99 | 100 | 101,...], 10=>'a0', 11=>'a1', 12=>'a2', 13=>'a3', 14=>'a4', 15=>'a5', 16=>'a6', 17=>'a7', 18=>'a8', 19=>'a9', 20=>'b0', 21=>'b1', 22=>'b2', 23=>'b3', 24=>'b4', 25=>'b5', 26=>'b6', 27=>'b7', 28=>'b8', 29=>'b9', 30=>[48 | 99,...], 31=>[49 | 99,...], 32=>[50 | 99,...], 33=>[51 | 99,...], 34=>[52 | 99,...], 35=>[53 | 99,...], 36=>[54 | 99,...], 37=>[55 | 99,...], 38=>[56 | 99,...], 39=>[57 | 99,...], <<_:16>> | [48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...] | float() | {[any(),...]} | #{'k16'=>'a6', 'k26'=>'b6', 'k36'=>[any(),...], 'map'=>'key', 'one'=>'small', 'second'=>'small', 'third'=>'small', 10=>'a0', 11=>'a1', 12=>'a2', 13=>'a3', 14=>'a4', 15=>'a5', 16=>'a6', 17=>'a7', 18=>'a8', 19=>'a9', 20=>'b0', 21=>'b1', 22=>'b2', 23=>'b3', 24=>'b4', 25=>'b5', 26=>'b6', 27=>'b7', 28=>'b8', 29=>'b9', 30=>[any(),...], 31=>[any(),...], 32=>[any(),...], 33=>[any(),...], 34=>[any(),...], 35=>[any(),...], 36=>[any(),...], 37=>[any(),...], 38=>[any(),...], 39=>[any(),...], <<_:16>> | [any(),...] | {_}=>[any(),...]}=>atom() | [1..255,...]}) +map_galore.erl:1210:63: The call map_galore:map_guard_sequence_2(#{'b':=5, 10:='a0', 11:='a1', 12:='a2', 13:='a3', 14:='a4', 15:='a5', 16:='a6', 17:='a7', 18:='a8', 19:='a9', 20:='b0', 21:='b1', 22:='b2', 23:='b3', 24:='b4', 25:='b5', 26:='b6', 27:='b7', 28:='b8', 29:='b9', 30:=[48 | 99,...], 31:=[49 | 99,...], 32:=[50 | 99,...], 33:=[51 | 99,...], 34:=[52 | 99,...], 35:=[53 | 99,...], 36:=[54 | 99,...], 37:=[55 | 99,...], 38:=[56 | 99,...], 39:=[57 | 99,...], <<_:16>> | [48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...] | float() | {[[48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...] | 3,...]} | #{'k16'=>'a6', 'k26'=>'b6', 'k36'=>[54 | 99,...], 'map'=>'key', 'one'=>'small', 'second'=>'small', 'third'=>'small', 10=>'a0', 11=>'a1', 12=>'a2', 13=>'a3', 14=>'a4', 15=>'a5', 16=>'a6', 17=>'a7', 18=>'a8', 19=>'a9', 20=>'b0', 21=>'b1', 22=>'b2', 23=>'b3', 24=>'b4', 25=>'b5', 26=>'b6', 27=>'b7', 28=>'b8', 29=>'b9', 30=>[48 | 99,...], 31=>[49 | 99,...], 32=>[50 | 99,...], 33=>[51 | 99,...], 34=>[52 | 99,...], 35=>[53 | 99,...], 36=>[54 | 99,...], 37=>[55 | 99,...], 38=>[56 | 99,...], 39=>[57 | 99,...], <<_:16>> | [48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...] | {[[48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...],...]}=>[48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 100 | 101,...]}=>atom() | [1..255,...]}) will never return since it differs in the 1st argument from the success typing arguments: (#{'a':='gg' | 'kk' | 'sc' | 3 | 4, 'b'=>'other' | 3 | 4 | 5, 'c'=>'sc2', 10=>'a0', 11=>'a1', 12=>'a2', 13=>'a3', 14=>'a4', 15=>'a5', 16=>'a6', 17=>'a7', 18=>'a8', 19=>'a9', 20=>'b0', 21=>'b1', 22=>'b2', 23=>'b3', 24=>'b4', 25=>'b5', 26=>'b6', 27=>'b7', 28=>'b8', 29=>'b9', 30=>[48 | 99,...], 31=>[49 | 99,...], 32=>[50 | 99,...], 33=>[51 | 99,...], 34=>[52 | 99,...], 35=>[53 | 99,...], 36=>[54 | 99,...], 37=>[55 | 99,...], 38=>[56 | 99,...], 39=>[57 | 99,...], <<_:16>> | [48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57,...] | float() | {[any(),...]} | #{'k16'=>'a6', 'k26'=>'b6', 'k36'=>[any(),...], 'map'=>'key', 'one'=>'small', 'second'=>'small', 'third'=>'small', 10=>'a0', 11=>'a1', 12=>'a2', 13=>'a3', 14=>'a4', 15=>'a5', 16=>'a6', 17=>'a7', 18=>'a8', 19=>'a9', 20=>'b0', 21=>'b1', 22=>'b2', 23=>'b3', 24=>'b4', 25=>'b5', 26=>'b6', 27=>'b7', 28=>'b8', 29=>'b9', 30=>[any(),...], 31=>[any(),...], 32=>[any(),...], 33=>[any(),...], 34=>[any(),...], 35=>[any(),...], 36=>[any(),...], 37=>[any(),...], 38=>[any(),...], 39=>[any(),...], <<_:16>> | [any(),...] | {_}=>[any(),...]}=>atom() | [1..255,...]}) +map_galore.erl:1418:84: Fun application with arguments (#{'s'=>'none', 'v'=>'none'}) will never return since it differs in the 1st argument from the success typing arguments: (#{'s':='l' | 't' | 'v', 'v':='none' | <<_:16>> | [<<_:16>>,...] | {<<_:16>>,<<_:16>>}}) +map_galore.erl:1491:13: The test #{} =:= #{'a':=1} can never evaluate to 'true' +map_galore.erl:1492:13: The test #{'a':=1} =:= #{} can never evaluate to 'true' +map_galore.erl:1495:13: The test #{'a':=1} =:= #{'a':=2} can never evaluate to 'true' +map_galore.erl:1496:13: The test #{'a':=2} =:= #{'a':=1} can never evaluate to 'true' +map_galore.erl:1497:13: The test #{'a':=2, 'b':=1} =:= #{'a':=1, 'b':=3} can never evaluate to 'true' +map_galore.erl:1498:13: The test #{'a':=1, 'b':=1} =:= #{'a':=1, 'b':=3} can never evaluate to 'true' +map_galore.erl:1762:9: The call maps:get({1, 1},#{{1,float()}=>[101 | 108 | 112 | 116 | 117,...]}) will never return since the success typing arguments are (any(),map()) +map_galore.erl:1763:55: The call maps:get('a',#{}) will never return since the success typing arguments are (any(),map()) +map_galore.erl:1765:9: The call maps:get('a',#{'b'=>1, 'c'=>2}) will never return since the success typing arguments are (any(),map()) +map_galore.erl:186:41: The pattern #{'x':=2} can never match the type #{'x':=3} +map_galore.erl:187:41: The pattern #{'x':=3} can never match the type {'a','b','c'} +map_galore.erl:188:41: The pattern #{'x':=3} can never match the type #{'y':=3} +map_galore.erl:189:41: The pattern #{'x':=3} can never match the type #{'x':=[101 | 104 | 114 | 116,...]} +map_galore.erl:2280:50: Cons will produce an improper list since its 2nd argument is {'b','a'} +map_galore.erl:2280:50: The call maps:from_list([{'a', 'b'} | {'b', 'a'}]) will never return since it differs in the 1st argument from the success typing arguments: ([{_,_}]) +map_galore.erl:2281:50: The call maps:from_list('a') will never return since it differs in the 1st argument from the success typing arguments: ([{_,_}]) +map_galore.erl:2282:50: The call maps:from_list(42) will never return since it differs in the 1st argument from the success typing arguments: ([{_,_}]) +map_galore.erl:997:55: A key of type 'nonexisting' cannot exist in a map of type #{} +map_galore.erl:998:52: A key of type 'nonexisting' cannot exist in a map of type #{1:='a', 2:='b', 4:='d', 5:='e', float()=>'c'} diff --git a/lib/dialyzer/test/map_SUITE_data/results/map_in_guard b/lib/dialyzer/test/map_SUITE_data/results/map_in_guard index 1015f76128..47c68406c7 100644 --- a/lib/dialyzer/test/map_SUITE_data/results/map_in_guard +++ b/lib/dialyzer/test/map_SUITE_data/results/map_in_guard @@ -1,4 +1,4 @@ -map_in_guard.erl:10: The call map_in_guard:assoc_update('not_a_map') will never return since it differs in the 1st argument from the success typing arguments: (#{}) -map_in_guard.erl:13: The call map_in_guard:assoc_guard_clause('not_a_map') will never return since it differs in the 1st argument from the success typing arguments: (#{}) -map_in_guard.erl:20: The call map_in_guard:exact_guard_clause(#{}) will never return since it differs in the 1st argument from the success typing arguments: (#{'a':='q'}) +map_in_guard.erl:10:24: The call map_in_guard:assoc_update('not_a_map') will never return since it differs in the 1st argument from the success typing arguments: (#{}) +map_in_guard.erl:13:30: The call map_in_guard:assoc_guard_clause('not_a_map') will never return since it differs in the 1st argument from the success typing arguments: (#{}) +map_in_guard.erl:20:30: The call map_in_guard:exact_guard_clause(#{}) will never return since it differs in the 1st argument from the success typing arguments: (#{'a':='q'}) diff --git a/lib/dialyzer/test/map_SUITE_data/results/map_in_guard2 b/lib/dialyzer/test/map_SUITE_data/results/map_in_guard2 index 46e2e8d36c..bd28896390 100644 --- a/lib/dialyzer/test/map_SUITE_data/results/map_in_guard2 +++ b/lib/dialyzer/test/map_SUITE_data/results/map_in_guard2 @@ -1,13 +1,13 @@ -map_in_guard2.erl:10: The call map_in_guard2:assoc_guard_clause('not_a_map') will never return since it differs in the 1st argument from the success typing arguments: (map()) -map_in_guard2.erl:12: The pattern 'true' can never match the type 'false' -map_in_guard2.erl:14: The call map_in_guard2:exact_guard_clause(#{}) will never return since it differs in the 1st argument from the success typing arguments: (#{'a':=_, _=>_}) -map_in_guard2.erl:17: Guard test is_map(M::'not_a_map') can never succeed -map_in_guard2.erl:20: Function assoc_update/1 has no local return -map_in_guard2.erl:20: Guard test is_map(M::'not_a_map') can never succeed -map_in_guard2.erl:22: Function assoc_guard_clause/1 has no local return -map_in_guard2.erl:22: Guard test is_map(M::'not_a_map') can never succeed -map_in_guard2.erl:24: Clause guard cannot succeed. The variable M was matched against the type #{} -map_in_guard2.erl:27: Clause guard cannot succeed. The variable M was matched against the type #{} -map_in_guard2.erl:27: Function exact_guard_clause/1 has no local return -map_in_guard2.erl:8: The call map_in_guard2:assoc_update('not_a_map') will never return since it differs in the 1st argument from the success typing arguments: (map()) +map_in_guard2.erl:10:30: The call map_in_guard2:assoc_guard_clause('not_a_map') will never return since it differs in the 1st argument from the success typing arguments: (map()) +map_in_guard2.erl:12:18: The pattern 'true' can never match the type 'false' +map_in_guard2.erl:14:30: The call map_in_guard2:exact_guard_clause(#{}) will never return since it differs in the 1st argument from the success typing arguments: (#{'a':=_, _=>_}) +map_in_guard2.erl:17:28: Guard test is_map(M::'not_a_map') can never succeed +map_in_guard2.erl:20:1: Function assoc_update/1 has no local return +map_in_guard2.erl:20:20: Guard test is_map(M::'not_a_map') can never succeed +map_in_guard2.erl:22:1: Function assoc_guard_clause/1 has no local return +map_in_guard2.erl:22:35: Guard test is_map(M::'not_a_map') can never succeed +map_in_guard2.erl:24:1: Clause guard cannot succeed. The variable M was matched against the type #{} +map_in_guard2.erl:27:1: Clause guard cannot succeed. The variable M was matched against the type #{} +map_in_guard2.erl:27:1: Function exact_guard_clause/1 has no local return +map_in_guard2.erl:8:24: The call map_in_guard2:assoc_update('not_a_map') will never return since it differs in the 1st argument from the success typing arguments: (map()) diff --git a/lib/dialyzer/test/map_SUITE_data/results/map_size b/lib/dialyzer/test/map_SUITE_data/results/map_size index fc6c1f028c..e049076863 100644 --- a/lib/dialyzer/test/map_SUITE_data/results/map_size +++ b/lib/dialyzer/test/map_SUITE_data/results/map_size @@ -1,13 +1,13 @@ -map_size.erl:11: The pattern 1 can never match the type 0 -map_size.erl:13: Function t2/0 has no local return -map_size.erl:15: Function p/1 has no local return -map_size.erl:15: Guard test 1 =:= 0 can never succeed -map_size.erl:17: Function t3/0 has no local return -map_size.erl:21: The pattern 4 can never match the type 1 | 2 | 3 -map_size.erl:23: Function t4/0 has no local return -map_size.erl:24: The pattern 0 can never match the type 1 | 2 | 3 -map_size.erl:26: Function t5/1 has no local return -map_size.erl:5: Function t1/0 has no local return -map_size.erl:7: The pattern 1 can never match the type 0 -map_size.erl:9: Function e1/0 has no local return +map_size.erl:11:5: The pattern 1 can never match the type 0 +map_size.erl:13:1: Function t2/0 has no local return +map_size.erl:15:11: Guard test 1 =:= 0 can never succeed +map_size.erl:15:1: Function p/1 has no local return +map_size.erl:17:1: Function t3/0 has no local return +map_size.erl:21:5: The pattern 4 can never match the type 1 | 2 | 3 +map_size.erl:23:1: Function t4/0 has no local return +map_size.erl:24:5: The pattern 0 can never match the type 1 | 2 | 3 +map_size.erl:26:1: Function t5/1 has no local return +map_size.erl:5:1: Function t1/0 has no local return +map_size.erl:7:5: The pattern 1 can never match the type 0 +map_size.erl:9:1: Function e1/0 has no local return diff --git a/lib/dialyzer/test/map_SUITE_data/results/maps_merge b/lib/dialyzer/test/map_SUITE_data/results/maps_merge index 0c347b4cdb..e9964b266e 100644 --- a/lib/dialyzer/test/map_SUITE_data/results/maps_merge +++ b/lib/dialyzer/test/map_SUITE_data/results/maps_merge @@ -1,11 +1,11 @@ -maps_merge.erl:10: The pattern #{_:=_} can never match the type #{'a':=1, 3:='ok', 'q'=>none(), 7=>none(), atom() | integer()=>_} -maps_merge.erl:12: Function t3/0 has no local return -maps_merge.erl:14: The pattern #{7:='q'} can never match the type #{'a':=1, 3:='ok', 'q'=>none(), 7=>none(), atom() | integer()=>_} -maps_merge.erl:16: Function t4/0 has no local return -maps_merge.erl:18: The pattern #{7:='q'} can never match the type #{'a':=1, 3:='ok', 'q'=>none(), 7=>none(), atom() | integer()=>_} -maps_merge.erl:20: Function t5/0 has no local return -maps_merge.erl:21: The pattern #{'a':=2} can never match the type #{'a':=1, 'q'=>none(), 11=>_, atom()=>_} -maps_merge.erl:5: Function t1/0 has no local return -maps_merge.erl:6: The pattern #{'a':=1} can never match the type #{} -maps_merge.erl:8: Function t2/0 has no local return +maps_merge.erl:10:5: The pattern #{_:=_} can never match the type #{'a':=1, 3:='ok', 'q'=>none(), 7=>none(), atom() | integer()=>_} +maps_merge.erl:12:1: Function t3/0 has no local return +maps_merge.erl:14:5: The pattern #{7:='q'} can never match the type #{'a':=1, 3:='ok', 'q'=>none(), 7=>none(), atom() | integer()=>_} +maps_merge.erl:16:1: Function t4/0 has no local return +maps_merge.erl:18:5: The pattern #{7:='q'} can never match the type #{'a':=1, 3:='ok', 'q'=>none(), 7=>none(), atom() | integer()=>_} +maps_merge.erl:20:1: Function t5/0 has no local return +maps_merge.erl:21:5: The pattern #{'a':=2} can never match the type #{'a':=1, 'q'=>none(), 11=>_, atom()=>_} +maps_merge.erl:5:1: Function t1/0 has no local return +maps_merge.erl:6:5: The pattern #{'a':=1} can never match the type #{} +maps_merge.erl:8:1: Function t2/0 has no local return diff --git a/lib/dialyzer/test/map_SUITE_data/results/maps_remove b/lib/dialyzer/test/map_SUITE_data/results/maps_remove index 32e43466b0..83fefc050d 100644 --- a/lib/dialyzer/test/map_SUITE_data/results/maps_remove +++ b/lib/dialyzer/test/map_SUITE_data/results/maps_remove @@ -1,4 +1,4 @@ -maps_remove.erl:22: Function get/2 has no local return -maps_remove.erl:23: The call maps:get(K::'a',M::#{}) will never return since the success typing arguments are (any(),map()) -maps_remove.erl:7: Function t1/0 has no local return +maps_remove.erl:22:1: Function get/2 has no local return +maps_remove.erl:23:5: The call maps:get(K::'a',M::#{}) will never return since the success typing arguments are (any(),map()) +maps_remove.erl:7:1: Function t1/0 has no local return diff --git a/lib/dialyzer/test/map_SUITE_data/results/opaque_key b/lib/dialyzer/test/map_SUITE_data/results/opaque_key index 8d6379b5e0..b3a2d2b78c 100644 --- a/lib/dialyzer/test/map_SUITE_data/results/opaque_key +++ b/lib/dialyzer/test/map_SUITE_data/results/opaque_key @@ -1,16 +1,16 @@ -opaque_key_adt.erl:35: Invalid type specification for function opaque_key_adt:s2/0. The success typing is () -> #{3:='a'} -opaque_key_adt.erl:41: Invalid type specification for function opaque_key_adt:s4/0. The success typing is () -> #{1:='a'} -opaque_key_adt.erl:44: Invalid type specification for function opaque_key_adt:s5/0. The success typing is () -> #{2:=3} -opaque_key_adt.erl:56: Invalid type specification for function opaque_key_adt:smt1/0. The success typing is () -> #{3:='a'} -opaque_key_adt.erl:59: Invalid type specification for function opaque_key_adt:smt2/0. The success typing is () -> #{1:='a'} -opaque_key_use.erl:13: The test opaque_key_use:t() =:= opaque_key_use:t(integer()) can never evaluate to 'true' -opaque_key_use.erl:24: Attempt to test for equality between a term of type opaque_key_adt:t(integer()) and a term of opaque type opaque_key_adt:t() -opaque_key_use.erl:37: Function adt_mm1/0 has no local return -opaque_key_use.erl:40: The attempt to match a term of type opaque_key_adt:m() against the pattern #{A:=R} breaks the opacity of the term -opaque_key_use.erl:48: Function adt_mu1/0 has no local return -opaque_key_use.erl:51: Guard test is_map(M::opaque_key_adt:m()) breaks the opacity of its argument -opaque_key_use.erl:53: Function adt_mu2/0 has no local return -opaque_key_use.erl:56: Guard test is_map(M::opaque_key_adt:m()) breaks the opacity of its argument -opaque_key_use.erl:58: Function adt_mu3/0 has no local return -opaque_key_use.erl:60: Guard test is_map(M::opaque_key_adt:m()) breaks the opacity of its argument +opaque_key_adt.erl:35:2: Invalid type specification for function opaque_key_adt:s2/0. The success typing is () -> #{3:='a'} +opaque_key_adt.erl:41:2: Invalid type specification for function opaque_key_adt:s4/0. The success typing is () -> #{1:='a'} +opaque_key_adt.erl:44:2: Invalid type specification for function opaque_key_adt:s5/0. The success typing is () -> #{2:=3} +opaque_key_adt.erl:56:2: Invalid type specification for function opaque_key_adt:smt1/0. The success typing is () -> #{3:='a'} +opaque_key_adt.erl:59:2: Invalid type specification for function opaque_key_adt:smt2/0. The success typing is () -> #{1:='a'} +opaque_key_use.erl:13:5: The test opaque_key_use:t() =:= opaque_key_use:t(integer()) can never evaluate to 'true' +opaque_key_use.erl:24:5: Attempt to test for equality between a term of type opaque_key_adt:t(integer()) and a term of opaque type opaque_key_adt:t() +opaque_key_use.erl:37:1: Function adt_mm1/0 has no local return +opaque_key_use.erl:40:5: The attempt to match a term of type opaque_key_adt:m() against the pattern #{A:=R} breaks the opacity of the term +opaque_key_use.erl:48:1: Function adt_mu1/0 has no local return +opaque_key_use.erl:51:5: Guard test is_map(M::opaque_key_adt:m()) breaks the opacity of its argument +opaque_key_use.erl:53:1: Function adt_mu2/0 has no local return +opaque_key_use.erl:56:5: Guard test is_map(M::opaque_key_adt:m()) breaks the opacity of its argument +opaque_key_use.erl:58:1: Function adt_mu3/0 has no local return +opaque_key_use.erl:60:5: Guard test is_map(M::opaque_key_adt:m()) breaks the opacity of its argument diff --git a/lib/dialyzer/test/map_SUITE_data/results/order b/lib/dialyzer/test/map_SUITE_data/results/order index 7be789a11a..d9994d3244 100644 --- a/lib/dialyzer/test/map_SUITE_data/results/order +++ b/lib/dialyzer/test/map_SUITE_data/results/order @@ -1,17 +1,17 @@ -order.erl:12: Function t2/0 has no local return -order.erl:14: Guard test is_integer(Int::'b') can never succeed -order.erl:16: The variable _Else can never match since previous clauses completely covered the type 'b' -order.erl:19: Function t3/0 has no local return -order.erl:21: Guard test is_integer(Int::'b') can never succeed -order.erl:23: The variable _Else can never match since previous clauses completely covered the type 'b' -order.erl:30: The variable _Else can never match since previous clauses completely covered the type 'b' | 1 -order.erl:33: Function t5/0 has no local return -order.erl:36: The variable Atom can never match since previous clauses completely covered the type 1 -order.erl:37: The variable _Else can never match since previous clauses completely covered the type 1 -order.erl:40: Function t6/0 has no local return -order.erl:42: Guard test is_integer(Int::'b') can never succeed -order.erl:44: The variable _Else can never match since previous clauses completely covered the type 'b' -order.erl:5: Function t1/0 has no local return -order.erl:7: Guard test is_integer(Int::'b') can never succeed -order.erl:9: The variable _Else can never match since previous clauses completely covered the type 'b' +order.erl:12:1: Function t2/0 has no local return +order.erl:14:11: Guard test is_integer(Int::'b') can never succeed +order.erl:16:2: The variable _Else can never match since previous clauses completely covered the type 'b' +order.erl:19:1: Function t3/0 has no local return +order.erl:21:11: Guard test is_integer(Int::'b') can never succeed +order.erl:23:2: The variable _Else can never match since previous clauses completely covered the type 'b' +order.erl:30:2: The variable _Else can never match since previous clauses completely covered the type 'b' | 1 +order.erl:33:1: Function t5/0 has no local return +order.erl:36:2: The variable Atom can never match since previous clauses completely covered the type 1 +order.erl:37:2: The variable _Else can never match since previous clauses completely covered the type 1 +order.erl:40:1: Function t6/0 has no local return +order.erl:42:11: Guard test is_integer(Int::'b') can never succeed +order.erl:44:2: The variable _Else can never match since previous clauses completely covered the type 'b' +order.erl:5:1: Function t1/0 has no local return +order.erl:7:11: Guard test is_integer(Int::'b') can never succeed +order.erl:9:2: The variable _Else can never match since previous clauses completely covered the type 'b' diff --git a/lib/dialyzer/test/map_SUITE_data/results/typeflow b/lib/dialyzer/test/map_SUITE_data/results/typeflow index acfb7f551e..a1f25cd2f0 100644 --- a/lib/dialyzer/test/map_SUITE_data/results/typeflow +++ b/lib/dialyzer/test/map_SUITE_data/results/typeflow @@ -1,4 +1,4 @@ -typeflow.erl:14: Function t2/1 has no local return -typeflow.erl:16: The call lists:sort(integer()) will never return since it differs in the 1st argument from the success typing arguments: ([any()]) -typeflow.erl:9: The variable _ can never match since previous clauses completely covered the type #{'a':=integer(), _=>_} +typeflow.erl:14:1: Function t2/1 has no local return +typeflow.erl:16:16: The call lists:sort(integer()) will never return since it differs in the 1st argument from the success typing arguments: ([any()]) +typeflow.erl:9:2: The variable _ can never match since previous clauses completely covered the type #{'a':=integer(), _=>_} diff --git a/lib/dialyzer/test/map_SUITE_data/results/typeflow2 b/lib/dialyzer/test/map_SUITE_data/results/typeflow2 index 3adf638978..a078562dc2 100644 --- a/lib/dialyzer/test/map_SUITE_data/results/typeflow2 +++ b/lib/dialyzer/test/map_SUITE_data/results/typeflow2 @@ -1,13 +1,13 @@ -typeflow2.erl:10: The pattern #{'a':=X} can never match the type #{'a'=>none(), _=>maybe_improper_list() | integer()} -typeflow2.erl:11: The pattern #{'a':=X} can never match the type #{'a'=>none(), _=>maybe_improper_list() | integer()} -typeflow2.erl:26: Function t2/1 has no local return -typeflow2.erl:29: The call lists:sort(integer()) will never return since it differs in the 1st argument from the success typing arguments: ([any()]) -typeflow2.erl:42: The pattern #{'a':=X} can never match since previous clauses completely covered the type #{'a':=integer()} -typeflow2.erl:43: The variable _ can never match since previous clauses completely covered the type #{'a':=integer()} -typeflow2.erl:48: The pattern #{} can never match since previous clauses completely covered the type #{'a':=atom() | maybe_improper_list() | integer()} -typeflow2.erl:58: The pattern #{'a':=X} can never match the type #{'a'=>none(), _=>maybe_improper_list() | integer()} -typeflow2.erl:59: The pattern #{'a':=X} can never match the type #{'a'=>none(), _=>maybe_improper_list() | integer()} -typeflow2.erl:60: The pattern #{'a':=X} can never match the type #{'a'=>none(), _=>maybe_improper_list() | integer()} -typeflow2.erl:82: The pattern #{'a':=X} can never match the type #{} -typeflow2.erl:83: The pattern #{'a':=X} can never match the type #{} +typeflow2.erl:10:2: The pattern #{'a':=X} can never match the type #{'a'=>none(), _=>maybe_improper_list() | integer()} +typeflow2.erl:11:2: The pattern #{'a':=X} can never match the type #{'a'=>none(), _=>maybe_improper_list() | integer()} +typeflow2.erl:26:1: Function t2/1 has no local return +typeflow2.erl:29:16: The call lists:sort(integer()) will never return since it differs in the 1st argument from the success typing arguments: ([any()]) +typeflow2.erl:42:2: The pattern #{'a':=X} can never match since previous clauses completely covered the type #{'a':=integer()} +typeflow2.erl:43:2: The variable _ can never match since previous clauses completely covered the type #{'a':=integer()} +typeflow2.erl:48:1: The pattern #{} can never match since previous clauses completely covered the type #{'a':=atom() | maybe_improper_list() | integer()} +typeflow2.erl:58:2: The pattern #{'a':=X} can never match the type #{'a'=>none(), _=>maybe_improper_list() | integer()} +typeflow2.erl:59:2: The pattern #{'a':=X} can never match the type #{'a'=>none(), _=>maybe_improper_list() | integer()} +typeflow2.erl:60:2: The pattern #{'a':=X} can never match the type #{'a'=>none(), _=>maybe_improper_list() | integer()} +typeflow2.erl:82:2: The pattern #{'a':=X} can never match the type #{} +typeflow2.erl:83:2: The pattern #{'a':=X} can never match the type #{} diff --git a/lib/dialyzer/test/map_SUITE_data/results/typesig b/lib/dialyzer/test/map_SUITE_data/results/typesig index 6a79fe35f1..352a06731b 100644 --- a/lib/dialyzer/test/map_SUITE_data/results/typesig +++ b/lib/dialyzer/test/map_SUITE_data/results/typesig @@ -1,5 +1,5 @@ -typesig.erl:5: Function t1/0 has no local return -typesig.erl:5: The call typesig:test(#{'a'=>1}) will never return since it differs in the 1st argument from the success typing arguments: (#{'a':={number()}, _=>_}) -typesig.erl:6: Function t2/0 has no local return -typesig.erl:6: The call typesig:test(#{'a':={'b'}}) will never return since it differs in the 1st argument from the success typing arguments: (#{'a':={number()}, _=>_}) +typesig.erl:5:14: The call typesig:test(#{'a'=>1}) will never return since it differs in the 1st argument from the success typing arguments: (#{'a':={number()}, _=>_}) +typesig.erl:5:1: Function t1/0 has no local return +typesig.erl:6:14: The call typesig:test(#{'a':={'b'}}) will never return since it differs in the 1st argument from the success typing arguments: (#{'a':={number()}, _=>_}) +typesig.erl:6:1: Function t2/0 has no local return diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/array b/lib/dialyzer/test/opaque_SUITE_data/results/array index 6f1aa1ce3d..d7f41014b2 100644 --- a/lib/dialyzer/test/opaque_SUITE_data/results/array +++ b/lib/dialyzer/test/opaque_SUITE_data/results/array @@ -1,3 +1,3 @@ -array_use.erl:12: The type test is_tuple(array:array(_)) breaks the opacity of the term array:array(_) -array_use.erl:9: The attempt to match a term of type array:array(_) against the pattern {'array', _, _, 'undefined', _} breaks the opacity of the term +array_use.erl:12:8: The type test is_tuple(array:array(_)) breaks the opacity of the term array:array(_) +array_use.erl:9:3: The attempt to match a term of type array:array(_) against the pattern {'array', _, _, 'undefined', _} breaks the opacity of the term diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/crash b/lib/dialyzer/test/opaque_SUITE_data/results/crash index d63389f79c..97bc5ea1d6 100644 --- a/lib/dialyzer/test/opaque_SUITE_data/results/crash +++ b/lib/dialyzer/test/opaque_SUITE_data/results/crash @@ -1,6 +1,6 @@ -crash_1.erl:45: Record construction #targetlist{list::[]} violates the declared type of field list::crash_1:target() -crash_1.erl:48: The call crash_1:get_using_branch2(Branch::maybe_improper_list(),L::crash_1:target()) will never return since it differs in the 2nd argument from the success typing arguments: (any(),maybe_improper_list()) -crash_1.erl:50: The pattern <_Branch, []> can never match the type <maybe_improper_list(),crash_1:target()> -crash_1.erl:52: The pattern <Branch, [H = {'target', _, _} | _T]> can never match the type <maybe_improper_list(),crash_1:target()> -crash_1.erl:54: The pattern <Branch, [{'target', _, _} | T]> can never match the type <maybe_improper_list(),crash_1:target()> +crash_1.erl:45:24: Record construction #targetlist{list::[]} violates the declared type of field list::crash_1:target() +crash_1.erl:48:31: The call crash_1:get_using_branch2(Branch::maybe_improper_list(),L::crash_1:target()) will never return since it differs in the 2nd argument from the success typing arguments: (any(),maybe_improper_list()) +crash_1.erl:50:1: The pattern <_Branch, []> can never match the type <maybe_improper_list(),crash_1:target()> +crash_1.erl:52:1: The pattern <Branch, [H = {'target', _, _} | _T]> can never match the type <maybe_improper_list(),crash_1:target()> +crash_1.erl:54:1: The pattern <Branch, [{'target', _, _} | T]> can never match the type <maybe_improper_list(),crash_1:target()> diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/dict b/lib/dialyzer/test/opaque_SUITE_data/results/dict index bda9bfc09f..461b30d376 100644 --- a/lib/dialyzer/test/opaque_SUITE_data/results/dict +++ b/lib/dialyzer/test/opaque_SUITE_data/results/dict @@ -1,15 +1,15 @@ -dict_use.erl:41: The attempt to match a term of type dict:dict(_,_) against the pattern 'gazonk' breaks the opacity of the term -dict_use.erl:45: The attempt to match a term of type dict:dict(_,_) against the pattern [] breaks the opacity of the term -dict_use.erl:46: The attempt to match a term of type dict:dict(_,_) against the pattern 42 breaks the opacity of the term -dict_use.erl:51: The attempt to match a term of type dict:dict(_,_) against the pattern [] breaks the opacity of the term -dict_use.erl:52: The attempt to match a term of type dict:dict(_,_) against the pattern 42 breaks the opacity of the term -dict_use.erl:58: Attempt to test for equality between a term of type maybe_improper_list() and a term of opaque type dict:dict(_,_) -dict_use.erl:60: Attempt to test for inequality between a term of type atom() and a term of opaque type dict:dict(_,_) -dict_use.erl:64: Guard test length(D::dict:dict(_,_)) breaks the opacity of its argument -dict_use.erl:65: Guard test is_atom(D::dict:dict(_,_)) breaks the opacity of its argument -dict_use.erl:66: Guard test is_list(D::dict:dict(_,_)) breaks the opacity of its argument -dict_use.erl:70: The type test is_list(dict:dict(_,_)) breaks the opacity of the term dict:dict(_,_) -dict_use.erl:73: The call dict:fetch('foo',[1, 2, 3]) does not have an opaque term of type dict:dict(_,_) as 2nd argument -dict_use.erl:76: The call dict:merge(Fun::any(),42,[1, 2]) does not have opaque terms as 2nd and 3rd arguments -dict_use.erl:79: The call dict:store(42,'elli',{'dict', 0, 16, 16, 8, 80, 48, {[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []}, {{[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []}}}) does not have an opaque term of type dict:dict(_,_) as 3rd argument +dict_use.erl:41:3: The attempt to match a term of type dict:dict(_,_) against the pattern 'gazonk' breaks the opacity of the term +dict_use.erl:45:5: The attempt to match a term of type dict:dict(_,_) against the pattern [] breaks the opacity of the term +dict_use.erl:46:5: The attempt to match a term of type dict:dict(_,_) against the pattern 42 breaks the opacity of the term +dict_use.erl:51:5: The attempt to match a term of type dict:dict(_,_) against the pattern [] breaks the opacity of the term +dict_use.erl:52:5: The attempt to match a term of type dict:dict(_,_) against the pattern 42 breaks the opacity of the term +dict_use.erl:58:3: Attempt to test for equality between a term of type maybe_improper_list() and a term of opaque type dict:dict(_,_) +dict_use.erl:60:3: Attempt to test for inequality between a term of type atom() and a term of opaque type dict:dict(_,_) +dict_use.erl:64:19: Guard test length(D::dict:dict(_,_)) breaks the opacity of its argument +dict_use.erl:65:20: Guard test is_atom(D::dict:dict(_,_)) breaks the opacity of its argument +dict_use.erl:66:20: Guard test is_list(D::dict:dict(_,_)) breaks the opacity of its argument +dict_use.erl:70:3: The type test is_list(dict:dict(_,_)) breaks the opacity of the term dict:dict(_,_) +dict_use.erl:73:19: The call dict:fetch('foo',[1, 2, 3]) does not have an opaque term of type dict:dict(_,_) as 2nd argument +dict_use.erl:76:19: The call dict:merge(Fun::any(),42,[1, 2]) does not have opaque terms as 2nd and 3rd arguments +dict_use.erl:80:7: The call dict:store(42,'elli',{'dict', 0, 16, 16, 8, 80, 48, {[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []}, {{[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []}}}) does not have an opaque term of type dict:dict(_,_) as 3rd argument diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/ets b/lib/dialyzer/test/opaque_SUITE_data/results/ets index 5dde23fb15..aba95ca9f4 100644 --- a/lib/dialyzer/test/opaque_SUITE_data/results/ets +++ b/lib/dialyzer/test/opaque_SUITE_data/results/ets @@ -1,4 +1,4 @@ -ets_use.erl:12: Guard test is_integer(T::atom() | ets:tid()) breaks the opacity of its argument -ets_use.erl:20: The type test is_integer(atom() | ets:tid()) breaks the opacity of the term atom() | ets:tid() -ets_use.erl:7: Guard test is_integer(T::ets:tid()) breaks the opacity of its argument +ets_use.erl:12:20: Guard test is_integer(T::atom() | ets:tid()) breaks the opacity of its argument +ets_use.erl:20:5: The type test is_integer(atom() | ets:tid()) breaks the opacity of the term atom() | ets:tid() +ets_use.erl:7:20: Guard test is_integer(T::ets:tid()) breaks the opacity of its argument diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/ewgi b/lib/dialyzer/test/opaque_SUITE_data/results/ewgi index 209f27b2f2..ed7e06a9db 100644 --- a/lib/dialyzer/test/opaque_SUITE_data/results/ewgi +++ b/lib/dialyzer/test/opaque_SUITE_data/results/ewgi @@ -1,4 +1,4 @@ -ewgi_api.erl:55: The call gb_trees:to_list({non_neg_integer(),'nil' | {_,_,_,_}}) does not have an opaque term of type gb_trees:tree(_,_) as 1st argument -ewgi_testapp.erl:35: The call ewgi_testapp:htmlise_data("request_data",{non_neg_integer(),'nil' | {_,_,_,_}}) does not have a term of type [{_,_}] | gb_trees:tree(_,_) (with opaque subterms) as 2nd argument -ewgi_testapp.erl:43: The call gb_trees:to_list(T::{non_neg_integer(),'nil' | {_,_,_,_}}) does not have an opaque term of type gb_trees:tree(_,_) as 1st argument +ewgi_api.erl:55:31: The call gb_trees:to_list({non_neg_integer(),'nil' | {_,_,_,_}}) does not have an opaque term of type gb_trees:tree(_,_) as 1st argument +ewgi_testapp.erl:35:91: The call ewgi_testapp:htmlise_data("request_data",{non_neg_integer(),'nil' | {_,_,_,_}}) does not have a term of type [{_,_}] | gb_trees:tree(_,_) (with opaque subterms) as 2nd argument +ewgi_testapp.erl:43:27: The call gb_trees:to_list(T::{non_neg_integer(),'nil' | {_,_,_,_}}) does not have an opaque term of type gb_trees:tree(_,_) as 1st argument diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/inf_loop1 b/lib/dialyzer/test/opaque_SUITE_data/results/inf_loop1 index ac5ef14041..26dfbb6923 100644 --- a/lib/dialyzer/test/opaque_SUITE_data/results/inf_loop1 +++ b/lib/dialyzer/test/opaque_SUITE_data/results/inf_loop1 @@ -1,5 +1,5 @@ -inf_loop1.erl:119: The pattern [{_, LNorms}] can never match the type [] -inf_loop1.erl:121: The pattern [{LinksA, LNormA}, {LinksB, LNormB}] can never match the type [] -inf_loop1.erl:129: The pattern [{_, Norm} | _] can never match the type [] -inf_loop1.erl:71: The call gb_trees:get(Edge::any(),Etab::array:array(_)) does not have an opaque term of type gb_trees:tree(_,_) as 2nd argument +inf_loop1.erl:119:1: The pattern [{_, LNorms}] can never match the type [] +inf_loop1.erl:121:1: The pattern [{LinksA, LNormA}, {LinksB, LNormB}] can never match the type [] +inf_loop1.erl:129:15: The pattern [{_, Norm} | _] can never match the type [] +inf_loop1.erl:71:74: The call gb_trees:get(Edge::any(),Etab::array:array(_)) does not have an opaque term of type gb_trees:tree(_,_) as 2nd argument diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/inf_loop2 b/lib/dialyzer/test/opaque_SUITE_data/results/inf_loop2 index 8cd2abe8cd..7b35563d43 100644 --- a/lib/dialyzer/test/opaque_SUITE_data/results/inf_loop2 +++ b/lib/dialyzer/test/opaque_SUITE_data/results/inf_loop2 @@ -1,5 +1,5 @@ -inf_loop2.erl:122: The pattern [{_, LNorms}] can never match the type [] -inf_loop2.erl:124: The pattern [{LinksA, LNormA}, {LinksB, LNormB}] can never match the type [] -inf_loop2.erl:132: The pattern [{_, Norm} | _] can never match the type [] -inf_loop2.erl:74: The call gb_trees:get(Edge::any(),Etab::array:array(_)) does not have an opaque term of type gb_trees:tree(_,_) as 2nd argument +inf_loop2.erl:122:1: The pattern [{_, LNorms}] can never match the type [] +inf_loop2.erl:124:1: The pattern [{LinksA, LNormA}, {LinksB, LNormB}] can never match the type [] +inf_loop2.erl:132:15: The pattern [{_, Norm} | _] can never match the type [] +inf_loop2.erl:74:74: The call gb_trees:get(Edge::any(),Etab::array:array(_)) does not have an opaque term of type gb_trees:tree(_,_) as 2nd argument diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/int b/lib/dialyzer/test/opaque_SUITE_data/results/int index dc806fa12c..42fd95e321 100644 --- a/lib/dialyzer/test/opaque_SUITE_data/results/int +++ b/lib/dialyzer/test/opaque_SUITE_data/results/int @@ -1,3 +1,3 @@ -int_adt.erl:28: Invalid type specification for function int_adt:add_f/2. The success typing is (number() | int_adt:int(),float()) -> number() | int_adt:int() -int_adt.erl:32: Invalid type specification for function int_adt:div_f/2. The success typing is (number() | int_adt:int(),number() | int_adt:int()) -> float() +int_adt.erl:28:2: Invalid type specification for function int_adt:add_f/2. The success typing is (number() | int_adt:int(),float()) -> number() | int_adt:int() +int_adt.erl:32:2: Invalid type specification for function int_adt:div_f/2. The success typing is (number() | int_adt:int(),number() | int_adt:int()) -> float() diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/mixed_opaque b/lib/dialyzer/test/opaque_SUITE_data/results/mixed_opaque index 0363be544d..77f45b1f20 100644 --- a/lib/dialyzer/test/opaque_SUITE_data/results/mixed_opaque +++ b/lib/dialyzer/test/opaque_SUITE_data/results/mixed_opaque @@ -1,2 +1,2 @@ -mixed_opaque_use.erl:31: The call mixed_opaque_rec_adt:get_a(Q::mixed_opaque_queue_adt:my_queue()) does not have an opaque term of type mixed_opaque_rec_adt:rec() as 1st argument +mixed_opaque_use.erl:31:16: The call mixed_opaque_rec_adt:get_a(Q::mixed_opaque_queue_adt:my_queue()) does not have an opaque term of type mixed_opaque_rec_adt:rec() as 1st argument diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/modules b/lib/dialyzer/test/opaque_SUITE_data/results/modules index f71334b9de..d283838dcd 100644 --- a/lib/dialyzer/test/opaque_SUITE_data/results/modules +++ b/lib/dialyzer/test/opaque_SUITE_data/results/modules @@ -1,3 +1,3 @@ -opaque_digraph.erl:353: Cons will produce an improper list since its 2nd argument is number() -opaque_digraph.erl:365: Cons will produce an improper list since its 2nd argument is number() +opaque_digraph.erl:353:5: Cons will produce an improper list since its 2nd argument is number() +opaque_digraph.erl:365:5: Cons will produce an improper list since its 2nd argument is number() diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/multiple_wrong_opaques b/lib/dialyzer/test/opaque_SUITE_data/results/multiple_wrong_opaques index 18ece8820c..fd702bf1d6 100644 --- a/lib/dialyzer/test/opaque_SUITE_data/results/multiple_wrong_opaques +++ b/lib/dialyzer/test/opaque_SUITE_data/results/multiple_wrong_opaques @@ -1,2 +1,2 @@ -multiple_wrong_opaques.erl:5: Invalid type specification for function multiple_wrong_opaques:weird/1. The success typing is ('gazonk') -> 42 +multiple_wrong_opaques.erl:5:2: Invalid type specification for function multiple_wrong_opaques:weird/1. The success typing is ('gazonk') -> 42 diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/my_queue b/lib/dialyzer/test/opaque_SUITE_data/results/my_queue index 67999b0e20..8364d8e9a5 100644 --- a/lib/dialyzer/test/opaque_SUITE_data/results/my_queue +++ b/lib/dialyzer/test/opaque_SUITE_data/results/my_queue @@ -1,7 +1,7 @@ -my_queue_use.erl:15: The call my_queue_adt:is_empty([]) does not have an opaque term of type my_queue_adt:my_queue() as 1st argument -my_queue_use.erl:19: The call my_queue_adt:add(42,Q0::[]) does not have an opaque term of type my_queue_adt:my_queue() as 2nd argument -my_queue_use.erl:24: The attempt to match a term of type my_queue_adt:my_queue() against the pattern [42 | Q2] breaks the opacity of the term -my_queue_use.erl:30: Attempt to test for equality between a term of type [] and a term of opaque type my_queue_adt:my_queue() -my_queue_use.erl:34: Cons will produce an improper list since its 2nd argument is my_queue_adt:my_queue() -my_queue_use.erl:34: The call my_queue_adt:dequeue(nonempty_maybe_improper_list(42,my_queue_adt:my_queue())) does not have an opaque term of type my_queue_adt:my_queue() as 1st argument +my_queue_use.erl:15:27: The call my_queue_adt:is_empty([]) does not have an opaque term of type my_queue_adt:my_queue() as 1st argument +my_queue_use.erl:19:26: The call my_queue_adt:add(42,Q0::[]) does not have an opaque term of type my_queue_adt:my_queue() as 2nd argument +my_queue_use.erl:24:5: The attempt to match a term of type my_queue_adt:my_queue() against the pattern [42 | Q2] breaks the opacity of the term +my_queue_use.erl:30:5: Attempt to test for equality between a term of type [] and a term of opaque type my_queue_adt:my_queue() +my_queue_use.erl:34:37: Cons will produce an improper list since its 2nd argument is my_queue_adt:my_queue() +my_queue_use.erl:34:37: The call my_queue_adt:dequeue(nonempty_maybe_improper_list(42,my_queue_adt:my_queue())) does not have an opaque term of type my_queue_adt:my_queue() as 1st argument diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/opaque b/lib/dialyzer/test/opaque_SUITE_data/results/opaque index 864e0d853c..cc793a71c7 100644 --- a/lib/dialyzer/test/opaque_SUITE_data/results/opaque +++ b/lib/dialyzer/test/opaque_SUITE_data/results/opaque @@ -1,3 +1,3 @@ -opaque_bug3.erl:19: The pattern 'a' can never match the type #c{} -opaque_bug4.erl:20: The attempt to match a term of type opaque_adt:abc() against the pattern 'a' breaks the opacity of the term +opaque_bug3.erl:19:1: The pattern 'a' can never match the type #c{} +opaque_bug4.erl:20:1: The attempt to match a term of type opaque_adt:abc() against the pattern 'a' breaks the opacity of the term diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/para b/lib/dialyzer/test/opaque_SUITE_data/results/para index eca445315c..d0ddab7b66 100644 --- a/lib/dialyzer/test/opaque_SUITE_data/results/para +++ b/lib/dialyzer/test/opaque_SUITE_data/results/para @@ -1,34 +1,34 @@ -para1.erl:18: The test para1:t(atom()) =:= para1:t(integer()) can never evaluate to 'true' -para1.erl:23: The test para1:t(atom()) =:= para1:t() can never evaluate to 'true' -para1.erl:28: The test para1:t() =:= para1:t(integer()) can never evaluate to 'true' -para1.erl:33: The test {3,2} =:= {'a','b'} can never evaluate to 'true' -para1.erl:38: Attempt to test for equality between a term of type para1_adt:t(integer()) and a term of opaque type para1_adt:t(atom()) -para1.erl:43: Attempt to test for equality between a term of type para1_adt:t() and a term of opaque type para1_adt:t(atom()) -para1.erl:48: Attempt to test for equality between a term of type para1_adt:t(integer()) and a term of opaque type para1_adt:t() -para1.erl:53: The test {3,2} =:= {'a','b'} can never evaluate to 'true' -para2.erl:103: Attempt to test for equality between a term of type para2_adt:circ(integer(),integer()) and a term of opaque type para2_adt:circ(integer()) -para2.erl:117: Attempt to test for equality between a term of type para2_adt:un(atom(),integer()) and a term of opaque type para2_adt:un(integer(),atom()) -para2.erl:31: The test 'a' =:= 'b' can never evaluate to 'true' -para2.erl:61: Attempt to test for equality between a term of type para2_adt:c2() and a term of opaque type para2_adt:c1() -para2.erl:66: The test 'a' =:= 'b' can never evaluate to 'true' -para2.erl:88: The test para2:circ(integer()) =:= para2:circ(integer(),integer()) can never evaluate to 'true' -para3.erl:28: Invalid type specification for function para3:ot2/0. The success typing is () -> 'foo' -para3.erl:36: The pattern {{{17}}} can never match the type {{{{{{_,_,_,_,_}}}}}} -para3.erl:55: Invalid type specification for function para3:t2/0. The success typing is () -> 'foo' -para3.erl:65: The attempt to match a term of type {{{{{para3_adt:ot1(_,_,_,_,_)}}}}} against the pattern {{{{{17}}}}} breaks the opacity of para3_adt:ot1(_,_,_,_,_) -para3.erl:68: The pattern {{{{17}}}} can never match the type {{{{{para3_adt:ot1(_,_,_,_,_)}}}}} -para3.erl:74: The specification for para3:exp_adt/0 has an opaque subtype para3_adt:exp1(para3_adt:exp2()) which is violated by the success typing () -> 3 -para4.erl:21: Invalid type specification for function para4:a/1. The success typing is (para4:d_all() | para4:d_atom()) -> [{atom() | integer(),atom() | integer()}] -para4.erl:26: Invalid type specification for function para4:i/1. The success typing is (para4:d_all() | para4:d_integer()) -> [{atom() | integer(),atom() | integer()}] -para4.erl:31: Invalid type specification for function para4:t/1. The success typing is (para4:d_all() | para4:d_tuple()) -> [{atom() | integer(),atom() | integer()}] -para4.erl:59: Attempt to test for equality between a term of type para4_adt:t(atom() | integer()) and a term of opaque type para4_adt:t(integer()) -para4.erl:64: Attempt to test for equality between a term of type para4_adt:t(atom() | integer()) and a term of opaque type para4_adt:t(atom()) -para4.erl:69: Attempt to test for equality between a term of type para4_adt:int(1 | 2 | 3 | 4) and a term of opaque type para4_adt:int(1 | 2) -para4.erl:74: Attempt to test for equality between a term of type para4_adt:int(2 | 3 | 4) and a term of opaque type para4_adt:int(1 | 2) -para4.erl:79: Attempt to test for equality between a term of type para4_adt:int(2 | 3 | 4) and a term of opaque type para4_adt:int(5 | 6 | 7) -para4.erl:84: Attempt to test for equality between a term of type para4_adt:un(3 | 4) and a term of opaque type para4_adt:un(1 | 2) -para4.erl:89: Attempt to test for equality between a term of type para4_adt:tup({_,_}) and a term of opaque type para4_adt:tup(tuple()) -para4.erl:94: Attempt to test for equality between a term of type para4_adt:t(#{1=>'a'}) and a term of opaque type para4_adt:t(#{2=>'b'}) -para5.erl:13: Attempt to test for inequality between a term of type para5_adt:dd(atom()) and a term of opaque type para5_adt:d() -para5.erl:8: The test para5_adt:d() =:= para5_adt:d() can never evaluate to 'true' +para1.erl:18:5: The test para1:t(atom()) =:= para1:t(integer()) can never evaluate to 'true' +para1.erl:23:5: The test para1:t(atom()) =:= para1:t() can never evaluate to 'true' +para1.erl:28:5: The test para1:t() =:= para1:t(integer()) can never evaluate to 'true' +para1.erl:33:5: The test {3,2} =:= {'a','b'} can never evaluate to 'true' +para1.erl:38:5: Attempt to test for equality between a term of type para1_adt:t(integer()) and a term of opaque type para1_adt:t(atom()) +para1.erl:43:5: Attempt to test for equality between a term of type para1_adt:t() and a term of opaque type para1_adt:t(atom()) +para1.erl:48:5: Attempt to test for equality between a term of type para1_adt:t(integer()) and a term of opaque type para1_adt:t() +para1.erl:53:5: The test {3,2} =:= {'a','b'} can never evaluate to 'true' +para2.erl:103:5: Attempt to test for equality between a term of type para2_adt:circ(integer(),integer()) and a term of opaque type para2_adt:circ(integer()) +para2.erl:117:5: Attempt to test for equality between a term of type para2_adt:un(atom(),integer()) and a term of opaque type para2_adt:un(integer(),atom()) +para2.erl:31:5: The test 'a' =:= 'b' can never evaluate to 'true' +para2.erl:61:5: Attempt to test for equality between a term of type para2_adt:c2() and a term of opaque type para2_adt:c1() +para2.erl:66:5: The test 'a' =:= 'b' can never evaluate to 'true' +para2.erl:88:5: The test para2:circ(integer()) =:= para2:circ(integer(),integer()) can never evaluate to 'true' +para3.erl:28:2: Invalid type specification for function para3:ot2/0. The success typing is () -> 'foo' +para3.erl:36:5: The pattern {{{17}}} can never match the type {{{{{{_,_,_,_,_}}}}}} +para3.erl:55:2: Invalid type specification for function para3:t2/0. The success typing is () -> 'foo' +para3.erl:65:5: The attempt to match a term of type {{{{{para3_adt:ot1(_,_,_,_,_)}}}}} against the pattern {{{{{17}}}}} breaks the opacity of para3_adt:ot1(_,_,_,_,_) +para3.erl:68:5: The pattern {{{{17}}}} can never match the type {{{{{para3_adt:ot1(_,_,_,_,_)}}}}} +para3.erl:74:2: The specification for para3:exp_adt/0 has an opaque subtype para3_adt:exp1(para3_adt:exp2()) which is violated by the success typing () -> 3 +para4.erl:21:2: Invalid type specification for function para4:a/1. The success typing is (para4:d_all() | para4:d_atom()) -> [{atom() | integer(),atom() | integer()}] +para4.erl:26:2: Invalid type specification for function para4:i/1. The success typing is (para4:d_all() | para4:d_integer()) -> [{atom() | integer(),atom() | integer()}] +para4.erl:31:2: Invalid type specification for function para4:t/1. The success typing is (para4:d_all() | para4:d_tuple()) -> [{atom() | integer(),atom() | integer()}] +para4.erl:59:5: Attempt to test for equality between a term of type para4_adt:t(atom() | integer()) and a term of opaque type para4_adt:t(integer()) +para4.erl:64:5: Attempt to test for equality between a term of type para4_adt:t(atom() | integer()) and a term of opaque type para4_adt:t(atom()) +para4.erl:69:5: Attempt to test for equality between a term of type para4_adt:int(1 | 2 | 3 | 4) and a term of opaque type para4_adt:int(1 | 2) +para4.erl:74:5: Attempt to test for equality between a term of type para4_adt:int(2 | 3 | 4) and a term of opaque type para4_adt:int(1 | 2) +para4.erl:79:5: Attempt to test for equality between a term of type para4_adt:int(2 | 3 | 4) and a term of opaque type para4_adt:int(5 | 6 | 7) +para4.erl:84:5: Attempt to test for equality between a term of type para4_adt:un(3 | 4) and a term of opaque type para4_adt:un(1 | 2) +para4.erl:89:5: Attempt to test for equality between a term of type para4_adt:tup({_,_}) and a term of opaque type para4_adt:tup(tuple()) +para4.erl:94:5: Attempt to test for equality between a term of type para4_adt:t(#{1=>'a'}) and a term of opaque type para4_adt:t(#{2=>'b'}) +para5.erl:13:5: Attempt to test for inequality between a term of type para5_adt:dd(atom()) and a term of opaque type para5_adt:d() +para5.erl:8:5: The test para5_adt:d() =:= para5_adt:d() can never evaluate to 'true' diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/queue b/lib/dialyzer/test/opaque_SUITE_data/results/queue index 8f9373e8e4..b66ffcb648 100644 --- a/lib/dialyzer/test/opaque_SUITE_data/results/queue +++ b/lib/dialyzer/test/opaque_SUITE_data/results/queue @@ -1,11 +1,11 @@ -queue_use.erl:18: The call queue:is_empty({[], []}) does not have an opaque term of type queue:queue(_) as 1st argument -queue_use.erl:22: The call queue:in(42,Q0::{[],[]}) does not have an opaque term of type queue:queue(_) as 2nd argument -queue_use.erl:27: The attempt to match a term of type queue:queue(_) against the pattern {"*", Q2} breaks the opacity of the term -queue_use.erl:33: Attempt to test for equality between a term of type {[42,...],[]} and a term of opaque type queue:queue(_) -queue_use.erl:36: The attempt to match a term of type queue:queue(_) against the pattern {F, _R} breaks the opacity of the term -queue_use.erl:40: The call queue:out({"*", []}) does not have an opaque term of type queue:queue(_) as 1st argument -queue_use.erl:51: The call queue_use:is_in_queue(E::42,DB::#db{p::[],q::queue:queue(_)}) contains an opaque term as 2nd argument when terms of different types are expected in these positions -queue_use.erl:56: The attempt to match a term of type #db{p::[],q::queue:queue(_)} against the pattern {'db', _, {L1, L2}} breaks the opacity of queue:queue(_) -queue_use.erl:62: The call queue_use:tuple_queue({42, 'gazonk'}) does not have a term of type {_,queue:queue(_)} (with opaque subterms) as 1st argument -queue_use.erl:65: The call queue:in(F::42,Q::'gazonk') does not have an opaque term of type queue:queue(_) as 2nd argument +queue_use.erl:18:20: The call queue:is_empty({[], []}) does not have an opaque term of type queue:queue(_) as 1st argument +queue_use.erl:22:18: The call queue:in(42,Q0::{[],[]}) does not have an opaque term of type queue:queue(_) as 2nd argument +queue_use.erl:27:5: The attempt to match a term of type queue:queue(_) against the pattern {"*", Q2} breaks the opacity of the term +queue_use.erl:33:5: Attempt to test for equality between a term of type {[42,...],[]} and a term of opaque type queue:queue(_) +queue_use.erl:36:5: The attempt to match a term of type queue:queue(_) against the pattern {F, _R} breaks the opacity of the term +queue_use.erl:40:35: The call queue:out({"*", []}) does not have an opaque term of type queue:queue(_) as 1st argument +queue_use.erl:51:25: The call queue_use:is_in_queue(E::42,DB::#db{p::[],q::queue:queue(_)}) contains an opaque term as 2nd argument when terms of different types are expected in these positions +queue_use.erl:56:1: The attempt to match a term of type #db{p::[],q::queue:queue(_)} against the pattern {'db', _, {L1, L2}} breaks the opacity of queue:queue(_) +queue_use.erl:62:17: The call queue_use:tuple_queue({42, 'gazonk'}) does not have a term of type {_,queue:queue(_)} (with opaque subterms) as 1st argument +queue_use.erl:65:17: The call queue:in(F::42,Q::'gazonk') does not have an opaque term of type queue:queue(_) as 2nd argument diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/rec b/lib/dialyzer/test/opaque_SUITE_data/results/rec index e9b217a93f..60943ea0ce 100644 --- a/lib/dialyzer/test/opaque_SUITE_data/results/rec +++ b/lib/dialyzer/test/opaque_SUITE_data/results/rec @@ -1,6 +1,6 @@ -rec_use.erl:17: The attempt to match a term of type rec_adt:rec() against the pattern {'rec', _, 42} breaks the opacity of the term -rec_use.erl:18: Guard test tuple_size(R::rec_adt:rec()) breaks the opacity of its argument -rec_use.erl:23: The call rec_adt:get_a(R::tuple()) does not have an opaque term of type rec_adt:rec() as 1st argument -rec_use.erl:27: Attempt to test for equality between a term of type {'rec','gazonk',42} and a term of opaque type rec_adt:rec() -rec_use.erl:30: The call erlang:tuple_size(rec_adt:rec()) contains an opaque term as 1st argument when a structured term of type tuple() is expected +rec_use.erl:17:2: The attempt to match a term of type rec_adt:rec() against the pattern {'rec', _, 42} breaks the opacity of the term +rec_use.erl:18:20: Guard test tuple_size(R::rec_adt:rec()) breaks the opacity of its argument +rec_use.erl:23:19: The call rec_adt:get_a(R::tuple()) does not have an opaque term of type rec_adt:rec() as 1st argument +rec_use.erl:27:5: Attempt to test for equality between a term of type {'rec','gazonk',42} and a term of opaque type rec_adt:rec() +rec_use.erl:30:16: The call erlang:tuple_size(rec_adt:rec()) contains an opaque term as 1st argument when a structured term of type tuple() is expected diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/simple b/lib/dialyzer/test/opaque_SUITE_data/results/simple index 5d13b56970..4959d14f15 100644 --- a/lib/dialyzer/test/opaque_SUITE_data/results/simple +++ b/lib/dialyzer/test/opaque_SUITE_data/results/simple @@ -1,92 +1,92 @@ -exact_api.erl:17: The call exact_api:set_type(A::#digraph{vtab::'notable',etab::'notable',ntab::'notable',cyclic::'true'}) does not have an opaque term of type digraph:graph() as 1st argument -exact_api.erl:23: The call digraph:delete(G::#digraph{vtab::'notable',etab::'notable',ntab::'notable',cyclic::'true'}) does not have an opaque term of type digraph:graph() as 1st argument -exact_api.erl:55: The attempt to match a term of type exact_adt:exact_adt() against the pattern {'exact_adt'} breaks the opacity of the term -exact_api.erl:59: The call exact_adt:exact_adt_set_type2(A::#exact_adt{}) does not have an opaque term of type exact_adt:exact_adt() as 1st argument -is_rec.erl:10: The call erlang:is_record(simple1_adt:d1(),'r',2) contains an opaque term as 1st argument when terms of different types are expected in these positions -is_rec.erl:15: The call erlang:is_record(A::simple1_adt:d1(),'r',I::1 | 2 | 3) contains an opaque term as 1st argument when terms of different types are expected in these positions -is_rec.erl:19: Guard test is_record(A::simple1_adt:d1(),'r',2) breaks the opacity of its argument -is_rec.erl:23: Guard test is_record({simple1_adt:d1(),1},'r',2) breaks the opacity of its argument -is_rec.erl:41: The call erlang:is_record(A::simple1_adt:d1(),R::'a') contains an opaque term as 1st argument when terms of different types are expected in these positions -is_rec.erl:45: The call erlang:is_record(A::simple1_adt:d1(),A::simple1_adt:d1(),1) contains an opaque term as 2nd argument when terms of different types are expected in these positions -is_rec.erl:49: The call erlang:is_record(A::simple1_adt:d1(),any(),1) contains an opaque term as 1st argument when terms of different types are expected in these positions -is_rec.erl:53: The call erlang:is_record(A::simple1_adt:d1(),A::simple1_adt:d1(),any()) contains an opaque term as 2nd argument when terms of different types are expected in these positions -is_rec.erl:57: Guard test is_record(A::simple1_adt:d1(),'r',2) breaks the opacity of its argument -is_rec.erl:61: The record #r{f1::simple1_adt:d1()} violates the declared type for #r{} -is_rec.erl:65: The call erlang:is_record({simple1_adt:d1(),1},'r',2) contains an opaque term as 1st argument when terms of different types are expected in these positions -rec_api.erl:104: Matching of pattern {'r2', 10} tagged with a record name violates the declared type of #r2{f1::10} -rec_api.erl:113: The attempt to match a term of type #r3{f1::queue:queue(_)} against the pattern {'r3', 'a'} breaks the opacity of queue:queue(_) -rec_api.erl:118: Record construction #r3{f1::10} violates the declared type of field f1::queue:queue(_) -rec_api.erl:123: The attempt to match a term of type #r3{f1::10} against the pattern {'r3', 10} breaks the opacity of queue:queue(_) -rec_api.erl:24: Record construction #r1{f1::10} violates the declared type of field f1::rec_api:a() -rec_api.erl:29: Matching of pattern {'r1', 10} tagged with a record name violates the declared type of #r1{f1::10} -rec_api.erl:33: The attempt to match a term of type rec_adt:r1() against the pattern {'r1', 'a'} breaks the opacity of the term -rec_api.erl:35: Invalid type specification for function rec_api:adt_t1/1. The success typing is (#r1{f1::'a'}) -> #r1{f1::'a'} -rec_api.erl:40: The specification for rec_api:adt_r1/0 has an opaque subtype rec_adt:r1() which is violated by the success typing () -> #r1{f1::'a'} -rec_api.erl:85: The attempt to match a term of type rec_adt:f() against the record field 'f' declared to be of type rec_api:f() breaks the opacity of the term -rec_api.erl:99: Record construction #r2{f1::10} violates the declared type of field f1::rec_api:a() -simple1_api.erl:113: The test simple1_api:d1() =:= simple1_api:d2() can never evaluate to 'true' -simple1_api.erl:118: Guard test simple1_api:d2() =:= A::simple1_api:d1() can never succeed -simple1_api.erl:142: Attempt to test for equality between a term of type simple1_adt:o2() and a term of opaque type simple1_adt:o1() -simple1_api.erl:148: Guard test simple1_adt:o2() =:= A::simple1_adt:o1() contains opaque terms as 1st and 2nd arguments -simple1_api.erl:154: Attempt to test for inequality between a term of type simple1_adt:o2() and a term of opaque type simple1_adt:o1() -simple1_api.erl:160: Attempt to test for inequality between a term of type simple1_adt:o2() and a term of opaque type simple1_adt:o1() -simple1_api.erl:165: Attempt to test for equality between a term of type simple1_adt:c2() and a term of opaque type simple1_adt:c1() -simple1_api.erl:181: Guard test A::simple1_adt:d1() =< B::simple1_adt:d2() contains opaque terms as 1st and 2nd arguments -simple1_api.erl:185: Guard test 'a' =< B::simple1_adt:d2() contains an opaque term as 2nd argument -simple1_api.erl:189: Guard test A::simple1_adt:d1() =< 'd' contains an opaque term as 1st argument -simple1_api.erl:197: The type test is_integer(A::simple1_adt:d1()) breaks the opacity of the term A::simple1_adt:d1() -simple1_api.erl:221: Guard test A::simple1_api:i1() > 3 can never succeed -simple1_api.erl:225: Guard test A::simple1_adt:i1() > 3 contains an opaque term as 1st argument -simple1_api.erl:233: Guard test A::simple1_adt:i1() < 3 contains an opaque term as 1st argument -simple1_api.erl:239: Guard test A::1 > 3 can never succeed -simple1_api.erl:243: Guard test A::1 > 3 can never succeed -simple1_api.erl:257: Guard test is_function(T::simple1_api:o1()) can never succeed -simple1_api.erl:265: Guard test is_function(T::simple1_adt:o1()) breaks the opacity of its argument -simple1_api.erl:269: The type test is_function(T::simple1_adt:o1()) breaks the opacity of the term T::simple1_adt:o1() -simple1_api.erl:274: Guard test is_function(T::simple1_api:o1(),A::simple1_api:i1()) can never succeed -simple1_api.erl:284: Guard test is_function(T::simple1_adt:o1(),A::simple1_adt:i1()) breaks the opacity of its argument -simple1_api.erl:289: The type test is_function(T::simple1_adt:o1(),A::simple1_adt:i1()) breaks the opacity of the term T::simple1_adt:o1() -simple1_api.erl:294: The call erlang:is_function(T::simple1_api:o1(),A::simple1_adt:i1()) contains an opaque term as 2nd argument when terms of different types are expected in these positions -simple1_api.erl:300: The type test is_function(T::simple1_adt:o1(),A::simple1_api:i1()) breaks the opacity of the term T::simple1_adt:o1() -simple1_api.erl:306: Guard test B::simple1_api:b2() =:= 'true' can never succeed -simple1_api.erl:315: Guard test A::simple1_api:b1() =:= 'false' can never succeed -simple1_api.erl:319: Guard test not(and('true','true')) can never succeed -simple1_api.erl:337: Clause guard cannot succeed. -simple1_api.erl:342: Guard test B::simple1_adt:b2() =:= 'true' contains an opaque term as 1st argument -simple1_api.erl:347: Guard test A::simple1_adt:b1() =:= 'true' contains an opaque term as 1st argument -simple1_api.erl:355: Invalid type specification for function simple1_api:bool_adt_t6/1. The success typing is ('true') -> 1 -simple1_api.erl:365: Clause guard cannot succeed. -simple1_api.erl:368: Invalid type specification for function simple1_api:bool_adt_t8/2. The success typing is (boolean(),boolean()) -> 1 -simple1_api.erl:378: Clause guard cannot succeed. -simple1_api.erl:381: Invalid type specification for function simple1_api:bool_adt_t9/2. The success typing is ('false','false') -> 1 -simple1_api.erl:407: The size simple1_adt:i1() breaks the opacity of A -simple1_api.erl:418: The attempt to match a term of type non_neg_integer() against the variable A breaks the opacity of simple1_adt:i1() -simple1_api.erl:425: The attempt to match a term of type non_neg_integer() against the variable B breaks the opacity of simple1_adt:i1() -simple1_api.erl:432: The pattern <<_:B>> can never match the type any() -simple1_api.erl:448: The attempt to match a term of type non_neg_integer() against the variable Sz breaks the opacity of simple1_adt:i1() -simple1_api.erl:460: The attempt to match a term of type simple1_adt:bit1() against the pattern <<_/binary>> breaks the opacity of the term -simple1_api.erl:478: The call 'foo':A(A::simple1_adt:a()) breaks the opacity of the term A :: simple1_adt:a() -simple1_api.erl:486: The call A:'foo'(A::simple1_adt:a()) breaks the opacity of the term A :: simple1_adt:a() -simple1_api.erl:499: The call 'foo':A(A::simple1_api:i()) requires that A is of type atom() not simple1_api:i() -simple1_api.erl:503: The call 'foo':A(A::simple1_adt:i()) requires that A is of type atom() not simple1_adt:i() -simple1_api.erl:507: The call A:'foo'(A::simple1_api:i()) requires that A is of type atom() not simple1_api:i() -simple1_api.erl:511: The call A:'foo'(A::simple1_adt:i()) requires that A is of type atom() not simple1_adt:i() -simple1_api.erl:519: Guard test A::simple1_adt:d2() == B::simple1_adt:d1() contains opaque terms as 1st and 2nd arguments -simple1_api.erl:534: Guard test A::simple1_adt:d1() >= 3 contains an opaque term as 1st argument -simple1_api.erl:536: Guard test A::simple1_adt:d1() == 3 contains an opaque term as 1st argument -simple1_api.erl:538: Guard test A::simple1_adt:d1() =:= 3 contains an opaque term as 1st argument -simple1_api.erl:548: The call erlang:'<'(A::simple1_adt:d1(),3) contains an opaque term as 1st argument when terms of different types are expected in these positions -simple1_api.erl:558: The call erlang:'=<'(A::simple1_adt:d1(),B::simple1_adt:d2()) contains opaque terms as 1st and 2nd arguments when terms of different types are expected in these positions -simple1_api.erl:565: Guard test {digraph:graph(),3} > {digraph:graph(),atom() | ets:tid()} contains an opaque term as 2nd argument -simple1_api.erl:91: The specification for simple1_api:tup/0 has an opaque subtype simple1_adt:tuple1() which is violated by the success typing () -> {'a','b'} -simple2_api.erl:100: The call lists:flatten(A::simple1_adt:tuple1()) contains an opaque term as 1st argument when a structured term of type [any()] is expected -simple2_api.erl:116: The call lists:flatten({simple1_adt:tuple1()}) will never return since it differs in the 1st argument from the success typing arguments: ([any()]) -simple2_api.erl:121: Guard test {simple1_adt:d1(),3} > {simple1_adt:d1(),simple1_adt:tuple1()} contains an opaque term as 2nd argument -simple2_api.erl:125: The call erlang:tuple_to_list(B::simple1_adt:tuple1()) contains an opaque term as 1st argument when a structured term of type tuple() is expected -simple2_api.erl:31: The call erlang:'!'(A::simple1_adt:d1(),'foo') contains an opaque term as 1st argument when terms of different types are expected in these positions -simple2_api.erl:35: The call erlang:send(A::simple1_adt:d1(),'foo') contains an opaque term as 1st argument when terms of different types are expected in these positions -simple2_api.erl:51: The call erlang:'<'(A::simple1_adt:d1(),3) contains an opaque term as 1st argument when terms of different types are expected in these positions -simple2_api.erl:59: The call lists:keysearch(1,A::simple1_adt:d1(),[]) contains an opaque term as 2nd argument when terms of different types are expected in these positions -simple2_api.erl:67: The call lists:keysearch('key',1,A::simple1_adt:tuple1()) contains an opaque term as 3rd argument when terms of different types are expected in these positions -simple2_api.erl:96: The call lists:keyreplace('a',1,[{1, 2}],A::simple1_adt:tuple1()) contains an opaque term as 4th argument when terms of different types are expected in these positions +exact_api.erl:17:14: The call exact_api:set_type(A::#digraph{vtab::'notable',etab::'notable',ntab::'notable',cyclic::'true'}) does not have an opaque term of type digraph:graph() as 1st argument +exact_api.erl:23:20: The call digraph:delete(G::#digraph{vtab::'notable',etab::'notable',ntab::'notable',cyclic::'true'}) does not have an opaque term of type digraph:graph() as 1st argument +exact_api.erl:55:5: The attempt to match a term of type exact_adt:exact_adt() against the pattern {'exact_adt'} breaks the opacity of the term +exact_api.erl:59:39: The call exact_adt:exact_adt_set_type2(A::#exact_adt{}) does not have an opaque term of type exact_adt:exact_adt() as 1st argument +is_rec.erl:10:5: The call erlang:is_record(simple1_adt:d1(),'r',2) contains an opaque term as 1st argument when terms of different types are expected in these positions +is_rec.erl:15:15: The call erlang:is_record(A::simple1_adt:d1(),'r',I::1 | 2 | 3) contains an opaque term as 1st argument when terms of different types are expected in these positions +is_rec.erl:19:18: Guard test is_record(A::simple1_adt:d1(),'r',2) breaks the opacity of its argument +is_rec.erl:23:18: Guard test is_record({simple1_adt:d1(),1},'r',2) breaks the opacity of its argument +is_rec.erl:41:15: The call erlang:is_record(A::simple1_adt:d1(),R::'a') contains an opaque term as 1st argument when terms of different types are expected in these positions +is_rec.erl:45:18: The call erlang:is_record(A::simple1_adt:d1(),A::simple1_adt:d1(),1) contains an opaque term as 2nd argument when terms of different types are expected in these positions +is_rec.erl:49:15: The call erlang:is_record(A::simple1_adt:d1(),any(),1) contains an opaque term as 1st argument when terms of different types are expected in these positions +is_rec.erl:53:18: The call erlang:is_record(A::simple1_adt:d1(),A::simple1_adt:d1(),any()) contains an opaque term as 2nd argument when terms of different types are expected in these positions +is_rec.erl:57:18: Guard test is_record(A::simple1_adt:d1(),'r',2) breaks the opacity of its argument +is_rec.erl:61:8: The record #r{f1::simple1_adt:d1()} violates the declared type for #r{} +is_rec.erl:65:5: The call erlang:is_record({simple1_adt:d1(),1},'r',2) contains an opaque term as 1st argument when terms of different types are expected in these positions +rec_api.erl:104:5: Matching of pattern {'r2', 10} tagged with a record name violates the declared type of #r2{f1::10} +rec_api.erl:113:5: The attempt to match a term of type #r3{f1::queue:queue(_)} against the pattern {'r3', 'a'} breaks the opacity of queue:queue(_) +rec_api.erl:118:18: Record construction #r3{f1::10} violates the declared type of field f1::queue:queue(_) +rec_api.erl:123:5: The attempt to match a term of type #r3{f1::10} against the pattern {'r3', 10} breaks the opacity of queue:queue(_) +rec_api.erl:24:18: Record construction #r1{f1::10} violates the declared type of field f1::rec_api:a() +rec_api.erl:29:5: Matching of pattern {'r1', 10} tagged with a record name violates the declared type of #r1{f1::10} +rec_api.erl:33:5: The attempt to match a term of type rec_adt:r1() against the pattern {'r1', 'a'} breaks the opacity of the term +rec_api.erl:35:2: Invalid type specification for function rec_api:adt_t1/1. The success typing is (#r1{f1::'a'}) -> #r1{f1::'a'} +rec_api.erl:40:2: The specification for rec_api:adt_r1/0 has an opaque subtype rec_adt:r1() which is violated by the success typing () -> #r1{f1::'a'} +rec_api.erl:85:13: The attempt to match a term of type rec_adt:f() against the record field 'f' declared to be of type rec_api:f() breaks the opacity of the term +rec_api.erl:99:18: Record construction #r2{f1::10} violates the declared type of field f1::rec_api:a() +simple1_api.erl:113:5: The test simple1_api:d1() =:= simple1_api:d2() can never evaluate to 'true' +simple1_api.erl:118:5: Guard test simple1_api:d2() =:= A::simple1_api:d1() can never succeed +simple1_api.erl:142:5: Attempt to test for equality between a term of type simple1_adt:o2() and a term of opaque type simple1_adt:o1() +simple1_api.erl:148:5: Guard test simple1_adt:o2() =:= A::simple1_adt:o1() contains opaque terms as 1st and 2nd arguments +simple1_api.erl:154:5: Attempt to test for inequality between a term of type simple1_adt:o2() and a term of opaque type simple1_adt:o1() +simple1_api.erl:160:5: Attempt to test for inequality between a term of type simple1_adt:o2() and a term of opaque type simple1_adt:o1() +simple1_api.erl:165:5: Attempt to test for equality between a term of type simple1_adt:c2() and a term of opaque type simple1_adt:c1() +simple1_api.erl:181:8: Guard test A::simple1_adt:d1() =< B::simple1_adt:d2() contains opaque terms as 1st and 2nd arguments +simple1_api.erl:185:13: Guard test 'a' =< B::simple1_adt:d2() contains an opaque term as 2nd argument +simple1_api.erl:189:8: Guard test A::simple1_adt:d1() =< 'd' contains an opaque term as 1st argument +simple1_api.erl:197:5: The type test is_integer(A::simple1_adt:d1()) breaks the opacity of the term A::simple1_adt:d1() +simple1_api.erl:221:8: Guard test A::simple1_api:i1() > 3 can never succeed +simple1_api.erl:225:8: Guard test A::simple1_adt:i1() > 3 contains an opaque term as 1st argument +simple1_api.erl:233:8: Guard test A::simple1_adt:i1() < 3 contains an opaque term as 1st argument +simple1_api.erl:239:8: Guard test A::1 > 3 can never succeed +simple1_api.erl:243:8: Guard test A::1 > 3 can never succeed +simple1_api.erl:257:8: Guard test is_function(T::simple1_api:o1()) can never succeed +simple1_api.erl:265:20: Guard test is_function(T::simple1_adt:o1()) breaks the opacity of its argument +simple1_api.erl:269:5: The type test is_function(T::simple1_adt:o1()) breaks the opacity of the term T::simple1_adt:o1() +simple1_api.erl:274:8: Guard test is_function(T::simple1_api:o1(),A::simple1_api:i1()) can never succeed +simple1_api.erl:284:20: Guard test is_function(T::simple1_adt:o1(),A::simple1_adt:i1()) breaks the opacity of its argument +simple1_api.erl:289:5: The type test is_function(T::simple1_adt:o1(),A::simple1_adt:i1()) breaks the opacity of the term T::simple1_adt:o1() +simple1_api.erl:294:20: The call erlang:is_function(T::simple1_api:o1(),A::simple1_adt:i1()) contains an opaque term as 2nd argument when terms of different types are expected in these positions +simple1_api.erl:300:5: The type test is_function(T::simple1_adt:o1(),A::simple1_api:i1()) breaks the opacity of the term T::simple1_adt:o1() +simple1_api.erl:306:8: Guard test B::simple1_api:b2() =:= 'true' can never succeed +simple1_api.erl:315:8: Guard test A::simple1_api:b1() =:= 'false' can never succeed +simple1_api.erl:319:16: Guard test not(and('true','true')) can never succeed +simple1_api.erl:337:8: Clause guard cannot succeed. +simple1_api.erl:342:8: Guard test B::simple1_adt:b2() =:= 'true' contains an opaque term as 1st argument +simple1_api.erl:347:8: Guard test A::simple1_adt:b1() =:= 'true' contains an opaque term as 1st argument +simple1_api.erl:355:2: Invalid type specification for function simple1_api:bool_adt_t6/1. The success typing is ('true') -> 1 +simple1_api.erl:365:8: Clause guard cannot succeed. +simple1_api.erl:368:2: Invalid type specification for function simple1_api:bool_adt_t8/2. The success typing is (boolean(),boolean()) -> 1 +simple1_api.erl:378:8: Clause guard cannot succeed. +simple1_api.erl:381:2: Invalid type specification for function simple1_api:bool_adt_t9/2. The success typing is ('false','false') -> 1 +simple1_api.erl:407:12: The size simple1_adt:i1() breaks the opacity of A +simple1_api.erl:418:9: The attempt to match a term of type non_neg_integer() against the variable A breaks the opacity of simple1_adt:i1() +simple1_api.erl:425:9: The attempt to match a term of type non_neg_integer() against the variable B breaks the opacity of simple1_adt:i1() +simple1_api.erl:432:9: The pattern <<_:B>> can never match the type any() +simple1_api.erl:448:9: The attempt to match a term of type non_neg_integer() against the variable Sz breaks the opacity of simple1_adt:i1() +simple1_api.erl:460:9: The attempt to match a term of type simple1_adt:bit1() against the pattern <<_/binary>> breaks the opacity of the term +simple1_api.erl:478:9: The call 'foo':A(A::simple1_adt:a()) breaks the opacity of the term A :: simple1_adt:a() +simple1_api.erl:486:5: The call A:'foo'(A::simple1_adt:a()) breaks the opacity of the term A :: simple1_adt:a() +simple1_api.erl:499:9: The call 'foo':A(A::simple1_api:i()) requires that A is of type atom() not simple1_api:i() +simple1_api.erl:503:9: The call 'foo':A(A::simple1_adt:i()) requires that A is of type atom() not simple1_adt:i() +simple1_api.erl:507:5: The call A:'foo'(A::simple1_api:i()) requires that A is of type atom() not simple1_api:i() +simple1_api.erl:511:5: The call A:'foo'(A::simple1_adt:i()) requires that A is of type atom() not simple1_adt:i() +simple1_api.erl:519:9: Guard test A::simple1_adt:d2() == B::simple1_adt:d1() contains opaque terms as 1st and 2nd arguments +simple1_api.erl:534:9: Guard test A::simple1_adt:d1() >= 3 contains an opaque term as 1st argument +simple1_api.erl:536:9: Guard test A::simple1_adt:d1() == 3 contains an opaque term as 1st argument +simple1_api.erl:538:9: Guard test A::simple1_adt:d1() =:= 3 contains an opaque term as 1st argument +simple1_api.erl:548:5: The call erlang:'<'(A::simple1_adt:d1(),3) contains an opaque term as 1st argument when terms of different types are expected in these positions +simple1_api.erl:558:5: The call erlang:'=<'(A::simple1_adt:d1(),B::simple1_adt:d2()) contains opaque terms as 1st and 2nd arguments when terms of different types are expected in these positions +simple1_api.erl:565:17: Guard test {digraph:graph(),3} > {digraph:graph(),atom() | ets:tid()} contains an opaque term as 2nd argument +simple1_api.erl:91:2: The specification for simple1_api:tup/0 has an opaque subtype simple1_adt:tuple1() which is violated by the success typing () -> {'a','b'} +simple2_api.erl:100:19: The call lists:flatten(A::simple1_adt:tuple1()) contains an opaque term as 1st argument when a structured term of type [any()] is expected +simple2_api.erl:116:19: The call lists:flatten({simple1_adt:tuple1()}) will never return since it differs in the 1st argument from the success typing arguments: ([any()]) +simple2_api.erl:121:16: Guard test {simple1_adt:d1(),3} > {simple1_adt:d1(),simple1_adt:tuple1()} contains an opaque term as 2nd argument +simple2_api.erl:125:19: The call erlang:tuple_to_list(B::simple1_adt:tuple1()) contains an opaque term as 1st argument when a structured term of type tuple() is expected +simple2_api.erl:31:5: The call erlang:'!'(A::simple1_adt:d1(),'foo') contains an opaque term as 1st argument when terms of different types are expected in these positions +simple2_api.erl:35:17: The call erlang:send(A::simple1_adt:d1(),'foo') contains an opaque term as 1st argument when terms of different types are expected in these positions +simple2_api.erl:51:5: The call erlang:'<'(A::simple1_adt:d1(),3) contains an opaque term as 1st argument when terms of different types are expected in these positions +simple2_api.erl:59:24: The call lists:keysearch(1,A::simple1_adt:d1(),[]) contains an opaque term as 2nd argument when terms of different types are expected in these positions +simple2_api.erl:67:29: The call lists:keysearch('key',1,A::simple1_adt:tuple1()) contains an opaque term as 3rd argument when terms of different types are expected in these positions +simple2_api.erl:96:37: The call lists:keyreplace('a',1,[{1, 2}],A::simple1_adt:tuple1()) contains an opaque term as 4th argument when terms of different types are expected in these positions diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/timer b/lib/dialyzer/test/opaque_SUITE_data/results/timer index 46c5a86307..d921968bc8 100644 --- a/lib/dialyzer/test/opaque_SUITE_data/results/timer +++ b/lib/dialyzer/test/opaque_SUITE_data/results/timer @@ -1,4 +1,4 @@ -timer_use.erl:16: The pattern 'gazonk' can never match the type {'error',_} | {'ok',timer:tref()} -timer_use.erl:17: The attempt to match a term of type {'error',_} | {'ok',timer:tref()} against the pattern {'ok', 42} breaks the opacity of timer:tref() -timer_use.erl:18: The attempt to match a term of type {'error',_} | {'ok',timer:tref()} against the pattern {Tag, 'gazonk'} breaks the opacity of timer:tref() +timer_use.erl:16:5: The pattern 'gazonk' can never match the type {'error',_} | {'ok',timer:tref()} +timer_use.erl:17:5: The attempt to match a term of type {'error',_} | {'ok',timer:tref()} against the pattern {'ok', 42} breaks the opacity of timer:tref() +timer_use.erl:18:5: The attempt to match a term of type {'error',_} | {'ok',timer:tref()} against the pattern {Tag, 'gazonk'} breaks the opacity of timer:tref() diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/union b/lib/dialyzer/test/opaque_SUITE_data/results/union index 8763088bf0..c05e17999e 100644 --- a/lib/dialyzer/test/opaque_SUITE_data/results/union +++ b/lib/dialyzer/test/opaque_SUITE_data/results/union @@ -1,5 +1,5 @@ -union_use.erl:12: The attempt to match a term of type union_adt:u() against the pattern 'aaa' breaks the opacity of the term -union_use.erl:16: The type test is_tuple(union_adt:u()) breaks the opacity of the term union_adt:u() -union_use.erl:7: Guard test is_atom(A::union_adt:u()) breaks the opacity of its argument -union_use.erl:8: Guard test is_tuple(T::union_adt:u()) breaks the opacity of its argument +union_use.erl:12:3: The attempt to match a term of type union_adt:u() against the pattern 'aaa' breaks the opacity of the term +union_use.erl:16:3: The type test is_tuple(union_adt:u()) breaks the opacity of the term union_adt:u() +union_use.erl:7:20: Guard test is_atom(A::union_adt:u()) breaks the opacity of its argument +union_use.erl:8:21: Guard test is_tuple(T::union_adt:u()) breaks the opacity of its argument diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/weird b/lib/dialyzer/test/opaque_SUITE_data/results/weird index d7f57cd152..8b9cda85dd 100644 --- a/lib/dialyzer/test/opaque_SUITE_data/results/weird +++ b/lib/dialyzer/test/opaque_SUITE_data/results/weird @@ -1,6 +1,6 @@ -weird_warning1.erl:15: Matching of pattern {'a', Dict} tagged with a record name violates the declared type of #b{q::queue:queue(_)} -weird_warning2.erl:13: Matching of pattern <{'b', Queue}, Key, Value> tagged with a record name violates the declared type of <#a{d::dict:dict(_,_)},'my_key','my_value'> -weird_warning3.erl:14: The call weird_warning3:add_element(#a{d::queue:queue(_)},'my_key','my_value') does not have a term of type #a{d::dict:dict(_,_)} | #b{q::queue:queue(_)} (with opaque subterms) as 1st argument -weird_warning3.erl:16: The attempt to match a term of type #a{d::queue:queue(_)} against the pattern {'a', Dict} breaks the opacity of queue:queue(_) -weird_warning3.erl:18: Matching of pattern {'b', Queue} tagged with a record name violates the declared type of #a{d::queue:queue(_)} +weird_warning1.erl:15:1: Matching of pattern {'a', Dict} tagged with a record name violates the declared type of #b{q::queue:queue(_)} +weird_warning2.erl:13:1: Matching of pattern <{'b', Queue}, Key, Value> tagged with a record name violates the declared type of <#a{d::dict:dict(_,_)},'my_key','my_value'> +weird_warning3.erl:14:17: The call weird_warning3:add_element(#a{d::queue:queue(_)},'my_key','my_value') does not have a term of type #a{d::dict:dict(_,_)} | #b{q::queue:queue(_)} (with opaque subterms) as 1st argument +weird_warning3.erl:16:1: The attempt to match a term of type #a{d::queue:queue(_)} against the pattern {'a', Dict} breaks the opacity of queue:queue(_) +weird_warning3.erl:18:1: Matching of pattern {'b', Queue} tagged with a record name violates the declared type of #a{d::queue:queue(_)} diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/wings b/lib/dialyzer/test/opaque_SUITE_data/results/wings index 391501d86f..8cb4602e3d 100644 --- a/lib/dialyzer/test/opaque_SUITE_data/results/wings +++ b/lib/dialyzer/test/opaque_SUITE_data/results/wings @@ -1,11 +1,11 @@ -wings_dissolve.erl:103: Guard test is_list(List::gb_sets:set(_)) breaks the opacity of its argument -wings_dissolve.erl:19: Guard test is_list(Faces::gb_sets:set(_)) breaks the opacity of its argument -wings_dissolve.erl:272: Guard test is_list(Faces::gb_sets:set(_)) breaks the opacity of its argument -wings_dissolve.erl:31: The call gb_sets:is_empty(Faces::[any(),...]) does not have an opaque term of type gb_sets:set(_) as 1st argument -wings_edge.erl:205: The pattern <Edge, 'hard', Htab> can never match the type <_,'soft',_> -wings_edge_cmd.erl:30: The call gb_trees:size(P::gb_sets:set(_)) does not have an opaque term of type gb_trees:tree(_,_) as 1st argument -wings_edge_cmd.erl:32: The pattern [_ | Parts] can never match the type [] -wings_edge_cmd.erl:32: The pattern [{_, P} | _] can never match the type [] -wings_io.erl:30: The attempt to match a term of type {'empty',queue:queue(_)} against the pattern {'empty', {In, Out}} breaks the opacity of queue:queue(_) -wings_we.erl:155: The call wings_util:gb_trees_largest_key(Etab::gb_trees:tree(_,_)) contains an opaque term as 1st argument when a structured term of type {_,{_,_,_,'nil' | {_,_,_,'nil' | {_,_,_,_}}}} is expected +wings_dissolve.erl:103:30: Guard test is_list(List::gb_sets:set(_)) breaks the opacity of its argument +wings_dissolve.erl:19:21: Guard test is_list(Faces::gb_sets:set(_)) breaks the opacity of its argument +wings_dissolve.erl:272:45: Guard test is_list(Faces::gb_sets:set(_)) breaks the opacity of its argument +wings_dissolve.erl:31:27: The call gb_sets:is_empty(Faces::[any(),...]) does not have an opaque term of type gb_sets:set(_) as 1st argument +wings_edge.erl:205:1: The pattern <Edge, 'hard', Htab> can never match the type <_,'soft',_> +wings_edge_cmd.erl:30:31: The call gb_trees:size(P::gb_sets:set(_)) does not have an opaque term of type gb_trees:tree(_,_) as 1st argument +wings_edge_cmd.erl:32:18: The pattern [{_, P} | _] can never match the type [] +wings_edge_cmd.erl:32:6: The pattern [_ | Parts] can never match the type [] +wings_io.erl:30:2: The attempt to match a term of type {'empty',queue:queue(_)} against the pattern {'empty', {In, Out}} breaks the opacity of queue:queue(_) +wings_we.erl:155:37: The call wings_util:gb_trees_largest_key(Etab::gb_trees:tree(_,_)) contains an opaque term as 1st argument when a structured term of type {_,{_,_,_,'nil' | {_,_,_,'nil' | {_,_,_,_}}}} is expected diff --git a/lib/dialyzer/test/options1_SUITE_data/results/compiler b/lib/dialyzer/test/options1_SUITE_data/results/compiler index 121163d7ca..093fbd83c8 100644 --- a/lib/dialyzer/test/options1_SUITE_data/results/compiler +++ b/lib/dialyzer/test/options1_SUITE_data/results/compiler @@ -1,38 +1,38 @@ -beam_asm.erl:32: The pattern {'error', Error} can never match the type <<_:64,_:_*8>> -beam_bool.erl:193: The pattern {[], _} can never match the type {[{_,_,_,_},...],[any()]} -beam_bool.erl:510: The pattern [{'set', [Dst], _, _}, {'%live', _}] can never match the type [{_,_,_,_}] -beam_disasm.erl:537: The variable X can never match since previous clauses completely covered the type 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 -beam_type.erl:284: The pattern <'pi', 0> can never match the type <_,1 | 2> -beam_validator.erl:396: Matching of pattern {'vst', 'none', _} tagged with a record name violates the declared type of #vst{current::#st{ct::[]}} -beam_validator.erl:690: The pattern <'term', OldT> can never match the type <{'tuple',[any(),...]},_> -beam_validator.erl:693: Guard test or('false','false') can never succeed -beam_validator.erl:700: Guard test or('false','false') can never succeed -beam_validator.erl:702: The pattern <'number', OldT = {Type, _}> can never match the type <{'tuple',[any(),...]},_> -beam_validator.erl:705: The pattern <'bool', {'atom', A}> can never match the type <{'tuple',[any(),...]},_> -beam_validator.erl:707: The pattern <{'atom', A}, 'bool'> can never match the type <{'tuple',[any(),...]},_> -beam_validator.erl:713: Guard test is_integer(Sz::[any(),...]) can never succeed -beam_validator.erl:727: Function upgrade_bool/1 will never be called -cerl_inline.erl:190: The pattern 'true' can never match the type 'false' -cerl_inline.erl:219: The pattern 'true' can never match the type 'false' -cerl_inline.erl:230: The pattern 'true' can never match the type 'false' -cerl_inline.erl:2333: The pattern 'true' can never match the type 'false' -cerl_inline.erl:2355: The pattern 'true' can never match the type 'false' -cerl_inline.erl:238: The pattern 'true' can never match the type 'false' -cerl_inline.erl:2436: Function filename/1 will never be called -cerl_inline.erl:244: Function counter_stats/0 will never be called -cerl_inline.erl:2700: The pattern 'true' can never match the type 'false' -cerl_inline.erl:2730: The pattern <{F, L, D}, Vs> can never match the type <[1..255,...],[any()]> -cerl_inline.erl:2738: The pattern <{F, L, D}, Vs> can never match the type <[1..255,...],[any()]> -cerl_inline.erl:2750: The pattern <{[], L, D}, Vs> can never match the type <[1..255,...],[any()]> -cerl_inline.erl:2752: The pattern <{[], _L, D}, Vs> can never match the type <[1..255,...],[any()]> -cerl_inline.erl:2754: The pattern <{F, L, D}, Vs> can never match the type <[1..255,...],[any()]> -cerl_inline.erl:2756: The pattern <{F, _L, D}, Vs> can never match the type <[1..255,...],[any()]> -compile.erl:792: The pattern {'error', Es} can never match the type {'ok',<<_:64,_:_*8>>} -core_lint.erl:473: The pattern <{'c_atom', _, 'all'}, 'binary', _Def, St> can never match the type <_,#c_nil{} | {'c_atom' | 'c_char' | 'c_float' | 'c_int' | 'c_string' | 'c_tuple',_,_} | #c_cons{hd::#c_nil{} | {'c_atom' | 'c_char' | 'c_float' | 'c_int' | 'c_string' | 'c_tuple',_,_} | #c_cons{hd::{_,_} | {_,_,_} | {_,_,_,_},tl::{_,_} | {_,_,_} | {_,_,_,_}},tl::#c_nil{} | {'c_atom' | 'c_char' | 'c_float' | 'c_int' | 'c_string' | 'c_tuple',_,_} | #c_cons{hd::{_,_} | {_,_,_} | {_,_,_,_},tl::{_,_} | {_,_,_} | {_,_,_,_}}},[any()],_> -core_lint.erl:505: The pattern <_Req, 'unknown', St> can never match the type <non_neg_integer(),non_neg_integer(),_> -sys_pre_expand.erl:625: Call to missing or unexported function erlang:hash/2 -v3_codegen.erl:1569: The call v3_codegen:load_reg_1(V::any(),I::0,Rs::any(),pos_integer()) will never return since it differs in the 4th argument from the success typing arguments: (any(),0,maybe_improper_list(),0) -v3_codegen.erl:1571: The call v3_codegen:load_reg_1(V::any(),I::0,[],pos_integer()) will never return since it differs in the 4th argument from the success typing arguments: (any(),0,maybe_improper_list(),0) -v3_core.erl:646: Matching of pattern {'iprimop', _, _, _} tagged with a record name violates the declared type of #c_nil{anno::[any(),...]} | {'c_atom' | 'c_char' | 'c_float' | 'c_int' | 'c_string' | 'c_tuple' | 'c_var' | 'ibinary' | 'icatch' | 'ireceive1',[any(),...] | {_,_,_,_},_} | #c_cons{anno::[any(),...]} | #c_fname{anno::[any(),...]} | #iletrec{anno::{_,_,_,_},defs::[any(),...],body::[any(),...]} | #icase{anno::{_,_,_,_},args::[any()],clauses::[any()],fc::{_,_,_,_,_,_}} | #ireceive2{anno::{_,_,_,_},clauses::[any()],action::[any()]} | #ifun{anno::{_,_,_,_},id::[any(),...],vars::[any()],clauses::[any(),...],fc::{_,_,_,_,_,_}} | #imatch{anno::{_,_,_,_},guard::[],fc::{_,_,_,_,_,_}} | #itry{anno::{_,_,_,_},args::[any()],vars::[any(),...],body::[any(),...],evars::[any(),...],handler::[any(),...]} -v3_kernel.erl:1381: Call to missing or unexported function erlang:hash/2 +beam_asm.erl:32:2: The pattern {'error', Error} can never match the type <<_:64,_:_*8>> +beam_bool.erl:193:2: The pattern {[], _} can never match the type {[{_,_,_,_},...],[any()]} +beam_bool.erl:510:1: The pattern [{'set', [Dst], _, _}, {'%live', _}] can never match the type [{_,_,_,_}] +beam_disasm.erl:537:1: The variable X can never match since previous clauses completely covered the type 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 +beam_type.erl:284:1: The pattern <'pi', 0> can never match the type <_,1 | 2> +beam_validator.erl:396:1: Matching of pattern {'vst', 'none', _} tagged with a record name violates the declared type of #vst{current::#st{ct::[]}} +beam_validator.erl:690:1: The pattern <'term', OldT> can never match the type <{'tuple',[any(),...]},_> +beam_validator.erl:693:13: Guard test or('false','false') can never succeed +beam_validator.erl:700:13: Guard test or('false','false') can never succeed +beam_validator.erl:702:1: The pattern <'number', OldT = {Type, _}> can never match the type <{'tuple',[any(),...]},_> +beam_validator.erl:705:1: The pattern <'bool', {'atom', A}> can never match the type <{'tuple',[any(),...]},_> +beam_validator.erl:707:1: The pattern <{'atom', A}, 'bool'> can never match the type <{'tuple',[any(),...]},_> +beam_validator.erl:713:8: Guard test is_integer(Sz::[any(),...]) can never succeed +beam_validator.erl:727:1: Function upgrade_bool/1 will never be called +cerl_inline.erl:190:9: The pattern 'true' can never match the type 'false' +cerl_inline.erl:219:9: The pattern 'true' can never match the type 'false' +cerl_inline.erl:230:9: The pattern 'true' can never match the type 'false' +cerl_inline.erl:2333:9: The pattern 'true' can never match the type 'false' +cerl_inline.erl:2355:9: The pattern 'true' can never match the type 'false' +cerl_inline.erl:238:9: The pattern 'true' can never match the type 'false' +cerl_inline.erl:2436:1: Function filename/1 will never be called +cerl_inline.erl:244:1: Function counter_stats/0 will never be called +cerl_inline.erl:2700:3: The pattern 'true' can never match the type 'false' +cerl_inline.erl:2730:1: The pattern <{F, L, D}, Vs> can never match the type <[1..255,...],[any()]> +cerl_inline.erl:2738:1: The pattern <{F, L, D}, Vs> can never match the type <[1..255,...],[any()]> +cerl_inline.erl:2750:1: The pattern <{[], L, D}, Vs> can never match the type <[1..255,...],[any()]> +cerl_inline.erl:2752:1: The pattern <{[], _L, D}, Vs> can never match the type <[1..255,...],[any()]> +cerl_inline.erl:2754:1: The pattern <{F, L, D}, Vs> can never match the type <[1..255,...],[any()]> +cerl_inline.erl:2756:1: The pattern <{F, _L, D}, Vs> can never match the type <[1..255,...],[any()]> +compile.erl:792:2: The pattern {'error', Es} can never match the type {'ok',<<_:64,_:_*8>>} +core_lint.erl:473:1: The pattern <{'c_atom', _, 'all'}, 'binary', _Def, St> can never match the type <_,#c_nil{} | {'c_atom' | 'c_char' | 'c_float' | 'c_int' | 'c_string' | 'c_tuple',_,_} | #c_cons{hd::#c_nil{} | {'c_atom' | 'c_char' | 'c_float' | 'c_int' | 'c_string' | 'c_tuple',_,_} | #c_cons{hd::{_,_} | {_,_,_} | {_,_,_,_},tl::{_,_} | {_,_,_} | {_,_,_,_}},tl::#c_nil{} | {'c_atom' | 'c_char' | 'c_float' | 'c_int' | 'c_string' | 'c_tuple',_,_} | #c_cons{hd::{_,_} | {_,_,_} | {_,_,_,_},tl::{_,_} | {_,_,_} | {_,_,_,_}}},[any()],_> +core_lint.erl:505:1: The pattern <_Req, 'unknown', St> can never match the type <non_neg_integer(),non_neg_integer(),_> +sys_pre_expand.erl:625:12: Call to missing or unexported function erlang:hash/2 +v3_codegen.erl:1569:57: The call v3_codegen:load_reg_1(V::any(),I::0,Rs::any(),pos_integer()) will never return since it differs in the 4th argument from the success typing arguments: (any(),0,maybe_improper_list(),0) +v3_codegen.erl:1571:56: The call v3_codegen:load_reg_1(V::any(),I::0,[],pos_integer()) will never return since it differs in the 4th argument from the success typing arguments: (any(),0,maybe_improper_list(),0) +v3_core.erl:646:1: Matching of pattern {'iprimop', _, _, _} tagged with a record name violates the declared type of #c_nil{anno::[any(),...]} | {'c_atom' | 'c_char' | 'c_float' | 'c_int' | 'c_string' | 'c_tuple' | 'c_var' | 'ibinary' | 'icatch' | 'ireceive1',[any(),...] | {_,_,_,_},_} | #c_cons{anno::[any(),...]} | #c_fname{anno::[any(),...]} | #iletrec{anno::{_,_,_,_},defs::[any(),...],body::[any(),...]} | #icase{anno::{_,_,_,_},args::[any()],clauses::[any()],fc::{_,_,_,_,_,_}} | #ireceive2{anno::{_,_,_,_},clauses::[any()],action::[any()]} | #ifun{anno::{_,_,_,_},id::[any(),...],vars::[any()],clauses::[any(),...],fc::{_,_,_,_,_,_}} | #imatch{anno::{_,_,_,_},guard::[],fc::{_,_,_,_,_,_}} | #itry{anno::{_,_,_,_},args::[any()],vars::[any(),...],body::[any(),...],evars::[any(),...],handler::[any(),...]} +v3_kernel.erl:1381:7: Call to missing or unexported function erlang:hash/2 diff --git a/lib/dialyzer/test/overspecs_SUITE_data/results/iodata b/lib/dialyzer/test/overspecs_SUITE_data/results/iodata index d9c70330ec..bc8466d59a 100644 --- a/lib/dialyzer/test/overspecs_SUITE_data/results/iodata +++ b/lib/dialyzer/test/overspecs_SUITE_data/results/iodata @@ -1,2 +1,2 @@ -iodata.erl:7: The success typing for iodata:encode/2 implies that the function might also return integer() but the specification return is binary() | maybe_improper_list(binary() | maybe_improper_list(any(),binary() | []) | byte(),binary() | []) +iodata.erl:7:2: The success typing for iodata:encode/2 implies that the function might also return integer() but the specification return is binary() | maybe_improper_list(binary() | maybe_improper_list(any(),binary() | []) | byte(),binary() | []) diff --git a/lib/dialyzer/test/overspecs_SUITE_data/results/iolist b/lib/dialyzer/test/overspecs_SUITE_data/results/iolist index ca556f017c..e348bbbd0b 100644 --- a/lib/dialyzer/test/overspecs_SUITE_data/results/iolist +++ b/lib/dialyzer/test/overspecs_SUITE_data/results/iolist @@ -1,2 +1,2 @@ -iolist.erl:7: The success typing for iolist:encode/2 implies that the function might also return integer() but the specification return is maybe_improper_list(binary() | maybe_improper_list(any(),binary() | []) | byte(),binary() | []) +iolist.erl:7:2: The success typing for iolist:encode/2 implies that the function might also return integer() but the specification return is maybe_improper_list(binary() | maybe_improper_list(any(),binary() | []) | byte(),binary() | []) diff --git a/lib/dialyzer/test/plt_SUITE.erl b/lib/dialyzer/test/plt_SUITE.erl index 0c7078b9bf..21b5a77fb6 100644 --- a/lib/dialyzer/test/plt_SUITE.erl +++ b/lib/dialyzer/test/plt_SUITE.erl @@ -285,7 +285,7 @@ bad_dialyzer_attr(Config) -> {dialyzer_error, "Analysis failed with error:\n" ++ Str1} = (catch dialyzer:run(Opts)), - S1 = string:find(Str1, "dial.erl:2: function undef/0 undefined"), + S1 = string:find(Str1, "dial.erl:2:17: function undef/0 undefined"), true = is_list(S1), Prog2 = <<"-module(dial). @@ -294,7 +294,7 @@ bad_dialyzer_attr(Config) -> {dialyzer_error, "Analysis failed with error:\n" ++ Str2} = (catch dialyzer:run(Opts)), - S2 = string:find(Str2, "dial.erl:2: badly formed dialyzer " + S2 = string:find(Str2, "dial.erl:2:17: badly formed dialyzer " "attribute: {no_return,{undef,1,2}}"), true = is_list(S2), @@ -393,7 +393,7 @@ bad_record_type(Config) -> "Analysis failed with error:\n" ++ Str} = (catch dialyzer:run(Opts)), P = string:str(Str, - "bad_record_type.erl:4: Illegal declaration of #r{f}"), + "bad_record_type.erl:4:16: Illegal declaration of #r{f}"), true = P > 0, ok. diff --git a/lib/dialyzer/test/r9c_SUITE_data/results/asn1 b/lib/dialyzer/test/r9c_SUITE_data/results/asn1 index 6e51b972af..a56f57a8e4 100644 --- a/lib/dialyzer/test/r9c_SUITE_data/results/asn1 +++ b/lib/dialyzer/test/r9c_SUITE_data/results/asn1 @@ -1,102 +1,102 @@ -asn1ct.erl:1500: The variable Err can never match since previous clauses completely covered the type #type{} -asn1ct.erl:1596: The variable _ can never match since previous clauses completely covered the type 'ber_bin_v2' -asn1ct.erl:1673: The pattern 'all' can never match the type 'asn1_module' | 'exclusive_decode' | 'partial_decode' -asn1ct.erl:672: The pattern <{'false', Result}, _, _> can never match the type <{'true','true'},atom() | binary() | [atom() | [any()] | char()],[any()]> -asn1ct.erl:909: Guard test is_atom(Ext::[49 | 97 | 98 | 100 | 110 | 115]) can never succeed -asn1ct_check.erl:1698: The pattern {'error', _} can never match the type [any()] -asn1ct_check.erl:2733: Matching of pattern {'type', Tag, _, _, _, _} tagged with a record name violates the declared type of 'ASN1_OPEN_TYPE' | {_,_} | {'fixedtypevaluefield',_,_} -asn1ct_check.erl:2738: The pattern <_S, _> can never match since previous clauses completely covered the type <#state{},#'ObjectClassFieldType'{class::#objectclass{fields::maybe_improper_list() | {_,_,_,_}},fieldname::{_,maybe_improper_list()},type::'ASN1_OPEN_TYPE' | {_,_} | {'fixedtypevaluefield',_,_}}> -asn1ct_check.erl:2887: The variable Other can never match since previous clauses completely covered the type any() -asn1ct_check.erl:3188: The pattern <_S, [], B> can never match the type <#state{},{'SingleValue',_},{'ValueRange',_}> -asn1ct_check.erl:3190: The pattern <_S, A, []> can never match the type <#state{},{'SingleValue',_},{'ValueRange',_}> -asn1ct_check.erl:3212: The pattern {[], C3} can never match the type {[any(),...],{'ValueRange',{'MIN','MAX'}}} -asn1ct_check.erl:3225: The pattern {L1, UbNew} can never match the type 'false' -asn1ct_check.erl:3228: The pattern {L1, LbNew} can never match the type 'false' -asn1ct_check.erl:3235: The call asn1ct_check:remove_val_from_list(number(),L::[any(),...]) will never return since it differs in the 1st argument from the success typing arguments: ([any()],any()) -asn1ct_check.erl:3240: The call asn1ct_check:remove_val_from_list(number(),L::[any(),...]) will never return since it differs in the 1st argument from the success typing arguments: ([any()],any()) -asn1ct_check.erl:3242: Function remove_val_from_list/2 has no local return -asn1ct_check.erl:3243: The call lists:member(Val::[any(),...],List::number()) will never return since it differs in the 2nd argument from the success typing arguments: (any(),[any()]) -asn1ct_check.erl:3283: The pattern [] can never match the type [any(),...] -asn1ct_check.erl:3362: The pattern <_, [], _VR> can never match the type <#state{},[any(),...],[any(),...]> -asn1ct_check.erl:3364: The pattern <_, _SV, []> can never match the type <#state{},[any(),...],[any(),...]> -asn1ct_check.erl:4150: The pattern <_, [_]> can never match the type <_,[]> -asn1ct_check.erl:4314: The pattern <S, Type, {Rlist, ExtList}> can never match the type <#state{},_,[any()]> -asn1ct_check.erl:4360: The pattern <S, Type, {Rlist, ExtList}> can never match the type <#state{},_,[any()]> -asn1ct_check.erl:4719: The call asn1ct_check:error({'type',{'asn1',[1..255,...],[any(),...]}}) will never return since it differs in the 1st argument from the success typing arguments: ({'ObjectSet' | 'class' | 'export' | 'ptype' | 'type' | 'value',_,#state{}}) -asn1ct_check.erl:5120: Guard test is_record(Type::{_,_} | {'fixedtypevaluefield',_,_},'type',6) can never succeed -asn1ct_check.erl:5128: Guard test is_record(Type::{_,_} | {'fixedtypevaluefield',_,_},'type',6) can never succeed -asn1ct_check.erl:540: The pattern <_S, {'poc', _ObjSet, _Params}> can never match since previous clauses completely covered the type <#state{},_> -asn1ct_check.erl:5517: The pattern <_, []> can never match the type <_,[{'ABSTRACT-SYNTAX',{_,_,_}} | {'TYPE-IDENTIFIER',{_,_,_}},...]> -asn1ct_constructed_ber.erl:1075: The pattern {{{'ObjectClassFieldType', _, _, _, {'objectfield', PrimFieldName1, PFNList}}, _}, {'componentrelation', _, _}} can never match the type {#type{},_} -asn1ct_constructed_ber.erl:695: The pattern {'EXTENSIONMARK', _, _} can never match the type #'ComponentType'{} -asn1ct_constructed_ber.erl:748: The pattern <Erules, TopType, {CompList, _ExtList}> can never match the type <_,maybe_improper_list(),[#'ComponentType'{typespec::{_,_,_,_,_,_}}]> -asn1ct_constructed_ber_bin_v2.erl:914: The pattern {{{'ObjectClassFieldType', _, _, _, {'objectfield', PrimFieldName1, PFNList}}, _}, {'componentrelation', _, _}} can never match the type {#type{},_} -asn1ct_gen.erl:740: The pattern [] can never match the type [any(),...] -asn1ct_gen_ber.erl:974: The pattern <Erules, [{Name, Def} | Rest]> can never match the type <_,[#typedef{name::atom(),typespec::{_,_,_,_,_,_}}]> -asn1ct_gen_ber_bin_v2.erl:975: The pattern <Erules, [{Name, Def} | Rest]> can never match the type <_,[#typedef{name::atom(),typespec::{_,_,_,_,_,_}}]> -asn1ct_gen_per.erl:646: The pattern <Erules, [{Name, Def} | Rest]> can never match the type <_,[#typedef{name::atom()}]> -asn1ct_gen_per_rt2ct.erl:1189: The pattern <Erules, [{Name, Def} | Rest]> can never match the type <_,[#typedef{name::atom()}]> -asn1ct_gen_per_rt2ct.erl:563: The pattern <C, ['EXT_MARK' | T], _Count> can never match the type <[{'ValueRange',{_,_}},...],[char() | {'asn1_enum',integer()},...],non_neg_integer()> -asn1ct_gen_per_rt2ct.erl:580: The pattern <_C, 'EXT_MARK', _Count> can never match the type <[{'ValueRange',{_,_}},...],char(),non_neg_integer()> -asn1ct_gen_per_rt2ct.erl:583: The pattern <_C, {1, EnumName}, Count> can never match the type <[{'ValueRange',{_,_}},...],char(),non_neg_integer()> -asn1ct_gen_per_rt2ct.erl:587: The pattern <C, {0, EnumName}, Count> can never match the type <[{'ValueRange',{_,_}},...],char(),non_neg_integer()> -asn1ct_gen_per_rt2ct.erl:656: The pattern <Type, C> can never match since previous clauses completely covered the type <'bitstring' | 'integer',_> -asn1ct_parser2.erl:2017: Call to missing or unexported function ordsets:list_to_set/1 -asn1ct_parser2.erl:2497: The variable _ can never match since previous clauses completely covered the type 'ok' -asn1ct_parser2.erl:2628: The pattern {Rlist, ExtList} can never match the type [{_,_,_},...] -asn1ct_parser2.erl:2660: Call to missing or unexported function ordsets:list_to_set/1 -asn1ct_parser2.erl:2685: Call to missing or unexported function ordsets:list_to_set/1 -asn1ct_parser2.erl:281: The variable Other can never match since previous clauses completely covered the type [any()] -asn1ct_parser2.erl:529: The variable _ can never match since previous clauses completely covered the type #constraint{} -asn1ct_parser2.erl:555: The variable _ can never match since previous clauses completely covered the type #constraint{} -asn1ct_parser2.erl:796: The variable _ can never match since previous clauses completely covered the type {_,_} -asn1ct_parser2.erl:814: The variable _ can never match since previous clauses completely covered the type {_,_} -asn1ct_parser2.erl:831: The variable _ can never match since previous clauses completely covered the type {_,_} -asn1ct_value.erl:247: The pattern <'undefined', Default> can never match the type <maybe_improper_list(),[1..255,...]> -asn1rt_ber_bin.erl:1125: Cons will produce an improper list since its 2nd argument is binary() | tuple() -asn1rt_ber_bin.erl:1276: The pattern <{{_Min1, Max1}, {Min2, Max2}}, BitListVal, _DoTag> can never match since previous clauses completely covered the type <{_,_},maybe_improper_list(),_> -asn1rt_ber_bin.erl:2057: The call asn1rt_ber_bin:check_if_valid_tag2('false',[],[],OptOrMand::any()) will never return since it differs in the 2nd argument from the success typing arguments: ('false' | {'APPLICATION',_} | {'CONTEXT',_} | {'PRIVATE',_} | {'UNIVERSAL',_},nonempty_maybe_improper_list(),[] | {_,_,_},any()) -asn1rt_ber_bin.erl:969: The pattern {Val01, Buffer01, Rb01} can never match the type {'MINUS-INFINITY' | 'PLUS-INFINITY' | 0,binary()} -asn1rt_ber_bin.erl:998: The pattern {FirstLen, {Exp, Buffer3}, RemBytes2} can never match the type {1..1114111,{integer(),binary(),number()},number()} -asn1rt_ber_bin_v2.erl:1230: The pattern <{{_Min1, Max1}, {Min2, Max2}}, BitListVal, TagIn> can never match since previous clauses completely covered the type <{_,_},maybe_improper_list(),_> -asn1rt_ber_bin_v2.erl:328: The variable _ can never match since previous clauses completely covered the type {{0 | 1,non_neg_integer(),'indefinite' | non_neg_integer(),binary()},binary() | []} -asn1rt_ber_bin_v2.erl:337: The variable _ can never match since previous clauses completely covered the type {{0 | 1,non_neg_integer(),'indefinite' | non_neg_integer(),binary()},binary() | []} -asn1rt_ber_bin_v2.erl:392: The variable _ can never match since previous clauses completely covered the type {{0 | 1,non_neg_integer(),'indefinite' | non_neg_integer(),binary()},binary() | []} -asn1rt_ber_bin_v2.erl:963: Function decode_real/3 has no local return -asn1rt_check.erl:100: The variable _ can never match since previous clauses completely covered the type [any()] -asn1rt_check.erl:85: The variable _ can never match since previous clauses completely covered the type [any()] -asn1rt_driver_handler.erl:32: The pattern 'already_done' can never match the type {'error',_} -asn1rt_per.erl:1065: The pattern {'BMPString', {'octets', Ol}} can never match the type {_,[{'bits',1 | 2 | 4 | 8 | 16 | 32,_}]} -asn1rt_per.erl:1231: The call erlang:'not'('implemented') will never return since it differs in the 1st argument from the success typing arguments: (boolean()) -asn1rt_per.erl:1233: The call erlang:'not'('implemented') will never return since it differs in the 1st argument from the success typing arguments: (boolean()) -asn1rt_per.erl:1235: The call erlang:'not'('implemented') will never return since it differs in the 1st argument from the success typing arguments: (boolean()) -asn1rt_per.erl:1237: The call erlang:'not'('implemented') will never return since it differs in the 1st argument from the success typing arguments: (boolean()) -asn1rt_per.erl:989: The pattern <_C, 'true', _Val> can never match the type <_,'false',_> -asn1rt_per_bin.erl:1361: The pattern <_, 'true', _> can never match the type <_,'false',_> -asn1rt_per_bin.erl:1436: The pattern {'BMPString', {'octets', Ol}} can never match the type {'BMPString' | 'IA5String' | 'NumericString' | 'PrintableString' | 'UniversalString' | 'VisibleString',[{'bits',1 | 2 | 4 | 8 | 16 | 32,_}]} -asn1rt_per_bin.erl:161: The call asn1rt_per_bin:getbit({0,maybe_improper_list()}) will never return since it differs in the 1st argument from the success typing arguments: (<<_:8,_:_*8>> | {non_neg_integer(),<<_:1,_:_*1>>}) -asn1rt_per_bin.erl:1812: The pattern {Name, Val} can never match since previous clauses completely covered the type any() -asn1rt_per_bin.erl:2106: Cons will produce an improper list since its 2nd argument is binary() -asn1rt_per_bin.erl:2111: Cons will produce an improper list since its 2nd argument is binary() -asn1rt_per_bin.erl:2111: Cons will produce an improper list since its 2nd argument is integer() -asn1rt_per_bin.erl:2117: Cons will produce an improper list since its 2nd argument is integer() -asn1rt_per_bin.erl:2121: Cons will produce an improper list since its 2nd argument is 0 -asn1rt_per_bin.erl:2123: Cons will produce an improper list since its 2nd argument is 0 -asn1rt_per_bin.erl:2127: Cons will produce an improper list since its 2nd argument is 0 -asn1rt_per_bin.erl:2129: Cons will produce an improper list since its 2nd argument is integer() -asn1rt_per_bin.erl:446: The variable _ can never match since previous clauses completely covered the type integer() -asn1rt_per_bin.erl:467: The variable _ can never match since previous clauses completely covered the type integer() -asn1rt_per_bin.erl:474: The pattern <{_N, <<_,Bs/binary>>}, C> can never match since previous clauses completely covered the type <{0,_},integer()> -asn1rt_per_bin.erl:487: The variable _ can never match since previous clauses completely covered the type integer() -asn1rt_per_bin.erl:498: The variable _ can never match since previous clauses completely covered the type integer() -asn1rt_per_bin_rt2ct.erl:152: The call asn1rt_per_bin_rt2ct:getbit({0,maybe_improper_list()}) will never return since it differs in the 1st argument from the success typing arguments: (<<_:8,_:_*8>> | {non_neg_integer(),<<_:1,_:_*1>>}) -asn1rt_per_bin_rt2ct.erl:1533: The pattern {'BMPString', {'octets', Ol}} can never match the type {_,[[any(),...]]} -asn1rt_per_bin_rt2ct.erl:1875: The pattern {Name, Val} can never match since previous clauses completely covered the type any() -asn1rt_per_bin_rt2ct.erl:443: The variable _ can never match since previous clauses completely covered the type integer() -asn1rt_per_bin_rt2ct.erl:464: The variable _ can never match since previous clauses completely covered the type integer() -asn1rt_per_bin_rt2ct.erl:471: The pattern <{_N, <<_B,Bs/binary>>}, C> can never match since previous clauses completely covered the type <{0,_},integer()> -asn1rt_per_bin_rt2ct.erl:484: The variable _ can never match since previous clauses completely covered the type integer() -asn1rt_per_bin_rt2ct.erl:495: The variable _ can never match since previous clauses completely covered the type integer() -asn1rt_per_v1.erl:1209: The pattern <_, 'true', _> can never match the type <_,'false',_> -asn1rt_per_v1.erl:1290: The pattern {'BMPString', {'octets', Ol}} can never match the type {'BMPString' | 'IA5String' | 'NumericString' | 'PrintableString' | 'UniversalString' | 'VisibleString',[{'bits',1 | 2 | 4 | 8 | 16 | 32,_}]} +asn1ct.erl:1500:2: The variable Err can never match since previous clauses completely covered the type #type{} +asn1ct.erl:1596:2: The variable _ can never match since previous clauses completely covered the type 'ber_bin_v2' +asn1ct.erl:1673:2: The pattern 'all' can never match the type 'asn1_module' | 'exclusive_decode' | 'partial_decode' +asn1ct.erl:672:1: The pattern <{'false', Result}, _, _> can never match the type <{'true','true'},atom() | binary() | [atom() | [any()] | char()],[any()]> +asn1ct.erl:909:31: Guard test is_atom(Ext::[49 | 97 | 98 | 100 | 110 | 115]) can never succeed +asn1ct_check.erl:1698:2: The pattern {'error', _} can never match the type [any()] +asn1ct_check.erl:2733:2: Matching of pattern {'type', Tag, _, _, _, _} tagged with a record name violates the declared type of 'ASN1_OPEN_TYPE' | {_,_} | {'fixedtypevaluefield',_,_} +asn1ct_check.erl:2738:1: The pattern <_S, _> can never match since previous clauses completely covered the type <#state{},#'ObjectClassFieldType'{class::#objectclass{fields::maybe_improper_list() | {_,_,_,_}},fieldname::{_,maybe_improper_list()},type::'ASN1_OPEN_TYPE' | {_,_} | {'fixedtypevaluefield',_,_}}> +asn1ct_check.erl:2887:2: The variable Other can never match since previous clauses completely covered the type any() +asn1ct_check.erl:3188:1: The pattern <_S, [], B> can never match the type <#state{},{'SingleValue',_},{'ValueRange',_}> +asn1ct_check.erl:3190:1: The pattern <_S, A, []> can never match the type <#state{},{'SingleValue',_},{'ValueRange',_}> +asn1ct_check.erl:3212:3: The pattern {[], C3} can never match the type {[any(),...],{'ValueRange',{'MIN','MAX'}}} +asn1ct_check.erl:3225:3: The pattern {L1, UbNew} can never match the type 'false' +asn1ct_check.erl:3228:2: The pattern {L1, LbNew} can never match the type 'false' +asn1ct_check.erl:3235:29: The call asn1ct_check:remove_val_from_list(number(),L::[any(),...]) will never return since it differs in the 1st argument from the success typing arguments: ([any()],any()) +asn1ct_check.erl:3240:29: The call asn1ct_check:remove_val_from_list(number(),L::[any(),...]) will never return since it differs in the 1st argument from the success typing arguments: ([any()],any()) +asn1ct_check.erl:3242:1: Function remove_val_from_list/2 has no local return +asn1ct_check.erl:3243:27: The call lists:member(Val::[any(),...],List::number()) will never return since it differs in the 2nd argument from the success typing arguments: (any(),[any()]) +asn1ct_check.erl:3283:1: The pattern [] can never match the type [any(),...] +asn1ct_check.erl:3362:1: The pattern <_, [], _VR> can never match the type <#state{},[any(),...],[any(),...]> +asn1ct_check.erl:3364:1: The pattern <_, _SV, []> can never match the type <#state{},[any(),...],[any(),...]> +asn1ct_check.erl:4150:1: The pattern <_, [_]> can never match the type <_,[]> +asn1ct_check.erl:4314:1: The pattern <S, Type, {Rlist, ExtList}> can never match the type <#state{},_,[any()]> +asn1ct_check.erl:4360:1: The pattern <S, Type, {Rlist, ExtList}> can never match the type <#state{},_,[any()]> +asn1ct_check.erl:4719:14: The call asn1ct_check:error({'type',{'asn1',[1..255,...],[any(),...]}}) will never return since it differs in the 1st argument from the success typing arguments: ({'ObjectSet' | 'class' | 'export' | 'ptype' | 'type' | 'value',_,#state{}}) +asn1ct_check.erl:5120:2: Guard test is_record(Type::{_,_} | {'fixedtypevaluefield',_,_},'type',6) can never succeed +asn1ct_check.erl:5128:2: Guard test is_record(Type::{_,_} | {'fixedtypevaluefield',_,_},'type',6) can never succeed +asn1ct_check.erl:540:1: The pattern <_S, {'poc', _ObjSet, _Params}> can never match since previous clauses completely covered the type <#state{},_> +asn1ct_check.erl:5517:1: The pattern <_, []> can never match the type <_,[{'ABSTRACT-SYNTAX',{_,_,_}} | {'TYPE-IDENTIFIER',{_,_,_}},...]> +asn1ct_constructed_ber.erl:1075:2: The pattern {{{'ObjectClassFieldType', _, _, _, {'objectfield', PrimFieldName1, PFNList}}, _}, {'componentrelation', _, _}} can never match the type {#type{},_} +asn1ct_constructed_ber.erl:695:2: The pattern {'EXTENSIONMARK', _, _} can never match the type #'ComponentType'{} +asn1ct_constructed_ber.erl:748:1: The pattern <Erules, TopType, {CompList, _ExtList}> can never match the type <_,maybe_improper_list(),[#'ComponentType'{typespec::{_,_,_,_,_,_}}]> +asn1ct_constructed_ber_bin_v2.erl:914:2: The pattern {{{'ObjectClassFieldType', _, _, _, {'objectfield', PrimFieldName1, PFNList}}, _}, {'componentrelation', _, _}} can never match the type {#type{},_} +asn1ct_gen.erl:740:2: The pattern [] can never match the type [any(),...] +asn1ct_gen_ber.erl:974:1: The pattern <Erules, [{Name, Def} | Rest]> can never match the type <_,[#typedef{name::atom(),typespec::{_,_,_,_,_,_}}]> +asn1ct_gen_ber_bin_v2.erl:975:1: The pattern <Erules, [{Name, Def} | Rest]> can never match the type <_,[#typedef{name::atom(),typespec::{_,_,_,_,_,_}}]> +asn1ct_gen_per.erl:646:1: The pattern <Erules, [{Name, Def} | Rest]> can never match the type <_,[#typedef{name::atom()}]> +asn1ct_gen_per_rt2ct.erl:1189:1: The pattern <Erules, [{Name, Def} | Rest]> can never match the type <_,[#typedef{name::atom()}]> +asn1ct_gen_per_rt2ct.erl:563:1: The pattern <C, ['EXT_MARK' | T], _Count> can never match the type <[{'ValueRange',{_,_}},...],[char() | {'asn1_enum',integer()},...],non_neg_integer()> +asn1ct_gen_per_rt2ct.erl:580:1: The pattern <_C, 'EXT_MARK', _Count> can never match the type <[{'ValueRange',{_,_}},...],char(),non_neg_integer()> +asn1ct_gen_per_rt2ct.erl:583:1: The pattern <_C, {1, EnumName}, Count> can never match the type <[{'ValueRange',{_,_}},...],char(),non_neg_integer()> +asn1ct_gen_per_rt2ct.erl:587:1: The pattern <C, {0, EnumName}, Count> can never match the type <[{'ValueRange',{_,_}},...],char(),non_neg_integer()> +asn1ct_gen_per_rt2ct.erl:656:1: The pattern <Type, C> can never match since previous clauses completely covered the type <'bitstring' | 'integer',_> +asn1ct_parser2.erl:2017:2: Call to missing or unexported function ordsets:list_to_set/1 +asn1ct_parser2.erl:2497:3: The variable _ can never match since previous clauses completely covered the type 'ok' +asn1ct_parser2.erl:2628:1: The pattern {Rlist, ExtList} can never match the type [{_,_,_},...] +asn1ct_parser2.erl:2660:5: Call to missing or unexported function ordsets:list_to_set/1 +asn1ct_parser2.erl:2685:2: Call to missing or unexported function ordsets:list_to_set/1 +asn1ct_parser2.erl:281:2: The variable Other can never match since previous clauses completely covered the type [any()] +asn1ct_parser2.erl:529:6: The variable _ can never match since previous clauses completely covered the type #constraint{} +asn1ct_parser2.erl:555:6: The variable _ can never match since previous clauses completely covered the type #constraint{} +asn1ct_parser2.erl:796:2: The variable _ can never match since previous clauses completely covered the type {_,_} +asn1ct_parser2.erl:814:2: The variable _ can never match since previous clauses completely covered the type {_,_} +asn1ct_parser2.erl:831:2: The variable _ can never match since previous clauses completely covered the type {_,_} +asn1ct_value.erl:247:1: The pattern <'undefined', Default> can never match the type <maybe_improper_list(),[1..255,...]> +asn1rt_ber_bin.erl:1125:33: Cons will produce an improper list since its 2nd argument is binary() | tuple() +asn1rt_ber_bin.erl:1276:1: The pattern <{{_Min1, Max1}, {Min2, Max2}}, BitListVal, _DoTag> can never match since previous clauses completely covered the type <{_,_},maybe_improper_list(),_> +asn1rt_ber_bin.erl:2057:31: The call asn1rt_ber_bin:check_if_valid_tag2('false',[],[],OptOrMand::any()) will never return since it differs in the 2nd argument from the success typing arguments: ('false' | {'APPLICATION',_} | {'CONTEXT',_} | {'PRIVATE',_} | {'UNIVERSAL',_},nonempty_maybe_improper_list(),[] | {_,_,_},any()) +asn1rt_ber_bin.erl:969:6: The pattern {Val01, Buffer01, Rb01} can never match the type {'MINUS-INFINITY' | 'PLUS-INFINITY' | 0,binary()} +asn1rt_ber_bin.erl:998:6: The pattern {FirstLen, {Exp, Buffer3}, RemBytes2} can never match the type {1..1114111,{integer(),binary(),number()},number()} +asn1rt_ber_bin_v2.erl:1230:1: The pattern <{{_Min1, Max1}, {Min2, Max2}}, BitListVal, TagIn> can never match since previous clauses completely covered the type <{_,_},maybe_improper_list(),_> +asn1rt_ber_bin_v2.erl:328:3: The variable _ can never match since previous clauses completely covered the type {{0 | 1,non_neg_integer(),'indefinite' | non_neg_integer(),binary()},binary() | []} +asn1rt_ber_bin_v2.erl:337:3: The variable _ can never match since previous clauses completely covered the type {{0 | 1,non_neg_integer(),'indefinite' | non_neg_integer(),binary()},binary() | []} +asn1rt_ber_bin_v2.erl:392:2: The variable _ can never match since previous clauses completely covered the type {{0 | 1,non_neg_integer(),'indefinite' | non_neg_integer(),binary()},binary() | []} +asn1rt_ber_bin_v2.erl:963:1: Function decode_real/3 has no local return +asn1rt_check.erl:100:2: The variable _ can never match since previous clauses completely covered the type [any()] +asn1rt_check.erl:85:2: The variable _ can never match since previous clauses completely covered the type [any()] +asn1rt_driver_handler.erl:32:6: The pattern 'already_done' can never match the type {'error',_} +asn1rt_per.erl:1065:3: The pattern {'BMPString', {'octets', Ol}} can never match the type {_,[{'bits',1 | 2 | 4 | 8 | 16 | 32,_}]} +asn1rt_per.erl:1231:30: The call erlang:'not'('implemented') will never return since it differs in the 1st argument from the success typing arguments: (boolean()) +asn1rt_per.erl:1233:30: The call erlang:'not'('implemented') will never return since it differs in the 1st argument from the success typing arguments: (boolean()) +asn1rt_per.erl:1235:30: The call erlang:'not'('implemented') will never return since it differs in the 1st argument from the success typing arguments: (boolean()) +asn1rt_per.erl:1237:30: The call erlang:'not'('implemented') will never return since it differs in the 1st argument from the success typing arguments: (boolean()) +asn1rt_per.erl:989:1: The pattern <_C, 'true', _Val> can never match the type <_,'false',_> +asn1rt_per_bin.erl:1361:1: The pattern <_, 'true', _> can never match the type <_,'false',_> +asn1rt_per_bin.erl:1436:3: The pattern {'BMPString', {'octets', Ol}} can never match the type {'BMPString' | 'IA5String' | 'NumericString' | 'PrintableString' | 'UniversalString' | 'VisibleString',[{'bits',1 | 2 | 4 | 8 | 16 | 32,_}]} +asn1rt_per_bin.erl:161:12: The call asn1rt_per_bin:getbit({0,maybe_improper_list()}) will never return since it differs in the 1st argument from the success typing arguments: (<<_:8,_:_*8>> | {non_neg_integer(),<<_:1,_:_*1>>}) +asn1rt_per_bin.erl:1812:1: The pattern {Name, Val} can never match since previous clauses completely covered the type any() +asn1rt_per_bin.erl:2106:17: Cons will produce an improper list since its 2nd argument is binary() +asn1rt_per_bin.erl:2111:17: Cons will produce an improper list since its 2nd argument is binary() +asn1rt_per_bin.erl:2111:26: Cons will produce an improper list since its 2nd argument is integer() +asn1rt_per_bin.erl:2117:31: Cons will produce an improper list since its 2nd argument is integer() +asn1rt_per_bin.erl:2121:26: Cons will produce an improper list since its 2nd argument is 0 +asn1rt_per_bin.erl:2123:5: Cons will produce an improper list since its 2nd argument is 0 +asn1rt_per_bin.erl:2127:26: Cons will produce an improper list since its 2nd argument is 0 +asn1rt_per_bin.erl:2129:5: Cons will produce an improper list since its 2nd argument is integer() +asn1rt_per_bin.erl:446:2: The variable _ can never match since previous clauses completely covered the type integer() +asn1rt_per_bin.erl:467:2: The variable _ can never match since previous clauses completely covered the type integer() +asn1rt_per_bin.erl:474:1: The pattern <{_N, <<_,Bs/binary>>}, C> can never match since previous clauses completely covered the type <{0,_},integer()> +asn1rt_per_bin.erl:487:2: The variable _ can never match since previous clauses completely covered the type integer() +asn1rt_per_bin.erl:498:2: The variable _ can never match since previous clauses completely covered the type integer() +asn1rt_per_bin_rt2ct.erl:152:12: The call asn1rt_per_bin_rt2ct:getbit({0,maybe_improper_list()}) will never return since it differs in the 1st argument from the success typing arguments: (<<_:8,_:_*8>> | {non_neg_integer(),<<_:1,_:_*1>>}) +asn1rt_per_bin_rt2ct.erl:1533:3: The pattern {'BMPString', {'octets', Ol}} can never match the type {_,[[any(),...]]} +asn1rt_per_bin_rt2ct.erl:1875:1: The pattern {Name, Val} can never match since previous clauses completely covered the type any() +asn1rt_per_bin_rt2ct.erl:443:2: The variable _ can never match since previous clauses completely covered the type integer() +asn1rt_per_bin_rt2ct.erl:464:2: The variable _ can never match since previous clauses completely covered the type integer() +asn1rt_per_bin_rt2ct.erl:471:1: The pattern <{_N, <<_B,Bs/binary>>}, C> can never match since previous clauses completely covered the type <{0,_},integer()> +asn1rt_per_bin_rt2ct.erl:484:2: The variable _ can never match since previous clauses completely covered the type integer() +asn1rt_per_bin_rt2ct.erl:495:2: The variable _ can never match since previous clauses completely covered the type integer() +asn1rt_per_v1.erl:1209:1: The pattern <_, 'true', _> can never match the type <_,'false',_> +asn1rt_per_v1.erl:1290:3: The pattern {'BMPString', {'octets', Ol}} can never match the type {'BMPString' | 'IA5String' | 'NumericString' | 'PrintableString' | 'UniversalString' | 'VisibleString',[{'bits',1 | 2 | 4 | 8 | 16 | 32,_}]} diff --git a/lib/dialyzer/test/r9c_SUITE_data/results/inets b/lib/dialyzer/test/r9c_SUITE_data/results/inets index 31e9f031ce..91da02a2bc 100644 --- a/lib/dialyzer/test/r9c_SUITE_data/results/inets +++ b/lib/dialyzer/test/r9c_SUITE_data/results/inets @@ -1,55 +1,55 @@ -ftp.erl:1243: The pattern {'ok', {N, Bytes}} can never match the type 'eof' | {'error',atom() | {'no_translation','unicode','latin1'}} | {'ok',binary() | string()} -ftp.erl:640: The pattern {'closed', _Why} can never match the type 'perm_fname_not_allowed' | 'perm_neg_compl' | 'perm_no_space' | 'pos_compl' | 'pos_interm' | 'pos_interm_acct' | 'trans_neg_compl' | 'trans_no_space' | {'error' | 'perm_fname_not_allowed' | 'perm_neg_compl' | 'perm_no_space' | 'pos_compl' | 'pos_interm' | 'pos_interm_acct' | 'pos_prel' | 'trans_neg_compl' | 'trans_no_space',atom() | [any()] | {'invalid_server_response',[any(),...]}} -http.erl:117: The pattern {'error', Reason} can never match the type #req_headers{connection::[45 | 97 | 101 | 105 | 107 | 108 | 112 | 118,...],content_length::[48,...],other::[{_,_}]} -http.erl:138: Function close_session/2 will never be called -http_lib.erl:286: The call http_lib:close('ip_comm' | {'ssl',_},any()) will never return since it differs in the 1st argument from the success typing arguments: ('http' | 'https',any()) -http_lib.erl:424: The variable _ can never match since previous clauses completely covered the type any() -http_lib.erl:438: The variable _ can never match since previous clauses completely covered the type any() -http_lib.erl:99: Function getHeaderValue/2 will never be called -httpc_handler.erl:660: Function exit_session_ok/2 has no local return -httpc_handler.erl:676: Function format_time/0 will never be called -httpc_manager.erl:145: The pattern {ErrorReply, State2} can never match the type {{'ok',number()},number(),#state{reqid::number()}} -httpc_manager.erl:160: The pattern {ErrorReply, State2} can never match the type {{'ok',number()},number(),#state{reqid::number()}} -httpc_manager.erl:478: The pattern {'error', Reason} can never match the type 'ok' | {number(),#session{clientclose::boolean(),pipeline::[],quelength::1}} -httpc_manager.erl:490: The pattern {'error', Reason} can never match the type 'ok' | {number(),#session{clientclose::boolean(),pipeline::[],quelength::1}} -httpd_acceptor.erl:105: The pattern {'error', Reason} can never match the type {'ok',pid()} -httpd_acceptor.erl:110: Function handle_connection_err/4 will never be called -httpd_acceptor.erl:168: Function report_error/2 will never be called -httpd_acceptor.erl:91: The call httpd_acceptor:handle_error({'EXIT',_},ConfigDb::any(),SocketType::any()) will never return since it differs in the 1st argument from the success typing arguments: ('econnaborted' | 'emfile' | 'esslaccept' | 'timeout' | {'enfile',_},any(),any()) -httpd_manager.erl:885: The pattern {'EXIT', Reason} can never match since previous clauses completely covered the type any() -httpd_manager.erl:919: Function auth_status/1 will never be called -httpd_manager.erl:926: Function sec_status/1 will never be called -httpd_manager.erl:933: Function acceptor_status/1 will never be called -httpd_request_handler.erl:374: The call httpd_response:send_status(Info::#mod{parsed_header::maybe_improper_list()},417,"Body to big") will never return since it differs in the 2nd argument from the success typing arguments: (#mod{socket_type::'ip_comm' | {'ssl',_}},100 | 301 | 304 | 400 | 401 | 403 | 404 | 412 | 414 | 416 | 500 | 501 | 503,any()) -httpd_request_handler.erl:378: The call httpd_response:send_status(Info::#mod{parsed_header::maybe_improper_list()},417,"Method not allowed") will never return since it differs in the 2nd argument from the success typing arguments: (#mod{socket_type::'ip_comm' | {'ssl',_}},100 | 301 | 304 | 400 | 401 | 403 | 404 | 412 | 414 | 416 | 500 | 501 | 503,any()) -httpd_request_handler.erl:401: The call httpd_response:send_status(Info::#mod{parsed_header::maybe_improper_list()},417,"Method not allowed") will never return since it differs in the 2nd argument from the success typing arguments: (#mod{socket_type::'ip_comm' | {'ssl',_}},100 | 301 | 304 | 400 | 401 | 403 | 404 | 412 | 414 | 416 | 500 | 501 | 503,any()) -httpd_request_handler.erl:649: Guard test [{_,_}] =:= Trailers::nonempty_string() can never succeed -httpd_sup.erl:63: The variable Else can never match since previous clauses completely covered the type {'error',_} | {'ok',[any()],_,_} -httpd_sup.erl:88: The pattern {'error', Reason} can never match the type {'ok',_,_} -httpd_sup.erl:92: The variable Else can never match since previous clauses completely covered the type {'ok',_,_} -mod_auth.erl:559: The pattern {'error', Reason} can never match the type {_,integer(),maybe_improper_list(),_} -mod_auth_dets.erl:120: The call lists:foreach(fun((_) -> 'true' | {'error','no_such_group' | 'no_such_group_member'}),{'ok',[any()]}) will never return since it differs in the 2nd argument from the success typing arguments: (fun((_) -> any()),[any()]) -mod_auth_plain.erl:100: The variable _ can never match since previous clauses completely covered the type {'ok',[any()]} -mod_auth_plain.erl:159: The variable _ can never match since previous clauses completely covered the type [[any()]] -mod_auth_plain.erl:83: The variable O can never match since previous clauses completely covered the type [[any()]] -mod_cgi.erl:372: The pattern {'http_response', NewAccResponse} can never match the type 'ok' -mod_dir.erl:101: The call lists:flatten(nonempty_improper_list(atom() | [any()] | char(),atom() | {'no_translation',binary()})) will never return since it differs in the 1st argument from the success typing arguments: ([any()]) -mod_dir.erl:72: The pattern {'error', Reason} can never match the type {'ok',[[[any()] | char()],...]} -mod_get.erl:135: The pattern <{'enfile', _}, _Info, Path> can never match the type <atom(),#mod{},atom() | binary() | [atom() | [any()] | char()]> -mod_head.erl:80: The pattern <{'enfile', _}, _Info, Path> can never match the type <atom(),#mod{},atom() | binary() | [atom() | [any()] | char()]> -mod_htaccess.erl:460: The pattern {'error', BadData} can never match the type {'ok',_} -mod_include.erl:193: The pattern {_, Name, {[], []}} can never match the type {[any()],[any()],maybe_improper_list()} -mod_include.erl:195: The pattern {_, Name, {PathInfo, []}} can never match the type {[any()],[any()],maybe_improper_list()} -mod_include.erl:197: The pattern {_, Name, {PathInfo, QueryString}} can never match the type {[any()],[any()],maybe_improper_list()} -mod_include.erl:201: The variable Gurka can never match since previous clauses completely covered the type {[any()],[any()],maybe_improper_list()} -mod_include.erl:692: The pattern <{'read', Reason}, Info, Path> can never match the type <{'open',atom()},#mod{},atom() | binary() | [atom() | [any()] | char()]> -mod_include.erl:706: The pattern <{'enfile', _}, _Info, Path> can never match the type <atom(),#mod{},atom() | binary() | [atom() | [any()] | char()]> -mod_include.erl:716: Function read_error/3 will never be called -mod_include.erl:719: Function read_error/4 will never be called -mod_security_server.erl:386: The variable O can never match since previous clauses completely covered the type [tuple()] -mod_security_server.erl:433: The variable Other can never match since previous clauses completely covered the type [tuple()] -mod_security_server.erl:585: The variable _ can never match since previous clauses completely covered the type [tuple()] -mod_security_server.erl:608: The variable _ can never match since previous clauses completely covered the type [tuple()] -mod_security_server.erl:641: The variable _ can never match since previous clauses completely covered the type [tuple()] -uri.erl:146: The pattern {'error', Error} can never match since previous clauses completely covered the type {_,{[],[]}} +ftp.erl:1243:5: The pattern {'ok', {N, Bytes}} can never match the type 'eof' | {'error',atom() | {'no_translation','unicode','latin1'}} | {'ok',binary() | string()} +ftp.erl:640:2: The pattern {'closed', _Why} can never match the type 'perm_fname_not_allowed' | 'perm_neg_compl' | 'perm_no_space' | 'pos_compl' | 'pos_interm' | 'pos_interm_acct' | 'trans_neg_compl' | 'trans_no_space' | {'error' | 'perm_fname_not_allowed' | 'perm_neg_compl' | 'perm_no_space' | 'pos_compl' | 'pos_interm' | 'pos_interm_acct' | 'pos_prel' | 'trans_neg_compl' | 'trans_no_space',atom() | [any()] | {'invalid_server_response',[any(),...]}} +http.erl:117:3: The pattern {'error', Reason} can never match the type #req_headers{connection::[45 | 97 | 101 | 105 | 107 | 108 | 112 | 118,...],content_length::[48,...],other::[{_,_}]} +http.erl:138:1: Function close_session/2 will never be called +http_lib.erl:286:21: The call http_lib:close('ip_comm' | {'ssl',_},any()) will never return since it differs in the 1st argument from the success typing arguments: ('http' | 'https',any()) +http_lib.erl:424:2: The variable _ can never match since previous clauses completely covered the type any() +http_lib.erl:438:2: The variable _ can never match since previous clauses completely covered the type any() +http_lib.erl:99:1: Function getHeaderValue/2 will never be called +httpc_handler.erl:660:1: Function exit_session_ok/2 has no local return +httpc_handler.erl:676:1: Function format_time/0 will never be called +httpc_manager.erl:145:3: The pattern {ErrorReply, State2} can never match the type {{'ok',number()},number(),#state{reqid::number()}} +httpc_manager.erl:160:4: The pattern {ErrorReply, State2} can never match the type {{'ok',number()},number(),#state{reqid::number()}} +httpc_manager.erl:478:2: The pattern {'error', Reason} can never match the type 'ok' | {number(),#session{clientclose::boolean(),pipeline::[],quelength::1}} +httpc_manager.erl:490:2: The pattern {'error', Reason} can never match the type 'ok' | {number(),#session{clientclose::boolean(),pipeline::[],quelength::1}} +httpd_acceptor.erl:105:2: The pattern {'error', Reason} can never match the type {'ok',pid()} +httpd_acceptor.erl:110:1: Function handle_connection_err/4 will never be called +httpd_acceptor.erl:168:1: Function report_error/2 will never be called +httpd_acceptor.erl:91:19: The call httpd_acceptor:handle_error({'EXIT',_},ConfigDb::any(),SocketType::any()) will never return since it differs in the 1st argument from the success typing arguments: ('econnaborted' | 'emfile' | 'esslaccept' | 'timeout' | {'enfile',_},any(),any()) +httpd_manager.erl:885:2: The pattern {'EXIT', Reason} can never match since previous clauses completely covered the type any() +httpd_manager.erl:919:1: Function auth_status/1 will never be called +httpd_manager.erl:926:1: Function sec_status/1 will never be called +httpd_manager.erl:933:1: Function acceptor_status/1 will never be called +httpd_request_handler.erl:374:39: The call httpd_response:send_status(Info::#mod{parsed_header::maybe_improper_list()},417,"Body to big") will never return since it differs in the 2nd argument from the success typing arguments: (#mod{socket_type::'ip_comm' | {'ssl',_}},100 | 301 | 304 | 400 | 401 | 403 | 404 | 412 | 414 | 416 | 500 | 501 | 503,any()) +httpd_request_handler.erl:378:39: The call httpd_response:send_status(Info::#mod{parsed_header::maybe_improper_list()},417,"Method not allowed") will never return since it differs in the 2nd argument from the success typing arguments: (#mod{socket_type::'ip_comm' | {'ssl',_}},100 | 301 | 304 | 400 | 401 | 403 | 404 | 412 | 414 | 416 | 500 | 501 | 503,any()) +httpd_request_handler.erl:401:39: The call httpd_response:send_status(Info::#mod{parsed_header::maybe_improper_list()},417,"Method not allowed") will never return since it differs in the 2nd argument from the success typing arguments: (#mod{socket_type::'ip_comm' | {'ssl',_}},100 | 301 | 304 | 400 | 401 | 403 | 404 | 412 | 414 | 416 | 500 | 501 | 503,any()) +httpd_request_handler.erl:649:6: Guard test [{_,_}] =:= Trailers::nonempty_string() can never succeed +httpd_sup.erl:63:2: The variable Else can never match since previous clauses completely covered the type {'error',_} | {'ok',[any()],_,_} +httpd_sup.erl:88:2: The pattern {'error', Reason} can never match the type {'ok',_,_} +httpd_sup.erl:92:2: The variable Else can never match since previous clauses completely covered the type {'ok',_,_} +mod_auth.erl:559:3: The pattern {'error', Reason} can never match the type {_,integer(),maybe_improper_list(),_} +mod_auth_dets.erl:121:6: The call lists:foreach(fun((_) -> 'true' | {'error','no_such_group' | 'no_such_group_member'}),{'ok',[any()]}) will never return since it differs in the 2nd argument from the success typing arguments: (fun((_) -> any()),[any()]) +mod_auth_plain.erl:100:3: The variable _ can never match since previous clauses completely covered the type {'ok',[any()]} +mod_auth_plain.erl:159:2: The variable _ can never match since previous clauses completely covered the type [[any()]] +mod_auth_plain.erl:83:2: The variable O can never match since previous clauses completely covered the type [[any()]] +mod_cgi.erl:372:3: The pattern {'http_response', NewAccResponse} can never match the type 'ok' +mod_dir.erl:101:14: The call lists:flatten(nonempty_improper_list(atom() | [any()] | char(),atom() | {'no_translation',binary()})) will never return since it differs in the 1st argument from the success typing arguments: ([any()]) +mod_dir.erl:72:3: The pattern {'error', Reason} can never match the type {'ok',[[[any()] | char()],...]} +mod_get.erl:135:1: The pattern <{'enfile', _}, _Info, Path> can never match the type <atom(),#mod{},atom() | binary() | [atom() | [any()] | char()]> +mod_head.erl:80:1: The pattern <{'enfile', _}, _Info, Path> can never match the type <atom(),#mod{},atom() | binary() | [atom() | [any()] | char()]> +mod_htaccess.erl:460:3: The pattern {'error', BadData} can never match the type {'ok',_} +mod_include.erl:193:6: The pattern {_, Name, {[], []}} can never match the type {[any()],[any()],maybe_improper_list()} +mod_include.erl:195:6: The pattern {_, Name, {PathInfo, []}} can never match the type {[any()],[any()],maybe_improper_list()} +mod_include.erl:197:6: The pattern {_, Name, {PathInfo, QueryString}} can never match the type {[any()],[any()],maybe_improper_list()} +mod_include.erl:201:6: The variable Gurka can never match since previous clauses completely covered the type {[any()],[any()],maybe_improper_list()} +mod_include.erl:692:1: The pattern <{'read', Reason}, Info, Path> can never match the type <{'open',atom()},#mod{},atom() | binary() | [atom() | [any()] | char()]> +mod_include.erl:706:1: The pattern <{'enfile', _}, _Info, Path> can never match the type <atom(),#mod{},atom() | binary() | [atom() | [any()] | char()]> +mod_include.erl:716:1: Function read_error/3 will never be called +mod_include.erl:719:1: Function read_error/4 will never be called +mod_security_server.erl:386:2: The variable O can never match since previous clauses completely covered the type [tuple()] +mod_security_server.erl:433:2: The variable Other can never match since previous clauses completely covered the type [tuple()] +mod_security_server.erl:585:2: The variable _ can never match since previous clauses completely covered the type [tuple()] +mod_security_server.erl:608:6: The variable _ can never match since previous clauses completely covered the type [tuple()] +mod_security_server.erl:641:2: The variable _ can never match since previous clauses completely covered the type [tuple()] +uri.erl:146:2: The pattern {'error', Error} can never match since previous clauses completely covered the type {_,{[],[]}} diff --git a/lib/dialyzer/test/r9c_SUITE_data/results/mnesia b/lib/dialyzer/test/r9c_SUITE_data/results/mnesia index 71acdd9c9e..ffeb712fc5 100644 --- a/lib/dialyzer/test/r9c_SUITE_data/results/mnesia +++ b/lib/dialyzer/test/r9c_SUITE_data/results/mnesia @@ -1,41 +1,41 @@ -mnesia.erl:1319: Guard test size(Spec::[{_,_,_},...]) can never succeed -mnesia.erl:1498: The call mnesia:bad_info_reply(Tab::atom(),Item::'type') will never return since it differs in the 2nd argument from the success typing arguments: (atom(),'memory' | 'size') -mnesia_backup.erl:49: Callback info about the mnesia_backup behaviour is not available -mnesia_bup.erl:111: The created fun has no local return -mnesia_bup.erl:574: Function fallback_receiver/2 has no local return -mnesia_bup.erl:967: Function uninstall_fallback_master/2 has no local return -mnesia_checkpoint.erl:1014: The variable Error can never match since previous clauses completely covered the type {'ok',#checkpoint_args{nodes::[any()],retainers::[any(),...]}} -mnesia_checkpoint.erl:894: The call sys:handle_system_msg(Msg::any(),From::any(),'no_parent','mnesia_checkpoint',[],Cp::#checkpoint_args{}) breaks the contract (Msg,From,Parent,Module,Debug,Misc) -> no_return() when Msg :: term(), From :: {pid(),Tag::_}, Parent :: pid(), Module :: module(), Debug :: [dbg_opt()], Misc :: term() -mnesia_controller.erl:1666: The variable Tab can never match since previous clauses completely covered the type [any()] -mnesia_controller.erl:1679: The pattern {'stop', Reason, Reply, State2} can never match the type {'noreply',_} | {'reply',_,_} | {'stop','shutdown',#state{}} -mnesia_controller.erl:1685: The pattern {'noreply', State2, _Timeout} can never match the type {'reply',_,_} -mnesia_event.erl:77: The pattern 'remove_handler' can never match the type {'ok',_} -mnesia_event.erl:79: The pattern {'swap_handler', Args1, State1, Mod2, Args2} can never match the type {'ok',_} -mnesia_frag.erl:26: Callback info about the mnesia_access behaviour is not available -mnesia_frag.erl:294: The call mnesia_frag:remote_collect(Ref::reference(),{'error',_},[],OldSelectFun::fun(() -> [any()])) will never return since it differs in the 2nd argument from the success typing arguments: (reference(),'ok',[any()],fun(() -> [any()])) -mnesia_frag.erl:304: The call mnesia_frag:remote_collect(Ref::reference(),{'error',{'node_not_running',_}},[],OldSelectFun::fun(() -> [any()])) will never return since it differs in the 2nd argument from the success typing arguments: (reference(),'ok',[any()],fun(() -> [any()])) -mnesia_frag.erl:312: The call mnesia_frag:remote_collect(Ref::reference(),LocalRes::{'error',_},[],OldSelectFun::fun(() -> [any()])) will never return since it differs in the 2nd argument from the success typing arguments: (reference(),'ok',[any()],fun(() -> [any()])) -mnesia_frag_hash.erl:24: Callback info about the mnesia_frag_hash behaviour is not available -mnesia_frag_old_hash.erl:105: Call to missing or unexported function erlang:hash/2 -mnesia_frag_old_hash.erl:23: Callback info about the mnesia_frag_hash behaviour is not available -mnesia_index.erl:52: The call mnesia_lib:other_val(Var::{_,'commit_work' | 'index' | 'setorbag' | 'storage_type' | {'index',_}},_ReASoN_::any()) will never return since it differs in the 1st argument from the success typing arguments: ({_,'active_replicas' | 'where_to_read' | 'where_to_write'},any()) -mnesia_lib.erl:1028: The pattern {'EXIT', Reason} can never match the type [any()] | {'error',_} -mnesia_lib.erl:957: The pattern {'ok', {0, _}} can never match the type 'eof' | {'error',atom() | {'no_translation','unicode','latin1'}} | {'ok',binary() | string()} -mnesia_lib.erl:959: The pattern {'ok', {_, Bin}} can never match the type 'eof' | {'error',atom() | {'no_translation','unicode','latin1'}} | {'ok',binary() | string()} -mnesia_loader.erl:36: The call mnesia_lib:other_val(Var::{_,'access_mode' | 'cstruct' | 'db_nodes' | 'setorbag' | 'snmp' | 'storage_type'},Reason::any()) will never return since it differs in the 1st argument from the success typing arguments: ({_,'active_replicas' | 'where_to_read' | 'where_to_write'},any()) -mnesia_locker.erl:1017: Function system_terminate/4 has no local return -mnesia_log.erl:707: The test {'error',{[1..255,...],[any(),...]}} | {'ok',_} == atom() can never evaluate to 'true' -mnesia_log.erl:727: The created fun has no local return -mnesia_monitor.erl:162: The pattern <[], []> can never match the type <[any(),...],[any(),...]> -mnesia_monitor.erl:354: The pattern {'error', Reason} can never match the type 'ok' -mnesia_recover.erl:159: The call mnesia_lib:other_val(Var::'latest_transient_decision' | 'max_wait_for_decision' | 'previous_transient_decisions' | 'recover_nodes',Reason::any()) will never return since it differs in the 1st argument from the success typing arguments: ({_,'active_replicas' | 'where_to_read' | 'where_to_write'},any()) -mnesia_recover.erl:884: The pattern {'stop', Reason, Reply, State2} can never match the type {'noreply',_} | {'stop','shutdown',#state{}} -mnesia_schema.erl:1088: Guard test Storage::'disc_copies' | 'disc_only_copies' | 'ram_copies' == 'unknown' can never succeed -mnesia_schema.erl:1258: Guard test FromS::'disc_copies' | 'disc_only_copies' | 'ram_copies' == 'unknown' can never succeed -mnesia_schema.erl:1639: The pattern {'false', 'mandatory'} can never match the type {'false','optional'} -mnesia_schema.erl:2434: The variable Reason can never match since previous clauses completely covered the type {'error',_} | {'ok',_} -mnesia_schema.erl:451: Guard test UseDirAnyway::'false' == 'true' can never succeed -mnesia_text.erl:180: The variable T can never match since previous clauses completely covered the type {'error',{non_neg_integer(),atom(),_}} | {'ok',_} -mnesia_tm.erl:1522: Function commit_participant/5 has no local return -mnesia_tm.erl:2169: Function system_terminate/4 has no local return +mnesia.erl:1319:50: Guard test size(Spec::[{_,_,_},...]) can never succeed +mnesia.erl:1498:27: The call mnesia:bad_info_reply(Tab::atom(),Item::'type') will never return since it differs in the 2nd argument from the success typing arguments: (atom(),'memory' | 'size') +mnesia_backup.erl:49:2: Callback info about the mnesia_backup behaviour is not available +mnesia_bup.erl:111:13: The created fun has no local return +mnesia_bup.erl:574:1: Function fallback_receiver/2 has no local return +mnesia_bup.erl:967:1: Function uninstall_fallback_master/2 has no local return +mnesia_checkpoint.erl:1014:6: The variable Error can never match since previous clauses completely covered the type {'ok',#checkpoint_args{nodes::[any()],retainers::[any(),...]}} +mnesia_checkpoint.erl:894:39: The call sys:handle_system_msg(Msg::any(),From::any(),'no_parent','mnesia_checkpoint',[],Cp::#checkpoint_args{}) breaks the contract (Msg,From,Parent,Module,Debug,Misc) -> no_return() when Msg :: term(), From :: {pid(),Tag::_}, Parent :: pid(), Module :: module(), Debug :: [dbg_opt()], Misc :: term() +mnesia_controller.erl:1666:1: The variable Tab can never match since previous clauses completely covered the type [any()] +mnesia_controller.erl:1679:9: The pattern {'stop', Reason, Reply, State2} can never match the type {'noreply',_} | {'reply',_,_} | {'stop','shutdown',#state{}} +mnesia_controller.erl:1685:2: The pattern {'noreply', State2, _Timeout} can never match the type {'reply',_,_} +mnesia_event.erl:77:2: The pattern 'remove_handler' can never match the type {'ok',_} +mnesia_event.erl:79:2: The pattern {'swap_handler', Args1, State1, Mod2, Args2} can never match the type {'ok',_} +mnesia_frag.erl:26:2: Callback info about the mnesia_access behaviour is not available +mnesia_frag.erl:294:26: The call mnesia_frag:remote_collect(Ref::reference(),{'error',_},[],OldSelectFun::fun(() -> [any()])) will never return since it differs in the 2nd argument from the success typing arguments: (reference(),'ok',[any()],fun(() -> [any()])) +mnesia_frag.erl:304:27: The call mnesia_frag:remote_collect(Ref::reference(),{'error',{'node_not_running',_}},[],OldSelectFun::fun(() -> [any()])) will never return since it differs in the 2nd argument from the success typing arguments: (reference(),'ok',[any()],fun(() -> [any()])) +mnesia_frag.erl:312:26: The call mnesia_frag:remote_collect(Ref::reference(),LocalRes::{'error',_},[],OldSelectFun::fun(() -> [any()])) will never return since it differs in the 2nd argument from the success typing arguments: (reference(),'ok',[any()],fun(() -> [any()])) +mnesia_frag_hash.erl:24:2: Callback info about the mnesia_frag_hash behaviour is not available +mnesia_frag_old_hash.erl:105:6: Call to missing or unexported function erlang:hash/2 +mnesia_frag_old_hash.erl:23:2: Callback info about the mnesia_frag_hash behaviour is not available +mnesia_index.erl:52:45: The call mnesia_lib:other_val(Var::{_,'commit_work' | 'index' | 'setorbag' | 'storage_type' | {'index',_}},_ReASoN_::any()) will never return since it differs in the 1st argument from the success typing arguments: ({_,'active_replicas' | 'where_to_read' | 'where_to_write'},any()) +mnesia_lib.erl:1028:2: The pattern {'EXIT', Reason} can never match the type [any()] | {'error',_} +mnesia_lib.erl:957:2: The pattern {'ok', {0, _}} can never match the type 'eof' | {'error',atom() | {'no_translation','unicode','latin1'}} | {'ok',binary() | string()} +mnesia_lib.erl:959:2: The pattern {'ok', {_, Bin}} can never match the type 'eof' | {'error',atom() | {'no_translation','unicode','latin1'}} | {'ok',binary() | string()} +mnesia_loader.erl:36:43: The call mnesia_lib:other_val(Var::{_,'access_mode' | 'cstruct' | 'db_nodes' | 'setorbag' | 'snmp' | 'storage_type'},Reason::any()) will never return since it differs in the 1st argument from the success typing arguments: ({_,'active_replicas' | 'where_to_read' | 'where_to_write'},any()) +mnesia_locker.erl:1017:1: Function system_terminate/4 has no local return +mnesia_log.erl:707:23: The test {'error',{[1..255,...],[any(),...]}} | {'ok',_} == atom() can never evaluate to 'true' +mnesia_log.erl:727:13: The created fun has no local return +mnesia_monitor.erl:162:1: The pattern <[], []> can never match the type <[any(),...],[any(),...]> +mnesia_monitor.erl:354:9: The pattern {'error', Reason} can never match the type 'ok' +mnesia_recover.erl:159:43: The call mnesia_lib:other_val(Var::'latest_transient_decision' | 'max_wait_for_decision' | 'previous_transient_decisions' | 'recover_nodes',Reason::any()) will never return since it differs in the 1st argument from the success typing arguments: ({_,'active_replicas' | 'where_to_read' | 'where_to_write'},any()) +mnesia_recover.erl:884:9: The pattern {'stop', Reason, Reply, State2} can never match the type {'noreply',_} | {'stop','shutdown',#state{}} +mnesia_schema.erl:1088:2: Guard test Storage::'disc_copies' | 'disc_only_copies' | 'ram_copies' == 'unknown' can never succeed +mnesia_schema.erl:1258:2: Guard test FromS::'disc_copies' | 'disc_only_copies' | 'ram_copies' == 'unknown' can never succeed +mnesia_schema.erl:1639:2: The pattern {'false', 'mandatory'} can never match the type {'false','optional'} +mnesia_schema.erl:2434:2: The variable Reason can never match since previous clauses completely covered the type {'error',_} | {'ok',_} +mnesia_schema.erl:451:36: Guard test UseDirAnyway::'false' == 'true' can never succeed +mnesia_text.erl:180:3: The variable T can never match since previous clauses completely covered the type {'error',{non_neg_integer() | {non_neg_integer(),pos_integer()},atom(),_}} | {'ok',_} +mnesia_tm.erl:1522:1: Function commit_participant/5 has no local return +mnesia_tm.erl:2169:1: Function system_terminate/4 has no local return diff --git a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_args1 b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_args1 index 3bbe99d4af..452b623f94 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_args1 +++ b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_args1 @@ -1,2 +1,2 @@ -ets_insert_args1.erl:9: The call ets:insert(T::'foo',[{'counter',number()},...]) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(T::'foo','counter') call in ets_insert_args1.erl on line 8 +ets_insert_args1.erl:9:16: The call ets:insert(T::'foo',[{'counter',number()},...]) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(T::'foo','counter') call in ets_insert_args1.erl on line {8,28} diff --git a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_args10 b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_args10 index c3c9b12bdd..cefface2f5 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_args10 +++ b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_args10 @@ -1,2 +1,2 @@ -ets_insert_args10.erl:9: The call ets:insert(T::'foo',[{'counter',number()},...]) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(T::'foo','counter') call in ets_insert_args10.erl on line 8 +ets_insert_args10.erl:9:16: The call ets:insert(T::'foo',[{'counter',number()},...]) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(T::'foo','counter') call in ets_insert_args10.erl on line {8,28} diff --git a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_args2 b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_args2 index 34176c66ac..1a529812f9 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_args2 +++ b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_args2 @@ -1,2 +1,2 @@ -ets_insert_args2.erl:9: The call ets:insert(T::'foo',[{'counter',number()} | {'kostis',number()} | {'maria',number()},...]) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(T::'foo','counter') call in ets_insert_args2.erl on line 8 +ets_insert_args2.erl:9:16: The call ets:insert(T::'foo',[{'counter',number()} | {'kostis',number()} | {'maria',number()},...]) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(T::'foo','counter') call in ets_insert_args2.erl on line {8,27} diff --git a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_args4 b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_args4 index 8c45de08c2..dd08666fe8 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_args4 +++ b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_args4 @@ -1,2 +1,2 @@ -ets_insert_args4.erl:9: The call ets:insert(T::'foo',{'counter',number()}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(T::'foo','counter') call in ets_insert_args4.erl on line 8 +ets_insert_args4.erl:9:16: The call ets:insert(T::'foo',{'counter',number()}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(T::'foo','counter') call in ets_insert_args4.erl on line {8,27} diff --git a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_args5 b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_args5 index a4a0c021c2..ec44a89f8f 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_args5 +++ b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_args5 @@ -1,2 +1,2 @@ -ets_insert_args5.erl:9: The call ets:insert(T::'foo',{'counter',number(),number()}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(T::'foo','counter') call in ets_insert_args5.erl on line 8 +ets_insert_args5.erl:9:16: The call ets:insert(T::'foo',{'counter',number(),number()}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(T::'foo','counter') call in ets_insert_args5.erl on line {8,27} diff --git a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_args6 b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_args6 index 10fa4c27e3..b7d4131ff6 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_args6 +++ b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_args6 @@ -1,2 +1,2 @@ -ets_insert_args6.erl:9: The call ets:insert(T::'foo',[{'counter',number(),number()},...]) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(T::'foo','counter') call in ets_insert_args6.erl on line 8 +ets_insert_args6.erl:9:16: The call ets:insert(T::'foo',[{'counter',number(),number()},...]) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(T::'foo','counter') call in ets_insert_args6.erl on line {8,27} diff --git a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_args7 b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_args7 index af43145c17..fc6ea50437 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_args7 +++ b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_args7 @@ -1,2 +1,2 @@ -ets_insert_args7.erl:17: The call ets:insert(Table::'foo',[{'counter',number()},...]) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Tab::'foo','counter') call in ets_insert_args7.erl on line 13 +ets_insert_args7.erl:17:3: The call ets:insert(Table::'foo',[{'counter',number()},...]) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Tab::'foo','counter') call in ets_insert_args7.erl on line {13,16} diff --git a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_args8 b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_args8 index 5a2b41ed8c..f263c0eaaf 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_args8 +++ b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_args8 @@ -1,2 +1,2 @@ -ets_insert_args8.erl:16: The call ets:insert(Table::atom(),[{'counter',number()},...]) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Tab::atom(),'counter') call in ets_insert_args8.erl on line 12 +ets_insert_args8.erl:16:3: The call ets:insert(Table::atom(),[{'counter',number()},...]) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Tab::atom(),'counter') call in ets_insert_args8.erl on line {12,16} diff --git a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_control_flow1 b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_control_flow1 index d7df214939..38c507582e 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_control_flow1 +++ b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_control_flow1 @@ -1,2 +1,2 @@ -ets_insert_control_flow1.erl:15: The call ets:insert('foo',{'random',integer()}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup('foo','random') call in ets_insert_control_flow1.erl on line 10 +ets_insert_control_flow1.erl:15:7: The call ets:insert('foo',{'random',integer()}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup('foo','random') call in ets_insert_control_flow1.erl on line {10,41} diff --git a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_control_flow2 b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_control_flow2 index cdaeafb0ed..1ca874c4d8 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_control_flow2 +++ b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_control_flow2 @@ -1,3 +1,3 @@ -ets_insert_control_flow2.erl:15: The call ets:insert('foo',[{'pass',[pos_integer()]} | {'random',integer()},...]) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup('foo','random') call in ets_insert_control_flow2.erl on line 10 -ets_insert_control_flow2.erl:19: The call ets:insert('foo',[{'pass',[pos_integer()]} | {'random',integer()},...]) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup('foo','random') call in ets_insert_control_flow2.erl on line 10 +ets_insert_control_flow2.erl:15:7: The call ets:insert('foo',[{'pass',[pos_integer()]} | {'random',integer()},...]) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup('foo','random') call in ets_insert_control_flow2.erl on line {10,41} +ets_insert_control_flow2.erl:19:7: The call ets:insert('foo',[{'pass',[pos_integer()]} | {'random',integer()},...]) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup('foo','random') call in ets_insert_control_flow2.erl on line {10,41} diff --git a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_control_flow3 b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_control_flow3 index 0382627cfc..ad011e918c 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_control_flow3 +++ b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_control_flow3 @@ -1,3 +1,3 @@ -ets_insert_control_flow3.erl:21: The call ets:insert(Table::atom() | ets:tid(),{'root',[pos_integer()]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Table::atom() | ets:tid(),'root') call in ets_insert_control_flow3.erl on line 12 -ets_insert_control_flow3.erl:23: The call ets:insert(Table::atom() | ets:tid(),{'user',[pos_integer()]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Table::atom() | ets:tid(),'user') call in ets_insert_control_flow3.erl on line 13 +ets_insert_control_flow3.erl:21:11: The call ets:insert(Table::atom() | ets:tid(),{'root',[pos_integer()]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Table::atom() | ets:tid(),'root') call in ets_insert_control_flow3.erl on line {12,15} +ets_insert_control_flow3.erl:23:11: The call ets:insert(Table::atom() | ets:tid(),{'user',[pos_integer()]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Table::atom() | ets:tid(),'user') call in ets_insert_control_flow3.erl on line {13,15} diff --git a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_control_flow4 b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_control_flow4 index 22944fd066..ad505c0ab8 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_control_flow4 +++ b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_control_flow4 @@ -1,3 +1,3 @@ -ets_insert_control_flow4.erl:21: The call ets:insert(Table::atom() | ets:tid(),{'pass',[pos_integer()]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Table::atom() | ets:tid(),'pass') call in ets_insert_control_flow4.erl on line 12, the ets:lookup(Table::atom() | ets:tid(),'pass') call in ets_insert_control_flow4.erl on line 13 -ets_insert_control_flow4.erl:23: The call ets:insert(Table::atom() | ets:tid(),{'pass',[pos_integer()]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Table::atom() | ets:tid(),'pass') call in ets_insert_control_flow4.erl on line 12, the ets:lookup(Table::atom() | ets:tid(),'pass') call in ets_insert_control_flow4.erl on line 13 +ets_insert_control_flow4.erl:21:11: The call ets:insert(Table::atom() | ets:tid(),{'pass',[pos_integer()]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Table::atom() | ets:tid(),'pass') call in ets_insert_control_flow4.erl on line {12,15}, the ets:lookup(Table::atom() | ets:tid(),'pass') call in ets_insert_control_flow4.erl on line {13,15} +ets_insert_control_flow4.erl:23:11: The call ets:insert(Table::atom() | ets:tid(),{'pass',[pos_integer()]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Table::atom() | ets:tid(),'pass') call in ets_insert_control_flow4.erl on line {12,15}, the ets:lookup(Table::atom() | ets:tid(),'pass') call in ets_insert_control_flow4.erl on line {13,15} diff --git a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_control_flow5 b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_control_flow5 index e172887f34..f98aa27654 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_control_flow5 +++ b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_control_flow5 @@ -1,5 +1,5 @@ -ets_insert_control_flow5.erl:22: The call ets:insert(Table::atom() | ets:tid(),{'welcome_msg',[any(),...]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Table::atom() | ets:tid(),'welcome_msg') call in ets_insert_control_flow5.erl on line 16 -ets_insert_control_flow5.erl:23: The call ets:insert(Table::atom() | ets:tid(),{'pass',[pos_integer()]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Table::atom() | ets:tid(),'pass') call in ets_insert_control_flow5.erl on line 12, the ets:lookup(Table::atom() | ets:tid(),'pass') call in ets_insert_control_flow5.erl on line 13 -ets_insert_control_flow5.erl:25: The call ets:insert(Table::atom() | ets:tid(),{'welcome_msg',[any(),...]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Table::atom() | ets:tid(),'welcome_msg') call in ets_insert_control_flow5.erl on line 16 -ets_insert_control_flow5.erl:26: The call ets:insert(Table::atom() | ets:tid(),{'pass',[pos_integer()]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Table::atom() | ets:tid(),'pass') call in ets_insert_control_flow5.erl on line 12, the ets:lookup(Table::atom() | ets:tid(),'pass') call in ets_insert_control_flow5.erl on line 13 +ets_insert_control_flow5.erl:22:11: The call ets:insert(Table::atom() | ets:tid(),{'welcome_msg',[any(),...]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Table::atom() | ets:tid(),'welcome_msg') call in ets_insert_control_flow5.erl on line {16,16} +ets_insert_control_flow5.erl:23:11: The call ets:insert(Table::atom() | ets:tid(),{'pass',[pos_integer()]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Table::atom() | ets:tid(),'pass') call in ets_insert_control_flow5.erl on line {12,15}, the ets:lookup(Table::atom() | ets:tid(),'pass') call in ets_insert_control_flow5.erl on line {13,15} +ets_insert_control_flow5.erl:25:11: The call ets:insert(Table::atom() | ets:tid(),{'welcome_msg',[any(),...]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Table::atom() | ets:tid(),'welcome_msg') call in ets_insert_control_flow5.erl on line {16,16} +ets_insert_control_flow5.erl:26:11: The call ets:insert(Table::atom() | ets:tid(),{'pass',[pos_integer()]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Table::atom() | ets:tid(),'pass') call in ets_insert_control_flow5.erl on line {12,15}, the ets:lookup(Table::atom() | ets:tid(),'pass') call in ets_insert_control_flow5.erl on line {13,15} diff --git a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_diff_atoms_race1 b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_diff_atoms_race1 index 98ccf34e7d..60e115ff1b 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_diff_atoms_race1 +++ b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_diff_atoms_race1 @@ -1,2 +1,2 @@ -ets_insert_diff_atoms_race1.erl:22: The call ets:insert(Table::'bar' | 'foo',[{'counter',number()},...]) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Tab::'foo','counter') call in ets_insert_diff_atoms_race1.erl on line 13 +ets_insert_diff_atoms_race1.erl:22:3: The call ets:insert(Table::'bar' | 'foo',[{'counter',number()},...]) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Tab::'foo','counter') call in ets_insert_diff_atoms_race1.erl on line {13,16} diff --git a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_diff_atoms_race2 b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_diff_atoms_race2 index b6af99b4cc..0e6546685c 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_diff_atoms_race2 +++ b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_diff_atoms_race2 @@ -1,2 +1,2 @@ -ets_insert_diff_atoms_race2.erl:22: The call ets:insert(Table::'bar' | 'foo',[{'counter',number()},...]) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Tab::'foo',Counter::'counter') call in ets_insert_diff_atoms_race2.erl on line 13 +ets_insert_diff_atoms_race2.erl:22:3: The call ets:insert(Table::'bar' | 'foo',[{'counter',number()},...]) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Tab::'foo',Counter::'counter') call in ets_insert_diff_atoms_race2.erl on line {13,16} diff --git a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_diff_atoms_race3 b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_diff_atoms_race3 index d79182c289..9a0e7dc936 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_diff_atoms_race3 +++ b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_diff_atoms_race3 @@ -1,2 +1,2 @@ -ets_insert_diff_atoms_race3.erl:22: The call ets:insert(Table::'bar' | 'foo',{'counter',number()}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Tab::'foo','counter') call in ets_insert_diff_atoms_race3.erl on line 13 +ets_insert_diff_atoms_race3.erl:22:3: The call ets:insert(Table::'bar' | 'foo',{'counter',number()}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Tab::'foo','counter') call in ets_insert_diff_atoms_race3.erl on line {13,16} diff --git a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_diff_atoms_race4 b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_diff_atoms_race4 index 5bb1b9f781..cc17f482ad 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_diff_atoms_race4 +++ b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_diff_atoms_race4 @@ -1,2 +1,2 @@ -ets_insert_diff_atoms_race4.erl:22: The call ets:insert(Table::'bar' | 'foo',{'counter',number()}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Tab::'foo',Counter::'counter') call in ets_insert_diff_atoms_race4.erl on line 13 +ets_insert_diff_atoms_race4.erl:22:3: The call ets:insert(Table::'bar' | 'foo',{'counter',number()}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Tab::'foo',Counter::'counter') call in ets_insert_diff_atoms_race4.erl on line {13,16} diff --git a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_diff_atoms_race5 b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_diff_atoms_race5 index 7db320e758..c6df36c0e2 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_diff_atoms_race5 +++ b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_diff_atoms_race5 @@ -1,2 +1,2 @@ -ets_insert_diff_atoms_race5.erl:22: The call ets:insert(Table::'foo',[{'counter',number()} | {'index',number()},...]) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Tab::'foo',Counter::'counter') call in ets_insert_diff_atoms_race5.erl on line 13 +ets_insert_diff_atoms_race5.erl:22:3: The call ets:insert(Table::'foo',[{'counter',number()} | {'index',number()},...]) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Tab::'foo',Counter::'counter') call in ets_insert_diff_atoms_race5.erl on line {13,16} diff --git a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_diff_atoms_race6 b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_diff_atoms_race6 index c029f79ed5..21e5cdf8f3 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_diff_atoms_race6 +++ b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_diff_atoms_race6 @@ -1,2 +1,2 @@ -ets_insert_diff_atoms_race6.erl:22: The call ets:insert(Table::'foo',{'counter',number()} | {'index',number()}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Tab::'foo',Counter::'counter') call in ets_insert_diff_atoms_race6.erl on line 13 +ets_insert_diff_atoms_race6.erl:22:3: The call ets:insert(Table::'foo',{'counter',number()} | {'index',number()}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Tab::'foo',Counter::'counter') call in ets_insert_diff_atoms_race6.erl on line {13,16} diff --git a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_double1 b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_double1 index 2473bf5d01..5de9983e9e 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_double1 +++ b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_double1 @@ -1,4 +1,4 @@ -ets_insert_double1.erl:15: The call ets:insert('foo',[{'pass',[number()]} | {'random',integer()},...]) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup('foo','random') call in ets_insert_double1.erl on line 10, the ets:lookup('foo','pass') call in ets_insert_double1.erl on line 27 -ets_insert_double1.erl:19: The call ets:insert('foo',[{'pass',[number()]} | {'random',integer()},...]) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup('foo','random') call in ets_insert_double1.erl on line 10, the ets:lookup('foo','pass') call in ets_insert_double1.erl on line 27 -ets_insert_double1.erl:24: The call ets:insert('foo',{'pass', 'empty'}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup('foo','pass') call in ets_insert_double1.erl on line 22 +ets_insert_double1.erl:15:7: The call ets:insert('foo',[{'pass',[number()]} | {'random',integer()},...]) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup('foo','random') call in ets_insert_double1.erl on line {10,41}, the ets:lookup('foo','pass') call in ets_insert_double1.erl on line {27,14} +ets_insert_double1.erl:19:7: The call ets:insert('foo',[{'pass',[number()]} | {'random',integer()},...]) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup('foo','random') call in ets_insert_double1.erl on line {10,41}, the ets:lookup('foo','pass') call in ets_insert_double1.erl on line {27,14} +ets_insert_double1.erl:24:3: The call ets:insert('foo',{'pass', 'empty'}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup('foo','pass') call in ets_insert_double1.erl on line {22,16} diff --git a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_double2 b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_double2 index cf61cb5ec3..532550efb7 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_double2 +++ b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_double2 @@ -1,4 +1,4 @@ -ets_insert_double2.erl:15: The call ets:insert('foo',[{_,[number()] | integer()},...]) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup('foo',Random::any()) call in ets_insert_double2.erl on line 10, the ets:lookup('foo',Pass::any()) call in ets_insert_double2.erl on line 27 -ets_insert_double2.erl:19: The call ets:insert('foo',[{_,[number()] | integer()},...]) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup('foo',Random::any()) call in ets_insert_double2.erl on line 10, the ets:lookup('foo',Pass::any()) call in ets_insert_double2.erl on line 27 -ets_insert_double2.erl:24: The call ets:insert('foo',{_,'empty'}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup('foo',Pass::any()) call in ets_insert_double2.erl on line 22 +ets_insert_double2.erl:15:7: The call ets:insert('foo',[{_,[number()] | integer()},...]) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup('foo',Random::any()) call in ets_insert_double2.erl on line {10,41}, the ets:lookup('foo',Pass::any()) call in ets_insert_double2.erl on line {27,14} +ets_insert_double2.erl:19:7: The call ets:insert('foo',[{_,[number()] | integer()},...]) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup('foo',Random::any()) call in ets_insert_double2.erl on line {10,41}, the ets:lookup('foo',Pass::any()) call in ets_insert_double2.erl on line {27,14} +ets_insert_double2.erl:24:3: The call ets:insert('foo',{_,'empty'}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup('foo',Pass::any()) call in ets_insert_double2.erl on line {22,16} diff --git a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_funs1 b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_funs1 index 540a0cf388..646921b7ab 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_funs1 +++ b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_funs1 @@ -1,2 +1,2 @@ -ets_insert_funs1.erl:15: The call ets:insert('foo',[{'counter',number()},...]) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(T::'foo','counter') call in ets_insert_funs1.erl on line 9 +ets_insert_funs1.erl:15:3: The call ets:insert('foo',[{'counter',number()},...]) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(T::'foo','counter') call in ets_insert_funs1.erl on line {9,9} diff --git a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_funs2 b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_funs2 index 6b618f72b6..1cb3e3a996 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_funs2 +++ b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_funs2 @@ -1,2 +1,2 @@ -ets_insert_funs2.erl:9: The call ets:insert(T::'foo',[{'counter',number()},...]) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup('foo','counter') call in ets_insert_funs2.erl on line 14 +ets_insert_funs2.erl:9:9: The call ets:insert(T::'foo',[{'counter',number()},...]) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup('foo','counter') call in ets_insert_funs2.erl on line {14,14} diff --git a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_param b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_param index 6a34337a2c..29b20f3386 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_param +++ b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_param @@ -1,5 +1,5 @@ -ets_insert_param.erl:13: The call ets:insert(Table::atom() | ets:tid(),{'welcome_msg',[any(),...]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Table::atom() | ets:tid(),'welcome_msg') call in ets_insert_param.erl on line 10 -ets_insert_param.erl:14: The call ets:insert(Table::atom() | ets:tid(),{'pass',[pos_integer()]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Table::atom() | ets:tid(),'pass') call in ets_insert_param.erl on line 14, the ets:lookup(Table::atom() | ets:tid(),'pass') call in ets_insert_param.erl on line 15 -ets_insert_param.erl:17: The call ets:insert(Table::atom() | ets:tid(),{'welcome_msg',[any(),...]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Table::atom() | ets:tid(),'welcome_msg') call in ets_insert_param.erl on line 10 -ets_insert_param.erl:18: The call ets:insert(Table::atom() | ets:tid(),{'pass',[pos_integer()]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Table::atom() | ets:tid(),'pass') call in ets_insert_param.erl on line 18 +ets_insert_param.erl:13:7: The call ets:insert(Table::atom() | ets:tid(),{'welcome_msg',[any(),...]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Table::atom() | ets:tid(),'welcome_msg') call in ets_insert_param.erl on line {10,16} +ets_insert_param.erl:14:7: The call ets:insert(Table::atom() | ets:tid(),{'pass',[pos_integer()]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Table::atom() | ets:tid(),'pass') call in ets_insert_param.erl on line {14,57}, the ets:lookup(Table::atom() | ets:tid(),'pass') call in ets_insert_param.erl on line {15,67} +ets_insert_param.erl:17:7: The call ets:insert(Table::atom() | ets:tid(),{'welcome_msg',[any(),...]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Table::atom() | ets:tid(),'welcome_msg') call in ets_insert_param.erl on line {10,16} +ets_insert_param.erl:18:7: The call ets:insert(Table::atom() | ets:tid(),{'pass',[pos_integer()]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Table::atom() | ets:tid(),'pass') call in ets_insert_param.erl on line {18,57} diff --git a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_public b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_public index d091ce3b50..27ce4b181a 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/ets_insert_public +++ b/lib/dialyzer/test/race_SUITE_data/results/ets_insert_public @@ -1,2 +1,2 @@ -ets_insert_public.erl:14: The call ets:insert(Foo::atom(),{'counter',number()}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Foo::atom(),'counter') call in ets_insert_public.erl on line 12 +ets_insert_public.erl:14:5: The call ets:insert(Foo::atom(),{'counter',number()}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup(Foo::atom(),'counter') call in ets_insert_public.erl on line {12,16} diff --git a/lib/dialyzer/test/race_SUITE_data/results/extract_translations b/lib/dialyzer/test/race_SUITE_data/results/extract_translations index 295404bfed..8804c0b9ee 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/extract_translations +++ b/lib/dialyzer/test/race_SUITE_data/results/extract_translations @@ -1,5 +1,5 @@ -extract_translations.erl:140: The call ets:insert('files',{atom() | [atom() | [any()] | char()]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup('files',File::atom() | [atom() | [any()] | char()]) call in extract_translations.erl on line 135 -extract_translations.erl:146: The call ets:insert('translations',{_,[]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup('translations',Str::any()) call in extract_translations.erl on line 126 -extract_translations.erl:152: The call ets:insert('files',{atom() | [atom() | [any()] | char()]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup('files',File::atom() | [atom() | [any()] | char()]) call in extract_translations.erl on line 148 -extract_translations.erl:154: The call ets:insert('translations',{_,[]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup('translations',Str::any()) call in extract_translations.erl on line 126 +extract_translations.erl:140:7: The call ets:insert('files',{atom() | [atom() | [any()] | char()]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup('files',File::atom() | [atom() | [any()] | char()]) call in extract_translations.erl on line {135,11} +extract_translations.erl:146:6: The call ets:insert('translations',{_,[]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup('translations',Str::any()) call in extract_translations.erl on line {126,11} +extract_translations.erl:152:7: The call ets:insert('files',{atom() | [atom() | [any()] | char()]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup('files',File::atom() | [atom() | [any()] | char()]) call in extract_translations.erl on line {148,11} +extract_translations.erl:154:6: The call ets:insert('translations',{_,[]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup('translations',Str::any()) call in extract_translations.erl on line {126,11} diff --git a/lib/dialyzer/test/race_SUITE_data/results/mnesia_diff_atoms_race1 b/lib/dialyzer/test/race_SUITE_data/results/mnesia_diff_atoms_race1 index f5e544dc2a..d7886f3b68 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/mnesia_diff_atoms_race1 +++ b/lib/dialyzer/test/race_SUITE_data/results/mnesia_diff_atoms_race1 @@ -1,2 +1,2 @@ -mnesia_diff_atoms_race1.erl:33: The call mnesia:dirty_write(Table::'employee' | 'employer',Record::#employee{salary::number()}) might have an unintended effect due to a possible race condition caused by its combination with the mnesia:dirty_read(Tab::'employee',Eno::any()) call in mnesia_diff_atoms_race1.erl on line 19 +mnesia_diff_atoms_race1.erl:33:3: The call mnesia:dirty_write(Table::'employee' | 'employer',Record::#employee{salary::number()}) might have an unintended effect due to a possible race condition caused by its combination with the mnesia:dirty_read(Tab::'employee',Eno::any()) call in mnesia_diff_atoms_race1.erl on line {19,11} diff --git a/lib/dialyzer/test/race_SUITE_data/results/mnesia_diff_atoms_race2 b/lib/dialyzer/test/race_SUITE_data/results/mnesia_diff_atoms_race2 index 0ad0bc0afd..51906dd548 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/mnesia_diff_atoms_race2 +++ b/lib/dialyzer/test/race_SUITE_data/results/mnesia_diff_atoms_race2 @@ -1,2 +1,2 @@ -mnesia_diff_atoms_race2.erl:37: The call mnesia:dirty_write(Record::#employee{salary::number()} | #employer{}) might have an unintended effect due to a possible race condition caused by its combination with the mnesia:dirty_read(Tab::'employee',Eno::any()) call in mnesia_diff_atoms_race2.erl on line 26 +mnesia_diff_atoms_race2.erl:37:3: The call mnesia:dirty_write(Record::#employee{salary::number()} | #employer{}) might have an unintended effect due to a possible race condition caused by its combination with the mnesia:dirty_read(Tab::'employee',Eno::any()) call in mnesia_diff_atoms_race2.erl on line {26,11} diff --git a/lib/dialyzer/test/race_SUITE_data/results/mnesia_dirty_read_one_write_two b/lib/dialyzer/test/race_SUITE_data/results/mnesia_dirty_read_one_write_two index a4f3c269f1..3ac7ed1f04 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/mnesia_dirty_read_one_write_two +++ b/lib/dialyzer/test/race_SUITE_data/results/mnesia_dirty_read_one_write_two @@ -1,2 +1,2 @@ -mnesia_dirty_read_one_write_two.erl:20: The call mnesia:dirty_write('employee',New::#employee{salary::number()}) might have an unintended effect due to a possible race condition caused by its combination with the mnesia:dirty_read({'employee',_}) call in mnesia_dirty_read_one_write_two.erl on line 17 +mnesia_dirty_read_one_write_two.erl:20:5: The call mnesia:dirty_write('employee',New::#employee{salary::number()}) might have an unintended effect due to a possible race condition caused by its combination with the mnesia:dirty_read({'employee',_}) call in mnesia_dirty_read_one_write_two.erl on line {17,11} diff --git a/lib/dialyzer/test/race_SUITE_data/results/mnesia_dirty_read_two_write_one b/lib/dialyzer/test/race_SUITE_data/results/mnesia_dirty_read_two_write_one index 6e666d755f..231e62c2c2 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/mnesia_dirty_read_two_write_one +++ b/lib/dialyzer/test/race_SUITE_data/results/mnesia_dirty_read_two_write_one @@ -1,2 +1,2 @@ -mnesia_dirty_read_two_write_one.erl:20: The call mnesia:dirty_write(New::#employee{salary::number()}) might have an unintended effect due to a possible race condition caused by its combination with the mnesia:dirty_read('employee',Eno::any()) call in mnesia_dirty_read_two_write_one.erl on line 17 +mnesia_dirty_read_two_write_one.erl:20:5: The call mnesia:dirty_write(New::#employee{salary::number()}) might have an unintended effect due to a possible race condition caused by its combination with the mnesia:dirty_read('employee',Eno::any()) call in mnesia_dirty_read_two_write_one.erl on line {17,11} diff --git a/lib/dialyzer/test/race_SUITE_data/results/mnesia_dirty_read_write_double1 b/lib/dialyzer/test/race_SUITE_data/results/mnesia_dirty_read_write_double1 index e953c6948b..1e2c4e379f 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/mnesia_dirty_read_write_double1 +++ b/lib/dialyzer/test/race_SUITE_data/results/mnesia_dirty_read_write_double1 @@ -1,2 +1,2 @@ -mnesia_dirty_read_write_double1.erl:20: The call mnesia:dirty_write('employee',New::#employee{salary::number()}) might have an unintended effect due to a possible race condition caused by its combination with the mnesia:dirty_read('employee',Eno::any()) call in mnesia_dirty_read_write_double1.erl on line 17 +mnesia_dirty_read_write_double1.erl:20:5: The call mnesia:dirty_write('employee',New::#employee{salary::number()}) might have an unintended effect due to a possible race condition caused by its combination with the mnesia:dirty_read('employee',Eno::any()) call in mnesia_dirty_read_write_double1.erl on line {17,11} diff --git a/lib/dialyzer/test/race_SUITE_data/results/mnesia_dirty_read_write_double2 b/lib/dialyzer/test/race_SUITE_data/results/mnesia_dirty_read_write_double2 index 2a0b4eddd0..3d28f32dc9 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/mnesia_dirty_read_write_double2 +++ b/lib/dialyzer/test/race_SUITE_data/results/mnesia_dirty_read_write_double2 @@ -1,2 +1,2 @@ -mnesia_dirty_read_write_double2.erl:20: The call mnesia:dirty_write(New::#employee{salary::number()}) might have an unintended effect due to a possible race condition caused by its combination with the mnesia:dirty_read({'employee',_}) call in mnesia_dirty_read_write_double2.erl on line 17 +mnesia_dirty_read_write_double2.erl:20:5: The call mnesia:dirty_write(New::#employee{salary::number()}) might have an unintended effect due to a possible race condition caused by its combination with the mnesia:dirty_read({'employee',_}) call in mnesia_dirty_read_write_double2.erl on line {17,11} diff --git a/lib/dialyzer/test/race_SUITE_data/results/mnesia_dirty_read_write_double3 b/lib/dialyzer/test/race_SUITE_data/results/mnesia_dirty_read_write_double3 index fe51a5e838..5b46129157 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/mnesia_dirty_read_write_double3 +++ b/lib/dialyzer/test/race_SUITE_data/results/mnesia_dirty_read_write_double3 @@ -1,2 +1,2 @@ -mnesia_dirty_read_write_double3.erl:20: The call mnesia:dirty_write('employee',New::#employee{salary::number()}) might have an unintended effect due to a possible race condition caused by its combination with the mnesia:dirty_read({'employee',_}) call in mnesia_dirty_read_write_double3.erl on line 17 +mnesia_dirty_read_write_double3.erl:20:5: The call mnesia:dirty_write('employee',New::#employee{salary::number()}) might have an unintended effect due to a possible race condition caused by its combination with the mnesia:dirty_read({'employee',_}) call in mnesia_dirty_read_write_double3.erl on line {17,11} diff --git a/lib/dialyzer/test/race_SUITE_data/results/mnesia_dirty_read_write_double4 b/lib/dialyzer/test/race_SUITE_data/results/mnesia_dirty_read_write_double4 index d6a60d847a..895faa4cad 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/mnesia_dirty_read_write_double4 +++ b/lib/dialyzer/test/race_SUITE_data/results/mnesia_dirty_read_write_double4 @@ -1,2 +1,2 @@ -mnesia_dirty_read_write_double4.erl:20: The call mnesia:dirty_write(New::#employee{salary::number()}) might have an unintended effect due to a possible race condition caused by its combination with the mnesia:dirty_read('employee',Eno::any()) call in mnesia_dirty_read_write_double4.erl on line 17 +mnesia_dirty_read_write_double4.erl:20:5: The call mnesia:dirty_write(New::#employee{salary::number()}) might have an unintended effect due to a possible race condition caused by its combination with the mnesia:dirty_read('employee',Eno::any()) call in mnesia_dirty_read_write_double4.erl on line {17,11} diff --git a/lib/dialyzer/test/race_SUITE_data/results/mnesia_dirty_read_write_one b/lib/dialyzer/test/race_SUITE_data/results/mnesia_dirty_read_write_one index b47f66eb79..d88e501f9c 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/mnesia_dirty_read_write_one +++ b/lib/dialyzer/test/race_SUITE_data/results/mnesia_dirty_read_write_one @@ -1,2 +1,2 @@ -mnesia_dirty_read_write_one.erl:20: The call mnesia:dirty_write(New::#employee{salary::number()}) might have an unintended effect due to a possible race condition caused by its combination with the mnesia:dirty_read({'employee',_}) call in mnesia_dirty_read_write_one.erl on line 17 +mnesia_dirty_read_write_one.erl:20:5: The call mnesia:dirty_write(New::#employee{salary::number()}) might have an unintended effect due to a possible race condition caused by its combination with the mnesia:dirty_read({'employee',_}) call in mnesia_dirty_read_write_one.erl on line {17,11} diff --git a/lib/dialyzer/test/race_SUITE_data/results/mnesia_dirty_read_write_two b/lib/dialyzer/test/race_SUITE_data/results/mnesia_dirty_read_write_two index 2faf55fe72..4ff8c0d9c4 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/mnesia_dirty_read_write_two +++ b/lib/dialyzer/test/race_SUITE_data/results/mnesia_dirty_read_write_two @@ -1,2 +1,2 @@ -mnesia_dirty_read_write_two.erl:20: The call mnesia:dirty_write('employee',New::#employee{salary::number()}) might have an unintended effect due to a possible race condition caused by its combination with the mnesia:dirty_read('employee',Eno::any()) call in mnesia_dirty_read_write_two.erl on line 17 +mnesia_dirty_read_write_two.erl:20:5: The call mnesia:dirty_write('employee',New::#employee{salary::number()}) might have an unintended effect due to a possible race condition caused by its combination with the mnesia:dirty_read('employee',Eno::any()) call in mnesia_dirty_read_write_two.erl on line {17,11} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_control_flow1 b/lib/dialyzer/test/race_SUITE_data/results/whereis_control_flow1 index 0fcf13c50a..c62a764338 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_control_flow1 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_control_flow1 @@ -1,2 +1,2 @@ -whereis_control_flow1.erl:13: The call erlang:register(AnAtom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_control_flow1.erl on line 8 +whereis_control_flow1.erl:13:18: The call erlang:register(AnAtom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_control_flow1.erl on line {8,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_control_flow2 b/lib/dialyzer/test/race_SUITE_data/results/whereis_control_flow2 index d0c048701d..1fc47a7218 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_control_flow2 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_control_flow2 @@ -1,3 +1,3 @@ -whereis_control_flow2.erl:14: The call erlang:register(AnAtom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_control_flow2.erl on line 8 -whereis_control_flow2.erl:15: The call erlang:register(AnAtom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_control_flow2.erl on line 8 +whereis_control_flow2.erl:14:4: The call erlang:register(AnAtom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_control_flow2.erl on line {8,8} +whereis_control_flow2.erl:15:18: The call erlang:register(AnAtom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_control_flow2.erl on line {8,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_control_flow3 b/lib/dialyzer/test/race_SUITE_data/results/whereis_control_flow3 index 0d93428758..f04acc840e 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_control_flow3 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_control_flow3 @@ -1,2 +1,2 @@ -whereis_control_flow3.erl:25: The call erlang:register(AnAtom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_control_flow3.erl on line 11, the erlang:whereis(AnAtom::any()) call in whereis_control_flow3.erl on line 18 +whereis_control_flow3.erl:25:3: The call erlang:register(AnAtom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_control_flow3.erl on line {11,14}, the erlang:whereis(AnAtom::any()) call in whereis_control_flow3.erl on line {18,14} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_control_flow4 b/lib/dialyzer/test/race_SUITE_data/results/whereis_control_flow4 index f0ce12d0a4..76b60a0db8 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_control_flow4 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_control_flow4 @@ -1,3 +1,3 @@ -whereis_control_flow4.erl:18: The call erlang:register('maria',Pid1::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis('maria') call in whereis_control_flow4.erl on line 8 -whereis_control_flow4.erl:19: The call erlang:register('kostis',Pid2::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis('kostis') call in whereis_control_flow4.erl on line 13 +whereis_control_flow4.erl:18:19: The call erlang:register('maria',Pid1::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis('maria') call in whereis_control_flow4.erl on line {8,8} +whereis_control_flow4.erl:19:19: The call erlang:register('kostis',Pid2::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis('kostis') call in whereis_control_flow4.erl on line {13,16} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_control_flow5 b/lib/dialyzer/test/race_SUITE_data/results/whereis_control_flow5 index fd809139e4..0a445d4f10 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_control_flow5 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_control_flow5 @@ -1,2 +1,2 @@ -whereis_control_flow5.erl:11: The call erlang:unregister(AnAtom::atom()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_control_flow5.erl on line 8 +whereis_control_flow5.erl:11:7: The call erlang:unregister(AnAtom::atom()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_control_flow5.erl on line {8,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_control_flow6 b/lib/dialyzer/test/race_SUITE_data/results/whereis_control_flow6 index ba89cc5624..2b6726731f 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_control_flow6 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_control_flow6 @@ -1,2 +1,2 @@ -whereis_control_flow6.erl:11: The call erlang:unregister('kostis') might fail due to a possible race condition caused by its combination with the erlang:whereis('kostis') call in whereis_control_flow6.erl on line 8 +whereis_control_flow6.erl:11:7: The call erlang:unregister('kostis') might fail due to a possible race condition caused by its combination with the erlang:whereis('kostis') call in whereis_control_flow6.erl on line {8,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_atoms_race b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_atoms_race index 76c746e2f4..4b7272e203 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_atoms_race +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_atoms_race @@ -1,2 +1,2 @@ -whereis_diff_atoms_race.erl:34: The call erlang:register(Atom::'kostis' | 'maria',Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::'maria') call in whereis_diff_atoms_race.erl on line 14 +whereis_diff_atoms_race.erl:34:3: The call erlang:register(Atom::'kostis' | 'maria',Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::'maria') call in whereis_diff_atoms_race.erl on line {14,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions1 b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions1 index 14c157885f..aac6a321cd 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions1 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions1 @@ -1,3 +1,3 @@ -whereis_diff_functions1.erl:10: The call erlang:register('master',pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis('master') call in whereis_diff_functions1.erl on line 8 -whereis_diff_functions1.erl:18: The call erlang:register(AnAtom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_diff_functions1.erl on line 15 +whereis_diff_functions1.erl:10:7: The call erlang:register('master',pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis('master') call in whereis_diff_functions1.erl on line {8,8} +whereis_diff_functions1.erl:18:7: The call erlang:register(AnAtom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_diff_functions1.erl on line {15,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions1_nested b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions1_nested index c791d4b347..85a8546bc6 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions1_nested +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions1_nested @@ -1,2 +1,2 @@ -whereis_diff_functions1_nested.erl:23: The call erlang:register(Atom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_diff_functions1_nested.erl on line 11 +whereis_diff_functions1_nested.erl:23:3: The call erlang:register(Atom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_diff_functions1_nested.erl on line {11,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions1_pathsens b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions1_pathsens index d22e696196..c9c4fe7b48 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions1_pathsens +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions1_pathsens @@ -1,2 +1,2 @@ -whereis_diff_functions1_pathsens.erl:32: The call erlang:register(Atom::'kostis',Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::'kostis') call in whereis_diff_functions1_pathsens.erl on line 15, the erlang:whereis(AnAtom::'kostis') call in whereis_diff_functions1_pathsens.erl on line 22 +whereis_diff_functions1_pathsens.erl:32:3: The call erlang:register(Atom::'kostis',Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::'kostis') call in whereis_diff_functions1_pathsens.erl on line {15,14}, the erlang:whereis(AnAtom::'kostis') call in whereis_diff_functions1_pathsens.erl on line {22,14} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions1_twice b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions1_twice index 3024c77d91..f2338ed249 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions1_twice +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions1_twice @@ -1,3 +1,3 @@ -whereis_diff_functions1_twice.erl:27: The call erlang:register(Atom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_diff_functions1_twice.erl on line 11 -whereis_diff_functions1_twice.erl:30: The call erlang:register(Atom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::atom()) call in whereis_diff_functions1_twice.erl on line 15 +whereis_diff_functions1_twice.erl:27:3: The call erlang:register(Atom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_diff_functions1_twice.erl on line {11,8} +whereis_diff_functions1_twice.erl:30:3: The call erlang:register(Atom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::atom()) call in whereis_diff_functions1_twice.erl on line {15,12} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions2 b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions2 index 9a22eb7e17..005428286e 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions2 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions2 @@ -1,2 +1,2 @@ -whereis_diff_functions2.erl:25: The call erlang:register(Atom::'kostis',Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::'kostis') call in whereis_diff_functions2.erl on line 13 +whereis_diff_functions2.erl:25:3: The call erlang:register(Atom::'kostis',Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::'kostis') call in whereis_diff_functions2.erl on line {13,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions2_nested b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions2_nested index 0e757fbccc..54ea8e70fd 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions2_nested +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions2_nested @@ -1,2 +1,2 @@ -whereis_diff_functions2_nested.erl:20: The call erlang:register(Atom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_diff_functions2_nested.erl on line 8 +whereis_diff_functions2_nested.erl:20:3: The call erlang:register(Atom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_diff_functions2_nested.erl on line {8,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions2_pathsens b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions2_pathsens index c102b39243..3ec2234046 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions2_pathsens +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions2_pathsens @@ -1,2 +1,2 @@ -whereis_diff_functions2_pathsens.erl:29: The call erlang:register(Atom::atom(),Pid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_diff_functions2_pathsens.erl on line 12, the erlang:whereis(AnAtom::any()) call in whereis_diff_functions2_pathsens.erl on line 19 +whereis_diff_functions2_pathsens.erl:29:3: The call erlang:register(Atom::atom(),Pid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_diff_functions2_pathsens.erl on line {12,14}, the erlang:whereis(AnAtom::any()) call in whereis_diff_functions2_pathsens.erl on line {19,14} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions2_twice b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions2_twice index b048bc6bed..d14a255040 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions2_twice +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions2_twice @@ -1,3 +1,3 @@ -whereis_diff_functions2_twice.erl:24: The call erlang:register(Atom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_diff_functions2_twice.erl on line 8 -whereis_diff_functions2_twice.erl:27: The call erlang:register(Atom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::atom()) call in whereis_diff_functions2_twice.erl on line 12 +whereis_diff_functions2_twice.erl:24:3: The call erlang:register(Atom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_diff_functions2_twice.erl on line {8,8} +whereis_diff_functions2_twice.erl:27:3: The call erlang:register(Atom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::atom()) call in whereis_diff_functions2_twice.erl on line {12,12} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions3 b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions3 index 6d5154b411..079ec9fb31 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions3 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions3 @@ -1,2 +1,2 @@ -whereis_diff_functions3.erl:8: The call erlang:register(AnAtom::atom(),'undefined' | pid() | port()) might fail due to a possible race condition caused by its combination with the erlang:whereis(Atom::any()) call in whereis_diff_functions3.erl on line 11 +whereis_diff_functions3.erl:8:3: The call erlang:register(AnAtom::atom(),'undefined' | pid() | port()) might fail due to a possible race condition caused by its combination with the erlang:whereis(Atom::any()) call in whereis_diff_functions3.erl on line {11,3} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions3_nested b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions3_nested index 298c4c7178..f1a4733585 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions3_nested +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions3_nested @@ -1,2 +1,2 @@ -whereis_diff_functions3_nested.erl:21: The call erlang:unregister(Atom::atom()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_diff_functions3_nested.erl on line 11 +whereis_diff_functions3_nested.erl:21:3: The call erlang:unregister(Atom::atom()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_diff_functions3_nested.erl on line {11,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions3_pathsens b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions3_pathsens index 5d1ea5bda5..44e1ba6fbc 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions3_pathsens +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions3_pathsens @@ -1,2 +1,2 @@ -whereis_diff_functions3_pathsens.erl:29: The call erlang:register(Atom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_diff_functions3_pathsens.erl on line 12, the erlang:whereis(AnAtom::any()) call in whereis_diff_functions3_pathsens.erl on line 19 +whereis_diff_functions3_pathsens.erl:29:3: The call erlang:register(Atom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_diff_functions3_pathsens.erl on line {12,14}, the erlang:whereis(AnAtom::any()) call in whereis_diff_functions3_pathsens.erl on line {19,14} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions4 b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions4 index cb51301f1e..2f39e19a03 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions4 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions4 @@ -1,2 +1,2 @@ -whereis_diff_functions4.erl:32: The call erlang:register(Atom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_diff_functions4.erl on line 13, the erlang:whereis(AnAtom::atom()) call in whereis_diff_functions4.erl on line 17 +whereis_diff_functions4.erl:32:3: The call erlang:register(Atom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_diff_functions4.erl on line {13,8}, the erlang:whereis(AnAtom::atom()) call in whereis_diff_functions4.erl on line {17,12} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions5 b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions5 index 34c477e05a..1e19cb26e7 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions5 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions5 @@ -1,2 +1,2 @@ -whereis_diff_functions5.erl:22: The call erlang:register(Atom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_diff_functions5.erl on line 10 +whereis_diff_functions5.erl:22:3: The call erlang:register(Atom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_diff_functions5.erl on line {10,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions6 b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions6 index 8840ef4ca7..5c8a093405 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions6 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_functions6 @@ -1,2 +1,2 @@ -whereis_diff_functions6.erl:29: The call erlang:register(Atom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_diff_functions6.erl on line 10, the erlang:whereis(AnAtom::atom()) call in whereis_diff_functions6.erl on line 14 +whereis_diff_functions6.erl:29:3: The call erlang:register(Atom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_diff_functions6.erl on line {10,8}, the erlang:whereis(AnAtom::atom()) call in whereis_diff_functions6.erl on line {14,12} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_modules1 b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_modules1 index 8f7d0b7a17..6a28376c07 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_modules1 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_modules1 @@ -1,2 +1,2 @@ -whereis_diff_modules2.erl:11: The call erlang:register(Atom::any(),Pid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_diff_modules1.erl on line 10 +whereis_diff_modules2.erl:11:3: The call erlang:register(Atom::any(),Pid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_diff_modules1.erl on line {10,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_modules1_pathsens b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_modules1_pathsens index 40d36eb7d2..f287ade224 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_modules1_pathsens +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_modules1_pathsens @@ -1,2 +1,2 @@ -whereis_diff_modules2_pathsens.erl:12: The call erlang:register(Atom::any(),Pid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_diff_modules1_pathsens.erl on line 12, the erlang:whereis(AnAtom::any()) call in whereis_diff_modules1_pathsens.erl on line 19 +whereis_diff_modules2_pathsens.erl:12:3: The call erlang:register(Atom::any(),Pid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_diff_modules1_pathsens.erl on line {12,14}, the erlang:whereis(AnAtom::any()) call in whereis_diff_modules1_pathsens.erl on line {19,14} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_modules1_rec b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_modules1_rec index 278b679aba..2d2033d172 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_modules1_rec +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_modules1_rec @@ -1,2 +1,2 @@ -whereis_diff_modules1_rec.erl:10: The call erlang:register(AnAtom::any(),Id::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(NextAtom::any()) call in whereis_diff_modules1_rec.erl on line 12 +whereis_diff_modules1_rec.erl:10:10: The call erlang:register(AnAtom::any(),Id::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(NextAtom::any()) call in whereis_diff_modules1_rec.erl on line {12,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_modules2 b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_modules2 index a4e5a000e2..3ae7f24bf7 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_modules2 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_modules2 @@ -1,2 +1,2 @@ -whereis_diff_modules3.erl:8: The call erlang:register(AnAtom::atom(),'undefined' | pid() | port()) might fail due to a possible race condition caused by its combination with the erlang:whereis(Atom::any()) call in whereis_diff_modules4.erl on line 11 +whereis_diff_modules3.erl:8:3: The call erlang:register(AnAtom::atom(),'undefined' | pid() | port()) might fail due to a possible race condition caused by its combination with the erlang:whereis(Atom::any()) call in whereis_diff_modules4.erl on line {11,3} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_modules2_pathsens b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_modules2_pathsens index cc93133019..b3a9a2130a 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_modules2_pathsens +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_modules2_pathsens @@ -1,2 +1,2 @@ -whereis_diff_modules4_pathsens.erl:13: The call erlang:register(Atom::atom(),Pid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_diff_modules3_pathsens.erl on line 12, the erlang:whereis(AnAtom::any()) call in whereis_diff_modules3_pathsens.erl on line 19 +whereis_diff_modules4_pathsens.erl:13:3: The call erlang:register(Atom::atom(),Pid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_diff_modules3_pathsens.erl on line {12,14}, the erlang:whereis(AnAtom::any()) call in whereis_diff_modules3_pathsens.erl on line {19,14} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_modules2_rec b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_modules2_rec index 8874ab3553..bca2659836 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_modules2_rec +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_modules2_rec @@ -1,2 +1,2 @@ -whereis_diff_modules3_rec.erl:13: The call erlang:register(AnAtom::any(),Id::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(NextAtom::any()) call in whereis_diff_modules3_rec.erl on line 15 +whereis_diff_modules3_rec.erl:13:10: The call erlang:register(AnAtom::any(),Id::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(NextAtom::any()) call in whereis_diff_modules3_rec.erl on line {15,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_modules3 b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_modules3 index 8e839a53dc..c8afd6603f 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_modules3 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_modules3 @@ -1,2 +1,2 @@ -whereis_diff_modules6.erl:11: The call erlang:register(Atom::any(),Pid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_diff_modules5.erl on line 10, the erlang:whereis(AnAtom::atom()) call in whereis_diff_modules5.erl on line 14 +whereis_diff_modules6.erl:11:3: The call erlang:register(Atom::any(),Pid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_diff_modules5.erl on line {10,8}, the erlang:whereis(AnAtom::atom()) call in whereis_diff_modules5.erl on line {14,12} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_modules_nested b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_modules_nested index 9192dc0708..b003518eb7 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_modules_nested +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_modules_nested @@ -1,2 +1,2 @@ -whereis_diff_modules3_nested.erl:11: The call erlang:register(Atom::any(),Pid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_diff_modules1_nested.erl on line 8 +whereis_diff_modules3_nested.erl:11:3: The call erlang:register(Atom::any(),Pid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_diff_modules1_nested.erl on line {8,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_modules_twice b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_modules_twice index 3758347255..c8d414d76c 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_modules_twice +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_modules_twice @@ -1,3 +1,3 @@ -whereis_diff_modules2_twice.erl:11: The call erlang:register(Atom::any(),Pid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::atom()) call in whereis_diff_modules1_twice.erl on line 12 -whereis_diff_modules2_twice.erl:8: The call erlang:register(Atom::any(),Pid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_diff_modules1_twice.erl on line 8 +whereis_diff_modules2_twice.erl:11:3: The call erlang:register(Atom::any(),Pid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::atom()) call in whereis_diff_modules1_twice.erl on line {12,12} +whereis_diff_modules2_twice.erl:8:3: The call erlang:register(Atom::any(),Pid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_diff_modules1_twice.erl on line {8,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_vars_race b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_vars_race index e34b4d2138..4309c8370c 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_vars_race +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_diff_vars_race @@ -1,2 +1,2 @@ -whereis_diff_vars_race.erl:16: The call erlang:register(Atom2::any(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(Atom1::any()) call in whereis_diff_vars_race.erl on line 13 +whereis_diff_vars_race.erl:16:7: The call erlang:register(Atom2::any(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(Atom1::any()) call in whereis_diff_vars_race.erl on line {13,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_intra_inter_module1 b/lib/dialyzer/test/race_SUITE_data/results/whereis_intra_inter_module1 index 3ed6f50d8d..cf4393654f 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_intra_inter_module1 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_intra_inter_module1 @@ -1,2 +1,2 @@ -whereis_intra_inter_module2.erl:11: The call erlang:register(Atom::any(),Pid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_intra_inter_module1.erl on line 10 +whereis_intra_inter_module2.erl:11:3: The call erlang:register(Atom::any(),Pid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_intra_inter_module1.erl on line {10,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_intra_inter_module2 b/lib/dialyzer/test/race_SUITE_data/results/whereis_intra_inter_module2 index 737054fe67..4ceffb2f1f 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_intra_inter_module2 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_intra_inter_module2 @@ -1,2 +1,2 @@ -whereis_intra_inter_module4.erl:14: The call erlang:register(Atom::any(),Pid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_intra_inter_module3.erl on line 10 +whereis_intra_inter_module4.erl:14:3: The call erlang:register(Atom::any(),Pid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_intra_inter_module3.erl on line {10,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_intra_inter_module3 b/lib/dialyzer/test/race_SUITE_data/results/whereis_intra_inter_module3 index 4111498efe..9b5aa5c867 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_intra_inter_module3 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_intra_inter_module3 @@ -1,2 +1,2 @@ -whereis_intra_inter_module6.erl:14: The call erlang:register(Atom::any(),Pid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_intra_inter_module5.erl on line 10 +whereis_intra_inter_module6.erl:14:3: The call erlang:register(Atom::any(),Pid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_intra_inter_module5.erl on line {10,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_intra_inter_module4 b/lib/dialyzer/test/race_SUITE_data/results/whereis_intra_inter_module4 index 4e70a8efa1..c42e9b967f 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_intra_inter_module4 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_intra_inter_module4 @@ -1,2 +1,2 @@ -whereis_intra_inter_module7.erl:8: The call erlang:register(AnAtom::atom(),pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_intra_inter_module8.erl on line 8 +whereis_intra_inter_module7.erl:8:3: The call erlang:register(AnAtom::atom(),pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_intra_inter_module8.erl on line {8,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_intra_inter_module5 b/lib/dialyzer/test/race_SUITE_data/results/whereis_intra_inter_module5 index f6a10f52fd..569d0f5976 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_intra_inter_module5 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_intra_inter_module5 @@ -1,2 +1,2 @@ -whereis_intra_inter_module9.erl:8: The call erlang:register(AnAtom::atom(),pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_intra_inter_module10.erl on line 11 +whereis_intra_inter_module9.erl:8:3: The call erlang:register(AnAtom::atom(),pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_intra_inter_module10.erl on line {11,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_intra_inter_module6 b/lib/dialyzer/test/race_SUITE_data/results/whereis_intra_inter_module6 index a8623ee985..cc848c493c 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_intra_inter_module6 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_intra_inter_module6 @@ -1,2 +1,2 @@ -whereis_intra_inter_module12.erl:14: The call erlang:register(Atom::any(),Pid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_intra_inter_module11.erl on line 10, the erlang:whereis(AnAtom::any()) call in whereis_intra_inter_module11.erl on line 21 +whereis_intra_inter_module12.erl:14:3: The call erlang:register(Atom::any(),Pid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_intra_inter_module11.erl on line {10,8}, the erlang:whereis(AnAtom::any()) call in whereis_intra_inter_module11.erl on line {21,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_intra_inter_module7 b/lib/dialyzer/test/race_SUITE_data/results/whereis_intra_inter_module7 index e39d630c75..5bb9fb794b 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_intra_inter_module7 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_intra_inter_module7 @@ -1,2 +1,2 @@ -whereis_intra_inter_module14.erl:11: The call erlang:register(Atom::any(),Pid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_intra_inter_module13.erl on line 10, the erlang:whereis(AnAtom::any()) call in whereis_intra_inter_module14.erl on line 16 +whereis_intra_inter_module14.erl:11:3: The call erlang:register(Atom::any(),Pid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_intra_inter_module13.erl on line {10,8}, the erlang:whereis(AnAtom::any()) call in whereis_intra_inter_module14.erl on line {16,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_intra_inter_module8 b/lib/dialyzer/test/race_SUITE_data/results/whereis_intra_inter_module8 index 58ae498bd4..6973b7422c 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_intra_inter_module8 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_intra_inter_module8 @@ -1,2 +1,2 @@ -whereis_intra_inter_module16.erl:11: The call erlang:register(Atom::any(),Pid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_intra_inter_module15.erl on line 10, the erlang:whereis(AnAtom::any()) call in whereis_intra_inter_module16.erl on line 16 +whereis_intra_inter_module16.erl:11:3: The call erlang:register(Atom::any(),Pid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_intra_inter_module15.erl on line {10,8}, the erlang:whereis(AnAtom::any()) call in whereis_intra_inter_module16.erl on line {16,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_param b/lib/dialyzer/test/race_SUITE_data/results/whereis_param index fb7563b1c7..f6735807c1 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_param +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_param @@ -1,2 +1,2 @@ -whereis_param.erl:8: The call erlang:register(AnAtom::atom(),pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_param.erl on line 11 +whereis_param.erl:8:3: The call erlang:register(AnAtom::atom(),pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_param.erl on line {11,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_param_inter_module b/lib/dialyzer/test/race_SUITE_data/results/whereis_param_inter_module index fc3e9ca59d..97c9d27789 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_param_inter_module +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_param_inter_module @@ -1,2 +1,2 @@ -whereis_param_inter_module1.erl:8: The call erlang:register(AnAtom::atom(),pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_param_inter_module2.erl on line 8 +whereis_param_inter_module1.erl:8:3: The call erlang:register(AnAtom::atom(),pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_param_inter_module2.erl on line {8,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_rec_function1 b/lib/dialyzer/test/race_SUITE_data/results/whereis_rec_function1 index 2cf1960d65..66248649a0 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_rec_function1 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_rec_function1 @@ -1,2 +1,2 @@ -whereis_rec_function1.erl:14: The call erlang:register(AnAtom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_rec_function1.erl on line 8 +whereis_rec_function1.erl:14:4: The call erlang:register(AnAtom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_rec_function1.erl on line {8,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_rec_function2 b/lib/dialyzer/test/race_SUITE_data/results/whereis_rec_function2 index 4b55bc61ad..83298a5c3c 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_rec_function2 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_rec_function2 @@ -1,2 +1,2 @@ -whereis_rec_function2.erl:13: The call erlang:register(AnAtom::atom(),Id::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(NextAtom::any()) call in whereis_rec_function2.erl on line 15 +whereis_rec_function2.erl:13:10: The call erlang:register(AnAtom::atom(),Id::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(NextAtom::any()) call in whereis_rec_function2.erl on line {15,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_rec_function3 b/lib/dialyzer/test/race_SUITE_data/results/whereis_rec_function3 index 638e9b0f4b..7b004aeb12 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_rec_function3 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_rec_function3 @@ -1,2 +1,2 @@ -whereis_rec_function3.erl:13: The call erlang:register(AnAtom::atom(),Id::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(NextAtom::any()) call in whereis_rec_function3.erl on line 16, the erlang:whereis(NextAtom::atom()) call in whereis_rec_function3.erl on line 20 +whereis_rec_function3.erl:13:10: The call erlang:register(AnAtom::atom(),Id::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(NextAtom::any()) call in whereis_rec_function3.erl on line {16,10}, the erlang:whereis(NextAtom::atom()) call in whereis_rec_function3.erl on line {20,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_rec_function4 b/lib/dialyzer/test/race_SUITE_data/results/whereis_rec_function4 index f255cb8170..b2885774ba 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_rec_function4 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_rec_function4 @@ -1,2 +1,2 @@ -whereis_rec_function4.erl:13: The call erlang:register(AnAtom::atom(),Id::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(NextAtom::any()) call in whereis_rec_function4.erl on line 15 +whereis_rec_function4.erl:13:10: The call erlang:register(AnAtom::atom(),Id::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(NextAtom::any()) call in whereis_rec_function4.erl on line {15,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_rec_function5 b/lib/dialyzer/test/race_SUITE_data/results/whereis_rec_function5 index 78d81b9a57..d5e9c4328a 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_rec_function5 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_rec_function5 @@ -1,2 +1,2 @@ -whereis_rec_function5.erl:10: The call erlang:register(AnAtom::any(),Id::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(NextAtom::any()) call in whereis_rec_function5.erl on line 12 +whereis_rec_function5.erl:10:10: The call erlang:register(AnAtom::any(),Id::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(NextAtom::any()) call in whereis_rec_function5.erl on line {12,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_rec_function6 b/lib/dialyzer/test/race_SUITE_data/results/whereis_rec_function6 index 6df6de1922..c4c7c55b02 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_rec_function6 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_rec_function6 @@ -1,2 +1,2 @@ -whereis_rec_function6.erl:10: The call erlang:register(AnAtom::any(),Id::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(NextAtom::any()) call in whereis_rec_function6.erl on line 12 +whereis_rec_function6.erl:10:10: The call erlang:register(AnAtom::any(),Id::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(NextAtom::any()) call in whereis_rec_function6.erl on line {12,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_rec_function7 b/lib/dialyzer/test/race_SUITE_data/results/whereis_rec_function7 index f3ddb0b537..0a0b07bcc0 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_rec_function7 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_rec_function7 @@ -1,2 +1,2 @@ -whereis_rec_function7.erl:15: The call erlang:register(AnAtom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_rec_function7.erl on line 8 +whereis_rec_function7.erl:15:4: The call erlang:register(AnAtom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_rec_function7.erl on line {8,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_rec_function8 b/lib/dialyzer/test/race_SUITE_data/results/whereis_rec_function8 index 9d731ada29..db37842e6b 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_rec_function8 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_rec_function8 @@ -1,2 +1,2 @@ -whereis_rec_function8.erl:18: The call erlang:register(AnAtom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_rec_function8.erl on line 11 +whereis_rec_function8.erl:18:4: The call erlang:register(AnAtom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_rec_function8.erl on line {11,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_try_catch b/lib/dialyzer/test/race_SUITE_data/results/whereis_try_catch index fecb0756bd..3cf78cf0d2 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_try_catch +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_try_catch @@ -1,3 +1,3 @@ -whereis_try_catch.erl:13: The call erlang:register('master',Pid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis('master') call in whereis_try_catch.erl on line 8 -whereis_try_catch.erl:21: The call erlang:register('master',Pid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis('master') call in whereis_try_catch.erl on line 18 +whereis_try_catch.erl:13:14: The call erlang:register('master',Pid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis('master') call in whereis_try_catch.erl on line {8,8} +whereis_try_catch.erl:21:9: The call erlang:register('master',Pid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis('master') call in whereis_try_catch.erl on line {18,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_vars10 b/lib/dialyzer/test/race_SUITE_data/results/whereis_vars10 index 36a59096e0..37c060def4 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_vars10 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_vars10 @@ -1,2 +1,2 @@ -whereis_vars10.erl:17: The call erlang:register(OtherAtom::'kostis',Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_vars10.erl on line 8 +whereis_vars10.erl:17:22: The call erlang:register(OtherAtom::'kostis',Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_vars10.erl on line {8,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_vars12 b/lib/dialyzer/test/race_SUITE_data/results/whereis_vars12 index d34e1b1c7e..bc19f7a756 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_vars12 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_vars12 @@ -1,2 +1,2 @@ -whereis_vars12.erl:16: The call erlang:register(OtherAtom::'kostis',Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_vars12.erl on line 8 +whereis_vars12.erl:16:37: The call erlang:register(OtherAtom::'kostis',Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_vars12.erl on line {8,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_vars13 b/lib/dialyzer/test/race_SUITE_data/results/whereis_vars13 index e6ae40cee0..864231d6b4 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_vars13 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_vars13 @@ -1,2 +1,2 @@ -whereis_vars13.erl:16: The call erlang:register(OtherAtom::'kostis',APid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_vars13.erl on line 8 +whereis_vars13.erl:16:52: The call erlang:register(OtherAtom::'kostis',APid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_vars13.erl on line {8,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_vars14 b/lib/dialyzer/test/race_SUITE_data/results/whereis_vars14 index cdd23a7471..4aaf586141 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_vars14 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_vars14 @@ -1,2 +1,2 @@ -whereis_vars14.erl:16: The call erlang:register(OtherAtom::'kostis',APid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_vars14.erl on line 8 +whereis_vars14.erl:16:52: The call erlang:register(OtherAtom::'kostis',APid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_vars14.erl on line {8,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_vars15 b/lib/dialyzer/test/race_SUITE_data/results/whereis_vars15 index 7f79852978..2042e119ca 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_vars15 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_vars15 @@ -1,2 +1,2 @@ -whereis_vars15.erl:17: The call erlang:register(OtherAtom::'kostis',Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_vars15.erl on line 8 +whereis_vars15.erl:17:15: The call erlang:register(OtherAtom::'kostis',Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_vars15.erl on line {8,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_vars16 b/lib/dialyzer/test/race_SUITE_data/results/whereis_vars16 index 0f28dff25d..89f5b963a8 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_vars16 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_vars16 @@ -1,2 +1,2 @@ -whereis_vars16.erl:17: The call erlang:register(OtherAtom::any(),APid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_vars16.erl on line 8 +whereis_vars16.erl:17:15: The call erlang:register(OtherAtom::any(),APid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_vars16.erl on line {8,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_vars17 b/lib/dialyzer/test/race_SUITE_data/results/whereis_vars17 index 3681c1aa9f..1f94cfef0e 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_vars17 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_vars17 @@ -1,2 +1,2 @@ -whereis_vars17.erl:17: The call erlang:register(OtherAtom::any(),APid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_vars17.erl on line 8 +whereis_vars17.erl:17:15: The call erlang:register(OtherAtom::any(),APid::any()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_vars17.erl on line {8,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_vars2 b/lib/dialyzer/test/race_SUITE_data/results/whereis_vars2 index 1636a6e908..6aa57fcdc5 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_vars2 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_vars2 @@ -1,2 +1,2 @@ -whereis_vars2.erl:14: The call erlang:register(OtherAtom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_vars2.erl on line 8 +whereis_vars2.erl:14:18: The call erlang:register(OtherAtom::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_vars2.erl on line {8,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_vars22 b/lib/dialyzer/test/race_SUITE_data/results/whereis_vars22 index 0f258cc097..613d788e59 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_vars22 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_vars22 @@ -1,2 +1,2 @@ -whereis_vars22.erl:21: The call erlang:register(OtherAtom::'kostis',Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_vars22.erl on line 8 +whereis_vars22.erl:21:21: The call erlang:register(OtherAtom::'kostis',Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_vars22.erl on line {8,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_vars3 b/lib/dialyzer/test/race_SUITE_data/results/whereis_vars3 index 4f43b9adca..74ab067e56 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_vars3 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_vars3 @@ -1,2 +1,2 @@ -whereis_vars3.erl:14: The call erlang:register(OtherAtom::atom(),APid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_vars3.erl on line 8 +whereis_vars3.erl:14:18: The call erlang:register(OtherAtom::atom(),APid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_vars3.erl on line {8,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_vars4 b/lib/dialyzer/test/race_SUITE_data/results/whereis_vars4 index 9eb833c42a..0584b03a8d 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_vars4 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_vars4 @@ -1,2 +1,2 @@ -whereis_vars4.erl:14: The call erlang:register(OtherAtom::atom() | pid(),APid::atom() | pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_vars4.erl on line 8 +whereis_vars4.erl:14:18: The call erlang:register(OtherAtom::atom() | pid(),APid::atom() | pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_vars4.erl on line {8,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_vars5 b/lib/dialyzer/test/race_SUITE_data/results/whereis_vars5 index b1c269c020..0482d31215 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_vars5 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_vars5 @@ -1,2 +1,2 @@ -whereis_vars5.erl:16: The call erlang:register(OtherAtom::'kostis',Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_vars5.erl on line 8 +whereis_vars5.erl:16:26: The call erlang:register(OtherAtom::'kostis',Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_vars5.erl on line {8,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_vars6 b/lib/dialyzer/test/race_SUITE_data/results/whereis_vars6 index 88c58cfdf2..6edcb8b756 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_vars6 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_vars6 @@ -1,2 +1,2 @@ -whereis_vars6.erl:16: The call erlang:register(OtherAtom::'kostis',APid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_vars6.erl on line 8 +whereis_vars6.erl:16:34: The call erlang:register(OtherAtom::'kostis',APid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_vars6.erl on line {8,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_vars7 b/lib/dialyzer/test/race_SUITE_data/results/whereis_vars7 index 8924869634..23c1ef2942 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_vars7 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_vars7 @@ -1,2 +1,2 @@ -whereis_vars7.erl:16: The call erlang:register(OtherAtom::'kostis',APid::atom() | pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_vars7.erl on line 8 +whereis_vars7.erl:16:34: The call erlang:register(OtherAtom::'kostis',APid::atom() | pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_vars7.erl on line {8,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_vars8 b/lib/dialyzer/test/race_SUITE_data/results/whereis_vars8 index d9d8f3872f..59019c74c0 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_vars8 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_vars8 @@ -1,2 +1,2 @@ -whereis_vars8.erl:16: The call erlang:register(OtherAtom::'kostis',Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_vars8.erl on line 8 +whereis_vars8.erl:16:21: The call erlang:register(OtherAtom::'kostis',Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_vars8.erl on line {8,8} diff --git a/lib/dialyzer/test/race_SUITE_data/results/whereis_vars9 b/lib/dialyzer/test/race_SUITE_data/results/whereis_vars9 index da52ca1f82..89fba57863 100644 --- a/lib/dialyzer/test/race_SUITE_data/results/whereis_vars9 +++ b/lib/dialyzer/test/race_SUITE_data/results/whereis_vars9 @@ -1,2 +1,2 @@ -whereis_vars9.erl:16: The call erlang:register(OtherAtom::'kostis',Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_vars9.erl on line 8 +whereis_vars9.erl:16:21: The call erlang:register(OtherAtom::'kostis',Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(AnAtom::any()) call in whereis_vars9.erl on line {8,8} diff --git a/lib/dialyzer/test/small_SUITE_data/results/abs b/lib/dialyzer/test/small_SUITE_data/results/abs index f229a6d036..a4ca39fe61 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/abs +++ b/lib/dialyzer/test/small_SUITE_data/results/abs @@ -1,9 +1,9 @@ -abs.erl:12: Function i1/0 has no local return -abs.erl:16: The pattern 'true' can never match the type 'false' -abs.erl:23: Function i2/0 has no local return -abs.erl:27: The pattern 'true' can never match the type 'false' -abs.erl:34: Function i3/0 has no local return -abs.erl:37: The pattern 'true' can never match the type 'false' -abs.erl:45: Function i4/0 has no local return -abs.erl:49: The pattern 'true' can never match the type 'false' +abs.erl:12:1: Function i1/0 has no local return +abs.erl:16:5: The pattern 'true' can never match the type 'false' +abs.erl:23:1: Function i2/0 has no local return +abs.erl:27:5: The pattern 'true' can never match the type 'false' +abs.erl:34:1: Function i3/0 has no local return +abs.erl:37:5: The pattern 'true' can never match the type 'false' +abs.erl:45:1: Function i4/0 has no local return +abs.erl:49:5: The pattern 'true' can never match the type 'false' diff --git a/lib/dialyzer/test/small_SUITE_data/results/app_call b/lib/dialyzer/test/small_SUITE_data/results/app_call index 1af649815a..2e2cc70a43 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/app_call +++ b/lib/dialyzer/test/small_SUITE_data/results/app_call @@ -1,3 +1,3 @@ -app_call.erl:6: The call M:'foo'() requires that M is of type atom() not 42 -app_call.erl:9: The call 'mod':F() requires that F is of type atom() not {'gazonk',[]} +app_call.erl:6:3: The call M:'foo'() requires that M is of type atom() not 42 +app_call.erl:9:7: The call 'mod':F() requires that F is of type atom() not {'gazonk',[]} diff --git a/lib/dialyzer/test/small_SUITE_data/results/areq b/lib/dialyzer/test/small_SUITE_data/results/areq index dd91f2d2bf..4fb6b68d27 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/areq +++ b/lib/dialyzer/test/small_SUITE_data/results/areq @@ -1,2 +1,2 @@ -areq.erl:11: The test float() =:= 3 can never evaluate to 'true' +areq.erl:11:18: The test float() =:= 3 can never evaluate to 'true' diff --git a/lib/dialyzer/test/small_SUITE_data/results/atom_call b/lib/dialyzer/test/small_SUITE_data/results/atom_call index 851bb7ab12..9c147e4b92 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/atom_call +++ b/lib/dialyzer/test/small_SUITE_data/results/atom_call @@ -1,3 +1,3 @@ -atom_call.erl:14: Fun application will fail since F :: 'f' is not a function of arity 0 -atom_call.erl:14: Function g/0 has no local return +atom_call.erl:14:15: Fun application will fail since F :: 'f' is not a function of arity 0 +atom_call.erl:14:1: Function g/0 has no local return diff --git a/lib/dialyzer/test/small_SUITE_data/results/atom_widen b/lib/dialyzer/test/small_SUITE_data/results/atom_widen index 6d0a7b2737..41ca42fdbb 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/atom_widen +++ b/lib/dialyzer/test/small_SUITE_data/results/atom_widen @@ -1,3 +1,3 @@ -atom_widen.erl:10: The call atom_widen:foo('z') will never return since it differs in the 1st argument from the success typing arguments: ('a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'k' | 'l' | 'm' | 'n') -atom_widen.erl:9: Function test/0 has no local return +atom_widen.erl:10:7: The call atom_widen:foo('z') will never return since it differs in the 1st argument from the success typing arguments: ('a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'k' | 'l' | 'm' | 'n') +atom_widen.erl:9:1: Function test/0 has no local return diff --git a/lib/dialyzer/test/small_SUITE_data/results/behaviour_info b/lib/dialyzer/test/small_SUITE_data/results/behaviour_info index 2da4d26acb..6497ddae80 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/behaviour_info +++ b/lib/dialyzer/test/small_SUITE_data/results/behaviour_info @@ -1,2 +1,2 @@ -with_bad_format_status.erl:12: The inferred type for the 1st argument of format_status/2 ('bad_arg') is not a supertype of 'normal' | 'terminate', which is expected type for this argument in the callback of the gen_server behaviour +with_bad_format_status.erl:12:1: The inferred type for the 1st argument of format_status/2 ('bad_arg') is not a supertype of 'normal' | 'terminate', which is expected type for this argument in the callback of the gen_server behaviour diff --git a/lib/dialyzer/test/small_SUITE_data/results/bif1 b/lib/dialyzer/test/small_SUITE_data/results/bif1 index 289b6f821f..f35efeab5a 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/bif1 +++ b/lib/dialyzer/test/small_SUITE_data/results/bif1 @@ -1,3 +1,3 @@ -bif1.erl:13: Function string_chars/0 has no local return -bif1.erl:16: The call string:chars(S::65,10,L2::bif1_adt:s()) contains an opaque term as 3rd argument when terms of different types are expected in these positions +bif1.erl:13:1: Function string_chars/0 has no local return +bif1.erl:16:25: The call string:chars(S::65,10,L2::bif1_adt:s()) contains an opaque term as 3rd argument when terms of different types are expected in these positions diff --git a/lib/dialyzer/test/small_SUITE_data/results/blame_contract_range b/lib/dialyzer/test/small_SUITE_data/results/blame_contract_range index 0c1c58ac8e..265eee6d00 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/blame_contract_range +++ b/lib/dialyzer/test/small_SUITE_data/results/blame_contract_range @@ -1,4 +1,4 @@ -blame_contract_range.erl:11: Function foo/0 has no local return -blame_contract_range.erl:14: The contract blame_contract_range:bar(atom()) -> 'a' cannot be right because the inferred return for bar('b') on line 12 is 'b' -blame_contract_range.erl:15: The pattern 'a' can never match the type 'b' +blame_contract_range.erl:11:1: Function foo/0 has no local return +blame_contract_range.erl:14:2: The contract blame_contract_range:bar(atom()) -> 'a' cannot be right because the inferred return for bar('b') on position 12:3 is 'b' +blame_contract_range.erl:15:1: The pattern 'a' can never match the type 'b' diff --git a/lib/dialyzer/test/small_SUITE_data/results/blame_contract_range_suppressed b/lib/dialyzer/test/small_SUITE_data/results/blame_contract_range_suppressed index 40733434f6..e1f854c591 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/blame_contract_range_suppressed +++ b/lib/dialyzer/test/small_SUITE_data/results/blame_contract_range_suppressed @@ -1,2 +1,2 @@ -blame_contract_range_suppressed.erl:8: Function foo/0 has no local return +blame_contract_range_suppressed.erl:8:1: Function foo/0 has no local return diff --git a/lib/dialyzer/test/small_SUITE_data/results/bs_fail_constr b/lib/dialyzer/test/small_SUITE_data/results/bs_fail_constr index 797f83956d..ce923a1c88 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/bs_fail_constr +++ b/lib/dialyzer/test/small_SUITE_data/results/bs_fail_constr @@ -1,9 +1,9 @@ -bs_fail_constr.erl:11: Function w3/1 has no local return -bs_fail_constr.erl:12: Binary construction will fail since the size field S in segment 42:S has type neg_integer() -bs_fail_constr.erl:14: Function w4/1 has no local return -bs_fail_constr.erl:15: Binary construction will fail since the value field V in segment V/utf32 has type float() -bs_fail_constr.erl:5: Function w1/1 has no local return -bs_fail_constr.erl:6: Binary construction will fail since the value field V in segment V has type float() -bs_fail_constr.erl:8: Function w2/1 has no local return -bs_fail_constr.erl:9: Binary construction will fail since the value field V in segment V/binary has type atom() +bs_fail_constr.erl:11:1: Function w3/1 has no local return +bs_fail_constr.erl:12:8: Binary construction will fail since the size field S in segment 42:S has type neg_integer() +bs_fail_constr.erl:14:1: Function w4/1 has no local return +bs_fail_constr.erl:15:5: Binary construction will fail since the value field V in segment V/utf32 has type float() +bs_fail_constr.erl:5:1: Function w1/1 has no local return +bs_fail_constr.erl:6:5: Binary construction will fail since the value field V in segment V has type float() +bs_fail_constr.erl:8:1: Function w2/1 has no local return +bs_fail_constr.erl:9:5: Binary construction will fail since the value field V in segment V/binary has type atom() diff --git a/lib/dialyzer/test/small_SUITE_data/results/chars b/lib/dialyzer/test/small_SUITE_data/results/chars index 02797f2a59..ec7b468e43 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/chars +++ b/lib/dialyzer/test/small_SUITE_data/results/chars @@ -1,4 +1,4 @@ -chars.erl:37: Invalid type specification for function chars:f/1. The success typing is (#{'b':=50}) -> 'ok' -chars.erl:40: Function t1/0 has no local return -chars.erl:40: The call chars:f(#{'b'=>50}) breaks the contract (#{'a':=49,'b'=>50,'c'=>51}) -> 'ok' +chars.erl:37:2: Invalid type specification for function chars:f/1. The success typing is (#{'b':=50}) -> 'ok' +chars.erl:40:11: The call chars:f(#{'b'=>50}) breaks the contract (#{'a':=49,'b'=>50,'c'=>51}) -> 'ok' +chars.erl:40:1: Function t1/0 has no local return diff --git a/lib/dialyzer/test/small_SUITE_data/results/common_eunit b/lib/dialyzer/test/small_SUITE_data/results/common_eunit index bb5fd1c9ac..f25f001837 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/common_eunit +++ b/lib/dialyzer/test/small_SUITE_data/results/common_eunit @@ -1,2 +1,2 @@ -common_eunit.erl:57: The created fun has no local return +common_eunit.erl:57:5: The created fun has no local return diff --git a/lib/dialyzer/test/small_SUITE_data/results/compare1 b/lib/dialyzer/test/small_SUITE_data/results/compare1 index f0d696ffcb..28e5b062ca 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/compare1 +++ b/lib/dialyzer/test/small_SUITE_data/results/compare1 @@ -1,4 +1,4 @@ -compare1.erl:15: Guard test X::42 > 42 can never succeed -compare1.erl:17: Guard test X::42 < 42 can never succeed -compare1.erl:19: Guard test X::42 =/= 42 can never succeed +compare1.erl:15:11: Guard test X::42 > 42 can never succeed +compare1.erl:17:11: Guard test X::42 < 42 can never succeed +compare1.erl:19:11: Guard test X::42 =/= 42 can never succeed diff --git a/lib/dialyzer/test/small_SUITE_data/results/comparisons b/lib/dialyzer/test/small_SUITE_data/results/comparisons index 5083d2695a..b5840c058c 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/comparisons +++ b/lib/dialyzer/test/small_SUITE_data/results/comparisons @@ -1,201 +1,201 @@ -comparisons.erl:100: The pattern 'true' can never match the type 'false' -comparisons.erl:101: The pattern 'false' can never match the type 'true' -comparisons.erl:102: The pattern 'false' can never match the type 'true' -comparisons.erl:103: The pattern 'true' can never match the type 'false' -comparisons.erl:104: The pattern 'true' can never match the type 'false' -comparisons.erl:118: The pattern 'false' can never match the type 'true' -comparisons.erl:119: The pattern 'false' can never match the type 'true' -comparisons.erl:120: The pattern 'true' can never match the type 'false' -comparisons.erl:121: The pattern 'true' can never match the type 'false' -comparisons.erl:122: The pattern 'false' can never match the type 'true' -comparisons.erl:123: The pattern 'false' can never match the type 'true' -comparisons.erl:124: The pattern 'true' can never match the type 'false' -comparisons.erl:125: The pattern 'true' can never match the type 'false' -comparisons.erl:126: The pattern 'false' can never match the type 'true' -comparisons.erl:127: The pattern 'false' can never match the type 'true' -comparisons.erl:128: The pattern 'true' can never match the type 'false' -comparisons.erl:129: The pattern 'true' can never match the type 'false' -comparisons.erl:130: The pattern 'false' can never match the type 'true' -comparisons.erl:131: The pattern 'false' can never match the type 'true' -comparisons.erl:132: The pattern 'true' can never match the type 'false' -comparisons.erl:133: The pattern 'true' can never match the type 'false' -comparisons.erl:134: The pattern 'false' can never match the type 'true' -comparisons.erl:135: The pattern 'false' can never match the type 'true' -comparisons.erl:136: The pattern 'true' can never match the type 'false' -comparisons.erl:137: The pattern 'true' can never match the type 'false' -comparisons.erl:139: The pattern 'true' can never match the type 'false' -comparisons.erl:140: The pattern 'true' can never match the type 'false' -comparisons.erl:141: The pattern 'false' can never match the type 'true' -comparisons.erl:142: The pattern 'false' can never match the type 'true' -comparisons.erl:143: The pattern 'true' can never match the type 'false' -comparisons.erl:144: The pattern 'true' can never match the type 'false' -comparisons.erl:145: The pattern 'false' can never match the type 'true' -comparisons.erl:146: The pattern 'false' can never match the type 'true' -comparisons.erl:147: The pattern 'true' can never match the type 'false' -comparisons.erl:148: The pattern 'true' can never match the type 'false' -comparisons.erl:149: The pattern 'false' can never match the type 'true' -comparisons.erl:150: The pattern 'false' can never match the type 'true' -comparisons.erl:155: The pattern 'false' can never match the type 'true' -comparisons.erl:156: The pattern 'false' can never match the type 'true' -comparisons.erl:157: The pattern 'true' can never match the type 'false' -comparisons.erl:158: The pattern 'true' can never match the type 'false' -comparisons.erl:159: The pattern 'false' can never match the type 'true' -comparisons.erl:160: The pattern 'false' can never match the type 'true' -comparisons.erl:161: The pattern 'true' can never match the type 'false' -comparisons.erl:162: The pattern 'true' can never match the type 'false' -comparisons.erl:163: The pattern 'false' can never match the type 'true' -comparisons.erl:164: The pattern 'false' can never match the type 'true' -comparisons.erl:165: The pattern 'true' can never match the type 'false' -comparisons.erl:166: The pattern 'true' can never match the type 'false' -comparisons.erl:167: The pattern 'false' can never match the type 'true' -comparisons.erl:168: The pattern 'false' can never match the type 'true' -comparisons.erl:169: The pattern 'true' can never match the type 'false' -comparisons.erl:170: The pattern 'true' can never match the type 'false' -comparisons.erl:172: The pattern 'true' can never match the type 'false' -comparisons.erl:173: The pattern 'true' can never match the type 'false' -comparisons.erl:174: The pattern 'false' can never match the type 'true' -comparisons.erl:175: The pattern 'false' can never match the type 'true' -comparisons.erl:176: The pattern 'true' can never match the type 'false' -comparisons.erl:177: The pattern 'true' can never match the type 'false' -comparisons.erl:178: The pattern 'false' can never match the type 'true' -comparisons.erl:179: The pattern 'false' can never match the type 'true' -comparisons.erl:180: The pattern 'true' can never match the type 'false' -comparisons.erl:181: The pattern 'true' can never match the type 'false' -comparisons.erl:182: The pattern 'false' can never match the type 'true' -comparisons.erl:183: The pattern 'false' can never match the type 'true' -comparisons.erl:184: The pattern 'true' can never match the type 'false' -comparisons.erl:185: The pattern 'true' can never match the type 'false' -comparisons.erl:186: The pattern 'false' can never match the type 'true' -comparisons.erl:187: The pattern 'false' can never match the type 'true' -comparisons.erl:192: The pattern 'false' can never match the type 'true' -comparisons.erl:193: The pattern 'false' can never match the type 'true' -comparisons.erl:194: The pattern 'true' can never match the type 'false' -comparisons.erl:195: The pattern 'true' can never match the type 'false' -comparisons.erl:196: The pattern 'false' can never match the type 'true' -comparisons.erl:197: The pattern 'false' can never match the type 'true' -comparisons.erl:198: The pattern 'true' can never match the type 'false' -comparisons.erl:199: The pattern 'true' can never match the type 'false' -comparisons.erl:200: The pattern 'false' can never match the type 'true' -comparisons.erl:201: The pattern 'false' can never match the type 'true' -comparisons.erl:202: The pattern 'true' can never match the type 'false' -comparisons.erl:203: The pattern 'true' can never match the type 'false' -comparisons.erl:205: The pattern 'true' can never match the type 'false' -comparisons.erl:206: The pattern 'true' can never match the type 'false' -comparisons.erl:207: The pattern 'false' can never match the type 'true' -comparisons.erl:208: The pattern 'false' can never match the type 'true' -comparisons.erl:209: The pattern 'true' can never match the type 'false' -comparisons.erl:210: The pattern 'true' can never match the type 'false' -comparisons.erl:211: The pattern 'false' can never match the type 'true' -comparisons.erl:212: The pattern 'false' can never match the type 'true' -comparisons.erl:213: The pattern 'true' can never match the type 'false' -comparisons.erl:214: The pattern 'true' can never match the type 'false' -comparisons.erl:215: The pattern 'false' can never match the type 'true' -comparisons.erl:216: The pattern 'false' can never match the type 'true' -comparisons.erl:217: The pattern 'true' can never match the type 'false' -comparisons.erl:218: The pattern 'true' can never match the type 'false' -comparisons.erl:219: The pattern 'false' can never match the type 'true' -comparisons.erl:220: The pattern 'false' can never match the type 'true' -comparisons.erl:221: The pattern 'true' can never match the type 'false' -comparisons.erl:222: The pattern 'true' can never match the type 'false' -comparisons.erl:223: The pattern 'false' can never match the type 'true' -comparisons.erl:224: The pattern 'false' can never match the type 'true' -comparisons.erl:229: The pattern 'true' can never match the type 'false' -comparisons.erl:230: The pattern 'true' can never match the type 'false' -comparisons.erl:231: The pattern 'false' can never match the type 'true' -comparisons.erl:232: The pattern 'false' can never match the type 'true' -comparisons.erl:233: The pattern 'false' can never match the type 'true' -comparisons.erl:234: The pattern 'false' can never match the type 'true' -comparisons.erl:235: The pattern 'true' can never match the type 'false' -comparisons.erl:236: The pattern 'true' can never match the type 'false' -comparisons.erl:242: The pattern 'false' can never match the type 'true' -comparisons.erl:243: The pattern 'false' can never match the type 'true' -comparisons.erl:244: The pattern 'true' can never match the type 'false' -comparisons.erl:245: The pattern 'true' can never match the type 'false' -comparisons.erl:246: The pattern 'false' can never match the type 'true' -comparisons.erl:247: The pattern 'false' can never match the type 'true' -comparisons.erl:248: The pattern 'true' can never match the type 'false' -comparisons.erl:249: The pattern 'true' can never match the type 'false' -comparisons.erl:259: The pattern 'false' can never match the type 'true' -comparisons.erl:260: The pattern 'false' can never match the type 'true' -comparisons.erl:261: The pattern 'true' can never match the type 'false' -comparisons.erl:262: The pattern 'true' can never match the type 'false' -comparisons.erl:264: The pattern 'true' can never match the type 'false' -comparisons.erl:265: The pattern 'true' can never match the type 'false' -comparisons.erl:266: The pattern 'false' can never match the type 'true' -comparisons.erl:267: The pattern 'false' can never match the type 'true' -comparisons.erl:277: The pattern 'true' can never match the type 'false' -comparisons.erl:278: The pattern 'true' can never match the type 'false' -comparisons.erl:279: The pattern 'false' can never match the type 'true' -comparisons.erl:280: The pattern 'false' can never match the type 'true' -comparisons.erl:281: The pattern 'true' can never match the type 'false' -comparisons.erl:282: The pattern 'true' can never match the type 'false' -comparisons.erl:283: The pattern 'false' can never match the type 'true' -comparisons.erl:284: The pattern 'false' can never match the type 'true' -comparisons.erl:298: The pattern 'false' can never match the type 'true' -comparisons.erl:299: The pattern 'false' can never match the type 'true' -comparisons.erl:300: The pattern 'true' can never match the type 'false' -comparisons.erl:301: The pattern 'true' can never match the type 'false' -comparisons.erl:302: The pattern 'false' can never match the type 'true' -comparisons.erl:303: The pattern 'false' can never match the type 'true' -comparisons.erl:304: The pattern 'true' can never match the type 'false' -comparisons.erl:305: The pattern 'true' can never match the type 'false' -comparisons.erl:307: The pattern 'true' can never match the type 'false' -comparisons.erl:308: The pattern 'true' can never match the type 'false' -comparisons.erl:309: The pattern 'false' can never match the type 'true' -comparisons.erl:310: The pattern 'false' can never match the type 'true' -comparisons.erl:319: The pattern 'false' can never match the type 'true' -comparisons.erl:320: The pattern 'false' can never match the type 'true' -comparisons.erl:321: The pattern 'true' can never match the type 'false' -comparisons.erl:322: The pattern 'true' can never match the type 'false' -comparisons.erl:324: The pattern 'true' can never match the type 'false' -comparisons.erl:325: The pattern 'true' can never match the type 'false' -comparisons.erl:326: The pattern 'false' can never match the type 'true' -comparisons.erl:327: The pattern 'false' can never match the type 'true' -comparisons.erl:328: The pattern 'true' can never match the type 'false' -comparisons.erl:329: The pattern 'true' can never match the type 'false' -comparisons.erl:330: The pattern 'false' can never match the type 'true' -comparisons.erl:331: The pattern 'false' can never match the type 'true' -comparisons.erl:349: The pattern 'false' can never match the type 'true' -comparisons.erl:350: The pattern 'false' can never match the type 'true' -comparisons.erl:351: The pattern 'true' can never match the type 'false' -comparisons.erl:352: The pattern 'true' can never match the type 'false' -comparisons.erl:367: The pattern 'true' can never match the type 'false' -comparisons.erl:368: The pattern 'true' can never match the type 'false' -comparisons.erl:369: The pattern 'false' can never match the type 'true' -comparisons.erl:370: The pattern 'false' can never match the type 'true' -comparisons.erl:52: The pattern 'false' can never match the type 'true' -comparisons.erl:53: The pattern 'false' can never match the type 'true' -comparisons.erl:54: The pattern 'true' can never match the type 'false' -comparisons.erl:55: The pattern 'true' can never match the type 'false' -comparisons.erl:56: The pattern 'false' can never match the type 'true' -comparisons.erl:57: The pattern 'false' can never match the type 'true' -comparisons.erl:58: The pattern 'true' can never match the type 'false' -comparisons.erl:59: The pattern 'true' can never match the type 'false' -comparisons.erl:60: The pattern 'false' can never match the type 'true' -comparisons.erl:61: The pattern 'false' can never match the type 'true' -comparisons.erl:62: The pattern 'true' can never match the type 'false' -comparisons.erl:63: The pattern 'true' can never match the type 'false' -comparisons.erl:64: The pattern 'false' can never match the type 'true' -comparisons.erl:65: The pattern 'false' can never match the type 'true' -comparisons.erl:66: The pattern 'true' can never match the type 'false' -comparisons.erl:67: The pattern 'true' can never match the type 'false' -comparisons.erl:68: The pattern 'false' can never match the type 'true' -comparisons.erl:69: The pattern 'false' can never match the type 'true' -comparisons.erl:70: The pattern 'true' can never match the type 'false' -comparisons.erl:71: The pattern 'true' can never match the type 'false' -comparisons.erl:85: The pattern 'false' can never match the type 'true' -comparisons.erl:86: The pattern 'false' can never match the type 'true' -comparisons.erl:87: The pattern 'true' can never match the type 'false' -comparisons.erl:88: The pattern 'true' can never match the type 'false' -comparisons.erl:89: The pattern 'false' can never match the type 'true' -comparisons.erl:90: The pattern 'false' can never match the type 'true' -comparisons.erl:91: The pattern 'true' can never match the type 'false' -comparisons.erl:92: The pattern 'true' can never match the type 'false' -comparisons.erl:93: The pattern 'false' can never match the type 'true' -comparisons.erl:94: The pattern 'false' can never match the type 'true' -comparisons.erl:95: The pattern 'true' can never match the type 'false' -comparisons.erl:96: The pattern 'true' can never match the type 'false' -comparisons.erl:97: The pattern 'false' can never match the type 'true' -comparisons.erl:98: The pattern 'false' can never match the type 'true' -comparisons.erl:99: The pattern 'true' can never match the type 'false' +comparisons.erl:100:37: The pattern 'true' can never match the type 'false' +comparisons.erl:101:53: The pattern 'false' can never match the type 'true' +comparisons.erl:102:53: The pattern 'false' can never match the type 'true' +comparisons.erl:103:37: The pattern 'true' can never match the type 'false' +comparisons.erl:104:37: The pattern 'true' can never match the type 'false' +comparisons.erl:118:53: The pattern 'false' can never match the type 'true' +comparisons.erl:119:53: The pattern 'false' can never match the type 'true' +comparisons.erl:120:37: The pattern 'true' can never match the type 'false' +comparisons.erl:121:37: The pattern 'true' can never match the type 'false' +comparisons.erl:122:53: The pattern 'false' can never match the type 'true' +comparisons.erl:123:53: The pattern 'false' can never match the type 'true' +comparisons.erl:124:37: The pattern 'true' can never match the type 'false' +comparisons.erl:125:37: The pattern 'true' can never match the type 'false' +comparisons.erl:126:53: The pattern 'false' can never match the type 'true' +comparisons.erl:127:53: The pattern 'false' can never match the type 'true' +comparisons.erl:128:37: The pattern 'true' can never match the type 'false' +comparisons.erl:129:37: The pattern 'true' can never match the type 'false' +comparisons.erl:130:53: The pattern 'false' can never match the type 'true' +comparisons.erl:131:53: The pattern 'false' can never match the type 'true' +comparisons.erl:132:37: The pattern 'true' can never match the type 'false' +comparisons.erl:133:37: The pattern 'true' can never match the type 'false' +comparisons.erl:134:53: The pattern 'false' can never match the type 'true' +comparisons.erl:135:53: The pattern 'false' can never match the type 'true' +comparisons.erl:136:37: The pattern 'true' can never match the type 'false' +comparisons.erl:137:37: The pattern 'true' can never match the type 'false' +comparisons.erl:139:37: The pattern 'true' can never match the type 'false' +comparisons.erl:140:37: The pattern 'true' can never match the type 'false' +comparisons.erl:141:53: The pattern 'false' can never match the type 'true' +comparisons.erl:142:53: The pattern 'false' can never match the type 'true' +comparisons.erl:143:37: The pattern 'true' can never match the type 'false' +comparisons.erl:144:37: The pattern 'true' can never match the type 'false' +comparisons.erl:145:53: The pattern 'false' can never match the type 'true' +comparisons.erl:146:53: The pattern 'false' can never match the type 'true' +comparisons.erl:147:37: The pattern 'true' can never match the type 'false' +comparisons.erl:148:37: The pattern 'true' can never match the type 'false' +comparisons.erl:149:53: The pattern 'false' can never match the type 'true' +comparisons.erl:150:53: The pattern 'false' can never match the type 'true' +comparisons.erl:155:53: The pattern 'false' can never match the type 'true' +comparisons.erl:156:53: The pattern 'false' can never match the type 'true' +comparisons.erl:157:37: The pattern 'true' can never match the type 'false' +comparisons.erl:158:37: The pattern 'true' can never match the type 'false' +comparisons.erl:159:53: The pattern 'false' can never match the type 'true' +comparisons.erl:160:53: The pattern 'false' can never match the type 'true' +comparisons.erl:161:37: The pattern 'true' can never match the type 'false' +comparisons.erl:162:37: The pattern 'true' can never match the type 'false' +comparisons.erl:163:53: The pattern 'false' can never match the type 'true' +comparisons.erl:164:53: The pattern 'false' can never match the type 'true' +comparisons.erl:165:37: The pattern 'true' can never match the type 'false' +comparisons.erl:166:37: The pattern 'true' can never match the type 'false' +comparisons.erl:167:53: The pattern 'false' can never match the type 'true' +comparisons.erl:168:53: The pattern 'false' can never match the type 'true' +comparisons.erl:169:37: The pattern 'true' can never match the type 'false' +comparisons.erl:170:37: The pattern 'true' can never match the type 'false' +comparisons.erl:172:37: The pattern 'true' can never match the type 'false' +comparisons.erl:173:37: The pattern 'true' can never match the type 'false' +comparisons.erl:174:53: The pattern 'false' can never match the type 'true' +comparisons.erl:175:53: The pattern 'false' can never match the type 'true' +comparisons.erl:176:37: The pattern 'true' can never match the type 'false' +comparisons.erl:177:37: The pattern 'true' can never match the type 'false' +comparisons.erl:178:53: The pattern 'false' can never match the type 'true' +comparisons.erl:179:53: The pattern 'false' can never match the type 'true' +comparisons.erl:180:37: The pattern 'true' can never match the type 'false' +comparisons.erl:181:37: The pattern 'true' can never match the type 'false' +comparisons.erl:182:53: The pattern 'false' can never match the type 'true' +comparisons.erl:183:53: The pattern 'false' can never match the type 'true' +comparisons.erl:184:37: The pattern 'true' can never match the type 'false' +comparisons.erl:185:37: The pattern 'true' can never match the type 'false' +comparisons.erl:186:53: The pattern 'false' can never match the type 'true' +comparisons.erl:187:53: The pattern 'false' can never match the type 'true' +comparisons.erl:192:53: The pattern 'false' can never match the type 'true' +comparisons.erl:193:53: The pattern 'false' can never match the type 'true' +comparisons.erl:194:37: The pattern 'true' can never match the type 'false' +comparisons.erl:195:37: The pattern 'true' can never match the type 'false' +comparisons.erl:196:53: The pattern 'false' can never match the type 'true' +comparisons.erl:197:53: The pattern 'false' can never match the type 'true' +comparisons.erl:198:37: The pattern 'true' can never match the type 'false' +comparisons.erl:199:37: The pattern 'true' can never match the type 'false' +comparisons.erl:200:53: The pattern 'false' can never match the type 'true' +comparisons.erl:201:53: The pattern 'false' can never match the type 'true' +comparisons.erl:202:37: The pattern 'true' can never match the type 'false' +comparisons.erl:203:37: The pattern 'true' can never match the type 'false' +comparisons.erl:205:37: The pattern 'true' can never match the type 'false' +comparisons.erl:206:37: The pattern 'true' can never match the type 'false' +comparisons.erl:207:53: The pattern 'false' can never match the type 'true' +comparisons.erl:208:53: The pattern 'false' can never match the type 'true' +comparisons.erl:209:37: The pattern 'true' can never match the type 'false' +comparisons.erl:210:37: The pattern 'true' can never match the type 'false' +comparisons.erl:211:53: The pattern 'false' can never match the type 'true' +comparisons.erl:212:53: The pattern 'false' can never match the type 'true' +comparisons.erl:213:37: The pattern 'true' can never match the type 'false' +comparisons.erl:214:37: The pattern 'true' can never match the type 'false' +comparisons.erl:215:53: The pattern 'false' can never match the type 'true' +comparisons.erl:216:53: The pattern 'false' can never match the type 'true' +comparisons.erl:217:37: The pattern 'true' can never match the type 'false' +comparisons.erl:218:37: The pattern 'true' can never match the type 'false' +comparisons.erl:219:53: The pattern 'false' can never match the type 'true' +comparisons.erl:220:53: The pattern 'false' can never match the type 'true' +comparisons.erl:221:37: The pattern 'true' can never match the type 'false' +comparisons.erl:222:37: The pattern 'true' can never match the type 'false' +comparisons.erl:223:53: The pattern 'false' can never match the type 'true' +comparisons.erl:224:53: The pattern 'false' can never match the type 'true' +comparisons.erl:229:37: The pattern 'true' can never match the type 'false' +comparisons.erl:230:37: The pattern 'true' can never match the type 'false' +comparisons.erl:231:53: The pattern 'false' can never match the type 'true' +comparisons.erl:232:53: The pattern 'false' can never match the type 'true' +comparisons.erl:233:53: The pattern 'false' can never match the type 'true' +comparisons.erl:234:53: The pattern 'false' can never match the type 'true' +comparisons.erl:235:37: The pattern 'true' can never match the type 'false' +comparisons.erl:236:37: The pattern 'true' can never match the type 'false' +comparisons.erl:242:55: The pattern 'false' can never match the type 'true' +comparisons.erl:243:55: The pattern 'false' can never match the type 'true' +comparisons.erl:244:39: The pattern 'true' can never match the type 'false' +comparisons.erl:245:39: The pattern 'true' can never match the type 'false' +comparisons.erl:246:55: The pattern 'false' can never match the type 'true' +comparisons.erl:247:55: The pattern 'false' can never match the type 'true' +comparisons.erl:248:39: The pattern 'true' can never match the type 'false' +comparisons.erl:249:39: The pattern 'true' can never match the type 'false' +comparisons.erl:259:55: The pattern 'false' can never match the type 'true' +comparisons.erl:260:55: The pattern 'false' can never match the type 'true' +comparisons.erl:261:39: The pattern 'true' can never match the type 'false' +comparisons.erl:262:39: The pattern 'true' can never match the type 'false' +comparisons.erl:264:39: The pattern 'true' can never match the type 'false' +comparisons.erl:265:39: The pattern 'true' can never match the type 'false' +comparisons.erl:266:55: The pattern 'false' can never match the type 'true' +comparisons.erl:267:55: The pattern 'false' can never match the type 'true' +comparisons.erl:277:39: The pattern 'true' can never match the type 'false' +comparisons.erl:278:39: The pattern 'true' can never match the type 'false' +comparisons.erl:279:55: The pattern 'false' can never match the type 'true' +comparisons.erl:280:55: The pattern 'false' can never match the type 'true' +comparisons.erl:281:39: The pattern 'true' can never match the type 'false' +comparisons.erl:282:39: The pattern 'true' can never match the type 'false' +comparisons.erl:283:55: The pattern 'false' can never match the type 'true' +comparisons.erl:284:55: The pattern 'false' can never match the type 'true' +comparisons.erl:298:55: The pattern 'false' can never match the type 'true' +comparisons.erl:299:55: The pattern 'false' can never match the type 'true' +comparisons.erl:300:39: The pattern 'true' can never match the type 'false' +comparisons.erl:301:39: The pattern 'true' can never match the type 'false' +comparisons.erl:302:55: The pattern 'false' can never match the type 'true' +comparisons.erl:303:55: The pattern 'false' can never match the type 'true' +comparisons.erl:304:39: The pattern 'true' can never match the type 'false' +comparisons.erl:305:39: The pattern 'true' can never match the type 'false' +comparisons.erl:307:39: The pattern 'true' can never match the type 'false' +comparisons.erl:308:39: The pattern 'true' can never match the type 'false' +comparisons.erl:309:55: The pattern 'false' can never match the type 'true' +comparisons.erl:310:55: The pattern 'false' can never match the type 'true' +comparisons.erl:319:55: The pattern 'false' can never match the type 'true' +comparisons.erl:320:55: The pattern 'false' can never match the type 'true' +comparisons.erl:321:39: The pattern 'true' can never match the type 'false' +comparisons.erl:322:39: The pattern 'true' can never match the type 'false' +comparisons.erl:324:39: The pattern 'true' can never match the type 'false' +comparisons.erl:325:39: The pattern 'true' can never match the type 'false' +comparisons.erl:326:55: The pattern 'false' can never match the type 'true' +comparisons.erl:327:55: The pattern 'false' can never match the type 'true' +comparisons.erl:328:39: The pattern 'true' can never match the type 'false' +comparisons.erl:329:39: The pattern 'true' can never match the type 'false' +comparisons.erl:330:55: The pattern 'false' can never match the type 'true' +comparisons.erl:331:55: The pattern 'false' can never match the type 'true' +comparisons.erl:349:57: The pattern 'false' can never match the type 'true' +comparisons.erl:350:57: The pattern 'false' can never match the type 'true' +comparisons.erl:351:41: The pattern 'true' can never match the type 'false' +comparisons.erl:352:41: The pattern 'true' can never match the type 'false' +comparisons.erl:367:41: The pattern 'true' can never match the type 'false' +comparisons.erl:368:41: The pattern 'true' can never match the type 'false' +comparisons.erl:369:57: The pattern 'false' can never match the type 'true' +comparisons.erl:370:57: The pattern 'false' can never match the type 'true' +comparisons.erl:52:53: The pattern 'false' can never match the type 'true' +comparisons.erl:53:53: The pattern 'false' can never match the type 'true' +comparisons.erl:54:37: The pattern 'true' can never match the type 'false' +comparisons.erl:55:37: The pattern 'true' can never match the type 'false' +comparisons.erl:56:53: The pattern 'false' can never match the type 'true' +comparisons.erl:57:53: The pattern 'false' can never match the type 'true' +comparisons.erl:58:37: The pattern 'true' can never match the type 'false' +comparisons.erl:59:37: The pattern 'true' can never match the type 'false' +comparisons.erl:60:53: The pattern 'false' can never match the type 'true' +comparisons.erl:61:53: The pattern 'false' can never match the type 'true' +comparisons.erl:62:37: The pattern 'true' can never match the type 'false' +comparisons.erl:63:37: The pattern 'true' can never match the type 'false' +comparisons.erl:64:53: The pattern 'false' can never match the type 'true' +comparisons.erl:65:53: The pattern 'false' can never match the type 'true' +comparisons.erl:66:37: The pattern 'true' can never match the type 'false' +comparisons.erl:67:37: The pattern 'true' can never match the type 'false' +comparisons.erl:68:53: The pattern 'false' can never match the type 'true' +comparisons.erl:69:53: The pattern 'false' can never match the type 'true' +comparisons.erl:70:37: The pattern 'true' can never match the type 'false' +comparisons.erl:71:37: The pattern 'true' can never match the type 'false' +comparisons.erl:85:53: The pattern 'false' can never match the type 'true' +comparisons.erl:86:53: The pattern 'false' can never match the type 'true' +comparisons.erl:87:37: The pattern 'true' can never match the type 'false' +comparisons.erl:88:37: The pattern 'true' can never match the type 'false' +comparisons.erl:89:53: The pattern 'false' can never match the type 'true' +comparisons.erl:90:53: The pattern 'false' can never match the type 'true' +comparisons.erl:91:37: The pattern 'true' can never match the type 'false' +comparisons.erl:92:37: The pattern 'true' can never match the type 'false' +comparisons.erl:93:53: The pattern 'false' can never match the type 'true' +comparisons.erl:94:53: The pattern 'false' can never match the type 'true' +comparisons.erl:95:37: The pattern 'true' can never match the type 'false' +comparisons.erl:96:37: The pattern 'true' can never match the type 'false' +comparisons.erl:97:53: The pattern 'false' can never match the type 'true' +comparisons.erl:98:53: The pattern 'false' can never match the type 'true' +comparisons.erl:99:37: The pattern 'true' can never match the type 'false' diff --git a/lib/dialyzer/test/small_SUITE_data/results/confusing_warning b/lib/dialyzer/test/small_SUITE_data/results/confusing_warning index d2d0c91fff..57e2556503 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/confusing_warning +++ b/lib/dialyzer/test/small_SUITE_data/results/confusing_warning @@ -1,2 +1,2 @@ -confusing_warning.erl:16: The pattern {'a', {_, L}} can never match the type {'b','aaa' | 'bbb'} +confusing_warning.erl:16:5: The pattern {'a', {_, L}} can never match the type {'b','aaa' | 'bbb'} diff --git a/lib/dialyzer/test/small_SUITE_data/results/contract2 b/lib/dialyzer/test/small_SUITE_data/results/contract2 index 6809e528c4..d4f369b0c6 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/contract2 +++ b/lib/dialyzer/test/small_SUITE_data/results/contract2 @@ -1,2 +1,2 @@ -contract2.erl:13: The call contract2:test(T::any(),nonempty_maybe_improper_list()) will never return since it differs in the 2nd argument from the success typing arguments: (['true'],[]) +contract2.erl:13:22: The call contract2:test(T::any(),nonempty_maybe_improper_list()) will never return since it differs in the 2nd argument from the success typing arguments: (['true'],[]) diff --git a/lib/dialyzer/test/small_SUITE_data/results/contract3 b/lib/dialyzer/test/small_SUITE_data/results/contract3 index 6e111f87d9..b290f232a2 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/contract3 +++ b/lib/dialyzer/test/small_SUITE_data/results/contract3 @@ -1,3 +1,3 @@ -contract3.erl:17: Overloaded contract for contract3:t1/1 has overlapping domains; such contracts are currently unsupported and are simply ignored -contract3.erl:29: Overloaded contract for contract3:t3/3 has overlapping domains; such contracts are currently unsupported and are simply ignored +contract3.erl:17:2: Overloaded contract for contract3:t1/1 has overlapping domains; such contracts are currently unsupported and are simply ignored +contract3.erl:29:2: Overloaded contract for contract3:t3/3 has overlapping domains; such contracts are currently unsupported and are simply ignored diff --git a/lib/dialyzer/test/small_SUITE_data/results/contract5 b/lib/dialyzer/test/small_SUITE_data/results/contract5 index 116c4f4d4d..10ea8ca362 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/contract5 +++ b/lib/dialyzer/test/small_SUITE_data/results/contract5 @@ -1,2 +1,2 @@ -contract5.erl:13: Invalid type specification for function contract5:t/0. The success typing is () -> #bar{baz::'not_a_boolean'} +contract5.erl:13:2: Invalid type specification for function contract5:t/0. The success typing is () -> #bar{baz::'not_a_boolean'} diff --git a/lib/dialyzer/test/small_SUITE_data/results/contracts_with_subtypes b/lib/dialyzer/test/small_SUITE_data/results/contracts_with_subtypes index 04336f43aa..44fd6056bd 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/contracts_with_subtypes +++ b/lib/dialyzer/test/small_SUITE_data/results/contracts_with_subtypes @@ -1,36 +1,36 @@ -contracts_with_subtypes.erl:106: The call contracts_with_subtypes:rec_arg({'a', 'b'}) breaks the contract (Arg) -> 'ok' when Arg :: {'a',A} | {'b',B}, A :: 'a' | {'b',B}, B :: 'b' | {'a',A} -contracts_with_subtypes.erl:107: The call contracts_with_subtypes:rec_arg({'b', 'a'}) breaks the contract (Arg) -> 'ok' when Arg :: {'a',A} | {'b',B}, A :: 'a' | {'b',B}, B :: 'b' | {'a',A} -contracts_with_subtypes.erl:109: The call contracts_with_subtypes:rec_arg({'b', {'a', 'b'}}) breaks the contract (Arg) -> 'ok' when Arg :: {'a',A} | {'b',B}, A :: 'a' | {'b',B}, B :: 'b' | {'a',A} -contracts_with_subtypes.erl:135: The call contracts_with_subtypes:rec2({'a', 'b'}) breaks the contract (Arg) -> 'ok' when Arg :: ab() -contracts_with_subtypes.erl:136: The call contracts_with_subtypes:rec2({'b', 'a'}) breaks the contract (Arg) -> 'ok' when Arg :: ab() -contracts_with_subtypes.erl:137: The call contracts_with_subtypes:rec2({'a', {'b', 'a'}}) breaks the contract (Arg) -> 'ok' when Arg :: ab() -contracts_with_subtypes.erl:138: The call contracts_with_subtypes:rec2({'b', {'a', 'b'}}) breaks the contract (Arg) -> 'ok' when Arg :: ab() -contracts_with_subtypes.erl:139: The call contracts_with_subtypes:rec2({'a', {'b', {'a', 'b'}}}) breaks the contract (Arg) -> 'ok' when Arg :: ab() -contracts_with_subtypes.erl:140: The call contracts_with_subtypes:rec2({'b', {'a', {'b', 'a'}}}) breaks the contract (Arg) -> 'ok' when Arg :: ab() -contracts_with_subtypes.erl:141: The call contracts_with_subtypes:rec2({'a', {'b', {'a', {'b', 'a'}}}}) breaks the contract (Arg) -> 'ok' when Arg :: ab() -contracts_with_subtypes.erl:142: The call contracts_with_subtypes:rec2({'b', {'a', {'b', {'a', 'b'}}}}) breaks the contract (Arg) -> 'ok' when Arg :: ab() -contracts_with_subtypes.erl:175: The pattern 1 can never match the type string() -contracts_with_subtypes.erl:178: The pattern 'alpha' can never match the type {'ok',_} | {'ok',_,string()} -contracts_with_subtypes.erl:180: The pattern 42 can never match the type {'ok',_} | {'ok',_,string()} -contracts_with_subtypes.erl:196: The pattern 'alpha' can never match the type {'ok',_} -contracts_with_subtypes.erl:198: The pattern 42 can never match the type {'ok',_} -contracts_with_subtypes.erl:216: The pattern 'alpha' can never match the type {'ok',_} -contracts_with_subtypes.erl:218: The pattern 42 can never match the type {'ok',_} -contracts_with_subtypes.erl:235: The pattern 1 can never match the type string() -contracts_with_subtypes.erl:238: The pattern {'ok', _} can never match the type {'ok',_,string()} -contracts_with_subtypes.erl:239: The pattern 'alpha' can never match the type {'ok',_,string()} -contracts_with_subtypes.erl:23: Invalid type specification for function contracts_with_subtypes:extract2/0. The success typing is () -> 'something' -contracts_with_subtypes.erl:240: The pattern {'ok', 42} can never match the type {'ok',_,string()} -contracts_with_subtypes.erl:241: The pattern 42 can never match the type {'ok',_,string()} -contracts_with_subtypes.erl:267: Function flat_ets_new_t/0 has no local return -contracts_with_subtypes.erl:268: The call contracts_with_subtypes:flat_ets_new(12,[]) breaks the contract (Name,Options) -> atom() when Name :: atom(), Options :: [Option], Option :: 'set' | 'ordered_set' | 'bag' | 'duplicate_bag' | 'public' | 'protected' | 'private' | 'named_table' | {'keypos',integer()} | {'heir',pid(),term()} | {'heir','none'} | {'write_concurrency',boolean()} | {'read_concurrency',boolean()} | 'compressed' -contracts_with_subtypes.erl:294: Function factored_ets_new_t/0 has no local return -contracts_with_subtypes.erl:295: The call contracts_with_subtypes:factored_ets_new(12,[]) breaks the contract (Name,Options) -> atom() when Name :: atom(), Options :: [Option], Option :: Type | Access | 'named_table' | {'keypos',Pos} | {'heir',Pid::pid(),HeirData} | {'heir','none'} | Tweaks, Type :: type(), Access :: access(), Tweaks :: {'write_concurrency',boolean()} | {'read_concurrency',boolean()} | 'compressed', Pos :: pos_integer(), HeirData :: term() -contracts_with_subtypes.erl:77: The call contracts_with_subtypes:foo1(5) breaks the contract (Arg1) -> Res when Arg1 :: atom(), Res :: atom() -contracts_with_subtypes.erl:78: The call contracts_with_subtypes:foo2(5) breaks the contract (Arg1) -> Res when Arg1 :: Arg2, Arg2 :: atom(), Res :: atom() -contracts_with_subtypes.erl:79: The call contracts_with_subtypes:foo3(5) breaks the contract (Arg1) -> Res when Arg2 :: atom(), Arg1 :: Arg2, Res :: atom() -contracts_with_subtypes.erl:7: Invalid type specification for function contracts_with_subtypes:extract/0. The success typing is () -> 'something' -contracts_with_subtypes.erl:80: The call contracts_with_subtypes:foo4(5) breaks the contract (Type) -> Type when Type :: atom() -contracts_with_subtypes.erl:81: The call contracts_with_subtypes:foo5(5) breaks the contract (Type::atom()) -> Type::atom() -contracts_with_subtypes.erl:82: The call contracts_with_subtypes:foo6(5) breaks the contract (Type) -> Type when Type :: atom() +contracts_with_subtypes.erl:106:18: The call contracts_with_subtypes:rec_arg({'a', 'b'}) breaks the contract (Arg) -> 'ok' when Arg :: {'a',A} | {'b',B}, A :: 'a' | {'b',B}, B :: 'b' | {'a',A} +contracts_with_subtypes.erl:107:18: The call contracts_with_subtypes:rec_arg({'b', 'a'}) breaks the contract (Arg) -> 'ok' when Arg :: {'a',A} | {'b',B}, A :: 'a' | {'b',B}, B :: 'b' | {'a',A} +contracts_with_subtypes.erl:109:19: The call contracts_with_subtypes:rec_arg({'b', {'a', 'b'}}) breaks the contract (Arg) -> 'ok' when Arg :: {'a',A} | {'b',B}, A :: 'a' | {'b',B}, B :: 'b' | {'a',A} +contracts_with_subtypes.erl:135:15: The call contracts_with_subtypes:rec2({'a', 'b'}) breaks the contract (Arg) -> 'ok' when Arg :: ab() +contracts_with_subtypes.erl:136:15: The call contracts_with_subtypes:rec2({'b', 'a'}) breaks the contract (Arg) -> 'ok' when Arg :: ab() +contracts_with_subtypes.erl:137:16: The call contracts_with_subtypes:rec2({'a', {'b', 'a'}}) breaks the contract (Arg) -> 'ok' when Arg :: ab() +contracts_with_subtypes.erl:138:16: The call contracts_with_subtypes:rec2({'b', {'a', 'b'}}) breaks the contract (Arg) -> 'ok' when Arg :: ab() +contracts_with_subtypes.erl:139:17: The call contracts_with_subtypes:rec2({'a', {'b', {'a', 'b'}}}) breaks the contract (Arg) -> 'ok' when Arg :: ab() +contracts_with_subtypes.erl:140:17: The call contracts_with_subtypes:rec2({'b', {'a', {'b', 'a'}}}) breaks the contract (Arg) -> 'ok' when Arg :: ab() +contracts_with_subtypes.erl:141:18: The call contracts_with_subtypes:rec2({'a', {'b', {'a', {'b', 'a'}}}}) breaks the contract (Arg) -> 'ok' when Arg :: ab() +contracts_with_subtypes.erl:142:18: The call contracts_with_subtypes:rec2({'b', {'a', {'b', {'a', 'b'}}}}) breaks the contract (Arg) -> 'ok' when Arg :: ab() +contracts_with_subtypes.erl:175:3: The pattern 1 can never match the type string() +contracts_with_subtypes.erl:178:2: The pattern 'alpha' can never match the type {'ok',_} | {'ok',_,string()} +contracts_with_subtypes.erl:180:2: The pattern 42 can never match the type {'ok',_} | {'ok',_,string()} +contracts_with_subtypes.erl:196:2: The pattern 'alpha' can never match the type {'ok',_} +contracts_with_subtypes.erl:198:2: The pattern 42 can never match the type {'ok',_} +contracts_with_subtypes.erl:216:2: The pattern 'alpha' can never match the type {'ok',_} +contracts_with_subtypes.erl:218:2: The pattern 42 can never match the type {'ok',_} +contracts_with_subtypes.erl:235:3: The pattern 1 can never match the type string() +contracts_with_subtypes.erl:238:2: The pattern {'ok', _} can never match the type {'ok',_,string()} +contracts_with_subtypes.erl:239:2: The pattern 'alpha' can never match the type {'ok',_,string()} +contracts_with_subtypes.erl:23:2: Invalid type specification for function contracts_with_subtypes:extract2/0. The success typing is () -> 'something' +contracts_with_subtypes.erl:240:2: The pattern {'ok', 42} can never match the type {'ok',_,string()} +contracts_with_subtypes.erl:241:2: The pattern 42 can never match the type {'ok',_,string()} +contracts_with_subtypes.erl:267:1: Function flat_ets_new_t/0 has no local return +contracts_with_subtypes.erl:268:18: The call contracts_with_subtypes:flat_ets_new(12,[]) breaks the contract (Name,Options) -> atom() when Name :: atom(), Options :: [Option], Option :: 'set' | 'ordered_set' | 'bag' | 'duplicate_bag' | 'public' | 'protected' | 'private' | 'named_table' | {'keypos',integer()} | {'heir',pid(),term()} | {'heir','none'} | {'write_concurrency',boolean()} | {'read_concurrency',boolean()} | 'compressed' +contracts_with_subtypes.erl:294:1: Function factored_ets_new_t/0 has no local return +contracts_with_subtypes.erl:295:22: The call contracts_with_subtypes:factored_ets_new(12,[]) breaks the contract (Name,Options) -> atom() when Name :: atom(), Options :: [Option], Option :: Type | Access | 'named_table' | {'keypos',Pos} | {'heir',Pid::pid(),HeirData} | {'heir','none'} | Tweaks, Type :: type(), Access :: access(), Tweaks :: {'write_concurrency',boolean()} | {'read_concurrency',boolean()} | 'compressed', Pos :: pos_integer(), HeirData :: term() +contracts_with_subtypes.erl:77:16: The call contracts_with_subtypes:foo1(5) breaks the contract (Arg1) -> Res when Arg1 :: atom(), Res :: atom() +contracts_with_subtypes.erl:78:16: The call contracts_with_subtypes:foo2(5) breaks the contract (Arg1) -> Res when Arg1 :: Arg2, Arg2 :: atom(), Res :: atom() +contracts_with_subtypes.erl:79:16: The call contracts_with_subtypes:foo3(5) breaks the contract (Arg1) -> Res when Arg2 :: atom(), Arg1 :: Arg2, Res :: atom() +contracts_with_subtypes.erl:7:2: Invalid type specification for function contracts_with_subtypes:extract/0. The success typing is () -> 'something' +contracts_with_subtypes.erl:80:16: The call contracts_with_subtypes:foo4(5) breaks the contract (Type) -> Type when Type :: atom() +contracts_with_subtypes.erl:81:16: The call contracts_with_subtypes:foo5(5) breaks the contract (Type::atom()) -> Type::atom() +contracts_with_subtypes.erl:82:16: The call contracts_with_subtypes:foo6(5) breaks the contract (Type) -> Type when Type :: atom() diff --git a/lib/dialyzer/test/small_SUITE_data/results/contracts_with_subtypes2 b/lib/dialyzer/test/small_SUITE_data/results/contracts_with_subtypes2 index 6d611db568..abb22e9e6c 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/contracts_with_subtypes2 +++ b/lib/dialyzer/test/small_SUITE_data/results/contracts_with_subtypes2 @@ -1,3 +1,3 @@ -contracts_with_subtypes2.erl:18: Function t/0 has no local return -contracts_with_subtypes2.erl:19: The call contracts_with_subtypes2:t({'a', {'b', {'c', {'d', {'e', {'g', 3}}}}}}) breaks the contract (Arg) -> 'ok' when Arg :: {'a',A}, A :: {'b',B}, B :: {'c',C}, C :: {'d',D}, D :: {'e',E}, E :: {'f',_} +contracts_with_subtypes2.erl:18:1: Function t/0 has no local return +contracts_with_subtypes2.erl:19:7: The call contracts_with_subtypes2:t({'a', {'b', {'c', {'d', {'e', {'g', 3}}}}}}) breaks the contract (Arg) -> 'ok' when Arg :: {'a',A}, A :: {'b',B}, B :: {'c',C}, C :: {'d',D}, D :: {'e',E}, E :: {'f',_} diff --git a/lib/dialyzer/test/small_SUITE_data/results/empty_list_infimum b/lib/dialyzer/test/small_SUITE_data/results/empty_list_infimum index 6f189099ed..cf44c15458 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/empty_list_infimum +++ b/lib/dialyzer/test/small_SUITE_data/results/empty_list_infimum @@ -1,2 +1,2 @@ -empty_list_infimum.erl:38: Invalid type specification for function empty_list_infimum:list_vhost_permissions/1. The success typing is (_) -> [[{_,_}]] +empty_list_infimum.erl:38:2: Invalid type specification for function empty_list_infimum:list_vhost_permissions/1. The success typing is (_) -> [[{_,_}]] diff --git a/lib/dialyzer/test/small_SUITE_data/results/eqeq b/lib/dialyzer/test/small_SUITE_data/results/eqeq index dabd38ebe3..9e16258133 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/eqeq +++ b/lib/dialyzer/test/small_SUITE_data/results/eqeq @@ -1,2 +1,2 @@ -eqeq.erl:15: The test float() =:= 'foo' can never evaluate to 'true' +eqeq.erl:15:15: The test float() =:= 'foo' can never evaluate to 'true' diff --git a/lib/dialyzer/test/small_SUITE_data/results/exhaust_case b/lib/dialyzer/test/small_SUITE_data/results/exhaust_case index 45cdd80b64..15138dbf26 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/exhaust_case +++ b/lib/dialyzer/test/small_SUITE_data/results/exhaust_case @@ -1,3 +1,3 @@ -exhaust_case.erl:17: The pattern 42 can never match the type 'bar' | 'foo' -exhaust_case.erl:18: The variable _other can never match since previous clauses completely covered the type 'bar' | 'foo' +exhaust_case.erl:17:5: The pattern 42 can never match the type 'bar' | 'foo' +exhaust_case.erl:18:5: The variable _other can never match since previous clauses completely covered the type 'bar' | 'foo' diff --git a/lib/dialyzer/test/small_SUITE_data/results/extra_range b/lib/dialyzer/test/small_SUITE_data/results/extra_range index ec50c95c4e..73e6647fac 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/extra_range +++ b/lib/dialyzer/test/small_SUITE_data/results/extra_range @@ -1,4 +1,4 @@ -extra_range.erl:29: The pattern 'ok' can never match the type 'error' -extra_range.erl:43: The pattern 'no' can never match the type 'maybe' | 'yes' -extra_range.erl:58: The pattern 'maybe' can never match the type 'no' | 'yes' +extra_range.erl:29:5: The pattern 'ok' can never match the type 'error' +extra_range.erl:43:5: The pattern 'no' can never match the type 'maybe' | 'yes' +extra_range.erl:58:5: The pattern 'maybe' can never match the type 'no' | 'yes' diff --git a/lib/dialyzer/test/small_SUITE_data/results/failing_funs b/lib/dialyzer/test/small_SUITE_data/results/failing_funs index a1fb22cbc6..83b6540462 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/failing_funs +++ b/lib/dialyzer/test/small_SUITE_data/results/failing_funs @@ -1,20 +1,20 @@ -failing_funs.erl:101: The created fun has no local return -failing_funs.erl:104: The created fun has no local return -failing_funs.erl:127: The created fun has no local return -failing_funs.erl:135: The created fun has no local return -failing_funs.erl:138: The created fun has no local return -failing_funs.erl:13: Function foo3/0 has no local return -failing_funs.erl:13: The pattern 'b' can never match the type 'a' -failing_funs.erl:161: The created fun has no local return -failing_funs.erl:169: The created fun has no local return -failing_funs.erl:172: The created fun has no local return -failing_funs.erl:17: The pattern 'b' can never match the type 'a' -failing_funs.erl:195: The created fun has no local return -failing_funs.erl:203: The created fun has no local return -failing_funs.erl:206: The created fun has no local return -failing_funs.erl:229: The created fun has no local return -failing_funs.erl:55: The created fun has no local return -failing_funs.erl:62: The created fun has no local return -failing_funs.erl:69: The created fun has no local return -failing_funs.erl:76: The created fun has no local return +failing_funs.erl:101:12: The created fun has no local return +failing_funs.erl:104:7: The created fun has no local return +failing_funs.erl:127:12: The created fun has no local return +failing_funs.erl:135:12: The created fun has no local return +failing_funs.erl:138:7: The created fun has no local return +failing_funs.erl:13:1: Function foo3/0 has no local return +failing_funs.erl:13:21: The pattern 'b' can never match the type 'a' +failing_funs.erl:161:12: The created fun has no local return +failing_funs.erl:169:12: The created fun has no local return +failing_funs.erl:172:7: The created fun has no local return +failing_funs.erl:17:21: The pattern 'b' can never match the type 'a' +failing_funs.erl:195:12: The created fun has no local return +failing_funs.erl:203:12: The created fun has no local return +failing_funs.erl:206:7: The created fun has no local return +failing_funs.erl:229:12: The created fun has no local return +failing_funs.erl:55:12: The created fun has no local return +failing_funs.erl:62:12: The created fun has no local return +failing_funs.erl:69:12: The created fun has no local return +failing_funs.erl:76:12: The created fun has no local return diff --git a/lib/dialyzer/test/small_SUITE_data/results/failing_guard1 b/lib/dialyzer/test/small_SUITE_data/results/failing_guard1 index 09fe076a6f..584044b096 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/failing_guard1 +++ b/lib/dialyzer/test/small_SUITE_data/results/failing_guard1 @@ -1,4 +1,4 @@ -failing_guard1.erl:12: Guard test float() =:= 2 can never succeed -failing_guard1.erl:13: Guard test integer() =:= 2.0 can never succeed -failing_guard1.erl:14: Guard test -2 | -1 | 0 | 1 | 2 =:= 2.0 can never succeed +failing_guard1.erl:12:14: Guard test float() =:= 2 can never succeed +failing_guard1.erl:13:14: Guard test integer() =:= 2.0 can never succeed +failing_guard1.erl:14:14: Guard test -2 | -1 | 0 | 1 | 2 =:= 2.0 can never succeed diff --git a/lib/dialyzer/test/small_SUITE_data/results/flatten b/lib/dialyzer/test/small_SUITE_data/results/flatten index 0bd866770c..f3ac40c127 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/flatten +++ b/lib/dialyzer/test/small_SUITE_data/results/flatten @@ -1,2 +1,2 @@ -flatten.erl:17: The call lists:flatten(nonempty_improper_list(atom() | [any()] | char(),atom() | {'no_translation',binary()})) will never return since it differs in the 1st argument from the success typing arguments: ([any()]) +flatten.erl:17:51: The call lists:flatten(nonempty_improper_list(atom() | [any()] | char(),atom() | {'no_translation',binary()})) will never return since it differs in the 1st argument from the success typing arguments: ([any()]) diff --git a/lib/dialyzer/test/small_SUITE_data/results/fun_app b/lib/dialyzer/test/small_SUITE_data/results/fun_app index b28baad43b..145695f7b0 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/fun_app +++ b/lib/dialyzer/test/small_SUITE_data/results/fun_app @@ -1,7 +1,7 @@ -fun_app.erl:37: Fun application will fail since F :: fun((_,_,_) -> 'ok' | 'true') is not a function of arity 1 -fun_app.erl:37: The created fun has no local return -fun_app.erl:38: Fun application will fail since F :: fun((_,_,_) -> 'ok' | 'true') is not a function of arity 2 -fun_app.erl:38: The created fun has no local return -fun_app.erl:40: Fun application will fail since F :: fun((_,_,_) -> 'ok' | 'true') is not a function of arity 4 -fun_app.erl:40: The created fun has no local return +fun_app.erl:37:14: The created fun has no local return +fun_app.erl:37:23: Fun application will fail since F :: fun((_,_,_) -> 'ok' | 'true') is not a function of arity 1 +fun_app.erl:38:14: The created fun has no local return +fun_app.erl:38:24: Fun application will fail since F :: fun((_,_,_) -> 'ok' | 'true') is not a function of arity 2 +fun_app.erl:40:14: The created fun has no local return +fun_app.erl:40:28: Fun application will fail since F :: fun((_,_,_) -> 'ok' | 'true') is not a function of arity 4 diff --git a/lib/dialyzer/test/small_SUITE_data/results/fun_app_args b/lib/dialyzer/test/small_SUITE_data/results/fun_app_args index ac153a6fb2..e59cd6c7a3 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/fun_app_args +++ b/lib/dialyzer/test/small_SUITE_data/results/fun_app_args @@ -1,3 +1,3 @@ -fun_app_args.erl:12: Fun application with arguments ('b',[]) will fail since the function has type 'c' | fun(('a',[]) -> any()), which differs in the 1st argument -fun_app_args.erl:12: The created fun has no local return +fun_app_args.erl:12:19: Fun application with arguments ('b',[]) will fail since the function has type 'c' | fun(('a',[]) -> any()), which differs in the 1st argument +fun_app_args.erl:12:5: The created fun has no local return diff --git a/lib/dialyzer/test/small_SUITE_data/results/fun_arity b/lib/dialyzer/test/small_SUITE_data/results/fun_arity index 8b7a538758..af260cf185 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/fun_arity +++ b/lib/dialyzer/test/small_SUITE_data/results/fun_arity @@ -1,37 +1,37 @@ -fun_arity.erl:100: Fun application will fail since _1 :: fun(() -> any()) is not a function of arity 1 -fun_arity.erl:100: Function 'Mfa_0_ko'/1 has no local return -fun_arity.erl:104: Fun application will fail since _1 :: fun((_) -> any()) is not a function of arity 0 -fun_arity.erl:104: Function 'Mfa_1_ko'/1 has no local return -fun_arity.erl:111: Fun application will fail since _1 :: fun(() -> any()) is not a function of arity 1 -fun_arity.erl:111: Function mFa_0_ko/1 has no local return -fun_arity.erl:115: Fun application will fail since _1 :: fun((_) -> any()) is not a function of arity 0 -fun_arity.erl:115: Function mFa_1_ko/1 has no local return -fun_arity.erl:122: Fun application will fail since _2 :: fun(() -> any()) is not a function of arity 1 -fun_arity.erl:122: Function 'MFa_0_ko'/2 has no local return -fun_arity.erl:126: Fun application will fail since _2 :: fun((_) -> any()) is not a function of arity 0 -fun_arity.erl:126: Function 'MFa_1_ko'/2 has no local return -fun_arity.erl:35: Fun application will fail since _0 :: fun(() -> 'ok') is not a function of arity 1 -fun_arity.erl:35: Function f_0_ko/0 has no local return -fun_arity.erl:39: Fun application will fail since _0 :: fun((_) -> 'ok') is not a function of arity 0 -fun_arity.erl:39: Function f_1_ko/0 has no local return -fun_arity.erl:48: Fun application will fail since _0 :: fun(() -> 'ok') is not a function of arity 1 -fun_arity.erl:48: Function fa_0_ko/0 has no local return -fun_arity.erl:53: Fun application will fail since _0 :: fun((_) -> 'ok') is not a function of arity 0 -fun_arity.erl:53: Function fa_1_ko/0 has no local return -fun_arity.erl:63: Fun application will fail since _0 :: fun(() -> any()) is not a function of arity 1 -fun_arity.erl:63: Function mfa_0_ko/0 has no local return -fun_arity.erl:68: Fun application will fail since _0 :: fun((_) -> any()) is not a function of arity 0 -fun_arity.erl:68: Function mfa_1_ko/0 has no local return -fun_arity.erl:76: Fun application will fail since _0 :: fun(() -> any()) is not a function of arity 1 -fun_arity.erl:76: Function mfa_ne_0_ko/0 has no local return -fun_arity.erl:78: Function mf_ne/0 will never be called -fun_arity.erl:81: Fun application will fail since _0 :: fun((_) -> any()) is not a function of arity 0 -fun_arity.erl:81: Function mfa_ne_1_ko/0 has no local return -fun_arity.erl:83: Function mf_ne/1 will never be called -fun_arity.erl:89: Fun application will fail since _0 :: fun(() -> any()) is not a function of arity 1 -fun_arity.erl:89: Function mfa_nd_0_ko/0 has no local return -fun_arity.erl:90: Call to missing or unexported function fun_arity:mf_nd/0 -fun_arity.erl:93: Fun application will fail since _0 :: fun((_) -> any()) is not a function of arity 0 -fun_arity.erl:93: Function mfa_nd_1_ko/0 has no local return -fun_arity.erl:94: Call to missing or unexported function fun_arity:mf_nd/1 +fun_arity.erl:100:19: Fun application will fail since _1 :: fun(() -> any()) is not a function of arity 1 +fun_arity.erl:100:1: Function 'Mfa_0_ko'/1 has no local return +fun_arity.erl:104:19: Fun application will fail since _1 :: fun((_) -> any()) is not a function of arity 0 +fun_arity.erl:104:1: Function 'Mfa_1_ko'/1 has no local return +fun_arity.erl:111:19: Fun application will fail since _1 :: fun(() -> any()) is not a function of arity 1 +fun_arity.erl:111:1: Function mFa_0_ko/1 has no local return +fun_arity.erl:115:19: Fun application will fail since _1 :: fun((_) -> any()) is not a function of arity 0 +fun_arity.erl:115:1: Function mFa_1_ko/1 has no local return +fun_arity.erl:122:1: Function 'MFa_0_ko'/2 has no local return +fun_arity.erl:122:22: Fun application will fail since _2 :: fun(() -> any()) is not a function of arity 1 +fun_arity.erl:126:1: Function 'MFa_1_ko'/2 has no local return +fun_arity.erl:126:22: Fun application will fail since _2 :: fun((_) -> any()) is not a function of arity 0 +fun_arity.erl:35:14: Fun application will fail since _0 :: fun(() -> 'ok') is not a function of arity 1 +fun_arity.erl:35:1: Function f_0_ko/0 has no local return +fun_arity.erl:39:14: Fun application will fail since _0 :: fun((_) -> 'ok') is not a function of arity 0 +fun_arity.erl:39:1: Function f_1_ko/0 has no local return +fun_arity.erl:48:15: Fun application will fail since _0 :: fun(() -> 'ok') is not a function of arity 1 +fun_arity.erl:48:1: Function fa_0_ko/0 has no local return +fun_arity.erl:53:15: Fun application will fail since _0 :: fun((_) -> 'ok') is not a function of arity 0 +fun_arity.erl:53:1: Function fa_1_ko/0 has no local return +fun_arity.erl:63:16: Fun application will fail since _0 :: fun(() -> any()) is not a function of arity 1 +fun_arity.erl:63:1: Function mfa_0_ko/0 has no local return +fun_arity.erl:68:16: Fun application will fail since _0 :: fun((_) -> any()) is not a function of arity 0 +fun_arity.erl:68:1: Function mfa_1_ko/0 has no local return +fun_arity.erl:76:19: Fun application will fail since _0 :: fun(() -> any()) is not a function of arity 1 +fun_arity.erl:76:1: Function mfa_ne_0_ko/0 has no local return +fun_arity.erl:78:1: Function mf_ne/0 will never be called +fun_arity.erl:81:19: Fun application will fail since _0 :: fun((_) -> any()) is not a function of arity 0 +fun_arity.erl:81:1: Function mfa_ne_1_ko/0 has no local return +fun_arity.erl:83:1: Function mf_ne/1 will never be called +fun_arity.erl:89:19: Fun application will fail since _0 :: fun(() -> any()) is not a function of arity 1 +fun_arity.erl:89:1: Function mfa_nd_0_ko/0 has no local return +fun_arity.erl:90:19: Call to missing or unexported function fun_arity:mf_nd/0 +fun_arity.erl:93:19: Fun application will fail since _0 :: fun((_) -> any()) is not a function of arity 0 +fun_arity.erl:93:1: Function mfa_nd_1_ko/0 has no local return +fun_arity.erl:94:19: Call to missing or unexported function fun_arity:mf_nd/1 diff --git a/lib/dialyzer/test/small_SUITE_data/results/funs_from_outside b/lib/dialyzer/test/small_SUITE_data/results/funs_from_outside index 3e597ef1bc..72f493441c 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/funs_from_outside +++ b/lib/dialyzer/test/small_SUITE_data/results/funs_from_outside @@ -1,7 +1,7 @@ -funs_from_outside.erl:18: The pattern 'error' can never match the type {'ok','nothing' | 'something'} -funs_from_outside.erl:32: Function run2/2 has no local return -funs_from_outside.erl:35: Function testb/3 has no local return -funs_from_outside.erl:41: The pattern 'error' can never match the type {'ok','nothing' | 'something'} -funs_from_outside.erl:78: Function test2/1 has no local return -funs_from_outside.erl:83: The pattern 'error' can never match the type 'ok' +funs_from_outside.erl:18:2: The pattern 'error' can never match the type {'ok','nothing' | 'something'} +funs_from_outside.erl:32:1: Function run2/2 has no local return +funs_from_outside.erl:35:1: Function testb/3 has no local return +funs_from_outside.erl:41:2: The pattern 'error' can never match the type {'ok','nothing' | 'something'} +funs_from_outside.erl:78:1: Function test2/1 has no local return +funs_from_outside.erl:83:5: The pattern 'error' can never match the type 'ok' diff --git a/lib/dialyzer/test/small_SUITE_data/results/gencall b/lib/dialyzer/test/small_SUITE_data/results/gencall index d0479ed738..b4dec09e4b 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/gencall +++ b/lib/dialyzer/test/small_SUITE_data/results/gencall @@ -1,4 +1,4 @@ -gencall.erl:11: Call to missing or unexported function gencall:foo/0 -gencall.erl:12: Call to missing or unexported function gen_server:handle_cast/2 -gencall.erl:9: Call to missing or unexported function ets:lookup/3 +gencall.erl:11:3: Call to missing or unexported function gencall:foo/0 +gencall.erl:12:3: Call to missing or unexported function gen_server:handle_cast/2 +gencall.erl:9:3: Call to missing or unexported function ets:lookup/3 diff --git a/lib/dialyzer/test/small_SUITE_data/results/guard_warnings b/lib/dialyzer/test/small_SUITE_data/results/guard_warnings index 14b7a9052c..c9c63656b3 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/guard_warnings +++ b/lib/dialyzer/test/small_SUITE_data/results/guard_warnings @@ -1,97 +1,97 @@ -guard_warnings.erl:100: Function test45/0 has no local return -guard_warnings.erl:100: Guard test not('true') can never succeed -guard_warnings.erl:102: Function test46/1 has no local return -guard_warnings.erl:102: Guard test X::'true' =:= 'false' can never succeed -guard_warnings.erl:104: Function test47/1 has no local return -guard_warnings.erl:104: Guard test X::'true' == 'false' can never succeed -guard_warnings.erl:106: Function test48/1 has no local return -guard_warnings.erl:106: Guard test X::'true' =/= 'true' can never succeed -guard_warnings.erl:114: Function test52_w/1 has no local return -guard_warnings.erl:118: Function test54_w/1 has no local return -guard_warnings.erl:12: Function test1/1 has no local return -guard_warnings.erl:12: Guard test X::'true' =:= 'false' can never succeed -guard_warnings.erl:14: Function test2/1 has no local return -guard_warnings.erl:14: Guard test X::'false' =:= 'true' can never succeed -guard_warnings.erl:16: Function test3/1 has no local return -guard_warnings.erl:16: Guard test not(X::'true') can never succeed -guard_warnings.erl:18: Function test4/1 has no local return -guard_warnings.erl:18: Guard test and('true',X::none()) can never succeed -guard_warnings.erl:20: Function test5/1 has no local return -guard_warnings.erl:20: Guard test not(X::'true') can never succeed -guard_warnings.erl:22: Function test6/1 has no local return -guard_warnings.erl:22: Guard test and('true',X::none()) can never succeed -guard_warnings.erl:24: Function test7_w/1 has no local return -guard_warnings.erl:26: Function test8_w/1 has no local return -guard_warnings.erl:28: Function test9/1 has no local return -guard_warnings.erl:28: Guard test not(not(X::'false')) can never succeed -guard_warnings.erl:30: Function test10/1 has no local return -guard_warnings.erl:30: Guard test not(or('false',X::none())) can never succeed -guard_warnings.erl:32: Function test11/1 has no local return -guard_warnings.erl:32: Guard test not(not(X::'false')) can never succeed -guard_warnings.erl:34: Function test12/1 has no local return -guard_warnings.erl:34: Guard test not(or('false',X::none())) can never succeed -guard_warnings.erl:36: Function test13/1 has no local return -guard_warnings.erl:36: Guard test and('true','false') can never succeed -guard_warnings.erl:38: Function test14/1 has no local return -guard_warnings.erl:38: Guard test and('false',any()) can never succeed -guard_warnings.erl:40: Function test15/1 has no local return -guard_warnings.erl:40: Guard test and(X::'true','false') can never succeed -guard_warnings.erl:42: Function test16/1 has no local return -guard_warnings.erl:42: Guard test and('false',X::any()) can never succeed -guard_warnings.erl:44: Function test17/1 has no local return -guard_warnings.erl:44: Guard test and(X::'true','false') can never succeed -guard_warnings.erl:46: Function test18/1 has no local return -guard_warnings.erl:46: Guard test and('false',X::any()) can never succeed -guard_warnings.erl:48: Function test19/1 has no local return -guard_warnings.erl:48: Guard test not(or('true',any())) can never succeed -guard_warnings.erl:50: Function test20/1 has no local return -guard_warnings.erl:50: Guard test not(or('false','true')) can never succeed -guard_warnings.erl:52: Function test21/1 has no local return -guard_warnings.erl:52: Guard test not(or('true',X::any())) can never succeed -guard_warnings.erl:54: Function test22/1 has no local return -guard_warnings.erl:54: Guard test not(or(X::'false','true')) can never succeed -guard_warnings.erl:56: Function test23/1 has no local return -guard_warnings.erl:56: Guard test not(or('true',X::any())) can never succeed -guard_warnings.erl:58: Function test24/1 has no local return -guard_warnings.erl:58: Guard test not(or(X::'false','true')) can never succeed -guard_warnings.erl:60: Function test25/1 has no local return -guard_warnings.erl:60: Guard test and('false',any()) can never succeed -guard_warnings.erl:62: Function test26/1 has no local return -guard_warnings.erl:62: Guard test and('true','false') can never succeed -guard_warnings.erl:64: Function test27/1 has no local return -guard_warnings.erl:64: Guard test and('false',X::any()) can never succeed -guard_warnings.erl:66: Function test28/1 has no local return -guard_warnings.erl:66: Guard test and(X::'true','false') can never succeed -guard_warnings.erl:68: Function test29/1 has no local return -guard_warnings.erl:68: Guard test and('false',X::any()) can never succeed -guard_warnings.erl:70: Function test30/1 has no local return -guard_warnings.erl:70: Guard test and(X::'true','false') can never succeed -guard_warnings.erl:72: Function test31/0 has no local return -guard_warnings.erl:72: Guard test and('false','false') can never succeed -guard_warnings.erl:74: Function test32/0 has no local return -guard_warnings.erl:74: Guard test and('false','false') can never succeed -guard_warnings.erl:76: Function test33/0 has no local return -guard_warnings.erl:76: Guard test not(and('true','true')) can never succeed -guard_warnings.erl:78: Function test34/0 has no local return -guard_warnings.erl:78: Guard test and('false','false') can never succeed -guard_warnings.erl:80: Function test35/0 has no local return -guard_warnings.erl:80: Guard test not(and('true','true')) can never succeed -guard_warnings.erl:82: Function test36/0 has no local return -guard_warnings.erl:82: Guard test or('false','false') can never succeed -guard_warnings.erl:84: Function test37/0 has no local return -guard_warnings.erl:84: Guard test or('false','false') can never succeed -guard_warnings.erl:86: Function test38/0 has no local return -guard_warnings.erl:86: Guard test or('false','false') can never succeed -guard_warnings.erl:88: Function test39/0 has no local return -guard_warnings.erl:88: Guard test or('false','false') can never succeed -guard_warnings.erl:90: Function test40/0 has no local return -guard_warnings.erl:90: Guard test or('false','false') can never succeed -guard_warnings.erl:92: Function test41/0 has no local return -guard_warnings.erl:92: Guard test 'true' =:= 'false' can never succeed -guard_warnings.erl:94: Function test42/0 has no local return -guard_warnings.erl:94: Guard test 'true' == 'false' can never succeed -guard_warnings.erl:96: Function test43/0 has no local return -guard_warnings.erl:96: Guard test 'true' =:= 'false' can never succeed -guard_warnings.erl:98: Function test44/0 has no local return -guard_warnings.erl:98: Guard test not('true' == 'true') can never succeed +guard_warnings.erl:100:1: Function test45/0 has no local return +guard_warnings.erl:100:45: Guard test not('true') can never succeed +guard_warnings.erl:102:1: Function test46/1 has no local return +guard_warnings.erl:102:34: Guard test X::'true' =:= 'false' can never succeed +guard_warnings.erl:104:1: Function test47/1 has no local return +guard_warnings.erl:104:33: Guard test X::'true' == 'false' can never succeed +guard_warnings.erl:106:1: Function test48/1 has no local return +guard_warnings.erl:106:52: Guard test X::'true' =/= 'true' can never succeed +guard_warnings.erl:114:1: Function test52_w/1 has no local return +guard_warnings.erl:118:1: Function test54_w/1 has no local return +guard_warnings.erl:12:1: Function test1/1 has no local return +guard_warnings.erl:12:1: Guard test X::'true' =:= 'false' can never succeed +guard_warnings.erl:14:1: Function test2/1 has no local return +guard_warnings.erl:14:1: Guard test X::'false' =:= 'true' can never succeed +guard_warnings.erl:16:1: Function test3/1 has no local return +guard_warnings.erl:16:22: Guard test not(X::'true') can never succeed +guard_warnings.erl:18:16: Guard test and('true',X::none()) can never succeed +guard_warnings.erl:18:1: Function test4/1 has no local return +guard_warnings.erl:20:1: Function test5/1 has no local return +guard_warnings.erl:20:22: Guard test not(X::'true') can never succeed +guard_warnings.erl:22:16: Guard test and('true',X::none()) can never succeed +guard_warnings.erl:22:1: Function test6/1 has no local return +guard_warnings.erl:24:1: Function test7_w/1 has no local return +guard_warnings.erl:26:1: Function test8_w/1 has no local return +guard_warnings.erl:28:1: Function test9/1 has no local return +guard_warnings.erl:28:21: Guard test not(not(X::'false')) can never succeed +guard_warnings.erl:30:17: Guard test not(or('false',X::none())) can never succeed +guard_warnings.erl:30:1: Function test10/1 has no local return +guard_warnings.erl:32:1: Function test11/1 has no local return +guard_warnings.erl:32:22: Guard test not(not(X::'false')) can never succeed +guard_warnings.erl:34:17: Guard test not(or('false',X::none())) can never succeed +guard_warnings.erl:34:1: Function test12/1 has no local return +guard_warnings.erl:36:18: Guard test and('true','false') can never succeed +guard_warnings.erl:36:1: Function test13/1 has no local return +guard_warnings.erl:38:16: Guard test and('false',any()) can never succeed +guard_warnings.erl:38:1: Function test14/1 has no local return +guard_warnings.erl:40:17: Guard test and(X::'true','false') can never succeed +guard_warnings.erl:40:1: Function test15/1 has no local return +guard_warnings.erl:42:17: Guard test and('false',X::any()) can never succeed +guard_warnings.erl:42:1: Function test16/1 has no local return +guard_warnings.erl:44:17: Guard test and(X::'true','false') can never succeed +guard_warnings.erl:44:1: Function test17/1 has no local return +guard_warnings.erl:46:17: Guard test and('false',X::any()) can never succeed +guard_warnings.erl:46:1: Function test18/1 has no local return +guard_warnings.erl:48:1: Function test19/1 has no local return +guard_warnings.erl:48:21: Guard test not(or('true',any())) can never succeed +guard_warnings.erl:50:1: Function test20/1 has no local return +guard_warnings.erl:50:23: Guard test not(or('false','true')) can never succeed +guard_warnings.erl:52:17: Guard test not(or('true',X::any())) can never succeed +guard_warnings.erl:52:1: Function test21/1 has no local return +guard_warnings.erl:54:17: Guard test not(or(X::'false','true')) can never succeed +guard_warnings.erl:54:1: Function test22/1 has no local return +guard_warnings.erl:56:17: Guard test not(or('true',X::any())) can never succeed +guard_warnings.erl:56:1: Function test23/1 has no local return +guard_warnings.erl:58:17: Guard test not(or(X::'false','true')) can never succeed +guard_warnings.erl:58:1: Function test24/1 has no local return +guard_warnings.erl:60:17: Guard test and('false',any()) can never succeed +guard_warnings.erl:60:1: Function test25/1 has no local return +guard_warnings.erl:62:19: Guard test and('true','false') can never succeed +guard_warnings.erl:62:1: Function test26/1 has no local return +guard_warnings.erl:64:17: Guard test and('false',X::any()) can never succeed +guard_warnings.erl:64:1: Function test27/1 has no local return +guard_warnings.erl:66:17: Guard test and(X::'true','false') can never succeed +guard_warnings.erl:66:1: Function test28/1 has no local return +guard_warnings.erl:68:17: Guard test and('false',X::any()) can never succeed +guard_warnings.erl:68:1: Function test29/1 has no local return +guard_warnings.erl:70:17: Guard test and(X::'true','false') can never succeed +guard_warnings.erl:70:1: Function test30/1 has no local return +guard_warnings.erl:72:15: Guard test and('false','false') can never succeed +guard_warnings.erl:72:1: Function test31/0 has no local return +guard_warnings.erl:74:16: Guard test and('false','false') can never succeed +guard_warnings.erl:74:1: Function test32/0 has no local return +guard_warnings.erl:76:1: Function test33/0 has no local return +guard_warnings.erl:76:20: Guard test not(and('true','true')) can never succeed +guard_warnings.erl:78:16: Guard test and('false','false') can never succeed +guard_warnings.erl:78:1: Function test34/0 has no local return +guard_warnings.erl:80:1: Function test35/0 has no local return +guard_warnings.erl:80:20: Guard test not(and('true','true')) can never succeed +guard_warnings.erl:82:15: Guard test or('false','false') can never succeed +guard_warnings.erl:82:1: Function test36/0 has no local return +guard_warnings.erl:84:16: Guard test or('false','false') can never succeed +guard_warnings.erl:84:1: Function test37/0 has no local return +guard_warnings.erl:86:1: Function test38/0 has no local return +guard_warnings.erl:86:20: Guard test or('false','false') can never succeed +guard_warnings.erl:88:16: Guard test or('false','false') can never succeed +guard_warnings.erl:88:1: Function test39/0 has no local return +guard_warnings.erl:90:1: Function test40/0 has no local return +guard_warnings.erl:90:20: Guard test or('false','false') can never succeed +guard_warnings.erl:92:15: Guard test 'true' =:= 'false' can never succeed +guard_warnings.erl:92:1: Function test41/0 has no local return +guard_warnings.erl:94:15: Guard test 'true' == 'false' can never succeed +guard_warnings.erl:94:1: Function test42/0 has no local return +guard_warnings.erl:96:1: Function test43/0 has no local return +guard_warnings.erl:96:20: Guard test 'true' =:= 'false' can never succeed +guard_warnings.erl:98:1: Function test44/0 has no local return +guard_warnings.erl:98:20: Guard test not('true' == 'true') can never succeed diff --git a/lib/dialyzer/test/small_SUITE_data/results/guards b/lib/dialyzer/test/small_SUITE_data/results/guards index cd0d3cace0..8e2386c77a 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/guards +++ b/lib/dialyzer/test/small_SUITE_data/results/guards @@ -1,17 +1,17 @@ -guards.erl:100: The variable _ can never match since previous clauses completely covered the type {'true','true'} -guards.erl:111: The pattern {_, _} can never match since previous clauses completely covered the type {'false',boolean()} | {'true',boolean()} -guards.erl:122: The pattern {_, _} can never match since previous clauses completely covered the type {'false',boolean()} | {'true',boolean()} -guards.erl:129: Function t15_a/0 has no local return -guards.erl:129: The call guards:t15('a') will never return since it differs in the 1st argument from the success typing arguments: ('b') -guards.erl:129: The call guards:t15('c') will never return since it differs in the 1st argument from the success typing arguments: ('b') -guards.erl:136: Function t16_a/0 has no local return -guards.erl:136: The call guards:t16('a') will never return since it differs in the 1st argument from the success typing arguments: ('b') -guards.erl:136: The call guards:t16('c') will never return since it differs in the 1st argument from the success typing arguments: ('b') -guards.erl:55: Function t5/1 has no local return -guards.erl:55: Guard test is_integer(A::atom()) can never succeed -guards.erl:59: Function t6/1 has no local return -guards.erl:59: Guard test is_integer(A::atom()) can never succeed -guards.erl:67: The call guards:t7({42}) will never return since it differs in the 1st argument from the success typing arguments: (atom() | integer()) -guards.erl:75: The call guards:t8({42}) will never return since it differs in the 1st argument from the success typing arguments: (atom() | integer()) -guards.erl:92: The variable _ can never match since previous clauses completely covered the type {'true','true'} +guards.erl:100:2: The variable _ can never match since previous clauses completely covered the type {'true','true'} +guards.erl:111:2: The pattern {_, _} can never match since previous clauses completely covered the type {'false',boolean()} | {'true',boolean()} +guards.erl:122:2: The pattern {_, _} can never match since previous clauses completely covered the type {'false',boolean()} | {'true',boolean()} +guards.erl:129:16: The call guards:t15('a') will never return since it differs in the 1st argument from the success typing arguments: ('b') +guards.erl:129:1: Function t15_a/0 has no local return +guards.erl:129:32: The call guards:t15('c') will never return since it differs in the 1st argument from the success typing arguments: ('b') +guards.erl:136:16: The call guards:t16('a') will never return since it differs in the 1st argument from the success typing arguments: ('b') +guards.erl:136:1: Function t16_a/0 has no local return +guards.erl:136:32: The call guards:t16('c') will never return since it differs in the 1st argument from the success typing arguments: ('b') +guards.erl:55:1: Function t5/1 has no local return +guards.erl:55:27: Guard test is_integer(A::atom()) can never succeed +guards.erl:59:1: Function t6/1 has no local return +guards.erl:59:31: Guard test is_integer(A::atom()) can never succeed +guards.erl:67:17: The call guards:t7({42}) will never return since it differs in the 1st argument from the success typing arguments: (atom() | integer()) +guards.erl:75:17: The call guards:t8({42}) will never return since it differs in the 1st argument from the success typing arguments: (atom() | integer()) +guards.erl:92:2: The variable _ can never match since previous clauses completely covered the type {'true','true'} diff --git a/lib/dialyzer/test/small_SUITE_data/results/higher_order_discrepancy b/lib/dialyzer/test/small_SUITE_data/results/higher_order_discrepancy index 11b9ecade6..82cd4cdf62 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/higher_order_discrepancy +++ b/lib/dialyzer/test/small_SUITE_data/results/higher_order_discrepancy @@ -1,3 +1,3 @@ -higher_order_discrepancy.erl:19: Function g/1 has no local return -higher_order_discrepancy.erl:19: The pattern 'bar' can never match the type 'foo' +higher_order_discrepancy.erl:19:1: Function g/1 has no local return +higher_order_discrepancy.erl:19:1: The pattern 'bar' can never match the type 'foo' diff --git a/lib/dialyzer/test/small_SUITE_data/results/higher_order_discrepancy_2 b/lib/dialyzer/test/small_SUITE_data/results/higher_order_discrepancy_2 index c1c7dbbfcc..f6784a2b30 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/higher_order_discrepancy_2 +++ b/lib/dialyzer/test/small_SUITE_data/results/higher_order_discrepancy_2 @@ -1,8 +1,8 @@ -higher_order_discrepancy_2.erl:11: The call higher_order_discrepancy_2:f('foo') will never return since it differs in the 1st argument from the success typing arguments: ('bar') -higher_order_discrepancy_2.erl:11: The call higher_order_discrepancy_2:g('foo') will never return since it differs in the 1st argument from the success typing arguments: ('baz') -higher_order_discrepancy_2.erl:13: Function f/1 has no local return -higher_order_discrepancy_2.erl:13: The pattern 'bar' can never match the type 'foo' -higher_order_discrepancy_2.erl:14: Function g/1 has no local return -higher_order_discrepancy_2.erl:14: The pattern 'baz' can never match the type 'foo' -higher_order_discrepancy_2.erl:5: Function test/1 has no local return +higher_order_discrepancy_2.erl:11:7: The call higher_order_discrepancy_2:f('foo') will never return since it differs in the 1st argument from the success typing arguments: ('bar') +higher_order_discrepancy_2.erl:11:7: The call higher_order_discrepancy_2:g('foo') will never return since it differs in the 1st argument from the success typing arguments: ('baz') +higher_order_discrepancy_2.erl:13:1: Function f/1 has no local return +higher_order_discrepancy_2.erl:13:1: The pattern 'bar' can never match the type 'foo' +higher_order_discrepancy_2.erl:14:1: Function g/1 has no local return +higher_order_discrepancy_2.erl:14:1: The pattern 'baz' can never match the type 'foo' +higher_order_discrepancy_2.erl:5:1: Function test/1 has no local return diff --git a/lib/dialyzer/test/small_SUITE_data/results/inf_loop2 b/lib/dialyzer/test/small_SUITE_data/results/inf_loop2 index 142e4b2c37..3f1b41c7a2 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/inf_loop2 +++ b/lib/dialyzer/test/small_SUITE_data/results/inf_loop2 @@ -1,4 +1,4 @@ -inf_loop2.erl:18: Function test/0 has no local return -inf_loop2.erl:19: The call lists:reverse('gazonk') will never return since it differs in the 1st argument from the success typing arguments: ([any()]) -inf_loop2.erl:22: Function loop/0 will never be called +inf_loop2.erl:18:1: Function test/0 has no local return +inf_loop2.erl:19:17: The call lists:reverse('gazonk') will never return since it differs in the 1st argument from the success typing arguments: ([any()]) +inf_loop2.erl:22:1: Function loop/0 will never be called diff --git a/lib/dialyzer/test/small_SUITE_data/results/invalid_spec_2 b/lib/dialyzer/test/small_SUITE_data/results/invalid_spec_2 index 4565112ea0..bfada119a2 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/invalid_spec_2 +++ b/lib/dialyzer/test/small_SUITE_data/results/invalid_spec_2 @@ -1,2 +1,2 @@ -scala_user.erl:5: Invalid type specification for function scala_user:is_list/2. The success typing is (maybe_improper_list() | tuple(),_) -> boolean() +scala_user.erl:5:2: Invalid type specification for function scala_user:is_list/2. The success typing is (maybe_improper_list() | tuple(),_) -> boolean() diff --git a/lib/dialyzer/test/small_SUITE_data/results/invalid_specs b/lib/dialyzer/test/small_SUITE_data/results/invalid_specs index c95c0ff1f8..0de8f0fcb4 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/invalid_specs +++ b/lib/dialyzer/test/small_SUITE_data/results/invalid_specs @@ -1,3 +1,3 @@ -invalid_spec1.erl:5: Invalid type specification for function invalid_spec1:get_plan_dirty/1. The success typing is ([string()]) -> {maybe_improper_list(),[atom()]} -invalid_spec2.erl:5: Function foo/0 has no local return +invalid_spec1.erl:5:2: Invalid type specification for function invalid_spec1:get_plan_dirty/1. The success typing is ([string()]) -> {maybe_improper_list(),[atom()]} +invalid_spec2.erl:5:1: Function foo/0 has no local return diff --git a/lib/dialyzer/test/small_SUITE_data/results/left_assoc b/lib/dialyzer/test/small_SUITE_data/results/left_assoc index 58cdad29de..7019c9d998 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/left_assoc +++ b/lib/dialyzer/test/small_SUITE_data/results/left_assoc @@ -1,2 +1,2 @@ -left_assoc.erl:93: The variable __@2 can never match since previous clauses completely covered the type binary() +left_assoc.erl:93:17: The variable __@2 can never match since previous clauses completely covered the type binary() diff --git a/lib/dialyzer/test/small_SUITE_data/results/list_match b/lib/dialyzer/test/small_SUITE_data/results/list_match index 95007da604..3ed7c83aa5 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/list_match +++ b/lib/dialyzer/test/small_SUITE_data/results/list_match @@ -1,2 +1,2 @@ -list_match.erl:19: The pattern [_ | T] can never match since previous clauses completely covered the type [1 | 2 | 3 | 4] +list_match.erl:19:1: The pattern [_ | T] can never match since previous clauses completely covered the type [1 | 2 | 3 | 4] diff --git a/lib/dialyzer/test/small_SUITE_data/results/literals b/lib/dialyzer/test/small_SUITE_data/results/literals index 1ee39453a4..66828461fb 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/literals +++ b/lib/dialyzer/test/small_SUITE_data/results/literals @@ -1,17 +1,17 @@ -literals.erl:11: Function t1/0 has no local return -literals.erl:12: Record construction #r{id::'a'} violates the declared type of field id::'integer' -literals.erl:14: Function t2/0 has no local return -literals.erl:15: Record construction #r{id::'a'} violates the declared type of field id::'integer' -literals.erl:17: Function t3/0 has no local return -literals.erl:18: Record construction #r{id::'a'} violates the declared type of field id::'integer' -literals.erl:20: Function t4/0 has no local return -literals.erl:21: Record construction #r{id::'a'} violates the declared type of field id::'integer' -literals.erl:23: Function m1/1 has no local return -literals.erl:23: Matching of pattern {'r', 'a'} tagged with a record name violates the declared type of #r{id::'integer'} -literals.erl:26: Function m2/1 has no local return -literals.erl:26: Matching of pattern {'r', 'a'} tagged with a record name violates the declared type of #r{id::'integer'} -literals.erl:29: Function m3/1 has no local return -literals.erl:29: The pattern {{'r', 'a'}} can never match the type any() -literals.erl:32: Function m4/1 has no local return -literals.erl:32: Matching of pattern {'r', 'a'} tagged with a record name violates the declared type of #r{id::'integer'} +literals.erl:11:1: Function t1/0 has no local return +literals.erl:12:13: Record construction #r{id::'a'} violates the declared type of field id::'integer' +literals.erl:14:1: Function t2/0 has no local return +literals.erl:15:14: Record construction #r{id::'a'} violates the declared type of field id::'integer' +literals.erl:17:1: Function t3/0 has no local return +literals.erl:18:14: Record construction #r{id::'a'} violates the declared type of field id::'integer' +literals.erl:20:1: Function t4/0 has no local return +literals.erl:21:20: Record construction #r{id::'a'} violates the declared type of field id::'integer' +literals.erl:23:1: Function m1/1 has no local return +literals.erl:23:1: Matching of pattern {'r', 'a'} tagged with a record name violates the declared type of #r{id::'integer'} +literals.erl:26:1: Function m2/1 has no local return +literals.erl:26:1: Matching of pattern {'r', 'a'} tagged with a record name violates the declared type of #r{id::'integer'} +literals.erl:29:1: Function m3/1 has no local return +literals.erl:29:1: The pattern {{'r', 'a'}} can never match the type any() +literals.erl:32:1: Function m4/1 has no local return +literals.erl:32:1: Matching of pattern {'r', 'a'} tagged with a record name violates the declared type of #r{id::'integer'} diff --git a/lib/dialyzer/test/small_SUITE_data/results/make_tuple b/lib/dialyzer/test/small_SUITE_data/results/make_tuple index 4d51586e35..a1563b4509 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/make_tuple +++ b/lib/dialyzer/test/small_SUITE_data/results/make_tuple @@ -1,3 +1,3 @@ -make_tuple.erl:4: Function test/0 has no local return -make_tuple.erl:5: The pattern {_, _} can never match the type {_,_,_} +make_tuple.erl:4:1: Function test/0 has no local return +make_tuple.erl:5:3: The pattern {_, _} can never match the type {_,_,_} diff --git a/lib/dialyzer/test/small_SUITE_data/results/maps1 b/lib/dialyzer/test/small_SUITE_data/results/maps1 index f36f7f4926..ab9e9a2590 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/maps1 +++ b/lib/dialyzer/test/small_SUITE_data/results/maps1 @@ -1,4 +1,4 @@ -maps1.erl:43: Function t3/0 has no local return -maps1.erl:44: The call maps1:foo(#{'greger'=>3, #{'arne'=>'anka'}=>45},1) will never return since it differs in the 1st and 2nd argument from the success typing arguments: (#{'beta':=_, _=>_},'b') -maps1.erl:52: The variable Mod can never match since previous clauses completely covered the type #{} +maps1.erl:43:1: Function t3/0 has no local return +maps1.erl:44:9: The call maps1:foo(#{'greger'=>3, #{'arne'=>'anka'}=>45},1) will never return since it differs in the 1st and 2nd argument from the success typing arguments: (#{'beta':=_, _=>_},'b') +maps1.erl:52:9: The variable Mod can never match since previous clauses completely covered the type #{} diff --git a/lib/dialyzer/test/small_SUITE_data/results/maps_difftype b/lib/dialyzer/test/small_SUITE_data/results/maps_difftype index 3018b888db..6558aad6b2 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/maps_difftype +++ b/lib/dialyzer/test/small_SUITE_data/results/maps_difftype @@ -1,3 +1,3 @@ -maps_difftype.erl:10: Function empty_mismatch/1 has no local return -maps_difftype.erl:11: The pattern #{} can never match the type tuple() +maps_difftype.erl:10:1: Function empty_mismatch/1 has no local return +maps_difftype.erl:11:19: The pattern #{} can never match the type tuple() diff --git a/lib/dialyzer/test/small_SUITE_data/results/maps_sum b/lib/dialyzer/test/small_SUITE_data/results/maps_sum index daa099e490..83e7c73ef2 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/maps_sum +++ b/lib/dialyzer/test/small_SUITE_data/results/maps_sum @@ -1,4 +1,4 @@ -maps_sum.erl:15: Invalid type specification for function maps_sum:wrong1/1. The success typing is (maps:iterator(_,_) | map()) -> any() -maps_sum.erl:26: Function wrong2/1 has no local return -maps_sum.erl:27: The call lists:foldl(fun((_,_,_) -> any()),0,Data::any()) will never return since it differs in the 1st argument from the success typing arguments: (fun((_,_) -> any()),any(),[any()]) +maps_sum.erl:15:2: Invalid type specification for function maps_sum:wrong1/1. The success typing is (maps:iterator(_,_) | map()) -> any() +maps_sum.erl:26:1: Function wrong2/1 has no local return +maps_sum.erl:27:17: The call lists:foldl(fun((_,_,_) -> any()),0,Data::any()) will never return since it differs in the 1st argument from the success typing arguments: (fun((_,_) -> any()),any(),[any()]) diff --git a/lib/dialyzer/test/small_SUITE_data/results/my_sofs b/lib/dialyzer/test/small_SUITE_data/results/my_sofs index 0b933e6cd7..5a33dde100 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/my_sofs +++ b/lib/dialyzer/test/small_SUITE_data/results/my_sofs @@ -1,3 +1,3 @@ -my_sofs.erl:34: Matching of pattern {'Set', _, _} tagged with a record name violates the declared type of #'OrdSet'{} -my_sofs.erl:54: Matching of pattern {'Set', _, _} tagged with a record name violates the declared type of #'OrdSet'{} +my_sofs.erl:34:28: Matching of pattern {'Set', _, _} tagged with a record name violates the declared type of #'OrdSet'{} +my_sofs.erl:54:31: Matching of pattern {'Set', _, _} tagged with a record name violates the declared type of #'OrdSet'{} diff --git a/lib/dialyzer/test/small_SUITE_data/results/no_local_return b/lib/dialyzer/test/small_SUITE_data/results/no_local_return index 6ca1ed51d8..ac818081a1 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/no_local_return +++ b/lib/dialyzer/test/small_SUITE_data/results/no_local_return @@ -1,3 +1,3 @@ -no_local_return.erl:11: Function bar/1 will never be called -no_local_return.erl:8: Function foo/0 will never be called +no_local_return.erl:11:1: Function bar/1 will never be called +no_local_return.erl:8:1: Function foo/0 will never be called diff --git a/lib/dialyzer/test/small_SUITE_data/results/no_match b/lib/dialyzer/test/small_SUITE_data/results/no_match index 644310a973..6e03f99221 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/no_match +++ b/lib/dialyzer/test/small_SUITE_data/results/no_match @@ -1,4 +1,4 @@ -no_match.erl:5: Function t1/1 has no local return -no_match.erl:7: Function t2/1 has no local return -no_match.erl:9: Function t3/1 has no local return +no_match.erl:5:1: Function t1/1 has no local return +no_match.erl:7:1: Function t2/1 has no local return +no_match.erl:9:1: Function t3/1 has no local return diff --git a/lib/dialyzer/test/small_SUITE_data/results/non_existing b/lib/dialyzer/test/small_SUITE_data/results/non_existing index b0da5998c7..6c9e2324ea 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/non_existing +++ b/lib/dialyzer/test/small_SUITE_data/results/non_existing @@ -1,3 +1,3 @@ -non_existing.erl:12: Call to missing or unexported function lists:non_existing_fun/1 -non_existing.erl:9: Call to missing or unexported function lists:non_existing_call/1 +non_existing.erl:12:9: Call to missing or unexported function lists:non_existing_fun/1 +non_existing.erl:9:3: Call to missing or unexported function lists:non_existing_call/1 diff --git a/lib/dialyzer/test/small_SUITE_data/results/none_scc_inf_loop b/lib/dialyzer/test/small_SUITE_data/results/none_scc_inf_loop index 3b1b204708..1460c9ff3b 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/none_scc_inf_loop +++ b/lib/dialyzer/test/small_SUITE_data/results/none_scc_inf_loop @@ -1,5 +1,5 @@ -none_scc_inf_loop.erl:10: Function foo/0 has no local return -none_scc_inf_loop.erl:13: Function foo/1 has no local return -none_scc_inf_loop.erl:13: The pattern 0 can never match the type 1 | 3 -none_scc_inf_loop.erl:18: Function bar/1 has no local return +none_scc_inf_loop.erl:10:1: Function foo/0 has no local return +none_scc_inf_loop.erl:13:1: Function foo/1 has no local return +none_scc_inf_loop.erl:13:1: The pattern 0 can never match the type 1 | 3 +none_scc_inf_loop.erl:18:1: Function bar/1 has no local return diff --git a/lib/dialyzer/test/small_SUITE_data/results/not_bogus_warning b/lib/dialyzer/test/small_SUITE_data/results/not_bogus_warning index e3a7f6b444..e1ddc78e95 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/not_bogus_warning +++ b/lib/dialyzer/test/small_SUITE_data/results/not_bogus_warning @@ -1,3 +1,3 @@ -not_bogus_warning.erl:11: Guard test not(is_atom(A::'bar' | 'foo')) can never succeed -not_bogus_warning.erl:24: Guard test not(is_integer(X::42)) can never succeed +not_bogus_warning.erl:11:30: Guard test not(is_atom(A::'bar' | 'foo')) can never succeed +not_bogus_warning.erl:24:35: Guard test not(is_integer(X::42)) can never succeed diff --git a/lib/dialyzer/test/small_SUITE_data/results/overloaded1 b/lib/dialyzer/test/small_SUITE_data/results/overloaded1 index ab57ec03ff..b3c45188b3 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/overloaded1 +++ b/lib/dialyzer/test/small_SUITE_data/results/overloaded1 @@ -1,3 +1,3 @@ -overloaded1.erl:10: The pattern {'ok', 'gazonk'} can never match the type {'error',_} | {'ok',{atom(),atom(),byte()}} -overloaded1.erl:9: Function test1/0 has no local return +overloaded1.erl:10:3: The pattern {'ok', 'gazonk'} can never match the type {'error',_} | {'ok',{atom(),atom(),byte()}} +overloaded1.erl:9:1: Function test1/0 has no local return diff --git a/lib/dialyzer/test/small_SUITE_data/results/port_info_test b/lib/dialyzer/test/small_SUITE_data/results/port_info_test index 53d20a415b..4f4f6d58d1 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/port_info_test +++ b/lib/dialyzer/test/small_SUITE_data/results/port_info_test @@ -1,7 +1,7 @@ -port_info_test.erl:10: The pattern {'connected', 42} can never match the type 'undefined' | {'connected',pid()} -port_info_test.erl:14: The pattern {'registered_name', "42"} can never match the type 'undefined' | [] | {'registered_name',atom()} -port_info_test.erl:19: The pattern {'output', 42} can never match the type 'undefined' | {'connected',pid()} -port_info_test.erl:24: Guard test 'links' =:= Atom::'connected' can never succeed -port_info_test.erl:28: The pattern {'gazonk', _} can never match the type 'undefined' | [] | {'connected' | 'id' | 'input' | 'links' | 'locking' | 'memory' | 'monitors' | 'name' | 'os_pid' | 'output' | 'parallelism' | 'queue_size' | 'registered_name',atom() | pid() | [pid() | char() | {'process',pid()}] | non_neg_integer()} -port_info_test.erl:32: The pattern {'os_pid', "42"} can never match the type 'undefined' | {'os_pid','undefined' | non_neg_integer()} +port_info_test.erl:10:3: The pattern {'connected', 42} can never match the type 'undefined' | {'connected',pid()} +port_info_test.erl:14:3: The pattern {'registered_name', "42"} can never match the type 'undefined' | [] | {'registered_name',atom()} +port_info_test.erl:19:3: The pattern {'output', 42} can never match the type 'undefined' | {'connected',pid()} +port_info_test.erl:24:3: Guard test 'links' =:= Atom::'connected' can never succeed +port_info_test.erl:28:3: The pattern {'gazonk', _} can never match the type 'undefined' | [] | {'connected' | 'id' | 'input' | 'links' | 'locking' | 'memory' | 'monitors' | 'name' | 'os_pid' | 'output' | 'parallelism' | 'queue_size' | 'registered_name',atom() | pid() | [pid() | char() | {'process',pid()}] | non_neg_integer()} +port_info_test.erl:32:3: The pattern {'os_pid', "42"} can never match the type 'undefined' | {'os_pid','undefined' | non_neg_integer()} diff --git a/lib/dialyzer/test/small_SUITE_data/results/predef b/lib/dialyzer/test/small_SUITE_data/results/predef index 85e210d6e4..f57f78d59e 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/predef +++ b/lib/dialyzer/test/small_SUITE_data/results/predef @@ -1,8 +1,8 @@ -predef.erl:19: Invalid type specification for function predef:array/1. The success typing is (array:array(_)) -> array:array(_) -predef.erl:24: Invalid type specification for function predef:dict/1. The success typing is (dict:dict(_,_)) -> dict:dict(_,_) -predef.erl:29: Invalid type specification for function predef:digraph/1. The success typing is (digraph:graph()) -> [any()] -predef.erl:39: Invalid type specification for function predef:gb_set/1. The success typing is (gb_sets:set(_)) -> gb_sets:set(_) -predef.erl:44: Invalid type specification for function predef:gb_tree/1. The success typing is (gb_trees:tree(_,_)) -> gb_trees:tree(_,_) -predef.erl:49: Invalid type specification for function predef:queue/1. The success typing is (queue:queue(_)) -> queue:queue(_) -predef.erl:54: Invalid type specification for function predef:set/1. The success typing is (sets:set(_)) -> sets:set(_) +predef.erl:19:2: Invalid type specification for function predef:array/1. The success typing is (array:array(_)) -> array:array(_) +predef.erl:24:2: Invalid type specification for function predef:dict/1. The success typing is (dict:dict(_,_)) -> dict:dict(_,_) +predef.erl:29:2: Invalid type specification for function predef:digraph/1. The success typing is (digraph:graph()) -> [any()] +predef.erl:39:2: Invalid type specification for function predef:gb_set/1. The success typing is (gb_sets:set(_)) -> gb_sets:set(_) +predef.erl:44:2: Invalid type specification for function predef:gb_tree/1. The success typing is (gb_trees:tree(_,_)) -> gb_trees:tree(_,_) +predef.erl:49:2: Invalid type specification for function predef:queue/1. The success typing is (queue:queue(_)) -> queue:queue(_) +predef.erl:54:2: Invalid type specification for function predef:set/1. The success typing is (sets:set(_)) -> sets:set(_) diff --git a/lib/dialyzer/test/small_SUITE_data/results/pretty_bitstring b/lib/dialyzer/test/small_SUITE_data/results/pretty_bitstring index dc3620fcf0..e8b3e7e1ad 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/pretty_bitstring +++ b/lib/dialyzer/test/small_SUITE_data/results/pretty_bitstring @@ -1,3 +1,3 @@ -pretty_bitstring.erl:7: Function t/0 has no local return -pretty_bitstring.erl:8: The call binary:copy(<<1,2,3:3>>,2) breaks the contract (Subject,N) -> binary() when Subject :: binary(), N :: non_neg_integer() +pretty_bitstring.erl:7:1: Function t/0 has no local return +pretty_bitstring.erl:8:17: The call binary:copy(<<1,2,3:3>>,2) breaks the contract (Subject,N) -> binary() when Subject :: binary(), N :: non_neg_integer() diff --git a/lib/dialyzer/test/small_SUITE_data/results/receive1 b/lib/dialyzer/test/small_SUITE_data/results/receive1 index abf6eec0ca..31fccd88a6 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/receive1 +++ b/lib/dialyzer/test/small_SUITE_data/results/receive1 @@ -1,2 +1,2 @@ -receive1.erl:12: Function t/1 has no local return +receive1.erl:12:1: Function t/1 has no local return diff --git a/lib/dialyzer/test/small_SUITE_data/results/record_construct b/lib/dialyzer/test/small_SUITE_data/results/record_construct index 4c40fec298..e781585f95 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/record_construct +++ b/lib/dialyzer/test/small_SUITE_data/results/record_construct @@ -1,7 +1,7 @@ -record_construct.erl:15: Function t_opa/0 has no local return -record_construct.erl:16: Record construction #r_opa{b::gb_sets:set(_),c::42,e::'false'} violates the declared type of field c::boolean() -record_construct.erl:20: Function t_rem/0 has no local return -record_construct.erl:21: Record construction #r_rem{a::'gazonk'} violates the declared type of field a::string() -record_construct.erl:6: Function t_loc/0 has no local return -record_construct.erl:7: Record construction #r_loc{a::'gazonk',b::42} violates the declared type of field a::integer() and b::atom() +record_construct.erl:15:1: Function t_opa/0 has no local return +record_construct.erl:16:3: Record construction #r_opa{b::gb_sets:set(_),c::42,e::'false'} violates the declared type of field c::boolean() +record_construct.erl:20:1: Function t_rem/0 has no local return +record_construct.erl:21:3: Record construction #r_rem{a::'gazonk'} violates the declared type of field a::string() +record_construct.erl:6:1: Function t_loc/0 has no local return +record_construct.erl:7:3: Record construction #r_loc{a::'gazonk',b::42} violates the declared type of field a::integer() and b::atom() diff --git a/lib/dialyzer/test/small_SUITE_data/results/record_creation_diffs b/lib/dialyzer/test/small_SUITE_data/results/record_creation_diffs index c971935bbf..a006a857ef 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/record_creation_diffs +++ b/lib/dialyzer/test/small_SUITE_data/results/record_creation_diffs @@ -1,3 +1,3 @@ -record_creation_diffs.erl:10: Function foo/1 has no local return -record_creation_diffs.erl:11: Record construction #bar{some_list::{'this','is','a','tuple'}} violates the declared type of field some_list::[any()] +record_creation_diffs.erl:10:1: Function foo/1 has no local return +record_creation_diffs.erl:11:41: Record construction #bar{some_list::{'this','is','a','tuple'}} violates the declared type of field some_list::[any()] diff --git a/lib/dialyzer/test/small_SUITE_data/results/record_match b/lib/dialyzer/test/small_SUITE_data/results/record_match index a0dd6f560a..7031fa227c 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/record_match +++ b/lib/dialyzer/test/small_SUITE_data/results/record_match @@ -1,3 +1,3 @@ -record_match.erl:16: Function select/0 has no local return -record_match.erl:17: Matching of pattern {'b_literal', 'undefined'} tagged with a record name violates the declared type of #b_local{} | #b_remote{} +record_match.erl:16:1: Function select/0 has no local return +record_match.erl:17:5: Matching of pattern {'b_literal', 'undefined'} tagged with a record name violates the declared type of #b_local{} | #b_remote{} diff --git a/lib/dialyzer/test/small_SUITE_data/results/record_pat b/lib/dialyzer/test/small_SUITE_data/results/record_pat index 8317ea041a..b321a1ee59 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/record_pat +++ b/lib/dialyzer/test/small_SUITE_data/results/record_pat @@ -1,2 +1,2 @@ -record_pat.erl:14: Matching of pattern {'foo', 'baz'} tagged with a record name violates the declared type of #foo{bar::integer()} +record_pat.erl:14:1: Matching of pattern {'foo', 'baz'} tagged with a record name violates the declared type of #foo{bar::integer()} diff --git a/lib/dialyzer/test/small_SUITE_data/results/record_send_test b/lib/dialyzer/test/small_SUITE_data/results/record_send_test index 4b587ec20b..0fa5135d46 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/record_send_test +++ b/lib/dialyzer/test/small_SUITE_data/results/record_send_test @@ -1,2 +1,2 @@ -record_send_test.erl:30: The call erlang:'!'(Rec1::#rec1{a::'a',b::'b',c::'c'},'hello_again') will never return since it differs in the 1st argument from the success typing arguments: (atom() | pid() | port() | reference() | {atom(),atom()},any()) +record_send_test.erl:30:7: The call erlang:'!'(Rec1::#rec1{a::'a',b::'b',c::'c'},'hello_again') will never return since it differs in the 1st argument from the success typing arguments: (atom() | pid() | port() | reference() | {atom(),atom()},any()) diff --git a/lib/dialyzer/test/small_SUITE_data/results/record_test b/lib/dialyzer/test/small_SUITE_data/results/record_test index 7060bfa200..ea13ff1e93 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/record_test +++ b/lib/dialyzer/test/small_SUITE_data/results/record_test @@ -1,3 +1,3 @@ -record_test.erl:19: Matching of pattern {'foo', _} tagged with a record name violates the declared type of 'foo' -record_test.erl:21: The variable _ can never match since previous clauses completely covered the type 'foo' +record_test.erl:19:5: Matching of pattern {'foo', _} tagged with a record name violates the declared type of 'foo' +record_test.erl:21:5: The variable _ can never match since previous clauses completely covered the type 'foo' diff --git a/lib/dialyzer/test/small_SUITE_data/results/record_update b/lib/dialyzer/test/small_SUITE_data/results/record_update index ea52057adf..b61d2e66b3 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/record_update +++ b/lib/dialyzer/test/small_SUITE_data/results/record_update @@ -1,2 +1,2 @@ -record_update.erl:7: Invalid type specification for function record_update:quux/2. The success typing is (#foo{bar::atom()},atom()) -> #foo{bar::atom()} +record_update.erl:7:2: Invalid type specification for function record_update:quux/2. The success typing is (#foo{bar::atom()},atom()) -> #foo{bar::atom()} diff --git a/lib/dialyzer/test/small_SUITE_data/results/refine_failing b/lib/dialyzer/test/small_SUITE_data/results/refine_failing index 2bf67c9d81..cc5615fdd5 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/refine_failing +++ b/lib/dialyzer/test/small_SUITE_data/results/refine_failing @@ -1,2 +1,2 @@ -refine_failing.erl:25: The call refine_failing:update_one(F::any(),Ds::{_,non_neg_integer()},[{_,non_neg_integer()},...]) will never return since it differs in the 2nd argument from the success typing arguments: (any(),[{_,non_neg_integer()}],[{_,non_neg_integer()}]) +refine_failing.erl:25:52: The call refine_failing:update_one(F::any(),Ds::{_,non_neg_integer()},[{_,non_neg_integer()},...]) will never return since it differs in the 2nd argument from the success typing arguments: (any(),[{_,non_neg_integer()}],[{_,non_neg_integer()}]) diff --git a/lib/dialyzer/test/small_SUITE_data/results/relevant_record_warning b/lib/dialyzer/test/small_SUITE_data/results/relevant_record_warning index ea3ac92d96..67d07abce2 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/relevant_record_warning +++ b/lib/dialyzer/test/small_SUITE_data/results/relevant_record_warning @@ -1,3 +1,3 @@ -relevant_record_warning.erl:22: Function test/1 has no local return -relevant_record_warning.erl:23: Record construction #r{field::<<_:8>>} violates the declared type of field field::'binary' +relevant_record_warning.erl:22:1: Function test/1 has no local return +relevant_record_warning.erl:23:14: Record construction #r{field::<<_:8>>} violates the declared type of field field::'binary' diff --git a/lib/dialyzer/test/small_SUITE_data/results/request1 b/lib/dialyzer/test/small_SUITE_data/results/request1 index 0cf4017403..8e4567c6fa 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/request1 +++ b/lib/dialyzer/test/small_SUITE_data/results/request1 @@ -1,2 +1,2 @@ -request1.erl:8: Expression produces a value of type {'a','b'}, but this value is unmatched +request1.erl:8:5: Expression produces a value of type {'a','b'}, but this value is unmatched diff --git a/lib/dialyzer/test/small_SUITE_data/results/stacktrace b/lib/dialyzer/test/small_SUITE_data/results/stacktrace index c18de09a0e..57ca31333b 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/stacktrace +++ b/lib/dialyzer/test/small_SUITE_data/results/stacktrace @@ -1,5 +1,5 @@ -stacktrace.erl:11: The pattern {'a', 'b'} can never match the type [{atom(),atom(),[any()] | byte(),[{'error_info',map()} | {'file',string()} | {'line',pos_integer()}]}] -stacktrace.erl:19: The pattern ['a', 'b'] can never match the type [{atom(),atom(),[any()] | byte(),[{'error_info',map()} | {'file',string()} | {'line',pos_integer()}]}] -stacktrace.erl:43: The pattern {'a', 'b'} can never match the type [{atom(),atom(),[any()] | byte(),[{'error_info',map()} | {'file',string()} | {'line',pos_integer()}]}] -stacktrace.erl:51: The pattern ['a', 'b'] can never match the type [{atom(),atom(),[any()] | byte(),[{'error_info',map()} | {'file',string()} | {'line',pos_integer()}]}] +stacktrace.erl:11:13: The pattern {'a', 'b'} can never match the type [{atom(),atom(),[any()] | byte(),[{'error_info',map()} | {'file',string()} | {'line',pos_integer()}]}] +stacktrace.erl:19:13: The pattern ['a', 'b'] can never match the type [{atom(),atom(),[any()] | byte(),[{'error_info',map()} | {'file',string()} | {'line',pos_integer()}]}] +stacktrace.erl:43:13: The pattern {'a', 'b'} can never match the type [{atom(),atom(),[any()] | byte(),[{'error_info',map()} | {'file',string()} | {'line',pos_integer()}]}] +stacktrace.erl:51:13: The pattern ['a', 'b'] can never match the type [{atom(),atom(),[any()] | byte(),[{'error_info',map()} | {'file',string()} | {'line',pos_integer()}]}] diff --git a/lib/dialyzer/test/small_SUITE_data/results/suppress_request b/lib/dialyzer/test/small_SUITE_data/results/suppress_request index 18e82b7972..f0336fac4d 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/suppress_request +++ b/lib/dialyzer/test/small_SUITE_data/results/suppress_request @@ -1,6 +1,6 @@ -suppress_request.erl:21: Expression produces a value of type {'a','b'}, but this value is unmatched -suppress_request.erl:25: Expression produces a value of type {'a','b'}, but this value is unmatched -suppress_request.erl:35: Function test3_b/0 has no local return -suppress_request.erl:39: Guard test 2 =:= A::fun((none()) -> no_return()) can never succeed -suppress_request.erl:7: Type specification suppress_request:test1('a' | 'b') -> 'ok' is a subtype of the success typing: suppress_request:test1('a' | 'b' | 'c') -> 'ok' +suppress_request.erl:21:5: Expression produces a value of type {'a','b'}, but this value is unmatched +suppress_request.erl:25:5: Expression produces a value of type {'a','b'}, but this value is unmatched +suppress_request.erl:35:1: Function test3_b/0 has no local return +suppress_request.erl:39:5: Guard test 2 =:= A::fun((none()) -> no_return()) can never succeed +suppress_request.erl:7:2: Type specification suppress_request:test1('a' | 'b') -> 'ok' is a subtype of the success typing: suppress_request:test1('a' | 'b' | 'c') -> 'ok' diff --git a/lib/dialyzer/test/small_SUITE_data/results/trec b/lib/dialyzer/test/small_SUITE_data/results/trec index b95df1e6ef..7cb7dc4311 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/trec +++ b/lib/dialyzer/test/small_SUITE_data/results/trec @@ -1,7 +1,7 @@ -trec.erl:28: Function test/0 has no local return -trec.erl:29: The call trec:mk_foo_loc(42,any()) will never return since it differs in the 1st argument from the success typing arguments: ('undefined',atom()) -trec.erl:31: Function mk_foo_loc/2 has no local return -trec.erl:32: Record construction violates the declared type for #foo{} since variable A cannot be of type atom() -trec.erl:38: Function mk_foo_exp/2 has no local return -trec.erl:39: Record construction violates the declared type for #foo{} since variable A cannot be of type atom() +trec.erl:28:1: Function test/0 has no local return +trec.erl:29:15: The call trec:mk_foo_loc(42,any()) will never return since it differs in the 1st argument from the success typing arguments: ('undefined',atom()) +trec.erl:31:1: Function mk_foo_loc/2 has no local return +trec.erl:32:22: Record construction violates the declared type for #foo{} since variable A cannot be of type atom() +trec.erl:38:1: Function mk_foo_exp/2 has no local return +trec.erl:39:22: Record construction violates the declared type for #foo{} since variable A cannot be of type atom() diff --git a/lib/dialyzer/test/small_SUITE_data/results/try2 b/lib/dialyzer/test/small_SUITE_data/results/try2 index e96cb22057..14306bb756 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/try2 +++ b/lib/dialyzer/test/small_SUITE_data/results/try2 @@ -1,2 +1,2 @@ -try2.erl:33: Function run3/2 has no local return +try2.erl:33:1: Function run3/2 has no local return diff --git a/lib/dialyzer/test/small_SUITE_data/results/tuple1 b/lib/dialyzer/test/small_SUITE_data/results/tuple1 index 1b5ed49b56..66c53e6fca 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/tuple1 +++ b/lib/dialyzer/test/small_SUITE_data/results/tuple1 @@ -1,5 +1,5 @@ -tuple1.erl:13: Function t1/2 has no local return -tuple1.erl:14: The call lists:mapfoldl(fun((_,_) -> 'a' | 'b'),X::any(),List::nonempty_maybe_improper_list()) will never return since the success typing arguments are (fun((_,_) -> {_,_}),any(),[any()]) -tuple1.erl:19: Function t3/2 has no local return -tuple1.erl:20: The call lists:mapfoldl(fun((_) -> 1),X::any(),List::nonempty_maybe_improper_list()) will never return since it differs in the 1st argument from the success typing arguments: (fun((_,_) -> {_,_}),any(),[any()]) +tuple1.erl:13:1: Function t1/2 has no local return +tuple1.erl:14:3: The call lists:mapfoldl(fun((_,_) -> 'a' | 'b'),X::any(),List::nonempty_maybe_improper_list()) will never return since the success typing arguments are (fun((_,_) -> {_,_}),any(),[any()]) +tuple1.erl:19:1: Function t3/2 has no local return +tuple1.erl:20:18: The call lists:mapfoldl(fun((_) -> 1),X::any(),List::nonempty_maybe_improper_list()) will never return since it differs in the 1st argument from the success typing arguments: (fun((_,_) -> {_,_}),any(),[any()]) diff --git a/lib/dialyzer/test/small_SUITE_data/results/tuple_set_crash b/lib/dialyzer/test/small_SUITE_data/results/tuple_set_crash index 7fd1f304cb..4d72467a06 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/tuple_set_crash +++ b/lib/dialyzer/test/small_SUITE_data/results/tuple_set_crash @@ -1,14 +1,14 @@ -tuple_set_crash.erl:103: Invalid type specification for function tuple_set_crash:parse_device_properties/1. The success typing is (<<_:48>>) -> [{'controller_description',binary()} | {'controller_name',binary()} | {'controller_status',byte()} | {'fw_version',<<_:24>>}] -tuple_set_crash.erl:123: Invalid type specification for function tuple_set_crash:parse_video_target_info/1. The success typing is (<<_:48>>) -> [{'status',byte()} | {'target_id',non_neg_integer()},...] -tuple_set_crash.erl:127: Invalid type specification for function tuple_set_crash:parse_audio_target_info/1. The success typing is (<<_:48>>) -> [{'master_volume',char()} | {'status',byte()} | {'target_id',non_neg_integer()},...] -tuple_set_crash.erl:138: Invalid type specification for function tuple_set_crash:parse_av_device_info/1. The success typing is (<<_:48>>) -> [{'address',byte()} | {'device_id',non_neg_integer()} | {'model',binary()} | {'status',byte()},...] -tuple_set_crash.erl:143: The pattern <<TargetId:32/integer-little-unit:1,Rest1/binary>> can never match the type <<_:8>> -tuple_set_crash.erl:155: Invalid type specification for function tuple_set_crash:parse_video_output_info/1. The success typing is (<<_:48>>) -> [{'audio_volume',char()} | {'display_type',binary()} | {'output_id',non_neg_integer()},...] -tuple_set_crash.erl:160: The pattern <<DeviceId:32/integer-little-unit:1,Rest1/binary>> can never match the type <<_:8>> -tuple_set_crash.erl:171: Invalid type specification for function tuple_set_crash:parse_audio_output_info/1. The success typing is (<<_:48>>) -> [{'output_id',non_neg_integer()},...] -tuple_set_crash.erl:176: The pattern <<DeviceId:32/integer-little-unit:1,Rest1/binary>> can never match the type <<_:8>> -tuple_set_crash.erl:179: The pattern <<AudioVolume:16/integer-little-unit:1,Rest2/binary>> can never match the type <<_:8>> -tuple_set_crash.erl:182: The pattern <<Delay:16/integer-little-unit:1,_Padding/binary>> can never match the type <<_:8>> -tuple_set_crash.erl:62: The pattern {'play_list', _Playlist} can never match the type 'ok' | {'device_properties',[{atom(),_}]} | {'error',[{atom(),_}]} -tuple_set_crash.erl:64: The pattern {'error', 17} can never match the type 'ok' | {'device_properties',[{atom(),_}]} | {'error',[{atom(),_}]} +tuple_set_crash.erl:103:2: Invalid type specification for function tuple_set_crash:parse_device_properties/1. The success typing is (<<_:48>>) -> [{'controller_description',binary()} | {'controller_name',binary()} | {'controller_status',byte()} | {'fw_version',<<_:24>>}] +tuple_set_crash.erl:123:2: Invalid type specification for function tuple_set_crash:parse_video_target_info/1. The success typing is (<<_:48>>) -> [{'status',byte()} | {'target_id',non_neg_integer()},...] +tuple_set_crash.erl:127:2: Invalid type specification for function tuple_set_crash:parse_audio_target_info/1. The success typing is (<<_:48>>) -> [{'master_volume',char()} | {'status',byte()} | {'target_id',non_neg_integer()},...] +tuple_set_crash.erl:138:2: Invalid type specification for function tuple_set_crash:parse_av_device_info/1. The success typing is (<<_:48>>) -> [{'address',byte()} | {'device_id',non_neg_integer()} | {'model',binary()} | {'status',byte()},...] +tuple_set_crash.erl:141:25: The pattern <<TargetId:32/integer-little-unit:1,Rest1/binary>> can never match the type <<_:8>> +tuple_set_crash.erl:155:2: Invalid type specification for function tuple_set_crash:parse_video_output_info/1. The success typing is (<<_:48>>) -> [{'audio_volume',char()} | {'display_type',binary()} | {'output_id',non_neg_integer()},...] +tuple_set_crash.erl:158:25: The pattern <<DeviceId:32/integer-little-unit:1,Rest1/binary>> can never match the type <<_:8>> +tuple_set_crash.erl:171:2: Invalid type specification for function tuple_set_crash:parse_audio_output_info/1. The success typing is (<<_:48>>) -> [{'output_id',non_neg_integer()},...] +tuple_set_crash.erl:174:25: The pattern <<DeviceId:32/integer-little-unit:1,Rest1/binary>> can never match the type <<_:8>> +tuple_set_crash.erl:177:25: The pattern <<AudioVolume:16/integer-little-unit:1,Rest2/binary>> can never match the type <<_:8>> +tuple_set_crash.erl:180:25: The pattern <<Delay:16/integer-little-unit:1,_Padding/binary>> can never match the type <<_:8>> +tuple_set_crash.erl:62:2: The pattern {'play_list', _Playlist} can never match the type 'ok' | {'device_properties',[{atom(),_}]} | {'error',[{atom(),_}]} +tuple_set_crash.erl:64:2: The pattern {'error', 17} can never match the type 'ok' | {'device_properties',[{atom(),_}]} | {'error',[{atom(),_}]} diff --git a/lib/dialyzer/test/small_SUITE_data/results/types_arity b/lib/dialyzer/test/small_SUITE_data/results/types_arity index 02641bd167..fae7455996 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/types_arity +++ b/lib/dialyzer/test/small_SUITE_data/results/types_arity @@ -1,2 +1,2 @@ -types_arity.erl:16: Invalid type specification for function types_arity:test2/0. The success typing is () -> {'node','a','nil','nil'} +types_arity.erl:16:2: Invalid type specification for function types_arity:test2/0. The success typing is () -> {'node','a','nil','nil'} diff --git a/lib/dialyzer/test/small_SUITE_data/results/union_paren b/lib/dialyzer/test/small_SUITE_data/results/union_paren index 1766773f2d..a2b99eec5d 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/union_paren +++ b/lib/dialyzer/test/small_SUITE_data/results/union_paren @@ -1,25 +1,25 @@ -union_paren.erl:20: Function r1/0 has no local return -union_paren.erl:21: Record construction #r1{f1::[4,...],f2::'undefined',f3::'undefined',f8::float()} violates the declared type of field f2::[atom() | pid() | integer()] and f3::[atom() | pid() | integer()] and f8::[atom() | pid() | integer()] -union_paren.erl:23: Function t1/0 has no local return -union_paren.erl:24: The call union_paren:t1(3.14) breaks the contract ((A::integer()) | (B::atom())) -> integer() -union_paren.erl:30: Function t2/0 has no local return -union_paren.erl:31: The call union_paren:t2(3.14) breaks the contract (integer() | atom()) -> integer() -union_paren.erl:37: Function t3/0 has no local return -union_paren.erl:38: The pattern 3.14 can never match the type atom() | integer() -union_paren.erl:44: Function c1/0 has no local return -union_paren.erl:45: The call union_paren:c1({'r0', 'a', 'undefined', 'undefined'}) breaks the contract (#r0{f1::integer() | pid()}) -> atom() -union_paren.erl:51: Function c2/0 has no local return -union_paren.erl:52: The call union_paren:c2({'r0', 'a', 'undefined', 'undefined'}) breaks the contract (#r0{f1::A::integer() | pid()}) -> atom() -union_paren.erl:58: Function c3/0 has no local return -union_paren.erl:59: The call union_paren:c3({'r0', 'a', 'undefined', 'undefined'}) breaks the contract (#r0{f1::(A::integer()) | (B::pid())}) -> atom() -union_paren.erl:65: Function c4/0 has no local return -union_paren.erl:66: The call union_paren:c4({'r0', 'a', 'undefined', 'undefined'}) breaks the contract (#r0{f1::X::(A::integer()) | (B::pid())}) -> atom() -union_paren.erl:72: Function c5/0 has no local return -union_paren.erl:73: The call union_paren:c5({'r1', ['a'], [1], ['a'], ['u']}) breaks the contract (#r1{f1::[integer()] | [pid()]}) -> atom() -union_paren.erl:79: Function c6/0 has no local return -union_paren.erl:80: The call union_paren:c6({'r1', ['a'], [1], ['a'], ['u']}) breaks the contract (#r1{f1::A::[integer()] | [pid()]}) -> atom() -union_paren.erl:86: Function c7/0 has no local return -union_paren.erl:87: The call union_paren:c7({'r1', ['a'], [1], ['a'], ['u']}) breaks the contract (#r1{f1::(A::[integer()]) | (B::[pid()])}) -> atom() -union_paren.erl:93: Function c8/0 has no local return -union_paren.erl:94: The call union_paren:c8({'r1', ['a'], [1], ['a'], ['u']}) breaks the contract (#r1{f1::X::(A::[integer()]) | (B::[pid()])}) -> atom() +union_paren.erl:20:1: Function r1/0 has no local return +union_paren.erl:21:5: Record construction #r1{f1::[4,...],f2::'undefined',f3::'undefined',f8::float()} violates the declared type of field f2::[atom() | pid() | integer()] and f3::[atom() | pid() | integer()] and f8::[atom() | pid() | integer()] +union_paren.erl:23:1: Function t1/0 has no local return +union_paren.erl:24:8: The call union_paren:t1(3.14) breaks the contract ((A::integer()) | (B::atom())) -> integer() +union_paren.erl:30:1: Function t2/0 has no local return +union_paren.erl:31:8: The call union_paren:t2(3.14) breaks the contract (integer() | atom()) -> integer() +union_paren.erl:37:1: Function t3/0 has no local return +union_paren.erl:38:5: The pattern 3.14 can never match the type atom() | integer() +union_paren.erl:44:1: Function c1/0 has no local return +union_paren.erl:45:8: The call union_paren:c1({'r0', 'a', 'undefined', 'undefined'}) breaks the contract (#r0{f1::integer() | pid()}) -> atom() +union_paren.erl:51:1: Function c2/0 has no local return +union_paren.erl:52:8: The call union_paren:c2({'r0', 'a', 'undefined', 'undefined'}) breaks the contract (#r0{f1::A::integer() | pid()}) -> atom() +union_paren.erl:58:1: Function c3/0 has no local return +union_paren.erl:59:8: The call union_paren:c3({'r0', 'a', 'undefined', 'undefined'}) breaks the contract (#r0{f1::(A::integer()) | (B::pid())}) -> atom() +union_paren.erl:65:1: Function c4/0 has no local return +union_paren.erl:66:8: The call union_paren:c4({'r0', 'a', 'undefined', 'undefined'}) breaks the contract (#r0{f1::X::(A::integer()) | (B::pid())}) -> atom() +union_paren.erl:72:1: Function c5/0 has no local return +union_paren.erl:73:8: The call union_paren:c5({'r1', ['a'], [1], ['a'], ['u']}) breaks the contract (#r1{f1::[integer()] | [pid()]}) -> atom() +union_paren.erl:79:1: Function c6/0 has no local return +union_paren.erl:80:8: The call union_paren:c6({'r1', ['a'], [1], ['a'], ['u']}) breaks the contract (#r1{f1::A::[integer()] | [pid()]}) -> atom() +union_paren.erl:86:1: Function c7/0 has no local return +union_paren.erl:87:8: The call union_paren:c7({'r1', ['a'], [1], ['a'], ['u']}) breaks the contract (#r1{f1::(A::[integer()]) | (B::[pid()])}) -> atom() +union_paren.erl:93:1: Function c8/0 has no local return +union_paren.erl:94:8: The call union_paren:c8({'r1', ['a'], [1], ['a'], ['u']}) breaks the contract (#r1{f1::X::(A::[integer()]) | (B::[pid()])}) -> atom() diff --git a/lib/dialyzer/test/small_SUITE_data/results/unused_cases b/lib/dialyzer/test/small_SUITE_data/results/unused_cases index cafe1c042b..f33e6f89d8 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/unused_cases +++ b/lib/dialyzer/test/small_SUITE_data/results/unused_cases @@ -1,4 +1,4 @@ -unused_cases.erl:21: The variable OTHER can never match since previous clauses completely covered the type {42,42} -unused_cases.erl:27: The pattern 'weird' can never match the type 'false' -unused_cases.erl:35: The variable OTHER can never match since previous clauses completely covered the type boolean() +unused_cases.erl:21:5: The variable OTHER can never match since previous clauses completely covered the type {42,42} +unused_cases.erl:27:5: The pattern 'weird' can never match the type 'false' +unused_cases.erl:35:5: The variable OTHER can never match since previous clauses completely covered the type boolean() diff --git a/lib/dialyzer/test/small_SUITE_data/results/unused_clauses b/lib/dialyzer/test/small_SUITE_data/results/unused_clauses index 4603e888c1..73c4961233 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/unused_clauses +++ b/lib/dialyzer/test/small_SUITE_data/results/unused_clauses @@ -1,3 +1,3 @@ -unused_clauses.erl:16: Guard test is_integer(X::{42}) can never succeed -unused_clauses.erl:18: The variable X can never match since previous clauses completely covered the type 'atom' | {42} +unused_clauses.erl:16:11: Guard test is_integer(X::{42}) can never succeed +unused_clauses.erl:18:1: The variable X can never match since previous clauses completely covered the type 'atom' | {42} diff --git a/lib/dialyzer/test/small_SUITE_data/results/unused_funs b/lib/dialyzer/test/small_SUITE_data/results/unused_funs index c468457ead..d4f2eeebfc 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/unused_funs +++ b/lib/dialyzer/test/small_SUITE_data/results/unused_funs @@ -1,5 +1,5 @@ -unused_funs.erl:10: The pattern 'error' can never match the type 'other_error' -unused_funs.erl:15: Function not_used/0 will never be called -unused_funs.erl:19: Function foo/1 will never be called -unused_funs.erl:7: Function test/0 has no local return +unused_funs.erl:10:9: The pattern 'error' can never match the type 'other_error' +unused_funs.erl:15:1: Function not_used/0 will never be called +unused_funs.erl:19:1: Function foo/1 will never be called +unused_funs.erl:7:1: Function test/0 has no local return diff --git a/lib/dialyzer/test/small_SUITE_data/results/wsp_pdu b/lib/dialyzer/test/small_SUITE_data/results/wsp_pdu new file mode 100644 index 0000000000..73a2c3b339 --- /dev/null +++ b/lib/dialyzer/test/small_SUITE_data/results/wsp_pdu @@ -0,0 +1,25 @@ + +wsp_pdu.erl:1063:1: The pattern [H | Hs] can never match the type [] +wsp_pdu.erl:1162:40: The call wsp_pdu:parse_push_flag(Value::[any()]) will never return since it differs in the 1st argument from the success typing arguments: (integer()) +wsp_pdu.erl:2400:1: Function decode_retry_after/2 has no local return +wsp_pdu.erl:2403:32: The call wsp_pdu:d_date(Data1::binary()) will never return since it differs in the 1st argument from the success typing arguments: (integer() | {'short',binary()}) +wsp_pdu.erl:2406:12: Guard test is_integer(Sec::{[byte()] | byte() | {'long',binary()} | {'short',binary()},binary()}) can never succeed +wsp_pdu.erl:2408:3: The pattern {'short', Data2} can never match the type {[byte()] | byte() | {'long',binary()} | {'short',binary()},binary()} +wsp_pdu.erl:2755:1: Function parse_push_flag/1 has no local return +wsp_pdu.erl:2756:38: The call erlang:integer_to_list(Value::[any()]) breaks the contract (Integer) -> string() when Integer :: integer() +wsp_pdu.erl:2875:36: The call wsp_pdu:d_text_string(Data::byte()) will never return since it differs in the 1st argument from the success typing arguments: (binary()) +wsp_pdu.erl:2976:32: The call wsp_pdu:d_q_value(QData::byte()) will never return since it differs in the 1st argument from the success typing arguments: (<<_:8,_:_*8>>) +wsp_pdu.erl:3336:31: The call wsp_pdu:encode_typed_field(Ver::any(),'Q-value',ParamValue::any()) will never return since it differs in the 2nd argument from the success typing arguments: (any(),'Constrained-encoding' | 'Date-value' | 'No-value' | 'Short-integer' | 'Text-string' | 'Text-value' | 'Well-known-charset',any()) +wsp_pdu.erl:3342:31: The call wsp_pdu:encode_typed_field(Ver::any(),'Ver-value',ParamValue::any()) will never return since it differs in the 2nd argument from the success typing arguments: (any(),'Constrained-encoding' | 'Date-value' | 'No-value' | 'Short-integer' | 'Text-string' | 'Text-value' | 'Well-known-charset',any()) +wsp_pdu.erl:3349:31: The call wsp_pdu:encode_typed_field(Ver::any(),'Integer-value',ParamValue::any()) will never return since it differs in the 2nd argument from the success typing arguments: (any(),'Constrained-encoding' | 'Date-value' | 'No-value' | 'Short-integer' | 'Text-string' | 'Text-value' | 'Well-known-charset',any()) +wsp_pdu.erl:3367:31: The call wsp_pdu:encode_typed_field(Ver::any(),'Field-name',ParamValue::any()) will never return since it differs in the 2nd argument from the success typing arguments: (any(),'Constrained-encoding' | 'Date-value' | 'No-value' | 'Short-integer' | 'Text-string' | 'Text-value' | 'Well-known-charset',any()) +wsp_pdu.erl:3405:31: The call wsp_pdu:encode_typed_field(Ver::any(),'Delta-seconds-value',ParamValue::any()) will never return since it differs in the 2nd argument from the success typing arguments: (any(),'Constrained-encoding' | 'Date-value' | 'No-value' | 'Short-integer' | 'Text-string' | 'Text-value' | 'Well-known-charset',any()) +wsp_pdu.erl:3437:31: The call wsp_pdu:encode_typed_field(Ver::any(),'Integer-value',ParamValue::any()) will never return since it differs in the 2nd argument from the success typing arguments: (any(),'Constrained-encoding' | 'Date-value' | 'No-value' | 'Short-integer' | 'Text-string' | 'Text-value' | 'Well-known-charset',any()) +wsp_pdu.erl:3455:39: The call wsp_pdu:decode_typed_field('Version-value',Data::binary(),Version::any()) will never return since it differs in the 1st argument from the success typing arguments: ('Constrained-encoding' | 'Date-value' | 'Delta-seconds-value' | 'Field-name' | 'No-value' | 'Q-value' | 'Short-integer' | 'Text-string' | 'Text-value' | 'Well-known-charset',binary(),any()) +wsp_pdu.erl:3459:39: The call wsp_pdu:decode_typed_field('Integer-value',Data::binary(),Version::any()) will never return since it differs in the 1st argument from the success typing arguments: ('Constrained-encoding' | 'Date-value' | 'Delta-seconds-value' | 'Field-name' | 'No-value' | 'Q-value' | 'Short-integer' | 'Text-string' | 'Text-value' | 'Well-known-charset',binary(),any()) +wsp_pdu.erl:3531:39: The call wsp_pdu:decode_typed_field('Integer-value',Data::binary(),Version::any()) will never return since it differs in the 1st argument from the success typing arguments: ('Constrained-encoding' | 'Date-value' | 'Delta-seconds-value' | 'Field-name' | 'No-value' | 'Q-value' | 'Short-integer' | 'Text-string' | 'Text-value' | 'Well-known-charset',binary(),any()) +wsp_pdu.erl:3593:2: The pattern 'Delta-Seconds-value' can never match the type 'Delta-seconds-value' | 'Field-name' | 'Integer-value' | 'No-value' | 'Q-value' | 'Ver-value' +wsp_pdu.erl:4844:36: The call wsp_pdu:d_long('data') will never return since it differs in the 1st argument from the success typing arguments: (binary()) +wsp_pdu.erl:510:2: The variable _ can never match since previous clauses completely covered the type 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 +wsp_pdu.erl:512:2: The variable _ can never match since previous clauses completely covered the type 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 +wsp_pdu.erl:5265:22: Call to missing or unexported function inet:ip_to_bytes/1 diff --git a/lib/dialyzer/test/small_SUITE_data/results/zero_tuple b/lib/dialyzer/test/small_SUITE_data/results/zero_tuple index bf5ec5cd6e..314f2a1a36 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/zero_tuple +++ b/lib/dialyzer/test/small_SUITE_data/results/zero_tuple @@ -1,5 +1,5 @@ -zero_tuple.erl:4: Function t1/0 has no local return -zero_tuple.erl:5: The pattern {} can never match the type 'a' -zero_tuple.erl:8: Function t2/0 has no local return -zero_tuple.erl:9: The pattern 'b' can never match the type 'a' +zero_tuple.erl:4:1: Function t1/0 has no local return +zero_tuple.erl:5:3: The pattern {} can never match the type 'a' +zero_tuple.erl:8:1: Function t2/0 has no local return +zero_tuple.erl:9:3: The pattern 'b' can never match the type 'a' diff --git a/lib/dialyzer/test/specdiffs_SUITE_data/results/iodata b/lib/dialyzer/test/specdiffs_SUITE_data/results/iodata index 3fb12fe000..d6e24fe277 100644 --- a/lib/dialyzer/test/specdiffs_SUITE_data/results/iodata +++ b/lib/dialyzer/test/specdiffs_SUITE_data/results/iodata @@ -1,3 +1,3 @@ -iodata.erl:7: The specification for iodata:encode/2 states that the function might also return binary() but the inferred return is nonempty_maybe_improper_list(<<_:8,_:_*8>> | nonempty_maybe_improper_list(<<_:8,_:_*8>> | nonempty_maybe_improper_list(any(),<<_:8,_:_*8>> | []) | byte(),<<_:8,_:_*8>> | []) | integer(),<<_:8,_:_*8>> | []) | integer() -iodata.erl:7: The success typing for iodata:encode/2 implies that the function might also return integer() but the specification return is binary() | maybe_improper_list(binary() | maybe_improper_list(any(),binary() | []) | byte(),binary() | []) +iodata.erl:7:2: The specification for iodata:encode/2 states that the function might also return binary() but the inferred return is nonempty_maybe_improper_list(<<_:8,_:_*8>> | nonempty_maybe_improper_list(<<_:8,_:_*8>> | nonempty_maybe_improper_list(any(),<<_:8,_:_*8>> | []) | byte(),<<_:8,_:_*8>> | []) | integer(),<<_:8,_:_*8>> | []) | integer() +iodata.erl:7:2: The success typing for iodata:encode/2 implies that the function might also return integer() but the specification return is binary() | maybe_improper_list(binary() | maybe_improper_list(any(),binary() | []) | byte(),binary() | []) diff --git a/lib/dialyzer/test/specdiffs_SUITE_data/results/iolist b/lib/dialyzer/test/specdiffs_SUITE_data/results/iolist index ca556f017c..e348bbbd0b 100644 --- a/lib/dialyzer/test/specdiffs_SUITE_data/results/iolist +++ b/lib/dialyzer/test/specdiffs_SUITE_data/results/iolist @@ -1,2 +1,2 @@ -iolist.erl:7: The success typing for iolist:encode/2 implies that the function might also return integer() but the specification return is maybe_improper_list(binary() | maybe_improper_list(any(),binary() | []) | byte(),binary() | []) +iolist.erl:7:2: The success typing for iolist:encode/2 implies that the function might also return integer() but the specification return is maybe_improper_list(binary() | maybe_improper_list(any(),binary() | []) | byte(),binary() | []) diff --git a/lib/dialyzer/test/specdiffs_SUITE_data/results/overloaded b/lib/dialyzer/test/specdiffs_SUITE_data/results/overloaded index f68917c009..b84cdebd93 100644 --- a/lib/dialyzer/test/specdiffs_SUITE_data/results/overloaded +++ b/lib/dialyzer/test/specdiffs_SUITE_data/results/overloaded @@ -1,6 +1,6 @@ -overloaded.erl:12: Type specification overloaded:u('a' | 'b' | 'c') -> term() is a subtype of the success typing: overloaded:u(_) -> any() -overloaded.erl:17: The success typing for overloaded:v/1 implies that the function might also return {'ok','term'} but the specification return is 'ok' -overloaded.erl:22: Type specification overloaded:x(_) -> {'ok','term'} | 'ok' is a supertype of the success typing: overloaded:x('a' | 'b') -> 'ok' | {'ok','term'} -overloaded.erl:29: The success typing for overloaded:over/1 implies that the function might also return 'ffyy3' but the specification return is 'ffyy1' | {'ffyy2',integer()} -overloaded.erl:7: Type specification overloaded:t('a' | 'b') -> term() is a subtype of the success typing: overloaded:t('a' | 'b' | 'c') -> any() +overloaded.erl:12:2: Type specification overloaded:u('a' | 'b' | 'c') -> term() is a subtype of the success typing: overloaded:u(_) -> any() +overloaded.erl:17:2: The success typing for overloaded:v/1 implies that the function might also return {'ok','term'} but the specification return is 'ok' +overloaded.erl:22:2: Type specification overloaded:x(_) -> {'ok','term'} | 'ok' is a supertype of the success typing: overloaded:x('a' | 'b') -> 'ok' | {'ok','term'} +overloaded.erl:29:2: The success typing for overloaded:over/1 implies that the function might also return 'ffyy3' but the specification return is 'ffyy1' | {'ffyy2',integer()} +overloaded.erl:7:2: Type specification overloaded:t('a' | 'b') -> term() is a subtype of the success typing: overloaded:t('a' | 'b' | 'c') -> any() diff --git a/lib/dialyzer/test/underspecs_SUITE_data/results/arr b/lib/dialyzer/test/underspecs_SUITE_data/results/arr index 9497d12eec..7f20d8a111 100644 --- a/lib/dialyzer/test/underspecs_SUITE_data/results/arr +++ b/lib/dialyzer/test/underspecs_SUITE_data/results/arr @@ -1,4 +1,4 @@ -arr.erl:14: Type specification arr:test2(array:array(T),non_neg_integer(),T) -> array:array(T) is a supertype of the success typing: arr:test2(array:array(_),pos_integer(),_) -> array:array(_) -arr.erl:24: Type specification arr:test4(array:array(T),non_neg_integer(),_) -> array:array(T) is a supertype of the success typing: arr:test4(array:array(_),pos_integer(),_) -> array:array(_) -arr.erl:29: Type specification arr:test5(array:array(T),non_neg_integer(),T) -> array:array(T) is a supertype of the success typing: arr:test5(array:array(_),non_neg_integer(),integer()) -> array:array(_) +arr.erl:14:2: Type specification arr:test2(array:array(T),non_neg_integer(),T) -> array:array(T) is a supertype of the success typing: arr:test2(array:array(_),pos_integer(),_) -> array:array(_) +arr.erl:24:2: Type specification arr:test4(array:array(T),non_neg_integer(),_) -> array:array(T) is a supertype of the success typing: arr:test4(array:array(_),pos_integer(),_) -> array:array(_) +arr.erl:29:2: Type specification arr:test5(array:array(T),non_neg_integer(),T) -> array:array(T) is a supertype of the success typing: arr:test5(array:array(_),non_neg_integer(),integer()) -> array:array(_) diff --git a/lib/dialyzer/test/underspecs_SUITE_data/results/remote b/lib/dialyzer/test/underspecs_SUITE_data/results/remote index 1e0cda3bde..f14b276214 100644 --- a/lib/dialyzer/test/underspecs_SUITE_data/results/remote +++ b/lib/dialyzer/test/underspecs_SUITE_data/results/remote @@ -1,9 +1,9 @@ -remotes1.erl:17: The specification for remotes1:foo5/1 states that the function might also return 'ko' but the inferred return is 'ok' -remotes1.erl:20: Type specification remotes1:foo6('ok' | 'ko') -> 'ok' is a supertype of the success typing: remotes1:foo6('ok') -> 'ok' -remotes1.erl:25: The specification for remotes1:foo7/1 states that the function might also return 'ko' but the inferred return is 'ok' -remotes1.erl:28: Type specification remotes1:foo8(local_type_42()) -> 'ok' is a supertype of the success typing: remotes1:foo8('ok') -> 'ok' -remotes1.erl:33: The specification for remotes1:foo9/1 states that the function might also return 'ko' but the inferred return is 'ok' -remotes1.erl:36: Type specification remotes1:foo10(local_and_known_remote_type_42()) -> 'ok' is a supertype of the success typing: remotes1:foo10('ok') -> 'ok' -remotes1.erl:49: Type specification remotes1:foo13('ok') -> local_and_unknown_remote_type_42() is a supertype of the success typing: remotes1:foo13('ok') -> 'ok' -remotes1.erl:52: Type specification remotes1:foo14(local_and_unknown_remote_type_42()) -> 'ok' is a supertype of the success typing: remotes1:foo14('ok') -> 'ok' +remotes1.erl:17:2: The specification for remotes1:foo5/1 states that the function might also return 'ko' but the inferred return is 'ok' +remotes1.erl:20:2: Type specification remotes1:foo6('ok' | 'ko') -> 'ok' is a supertype of the success typing: remotes1:foo6('ok') -> 'ok' +remotes1.erl:25:2: The specification for remotes1:foo7/1 states that the function might also return 'ko' but the inferred return is 'ok' +remotes1.erl:28:2: Type specification remotes1:foo8(local_type_42()) -> 'ok' is a supertype of the success typing: remotes1:foo8('ok') -> 'ok' +remotes1.erl:33:2: The specification for remotes1:foo9/1 states that the function might also return 'ko' but the inferred return is 'ok' +remotes1.erl:36:2: Type specification remotes1:foo10(local_and_known_remote_type_42()) -> 'ok' is a supertype of the success typing: remotes1:foo10('ok') -> 'ok' +remotes1.erl:49:2: Type specification remotes1:foo13('ok') -> local_and_unknown_remote_type_42() is a supertype of the success typing: remotes1:foo13('ok') -> 'ok' +remotes1.erl:52:2: Type specification remotes1:foo14(local_and_unknown_remote_type_42()) -> 'ok' is a supertype of the success typing: remotes1:foo14('ok') -> 'ok' diff --git a/lib/dialyzer/test/unmatched_returns_SUITE_data/results/lc_warnings b/lib/dialyzer/test/unmatched_returns_SUITE_data/results/lc_warnings index 24b44c1b5c..44913ba8b7 100644 --- a/lib/dialyzer/test/unmatched_returns_SUITE_data/results/lc_warnings +++ b/lib/dialyzer/test/unmatched_returns_SUITE_data/results/lc_warnings @@ -1,5 +1,5 @@ -lc_warnings.erl:32: Expression produces a value of type [opaque_atom_adt:opaque_atom()], but this value is unmatched -lc_warnings.erl:43: Expression produces a value of type [array:array(_)], but this value is unmatched -lc_warnings.erl:65: Expression produces a value of type [lc_warnings:opaque_tuple()], but this value is unmatched -lc_warnings.erl:7: Expression produces a value of type ['ok' | {'error',atom()}], but this value is unmatched +lc_warnings.erl:32:5: Expression produces a value of type [opaque_atom_adt:opaque_atom()], but this value is unmatched +lc_warnings.erl:43:5: Expression produces a value of type [array:array(_)], but this value is unmatched +lc_warnings.erl:65:5: Expression produces a value of type [lc_warnings:opaque_tuple()], but this value is unmatched +lc_warnings.erl:7:5: Expression produces a value of type ['ok' | {'error',atom()}], but this value is unmatched diff --git a/lib/dialyzer/test/user_SUITE_data/results/gcpFlowControl b/lib/dialyzer/test/user_SUITE_data/results/gcpFlowControl index 7938c53fc6..7bf005d8ad 100644 --- a/lib/dialyzer/test/user_SUITE_data/results/gcpFlowControl +++ b/lib/dialyzer/test/user_SUITE_data/results/gcpFlowControl @@ -1,2 +1,2 @@ -gcpFlowControl.erl:171: The pattern <Key, 'errors', X> can never match the type <_,'available' | 'bucket' | 'rejectable' | 'rejects' | 'window',0 | 1 | 20> +gcpFlowControl.erl:171:2: The pattern <Key, 'errors', X> can never match the type <_,'available' | 'bucket' | 'rejectable' | 'rejects' | 'window',0 | 1 | 20> diff --git a/lib/dialyzer/test/user_SUITE_data/results/nowarn_unused_function_1 b/lib/dialyzer/test/user_SUITE_data/results/nowarn_unused_function_1 index de416455e2..2734b4b124 100644 --- a/lib/dialyzer/test/user_SUITE_data/results/nowarn_unused_function_1 +++ b/lib/dialyzer/test/user_SUITE_data/results/nowarn_unused_function_1 @@ -1,2 +1,2 @@ -nowarn_unused_function_1.erl:17: Function f3/1 will never be called +nowarn_unused_function_1.erl:17:1: Function f3/1 will never be called diff --git a/lib/dialyzer/test/user_SUITE_data/results/nowarn_unused_function_3 b/lib/dialyzer/test/user_SUITE_data/results/nowarn_unused_function_3 index 8ae78673d5..ebf5230649 100644 --- a/lib/dialyzer/test/user_SUITE_data/results/nowarn_unused_function_3 +++ b/lib/dialyzer/test/user_SUITE_data/results/nowarn_unused_function_3 @@ -1,3 +1,3 @@ -nowarn_unused_function_3.erl:12: Function f2/1 will never be called -nowarn_unused_function_3.erl:9: Function f1/1 will never be called +nowarn_unused_function_3.erl:12:1: Function f2/1 will never be called +nowarn_unused_function_3.erl:9:1: Function f1/1 will never be called diff --git a/lib/dialyzer/test/user_SUITE_data/results/spvcOrig b/lib/dialyzer/test/user_SUITE_data/results/spvcOrig index 8c57358af0..c41400e023 100644 --- a/lib/dialyzer/test/user_SUITE_data/results/spvcOrig +++ b/lib/dialyzer/test/user_SUITE_data/results/spvcOrig @@ -1,193 +1,193 @@ -spvcOrig.erl:1238: Guard test is_record(Spvc::[] | #spvcObj{},'spvcVcc',25) can never succeed -spvcOrig.erl:1241: Guard test is_record(Spvc::[] | #spvcObj{},'spvcVpc',20) can never succeed -spvcOrig.erl:1244: Guard test is_record(Spvc::[] | #spvcObj{},'spvcVpcPerm',12) can never succeed -spvcOrig.erl:1247: Guard test is_record(Spvc::[] | #spvcObj{},'spvcVccPerm',17) can never succeed -spvcOrig.erl:1250: Guard test is_record(Spvc::[] | #spvcObj{},'spvcTargetVc',6) can never succeed -spvcOrig.erl:1253: Guard test is_record(Spvc::[] | #spvcObj{},'spvcTargetVp',6) can never succeed -spvcOrig.erl:1256: Guard test is_record(Spvc::[] | #spvcObj{},'pchVc',32) can never succeed -spvcOrig.erl:1259: Guard test is_record(Spvc::[] | #spvcObj{},'pchVp',33) can never succeed -spvcOrig.erl:1262: Guard test is_record(Spvc::[] | #spvcObj{},'spvcFr',21) can never succeed -spvcOrig.erl:1265: Guard test is_record(Spvc::[] | #spvcObj{},'spvcFrPerm',6) can never succeed -spvcOrig.erl:1268: The pattern {If_Value, _, _, _} can never match the type [] | #spvcObj{} -spvcOrig.erl:1270: The pattern {If_Value, _, _} can never match the type [] | #spvcObj{} -spvcOrig.erl:1272: The pattern {If_Value, _} can never match the type [] | #spvcObj{} -spvcOrig.erl:1274: The pattern [If_Value | _] can never match the type [] | #spvcObj{} -spvcOrig.erl:1380: The variable _ can never match since previous clauses completely covered the type any() -spvcOrig.erl:1389: The variable _ can never match since previous clauses completely covered the type any() -spvcOrig.erl:1576: Guard test is_record(Row::[any(),...],'spvcObj',24) can never succeed -spvcOrig.erl:1583: Guard test is_record(Row::[any(),...],'spvcVcc',25) can never succeed -spvcOrig.erl:1586: Guard test is_record(Row::[any(),...],'spvcVpc',20) can never succeed -spvcOrig.erl:1589: Guard test is_record(Row::[any(),...],'spvcVpcPerm',12) can never succeed -spvcOrig.erl:1592: Guard test is_record(Row::[any(),...],'spvcVccPerm',17) can never succeed -spvcOrig.erl:1595: Guard test is_record(Row::[any(),...],'spvcTargetVc',6) can never succeed -spvcOrig.erl:1598: Guard test is_record(Row::[any(),...],'spvcTargetVp',6) can never succeed -spvcOrig.erl:1601: Guard test is_record(Row::[any(),...],'pchVc',32) can never succeed -spvcOrig.erl:1604: Guard test is_record(Row::[any(),...],'pchVp',33) can never succeed -spvcOrig.erl:1607: Guard test is_record(Row::[any(),...],'spvcFr',21) can never succeed -spvcOrig.erl:1610: Guard test is_record(Row::[any(),...],'spvcFrPerm',6) can never succeed -spvcOrig.erl:1613: The pattern {If_Value, _, _, _} can never match the type [any(),...] -spvcOrig.erl:1615: The pattern {If_Value, _, _} can never match the type [any(),...] -spvcOrig.erl:1617: The pattern {If_Value, _} can never match the type [any(),...] -spvcOrig.erl:1621: The variable _ can never match since previous clauses completely covered the type [any(),...] -spvcOrig.erl:1731: The pattern [_, _, _, _] can never match the type tuple() -spvcOrig.erl:1733: The pattern [_, _, _] can never match the type tuple() -spvcOrig.erl:1735: The pattern [_, _] can never match the type tuple() -spvcOrig.erl:264: The pattern {If_Value, Vpi_Value} can never match the type {_,_,_} -spvcOrig.erl:271: Guard test is_integer(Vci_Value::'no_vc') can never succeed -spvcOrig.erl:275: The pattern {If_Value, Vpi_Value} can never match the type {_,_,'no_vc'} -spvcOrig.erl:305: The pattern {'spvcVcc', 'targetAddress'} can never match the type {'spvcFr','rowStatus'} | {'spvcVcc','rowStatus'} | {'spvcVpc','rowStatus'} -spvcOrig.erl:307: The pattern {'spvcVcc', 'selectType'} can never match the type {'spvcFr','rowStatus'} | {'spvcVcc','rowStatus'} | {'spvcVpc','rowStatus'} -spvcOrig.erl:309: The pattern {'spvcVcc', 'targetVpi'} can never match the type {'spvcFr','rowStatus'} | {'spvcVcc','rowStatus'} | {'spvcVpc','rowStatus'} -spvcOrig.erl:311: The pattern {'spvcVcc', 'targetVci'} can never match the type {'spvcFr','rowStatus'} | {'spvcVcc','rowStatus'} | {'spvcVpc','rowStatus'} -spvcOrig.erl:313: The pattern {'spvcVcc', 'releaseCause'} can never match the type {'spvcFr','rowStatus'} | {'spvcVcc','rowStatus'} | {'spvcVpc','rowStatus'} -spvcOrig.erl:315: The pattern {'spvcVcc', 'releaseDiagnostic'} can never match the type {'spvcFr','rowStatus'} | {'spvcVcc','rowStatus'} | {'spvcVpc','rowStatus'} -spvcOrig.erl:317: The pattern {'spvcVcc', 'retryInterval'} can never match the type {'spvcFr','rowStatus'} | {'spvcVcc','rowStatus'} | {'spvcVpc','rowStatus'} -spvcOrig.erl:319: The pattern {'spvcVcc', 'retryTimer'} can never match the type {'spvcFr','rowStatus'} | {'spvcVcc','rowStatus'} | {'spvcVpc','rowStatus'} -spvcOrig.erl:321: The pattern {'spvcVcc', 'retryThreshold'} can never match the type {'spvcFr','rowStatus'} | {'spvcVcc','rowStatus'} | {'spvcVpc','rowStatus'} -spvcOrig.erl:323: The pattern {'spvcVcc', 'retryFailures'} can never match the type {'spvcFr','rowStatus'} | {'spvcVcc','rowStatus'} | {'spvcVpc','rowStatus'} -spvcOrig.erl:325: The pattern {'spvcVcc', 'retryLimit'} can never match the type {'spvcFr','rowStatus'} | {'spvcVcc','rowStatus'} | {'spvcVpc','rowStatus'} -spvcOrig.erl:329: The pattern {'spvcVcc', 'restart'} can never match the type {'spvcFr','rowStatus'} | {'spvcVpc','rowStatus'} -spvcOrig.erl:331: The pattern {'spvcVcc', 'targetSelectType_any'} can never match the type {'spvcFr','rowStatus'} | {'spvcVpc','rowStatus'} -spvcOrig.erl:333: The pattern {'spvcVcc', 'targetSelectType_required'} can never match the type {'spvcFr','rowStatus'} | {'spvcVpc','rowStatus'} -spvcOrig.erl:335: The pattern {'spvcVpc', 'targetAddress'} can never match the type {'spvcFr','rowStatus'} | {'spvcVpc','rowStatus'} -spvcOrig.erl:337: The pattern {'spvcVpc', 'selectType'} can never match the type {'spvcFr','rowStatus'} | {'spvcVpc','rowStatus'} -spvcOrig.erl:339: The pattern {'spvcVpc', 'targetVpi'} can never match the type {'spvcFr','rowStatus'} | {'spvcVpc','rowStatus'} -spvcOrig.erl:341: The pattern {'spvcVpc', 'releaseCause'} can never match the type {'spvcFr','rowStatus'} | {'spvcVpc','rowStatus'} -spvcOrig.erl:343: The pattern {'spvcVpc', 'releaseDiagnostic'} can never match the type {'spvcFr','rowStatus'} | {'spvcVpc','rowStatus'} -spvcOrig.erl:345: The pattern {'spvcVpc', 'retryInterval'} can never match the type {'spvcFr','rowStatus'} | {'spvcVpc','rowStatus'} -spvcOrig.erl:347: The pattern {'spvcVpc', 'retryTimer'} can never match the type {'spvcFr','rowStatus'} | {'spvcVpc','rowStatus'} -spvcOrig.erl:349: The pattern {'spvcVpc', 'retryThreshold'} can never match the type {'spvcFr','rowStatus'} | {'spvcVpc','rowStatus'} -spvcOrig.erl:351: The pattern {'spvcVpc', 'retryFailures'} can never match the type {'spvcFr','rowStatus'} | {'spvcVpc','rowStatus'} -spvcOrig.erl:353: The pattern {'spvcVpc', 'retryLimit'} can never match the type {'spvcFr','rowStatus'} | {'spvcVpc','rowStatus'} -spvcOrig.erl:357: The pattern {'spvcVpc', 'restart'} can never match the type {'spvcFr','rowStatus'} -spvcOrig.erl:359: The pattern {'spvcVpc', 'targetSelectType_any'} can never match the type {'spvcFr','rowStatus'} -spvcOrig.erl:361: The pattern {'spvcVpc', 'targetSelectType_required'} can never match the type {'spvcFr','rowStatus'} -spvcOrig.erl:363: The pattern {'spvcFr', 'targetAddress'} can never match the type {'spvcFr','rowStatus'} -spvcOrig.erl:365: The pattern {'spvcFr', 'selectType'} can never match the type {'spvcFr','rowStatus'} -spvcOrig.erl:367: The pattern {'spvcFr', 'identifier'} can never match the type {'spvcFr','rowStatus'} -spvcOrig.erl:369: The pattern {'spvcFr', 'targetVpi'} can never match the type {'spvcFr','rowStatus'} -spvcOrig.erl:371: The pattern {'spvcFr', 'targetVci'} can never match the type {'spvcFr','rowStatus'} -spvcOrig.erl:373: The pattern {'spvcFr', 'translation'} can never match the type {'spvcFr','rowStatus'} -spvcOrig.erl:375: The pattern {'spvcFr', 'releaseCause'} can never match the type {'spvcFr','rowStatus'} -spvcOrig.erl:377: The pattern {'spvcFr', 'releaseDiagnostic'} can never match the type {'spvcFr','rowStatus'} -spvcOrig.erl:379: The pattern {'spvcFr', 'operStatus'} can never match the type {'spvcFr','rowStatus'} -spvcOrig.erl:381: The pattern {'spvcFr', 'adminStatus'} can never match the type {'spvcFr','rowStatus'} -spvcOrig.erl:383: The pattern {'spvcFr', 'restart'} can never match the type {'spvcFr','rowStatus'} -spvcOrig.erl:385: The pattern {'spvcFr', 'retryInterval'} can never match the type {'spvcFr','rowStatus'} -spvcOrig.erl:387: The pattern {'spvcFr', 'retryTimer'} can never match the type {'spvcFr','rowStatus'} -spvcOrig.erl:389: The pattern {'spvcFr', 'retryThreshold'} can never match the type {'spvcFr','rowStatus'} -spvcOrig.erl:391: The pattern {'spvcFr', 'retryFailures'} can never match the type {'spvcFr','rowStatus'} -spvcOrig.erl:393: The pattern {'spvcFr', 'retryLimit'} can never match the type {'spvcFr','rowStatus'} -spvcOrig.erl:395: The pattern {'spvcFr', 'lastChange'} can never match the type {'spvcFr','rowStatus'} -spvcOrig.erl:404: Guard test is_record(Row::[any(),...],'spvcObj',24) can never succeed -spvcOrig.erl:411: Guard test is_record(Row::[any(),...],'spvcVcc',25) can never succeed -spvcOrig.erl:414: Guard test is_record(Row::[any(),...],'spvcVpc',20) can never succeed -spvcOrig.erl:417: Guard test is_record(Row::[any(),...],'spvcVpcPerm',12) can never succeed -spvcOrig.erl:420: Guard test is_record(Row::[any(),...],'spvcVccPerm',17) can never succeed -spvcOrig.erl:423: Guard test is_record(Row::[any(),...],'spvcTargetVc',6) can never succeed -spvcOrig.erl:426: Guard test is_record(Row::[any(),...],'spvcTargetVp',6) can never succeed -spvcOrig.erl:429: Guard test is_record(Row::[any(),...],'pchVc',32) can never succeed -spvcOrig.erl:432: Guard test is_record(Row::[any(),...],'pchVp',33) can never succeed -spvcOrig.erl:435: Guard test is_record(Row::[any(),...],'spvcFr',21) can never succeed -spvcOrig.erl:438: Guard test is_record(Row::[any(),...],'spvcFrPerm',6) can never succeed -spvcOrig.erl:441: The pattern {If_Value, _, _, _} can never match the type [any(),...] -spvcOrig.erl:443: The pattern {If_Value, _, _} can never match the type [any(),...] -spvcOrig.erl:445: The pattern {If_Value, _} can never match the type [any(),...] -spvcOrig.erl:449: The variable _ can never match since previous clauses completely covered the type [any(),...] -spvcOrig.erl:468: Guard test is_record(Row::[any(),...],'spvcObj',24) can never succeed -spvcOrig.erl:475: Guard test is_record(Row::[any(),...],'spvcVcc',25) can never succeed -spvcOrig.erl:478: Guard test is_record(Row::[any(),...],'spvcVpc',20) can never succeed -spvcOrig.erl:481: Guard test is_record(Row::[any(),...],'spvcVpcPerm',12) can never succeed -spvcOrig.erl:484: Guard test is_record(Row::[any(),...],'spvcVccPerm',17) can never succeed -spvcOrig.erl:487: Guard test is_record(Row::[any(),...],'spvcTargetVc',6) can never succeed -spvcOrig.erl:490: Guard test is_record(Row::[any(),...],'spvcTargetVp',6) can never succeed -spvcOrig.erl:493: Guard test is_record(Row::[any(),...],'pchVc',32) can never succeed -spvcOrig.erl:496: Guard test is_record(Row::[any(),...],'pchVp',33) can never succeed -spvcOrig.erl:499: Guard test is_record(Row::[any(),...],'spvcFr',21) can never succeed -spvcOrig.erl:502: Guard test is_record(Row::[any(),...],'spvcFrPerm',6) can never succeed -spvcOrig.erl:505: The pattern {If_Value, _, _, _} can never match the type [any(),...] -spvcOrig.erl:507: The pattern {If_Value, _, _} can never match the type [any(),...] -spvcOrig.erl:509: The pattern {If_Value, _} can never match the type [any(),...] -spvcOrig.erl:513: The variable _ can never match since previous clauses completely covered the type [any(),...] -spvcOrig.erl:546: The pattern {_, _, _, _} can never match the type [any(),...] -spvcOrig.erl:548: The pattern {_, _, _} can never match the type [any(),...] -spvcOrig.erl:550: The pattern {_, _} can never match the type [any(),...] -spvcOrig.erl:559: The pattern {'spvcVcc', 'targetAddress'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} -spvcOrig.erl:561: The pattern {'spvcVcc', 'selectType'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} -spvcOrig.erl:563: The pattern {'spvcVcc', 'targetVpi'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} -spvcOrig.erl:565: The pattern {'spvcVcc', 'targetVci'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} -spvcOrig.erl:567: The pattern {'spvcVcc', 'releaseCause'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} -spvcOrig.erl:569: The pattern {'spvcVcc', 'releaseDiagnostic'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} -spvcOrig.erl:571: The pattern {'spvcVcc', 'retryInterval'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} -spvcOrig.erl:573: The pattern {'spvcVcc', 'retryTimer'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} -spvcOrig.erl:575: The pattern {'spvcVcc', 'retryThreshold'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} -spvcOrig.erl:577: The pattern {'spvcVcc', 'retryFailures'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} -spvcOrig.erl:579: The pattern {'spvcVcc', 'retryLimit'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} -spvcOrig.erl:581: The pattern {'spvcVcc', 'rowStatus'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} -spvcOrig.erl:585: The pattern {'spvcVcc', 'targetSelectType_any'} can never match the type {'spvcFr','restart'} | {'spvcVpc','restart'} -spvcOrig.erl:587: The pattern {'spvcVcc', 'targetSelectType_required'} can never match the type {'spvcFr','restart'} | {'spvcVpc','restart'} -spvcOrig.erl:589: The pattern {'spvcVpc', 'targetAddress'} can never match the type {'spvcFr','restart'} | {'spvcVpc','restart'} -spvcOrig.erl:591: The pattern {'spvcVpc', 'selectType'} can never match the type {'spvcFr','restart'} | {'spvcVpc','restart'} -spvcOrig.erl:593: The pattern {'spvcVpc', 'targetVpi'} can never match the type {'spvcFr','restart'} | {'spvcVpc','restart'} -spvcOrig.erl:595: The pattern {'spvcVpc', 'releaseCause'} can never match the type {'spvcFr','restart'} | {'spvcVpc','restart'} -spvcOrig.erl:597: The pattern {'spvcVpc', 'releaseDiagnostic'} can never match the type {'spvcFr','restart'} | {'spvcVpc','restart'} -spvcOrig.erl:599: The pattern {'spvcVpc', 'retryInterval'} can never match the type {'spvcFr','restart'} | {'spvcVpc','restart'} -spvcOrig.erl:601: The pattern {'spvcVpc', 'retryTimer'} can never match the type {'spvcFr','restart'} | {'spvcVpc','restart'} -spvcOrig.erl:603: The pattern {'spvcVpc', 'retryThreshold'} can never match the type {'spvcFr','restart'} | {'spvcVpc','restart'} -spvcOrig.erl:605: The pattern {'spvcVpc', 'retryFailures'} can never match the type {'spvcFr','restart'} | {'spvcVpc','restart'} -spvcOrig.erl:607: The pattern {'spvcVpc', 'retryLimit'} can never match the type {'spvcFr','restart'} | {'spvcVpc','restart'} -spvcOrig.erl:609: The pattern {'spvcVpc', 'rowStatus'} can never match the type {'spvcFr','restart'} | {'spvcVpc','restart'} -spvcOrig.erl:613: The pattern {'spvcVpc', 'targetSelectType_any'} can never match the type {'spvcFr','restart'} -spvcOrig.erl:615: The pattern {'spvcVpc', 'targetSelectType_required'} can never match the type {'spvcFr','restart'} -spvcOrig.erl:617: The pattern {'spvcFr', 'targetAddress'} can never match the type {'spvcFr','restart'} -spvcOrig.erl:619: The pattern {'spvcFr', 'selectType'} can never match the type {'spvcFr','restart'} -spvcOrig.erl:621: The pattern {'spvcFr', 'identifier'} can never match the type {'spvcFr','restart'} -spvcOrig.erl:623: The pattern {'spvcFr', 'targetVpi'} can never match the type {'spvcFr','restart'} -spvcOrig.erl:625: The pattern {'spvcFr', 'targetVci'} can never match the type {'spvcFr','restart'} -spvcOrig.erl:627: The pattern {'spvcFr', 'translation'} can never match the type {'spvcFr','restart'} -spvcOrig.erl:629: The pattern {'spvcFr', 'releaseCause'} can never match the type {'spvcFr','restart'} -spvcOrig.erl:631: The pattern {'spvcFr', 'releaseDiagnostic'} can never match the type {'spvcFr','restart'} -spvcOrig.erl:633: The pattern {'spvcFr', 'operStatus'} can never match the type {'spvcFr','restart'} -spvcOrig.erl:635: The pattern {'spvcFr', 'adminStatus'} can never match the type {'spvcFr','restart'} -spvcOrig.erl:639: The pattern {'spvcFr', 'retryInterval'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} -spvcOrig.erl:641: The pattern {'spvcFr', 'retryTimer'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} -spvcOrig.erl:643: The pattern {'spvcFr', 'retryThreshold'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} -spvcOrig.erl:645: The pattern {'spvcFr', 'retryFailures'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} -spvcOrig.erl:647: The pattern {'spvcFr', 'retryLimit'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} -spvcOrig.erl:649: The pattern {'spvcFr', 'lastChange'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} -spvcOrig.erl:651: The pattern {'spvcFr', 'rowStatus'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} -spvcOrig.erl:730: Guard test is_record(Spvc::[] | #spvcObj{},'spvcVcc',25) can never succeed -spvcOrig.erl:733: Guard test is_record(Spvc::[] | #spvcObj{},'spvcVpc',20) can never succeed -spvcOrig.erl:736: Guard test is_record(Spvc::[] | #spvcObj{},'spvcVpcPerm',12) can never succeed -spvcOrig.erl:739: Guard test is_record(Spvc::[] | #spvcObj{},'spvcVccPerm',17) can never succeed -spvcOrig.erl:742: Guard test is_record(Spvc::[] | #spvcObj{},'spvcTargetVc',6) can never succeed -spvcOrig.erl:745: Guard test is_record(Spvc::[] | #spvcObj{},'spvcTargetVp',6) can never succeed -spvcOrig.erl:748: Guard test is_record(Spvc::[] | #spvcObj{},'pchVc',32) can never succeed -spvcOrig.erl:751: Guard test is_record(Spvc::[] | #spvcObj{},'pchVp',33) can never succeed -spvcOrig.erl:754: Guard test is_record(Spvc::[] | #spvcObj{},'spvcFr',21) can never succeed -spvcOrig.erl:757: Guard test is_record(Spvc::[] | #spvcObj{},'spvcFrPerm',6) can never succeed -spvcOrig.erl:760: The pattern {If_Value, _, _, _} can never match the type [] | #spvcObj{} -spvcOrig.erl:762: The pattern {If_Value, _, _} can never match the type [] | #spvcObj{} -spvcOrig.erl:764: The pattern {If_Value, _} can never match the type [] | #spvcObj{} -spvcOrig.erl:766: The pattern [If_Value | _] can never match the type [] | #spvcObj{} -spvcOrig.erl:802: Guard test is_record(Spvc::[] | #spvcObj{},'spvcVcc',25) can never succeed -spvcOrig.erl:805: Guard test is_record(Spvc::[] | #spvcObj{},'spvcVpc',20) can never succeed -spvcOrig.erl:808: Guard test is_record(Spvc::[] | #spvcObj{},'spvcVpcPerm',12) can never succeed -spvcOrig.erl:811: Guard test is_record(Spvc::[] | #spvcObj{},'spvcVccPerm',17) can never succeed -spvcOrig.erl:814: Guard test is_record(Spvc::[] | #spvcObj{},'spvcTargetVc',6) can never succeed -spvcOrig.erl:817: Guard test is_record(Spvc::[] | #spvcObj{},'spvcTargetVp',6) can never succeed -spvcOrig.erl:820: Guard test is_record(Spvc::[] | #spvcObj{},'pchVc',32) can never succeed -spvcOrig.erl:823: Guard test is_record(Spvc::[] | #spvcObj{},'pchVp',33) can never succeed -spvcOrig.erl:826: Guard test is_record(Spvc::[] | #spvcObj{},'spvcFr',21) can never succeed -spvcOrig.erl:829: Guard test is_record(Spvc::[] | #spvcObj{},'spvcFrPerm',6) can never succeed -spvcOrig.erl:832: The pattern {If_Value, _, _, _} can never match the type [] | #spvcObj{} -spvcOrig.erl:834: The pattern {If_Value, _, _} can never match the type [] | #spvcObj{} -spvcOrig.erl:836: The pattern {If_Value, _} can never match the type [] | #spvcObj{} -spvcOrig.erl:838: The pattern [If_Value | _] can never match the type [] | #spvcObj{} -spvcOrig.erl:951: The pattern [IfIndex_Value, Vpi_Value, Vci_Value, _] can never match the type tuple() -spvcOrig.erl:953: The pattern [IfIndex_Value, Vpi_Value, _] can never match the type tuple() -spvcOrig.erl:974: The pattern [IfIndex_Value, Vpi_Value, Vci_Value, _] can never match the type tuple() -spvcOrig.erl:976: The pattern [IfIndex_Value, Vpi_Value, _] can never match the type tuple() -spvcOrig.erl:996: The pattern [IfIndex_Value, Vpi_Value, Vci_Value, _] can never match the type tuple() -spvcOrig.erl:998: The pattern [IfIndex_Value, Vpi_Value, _] can never match the type tuple() +spvcOrig.erl:1238:34: Guard test is_record(Spvc::[] | #spvcObj{},'spvcVcc',25) can never succeed +spvcOrig.erl:1241:34: Guard test is_record(Spvc::[] | #spvcObj{},'spvcVpc',20) can never succeed +spvcOrig.erl:1244:34: Guard test is_record(Spvc::[] | #spvcObj{},'spvcVpcPerm',12) can never succeed +spvcOrig.erl:1247:34: Guard test is_record(Spvc::[] | #spvcObj{},'spvcVccPerm',17) can never succeed +spvcOrig.erl:1250:34: Guard test is_record(Spvc::[] | #spvcObj{},'spvcTargetVc',6) can never succeed +spvcOrig.erl:1253:34: Guard test is_record(Spvc::[] | #spvcObj{},'spvcTargetVp',6) can never succeed +spvcOrig.erl:1256:34: Guard test is_record(Spvc::[] | #spvcObj{},'pchVc',32) can never succeed +spvcOrig.erl:1259:34: Guard test is_record(Spvc::[] | #spvcObj{},'pchVp',33) can never succeed +spvcOrig.erl:1262:34: Guard test is_record(Spvc::[] | #spvcObj{},'spvcFr',21) can never succeed +spvcOrig.erl:1265:34: Guard test is_record(Spvc::[] | #spvcObj{},'spvcFrPerm',6) can never succeed +spvcOrig.erl:1268:34: The pattern {If_Value, _, _, _} can never match the type [] | #spvcObj{} +spvcOrig.erl:1270:34: The pattern {If_Value, _, _} can never match the type [] | #spvcObj{} +spvcOrig.erl:1272:34: The pattern {If_Value, _} can never match the type [] | #spvcObj{} +spvcOrig.erl:1274:34: The pattern [If_Value | _] can never match the type [] | #spvcObj{} +spvcOrig.erl:1380:17: The variable _ can never match since previous clauses completely covered the type any() +spvcOrig.erl:1389:17: The variable _ can never match since previous clauses completely covered the type any() +spvcOrig.erl:1576:36: Guard test is_record(Row::[any(),...],'spvcObj',24) can never succeed +spvcOrig.erl:1583:36: Guard test is_record(Row::[any(),...],'spvcVcc',25) can never succeed +spvcOrig.erl:1586:36: Guard test is_record(Row::[any(),...],'spvcVpc',20) can never succeed +spvcOrig.erl:1589:36: Guard test is_record(Row::[any(),...],'spvcVpcPerm',12) can never succeed +spvcOrig.erl:1592:36: Guard test is_record(Row::[any(),...],'spvcVccPerm',17) can never succeed +spvcOrig.erl:1595:36: Guard test is_record(Row::[any(),...],'spvcTargetVc',6) can never succeed +spvcOrig.erl:1598:36: Guard test is_record(Row::[any(),...],'spvcTargetVp',6) can never succeed +spvcOrig.erl:1601:36: Guard test is_record(Row::[any(),...],'pchVc',32) can never succeed +spvcOrig.erl:1604:36: Guard test is_record(Row::[any(),...],'pchVp',33) can never succeed +spvcOrig.erl:1607:36: Guard test is_record(Row::[any(),...],'spvcFr',21) can never succeed +spvcOrig.erl:1610:36: Guard test is_record(Row::[any(),...],'spvcFrPerm',6) can never succeed +spvcOrig.erl:1613:36: The pattern {If_Value, _, _, _} can never match the type [any(),...] +spvcOrig.erl:1615:36: The pattern {If_Value, _, _} can never match the type [any(),...] +spvcOrig.erl:1617:36: The pattern {If_Value, _} can never match the type [any(),...] +spvcOrig.erl:1621:36: The variable _ can never match since previous clauses completely covered the type [any(),...] +spvcOrig.erl:1731:37: The pattern [_, _, _, _] can never match the type tuple() +spvcOrig.erl:1733:37: The pattern [_, _, _] can never match the type tuple() +spvcOrig.erl:1735:37: The pattern [_, _] can never match the type tuple() +spvcOrig.erl:264:15: The pattern {If_Value, Vpi_Value} can never match the type {_,_,_} +spvcOrig.erl:271:51: Guard test is_integer(Vci_Value::'no_vc') can never succeed +spvcOrig.erl:275:15: The pattern {If_Value, Vpi_Value} can never match the type {_,_,'no_vc'} +spvcOrig.erl:305:30: The pattern {'spvcVcc', 'targetAddress'} can never match the type {'spvcFr','rowStatus'} | {'spvcVcc','rowStatus'} | {'spvcVpc','rowStatus'} +spvcOrig.erl:307:30: The pattern {'spvcVcc', 'selectType'} can never match the type {'spvcFr','rowStatus'} | {'spvcVcc','rowStatus'} | {'spvcVpc','rowStatus'} +spvcOrig.erl:309:30: The pattern {'spvcVcc', 'targetVpi'} can never match the type {'spvcFr','rowStatus'} | {'spvcVcc','rowStatus'} | {'spvcVpc','rowStatus'} +spvcOrig.erl:311:30: The pattern {'spvcVcc', 'targetVci'} can never match the type {'spvcFr','rowStatus'} | {'spvcVcc','rowStatus'} | {'spvcVpc','rowStatus'} +spvcOrig.erl:313:30: The pattern {'spvcVcc', 'releaseCause'} can never match the type {'spvcFr','rowStatus'} | {'spvcVcc','rowStatus'} | {'spvcVpc','rowStatus'} +spvcOrig.erl:315:30: The pattern {'spvcVcc', 'releaseDiagnostic'} can never match the type {'spvcFr','rowStatus'} | {'spvcVcc','rowStatus'} | {'spvcVpc','rowStatus'} +spvcOrig.erl:317:30: The pattern {'spvcVcc', 'retryInterval'} can never match the type {'spvcFr','rowStatus'} | {'spvcVcc','rowStatus'} | {'spvcVpc','rowStatus'} +spvcOrig.erl:319:30: The pattern {'spvcVcc', 'retryTimer'} can never match the type {'spvcFr','rowStatus'} | {'spvcVcc','rowStatus'} | {'spvcVpc','rowStatus'} +spvcOrig.erl:321:30: The pattern {'spvcVcc', 'retryThreshold'} can never match the type {'spvcFr','rowStatus'} | {'spvcVcc','rowStatus'} | {'spvcVpc','rowStatus'} +spvcOrig.erl:323:30: The pattern {'spvcVcc', 'retryFailures'} can never match the type {'spvcFr','rowStatus'} | {'spvcVcc','rowStatus'} | {'spvcVpc','rowStatus'} +spvcOrig.erl:325:30: The pattern {'spvcVcc', 'retryLimit'} can never match the type {'spvcFr','rowStatus'} | {'spvcVcc','rowStatus'} | {'spvcVpc','rowStatus'} +spvcOrig.erl:329:30: The pattern {'spvcVcc', 'restart'} can never match the type {'spvcFr','rowStatus'} | {'spvcVpc','rowStatus'} +spvcOrig.erl:331:30: The pattern {'spvcVcc', 'targetSelectType_any'} can never match the type {'spvcFr','rowStatus'} | {'spvcVpc','rowStatus'} +spvcOrig.erl:333:30: The pattern {'spvcVcc', 'targetSelectType_required'} can never match the type {'spvcFr','rowStatus'} | {'spvcVpc','rowStatus'} +spvcOrig.erl:335:30: The pattern {'spvcVpc', 'targetAddress'} can never match the type {'spvcFr','rowStatus'} | {'spvcVpc','rowStatus'} +spvcOrig.erl:337:30: The pattern {'spvcVpc', 'selectType'} can never match the type {'spvcFr','rowStatus'} | {'spvcVpc','rowStatus'} +spvcOrig.erl:339:30: The pattern {'spvcVpc', 'targetVpi'} can never match the type {'spvcFr','rowStatus'} | {'spvcVpc','rowStatus'} +spvcOrig.erl:341:30: The pattern {'spvcVpc', 'releaseCause'} can never match the type {'spvcFr','rowStatus'} | {'spvcVpc','rowStatus'} +spvcOrig.erl:343:30: The pattern {'spvcVpc', 'releaseDiagnostic'} can never match the type {'spvcFr','rowStatus'} | {'spvcVpc','rowStatus'} +spvcOrig.erl:345:30: The pattern {'spvcVpc', 'retryInterval'} can never match the type {'spvcFr','rowStatus'} | {'spvcVpc','rowStatus'} +spvcOrig.erl:347:30: The pattern {'spvcVpc', 'retryTimer'} can never match the type {'spvcFr','rowStatus'} | {'spvcVpc','rowStatus'} +spvcOrig.erl:349:30: The pattern {'spvcVpc', 'retryThreshold'} can never match the type {'spvcFr','rowStatus'} | {'spvcVpc','rowStatus'} +spvcOrig.erl:351:30: The pattern {'spvcVpc', 'retryFailures'} can never match the type {'spvcFr','rowStatus'} | {'spvcVpc','rowStatus'} +spvcOrig.erl:353:30: The pattern {'spvcVpc', 'retryLimit'} can never match the type {'spvcFr','rowStatus'} | {'spvcVpc','rowStatus'} +spvcOrig.erl:357:30: The pattern {'spvcVpc', 'restart'} can never match the type {'spvcFr','rowStatus'} +spvcOrig.erl:359:30: The pattern {'spvcVpc', 'targetSelectType_any'} can never match the type {'spvcFr','rowStatus'} +spvcOrig.erl:361:30: The pattern {'spvcVpc', 'targetSelectType_required'} can never match the type {'spvcFr','rowStatus'} +spvcOrig.erl:363:30: The pattern {'spvcFr', 'targetAddress'} can never match the type {'spvcFr','rowStatus'} +spvcOrig.erl:365:30: The pattern {'spvcFr', 'selectType'} can never match the type {'spvcFr','rowStatus'} +spvcOrig.erl:367:30: The pattern {'spvcFr', 'identifier'} can never match the type {'spvcFr','rowStatus'} +spvcOrig.erl:369:30: The pattern {'spvcFr', 'targetVpi'} can never match the type {'spvcFr','rowStatus'} +spvcOrig.erl:371:30: The pattern {'spvcFr', 'targetVci'} can never match the type {'spvcFr','rowStatus'} +spvcOrig.erl:373:30: The pattern {'spvcFr', 'translation'} can never match the type {'spvcFr','rowStatus'} +spvcOrig.erl:375:30: The pattern {'spvcFr', 'releaseCause'} can never match the type {'spvcFr','rowStatus'} +spvcOrig.erl:377:30: The pattern {'spvcFr', 'releaseDiagnostic'} can never match the type {'spvcFr','rowStatus'} +spvcOrig.erl:379:30: The pattern {'spvcFr', 'operStatus'} can never match the type {'spvcFr','rowStatus'} +spvcOrig.erl:381:30: The pattern {'spvcFr', 'adminStatus'} can never match the type {'spvcFr','rowStatus'} +spvcOrig.erl:383:30: The pattern {'spvcFr', 'restart'} can never match the type {'spvcFr','rowStatus'} +spvcOrig.erl:385:30: The pattern {'spvcFr', 'retryInterval'} can never match the type {'spvcFr','rowStatus'} +spvcOrig.erl:387:30: The pattern {'spvcFr', 'retryTimer'} can never match the type {'spvcFr','rowStatus'} +spvcOrig.erl:389:30: The pattern {'spvcFr', 'retryThreshold'} can never match the type {'spvcFr','rowStatus'} +spvcOrig.erl:391:30: The pattern {'spvcFr', 'retryFailures'} can never match the type {'spvcFr','rowStatus'} +spvcOrig.erl:393:30: The pattern {'spvcFr', 'retryLimit'} can never match the type {'spvcFr','rowStatus'} +spvcOrig.erl:395:30: The pattern {'spvcFr', 'lastChange'} can never match the type {'spvcFr','rowStatus'} +spvcOrig.erl:404:37: Guard test is_record(Row::[any(),...],'spvcObj',24) can never succeed +spvcOrig.erl:411:37: Guard test is_record(Row::[any(),...],'spvcVcc',25) can never succeed +spvcOrig.erl:414:37: Guard test is_record(Row::[any(),...],'spvcVpc',20) can never succeed +spvcOrig.erl:417:37: Guard test is_record(Row::[any(),...],'spvcVpcPerm',12) can never succeed +spvcOrig.erl:420:37: Guard test is_record(Row::[any(),...],'spvcVccPerm',17) can never succeed +spvcOrig.erl:423:37: Guard test is_record(Row::[any(),...],'spvcTargetVc',6) can never succeed +spvcOrig.erl:426:37: Guard test is_record(Row::[any(),...],'spvcTargetVp',6) can never succeed +spvcOrig.erl:429:37: Guard test is_record(Row::[any(),...],'pchVc',32) can never succeed +spvcOrig.erl:432:37: Guard test is_record(Row::[any(),...],'pchVp',33) can never succeed +spvcOrig.erl:435:37: Guard test is_record(Row::[any(),...],'spvcFr',21) can never succeed +spvcOrig.erl:438:37: Guard test is_record(Row::[any(),...],'spvcFrPerm',6) can never succeed +spvcOrig.erl:441:37: The pattern {If_Value, _, _, _} can never match the type [any(),...] +spvcOrig.erl:443:37: The pattern {If_Value, _, _} can never match the type [any(),...] +spvcOrig.erl:445:37: The pattern {If_Value, _} can never match the type [any(),...] +spvcOrig.erl:449:37: The variable _ can never match since previous clauses completely covered the type [any(),...] +spvcOrig.erl:468:45: Guard test is_record(Row::[any(),...],'spvcObj',24) can never succeed +spvcOrig.erl:475:45: Guard test is_record(Row::[any(),...],'spvcVcc',25) can never succeed +spvcOrig.erl:478:45: Guard test is_record(Row::[any(),...],'spvcVpc',20) can never succeed +spvcOrig.erl:481:45: Guard test is_record(Row::[any(),...],'spvcVpcPerm',12) can never succeed +spvcOrig.erl:484:45: Guard test is_record(Row::[any(),...],'spvcVccPerm',17) can never succeed +spvcOrig.erl:487:45: Guard test is_record(Row::[any(),...],'spvcTargetVc',6) can never succeed +spvcOrig.erl:490:45: Guard test is_record(Row::[any(),...],'spvcTargetVp',6) can never succeed +spvcOrig.erl:493:45: Guard test is_record(Row::[any(),...],'pchVc',32) can never succeed +spvcOrig.erl:496:45: Guard test is_record(Row::[any(),...],'pchVp',33) can never succeed +spvcOrig.erl:499:45: Guard test is_record(Row::[any(),...],'spvcFr',21) can never succeed +spvcOrig.erl:502:45: Guard test is_record(Row::[any(),...],'spvcFrPerm',6) can never succeed +spvcOrig.erl:505:45: The pattern {If_Value, _, _, _} can never match the type [any(),...] +spvcOrig.erl:507:45: The pattern {If_Value, _, _} can never match the type [any(),...] +spvcOrig.erl:509:45: The pattern {If_Value, _} can never match the type [any(),...] +spvcOrig.erl:513:45: The variable _ can never match since previous clauses completely covered the type [any(),...] +spvcOrig.erl:546:33: The pattern {_, _, _, _} can never match the type [any(),...] +spvcOrig.erl:548:33: The pattern {_, _, _} can never match the type [any(),...] +spvcOrig.erl:550:33: The pattern {_, _} can never match the type [any(),...] +spvcOrig.erl:559:27: The pattern {'spvcVcc', 'targetAddress'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} +spvcOrig.erl:561:27: The pattern {'spvcVcc', 'selectType'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} +spvcOrig.erl:563:27: The pattern {'spvcVcc', 'targetVpi'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} +spvcOrig.erl:565:27: The pattern {'spvcVcc', 'targetVci'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} +spvcOrig.erl:567:27: The pattern {'spvcVcc', 'releaseCause'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} +spvcOrig.erl:569:27: The pattern {'spvcVcc', 'releaseDiagnostic'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} +spvcOrig.erl:571:27: The pattern {'spvcVcc', 'retryInterval'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} +spvcOrig.erl:573:27: The pattern {'spvcVcc', 'retryTimer'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} +spvcOrig.erl:575:27: The pattern {'spvcVcc', 'retryThreshold'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} +spvcOrig.erl:577:27: The pattern {'spvcVcc', 'retryFailures'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} +spvcOrig.erl:579:27: The pattern {'spvcVcc', 'retryLimit'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} +spvcOrig.erl:581:27: The pattern {'spvcVcc', 'rowStatus'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} +spvcOrig.erl:585:27: The pattern {'spvcVcc', 'targetSelectType_any'} can never match the type {'spvcFr','restart'} | {'spvcVpc','restart'} +spvcOrig.erl:587:27: The pattern {'spvcVcc', 'targetSelectType_required'} can never match the type {'spvcFr','restart'} | {'spvcVpc','restart'} +spvcOrig.erl:589:27: The pattern {'spvcVpc', 'targetAddress'} can never match the type {'spvcFr','restart'} | {'spvcVpc','restart'} +spvcOrig.erl:591:27: The pattern {'spvcVpc', 'selectType'} can never match the type {'spvcFr','restart'} | {'spvcVpc','restart'} +spvcOrig.erl:593:27: The pattern {'spvcVpc', 'targetVpi'} can never match the type {'spvcFr','restart'} | {'spvcVpc','restart'} +spvcOrig.erl:595:27: The pattern {'spvcVpc', 'releaseCause'} can never match the type {'spvcFr','restart'} | {'spvcVpc','restart'} +spvcOrig.erl:597:27: The pattern {'spvcVpc', 'releaseDiagnostic'} can never match the type {'spvcFr','restart'} | {'spvcVpc','restart'} +spvcOrig.erl:599:27: The pattern {'spvcVpc', 'retryInterval'} can never match the type {'spvcFr','restart'} | {'spvcVpc','restart'} +spvcOrig.erl:601:27: The pattern {'spvcVpc', 'retryTimer'} can never match the type {'spvcFr','restart'} | {'spvcVpc','restart'} +spvcOrig.erl:603:27: The pattern {'spvcVpc', 'retryThreshold'} can never match the type {'spvcFr','restart'} | {'spvcVpc','restart'} +spvcOrig.erl:605:27: The pattern {'spvcVpc', 'retryFailures'} can never match the type {'spvcFr','restart'} | {'spvcVpc','restart'} +spvcOrig.erl:607:27: The pattern {'spvcVpc', 'retryLimit'} can never match the type {'spvcFr','restart'} | {'spvcVpc','restart'} +spvcOrig.erl:609:27: The pattern {'spvcVpc', 'rowStatus'} can never match the type {'spvcFr','restart'} | {'spvcVpc','restart'} +spvcOrig.erl:613:27: The pattern {'spvcVpc', 'targetSelectType_any'} can never match the type {'spvcFr','restart'} +spvcOrig.erl:615:27: The pattern {'spvcVpc', 'targetSelectType_required'} can never match the type {'spvcFr','restart'} +spvcOrig.erl:617:27: The pattern {'spvcFr', 'targetAddress'} can never match the type {'spvcFr','restart'} +spvcOrig.erl:619:27: The pattern {'spvcFr', 'selectType'} can never match the type {'spvcFr','restart'} +spvcOrig.erl:621:27: The pattern {'spvcFr', 'identifier'} can never match the type {'spvcFr','restart'} +spvcOrig.erl:623:27: The pattern {'spvcFr', 'targetVpi'} can never match the type {'spvcFr','restart'} +spvcOrig.erl:625:27: The pattern {'spvcFr', 'targetVci'} can never match the type {'spvcFr','restart'} +spvcOrig.erl:627:27: The pattern {'spvcFr', 'translation'} can never match the type {'spvcFr','restart'} +spvcOrig.erl:629:27: The pattern {'spvcFr', 'releaseCause'} can never match the type {'spvcFr','restart'} +spvcOrig.erl:631:27: The pattern {'spvcFr', 'releaseDiagnostic'} can never match the type {'spvcFr','restart'} +spvcOrig.erl:633:27: The pattern {'spvcFr', 'operStatus'} can never match the type {'spvcFr','restart'} +spvcOrig.erl:635:27: The pattern {'spvcFr', 'adminStatus'} can never match the type {'spvcFr','restart'} +spvcOrig.erl:639:27: The pattern {'spvcFr', 'retryInterval'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} +spvcOrig.erl:641:27: The pattern {'spvcFr', 'retryTimer'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} +spvcOrig.erl:643:27: The pattern {'spvcFr', 'retryThreshold'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} +spvcOrig.erl:645:27: The pattern {'spvcFr', 'retryFailures'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} +spvcOrig.erl:647:27: The pattern {'spvcFr', 'retryLimit'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} +spvcOrig.erl:649:27: The pattern {'spvcFr', 'lastChange'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} +spvcOrig.erl:651:27: The pattern {'spvcFr', 'rowStatus'} can never match the type {'spvcFr','restart'} | {'spvcVcc','restart'} | {'spvcVpc','restart'} +spvcOrig.erl:730:34: Guard test is_record(Spvc::[] | #spvcObj{},'spvcVcc',25) can never succeed +spvcOrig.erl:733:34: Guard test is_record(Spvc::[] | #spvcObj{},'spvcVpc',20) can never succeed +spvcOrig.erl:736:34: Guard test is_record(Spvc::[] | #spvcObj{},'spvcVpcPerm',12) can never succeed +spvcOrig.erl:739:34: Guard test is_record(Spvc::[] | #spvcObj{},'spvcVccPerm',17) can never succeed +spvcOrig.erl:742:34: Guard test is_record(Spvc::[] | #spvcObj{},'spvcTargetVc',6) can never succeed +spvcOrig.erl:745:34: Guard test is_record(Spvc::[] | #spvcObj{},'spvcTargetVp',6) can never succeed +spvcOrig.erl:748:34: Guard test is_record(Spvc::[] | #spvcObj{},'pchVc',32) can never succeed +spvcOrig.erl:751:34: Guard test is_record(Spvc::[] | #spvcObj{},'pchVp',33) can never succeed +spvcOrig.erl:754:34: Guard test is_record(Spvc::[] | #spvcObj{},'spvcFr',21) can never succeed +spvcOrig.erl:757:34: Guard test is_record(Spvc::[] | #spvcObj{},'spvcFrPerm',6) can never succeed +spvcOrig.erl:760:34: The pattern {If_Value, _, _, _} can never match the type [] | #spvcObj{} +spvcOrig.erl:762:34: The pattern {If_Value, _, _} can never match the type [] | #spvcObj{} +spvcOrig.erl:764:34: The pattern {If_Value, _} can never match the type [] | #spvcObj{} +spvcOrig.erl:766:34: The pattern [If_Value | _] can never match the type [] | #spvcObj{} +spvcOrig.erl:802:38: Guard test is_record(Spvc::[] | #spvcObj{},'spvcVcc',25) can never succeed +spvcOrig.erl:805:38: Guard test is_record(Spvc::[] | #spvcObj{},'spvcVpc',20) can never succeed +spvcOrig.erl:808:38: Guard test is_record(Spvc::[] | #spvcObj{},'spvcVpcPerm',12) can never succeed +spvcOrig.erl:811:38: Guard test is_record(Spvc::[] | #spvcObj{},'spvcVccPerm',17) can never succeed +spvcOrig.erl:814:38: Guard test is_record(Spvc::[] | #spvcObj{},'spvcTargetVc',6) can never succeed +spvcOrig.erl:817:38: Guard test is_record(Spvc::[] | #spvcObj{},'spvcTargetVp',6) can never succeed +spvcOrig.erl:820:38: Guard test is_record(Spvc::[] | #spvcObj{},'pchVc',32) can never succeed +spvcOrig.erl:823:38: Guard test is_record(Spvc::[] | #spvcObj{},'pchVp',33) can never succeed +spvcOrig.erl:826:38: Guard test is_record(Spvc::[] | #spvcObj{},'spvcFr',21) can never succeed +spvcOrig.erl:829:38: Guard test is_record(Spvc::[] | #spvcObj{},'spvcFrPerm',6) can never succeed +spvcOrig.erl:832:38: The pattern {If_Value, _, _, _} can never match the type [] | #spvcObj{} +spvcOrig.erl:834:38: The pattern {If_Value, _, _} can never match the type [] | #spvcObj{} +spvcOrig.erl:836:38: The pattern {If_Value, _} can never match the type [] | #spvcObj{} +spvcOrig.erl:838:38: The pattern [If_Value | _] can never match the type [] | #spvcObj{} +spvcOrig.erl:951:21: The pattern [IfIndex_Value, Vpi_Value, Vci_Value, _] can never match the type tuple() +spvcOrig.erl:953:21: The pattern [IfIndex_Value, Vpi_Value, _] can never match the type tuple() +spvcOrig.erl:974:29: The pattern [IfIndex_Value, Vpi_Value, Vci_Value, _] can never match the type tuple() +spvcOrig.erl:976:29: The pattern [IfIndex_Value, Vpi_Value, _] can never match the type tuple() +spvcOrig.erl:996:21: The pattern [IfIndex_Value, Vpi_Value, Vci_Value, _] can never match the type tuple() +spvcOrig.erl:998:21: The pattern [IfIndex_Value, Vpi_Value, _] can never match the type tuple() diff --git a/lib/dialyzer/test/user_SUITE_data/results/wpc_hlines b/lib/dialyzer/test/user_SUITE_data/results/wpc_hlines index d6e3f29ab9..25f04ae1f7 100644 --- a/lib/dialyzer/test/user_SUITE_data/results/wpc_hlines +++ b/lib/dialyzer/test/user_SUITE_data/results/wpc_hlines @@ -1,3 +1,3 @@ -wpc_hlines.erl:22: Function bad/1 has no local return -wpc_hlines.erl:22: The pattern 'false' can never match the type 'true' +wpc_hlines.erl:22:1: Function bad/1 has no local return +wpc_hlines.erl:22:1: The pattern 'false' can never match the type 'true' diff --git a/lib/dialyzer/test/user_SUITE_data/results/wsp_pdu b/lib/dialyzer/test/user_SUITE_data/results/wsp_pdu index 626e677524..73a2c3b339 100644 --- a/lib/dialyzer/test/user_SUITE_data/results/wsp_pdu +++ b/lib/dialyzer/test/user_SUITE_data/results/wsp_pdu @@ -1,25 +1,25 @@ -wsp_pdu.erl:1063: The pattern [H | Hs] can never match the type [] -wsp_pdu.erl:1162: The call wsp_pdu:parse_push_flag(Value::[any()]) will never return since it differs in the 1st argument from the success typing arguments: (integer()) -wsp_pdu.erl:2400: Function decode_retry_after/2 has no local return -wsp_pdu.erl:2403: The call wsp_pdu:d_date(Data1::binary()) will never return since it differs in the 1st argument from the success typing arguments: (integer() | {'short',binary()}) -wsp_pdu.erl:2406: Guard test is_integer(Sec::{[byte()] | byte() | {'long',binary()} | {'short',binary()},binary()}) can never succeed -wsp_pdu.erl:2408: The pattern {'short', Data2} can never match the type {[byte()] | byte() | {'long',binary()} | {'short',binary()},binary()} -wsp_pdu.erl:2755: Function parse_push_flag/1 has no local return -wsp_pdu.erl:2756: The call erlang:integer_to_list(Value::[any()]) breaks the contract (Integer) -> string() when Integer :: integer() -wsp_pdu.erl:2875: The call wsp_pdu:d_text_string(Data::byte()) will never return since it differs in the 1st argument from the success typing arguments: (binary()) -wsp_pdu.erl:2976: The call wsp_pdu:d_q_value(QData::byte()) will never return since it differs in the 1st argument from the success typing arguments: (<<_:8,_:_*8>>) -wsp_pdu.erl:3336: The call wsp_pdu:encode_typed_field(Ver::any(),'Q-value',ParamValue::any()) will never return since it differs in the 2nd argument from the success typing arguments: (any(),'Constrained-encoding' | 'Date-value' | 'No-value' | 'Short-integer' | 'Text-string' | 'Text-value' | 'Well-known-charset',any()) -wsp_pdu.erl:3342: The call wsp_pdu:encode_typed_field(Ver::any(),'Ver-value',ParamValue::any()) will never return since it differs in the 2nd argument from the success typing arguments: (any(),'Constrained-encoding' | 'Date-value' | 'No-value' | 'Short-integer' | 'Text-string' | 'Text-value' | 'Well-known-charset',any()) -wsp_pdu.erl:3349: The call wsp_pdu:encode_typed_field(Ver::any(),'Integer-value',ParamValue::any()) will never return since it differs in the 2nd argument from the success typing arguments: (any(),'Constrained-encoding' | 'Date-value' | 'No-value' | 'Short-integer' | 'Text-string' | 'Text-value' | 'Well-known-charset',any()) -wsp_pdu.erl:3367: The call wsp_pdu:encode_typed_field(Ver::any(),'Field-name',ParamValue::any()) will never return since it differs in the 2nd argument from the success typing arguments: (any(),'Constrained-encoding' | 'Date-value' | 'No-value' | 'Short-integer' | 'Text-string' | 'Text-value' | 'Well-known-charset',any()) -wsp_pdu.erl:3405: The call wsp_pdu:encode_typed_field(Ver::any(),'Delta-seconds-value',ParamValue::any()) will never return since it differs in the 2nd argument from the success typing arguments: (any(),'Constrained-encoding' | 'Date-value' | 'No-value' | 'Short-integer' | 'Text-string' | 'Text-value' | 'Well-known-charset',any()) -wsp_pdu.erl:3437: The call wsp_pdu:encode_typed_field(Ver::any(),'Integer-value',ParamValue::any()) will never return since it differs in the 2nd argument from the success typing arguments: (any(),'Constrained-encoding' | 'Date-value' | 'No-value' | 'Short-integer' | 'Text-string' | 'Text-value' | 'Well-known-charset',any()) -wsp_pdu.erl:3455: The call wsp_pdu:decode_typed_field('Version-value',Data::binary(),Version::any()) will never return since it differs in the 1st argument from the success typing arguments: ('Constrained-encoding' | 'Date-value' | 'Delta-seconds-value' | 'Field-name' | 'No-value' | 'Q-value' | 'Short-integer' | 'Text-string' | 'Text-value' | 'Well-known-charset',binary(),any()) -wsp_pdu.erl:3459: The call wsp_pdu:decode_typed_field('Integer-value',Data::binary(),Version::any()) will never return since it differs in the 1st argument from the success typing arguments: ('Constrained-encoding' | 'Date-value' | 'Delta-seconds-value' | 'Field-name' | 'No-value' | 'Q-value' | 'Short-integer' | 'Text-string' | 'Text-value' | 'Well-known-charset',binary(),any()) -wsp_pdu.erl:3531: The call wsp_pdu:decode_typed_field('Integer-value',Data::binary(),Version::any()) will never return since it differs in the 1st argument from the success typing arguments: ('Constrained-encoding' | 'Date-value' | 'Delta-seconds-value' | 'Field-name' | 'No-value' | 'Q-value' | 'Short-integer' | 'Text-string' | 'Text-value' | 'Well-known-charset',binary(),any()) -wsp_pdu.erl:3593: The pattern 'Delta-Seconds-value' can never match the type 'Delta-seconds-value' | 'Field-name' | 'Integer-value' | 'No-value' | 'Q-value' | 'Ver-value' -wsp_pdu.erl:4844: The call wsp_pdu:d_long('data') will never return since it differs in the 1st argument from the success typing arguments: (binary()) -wsp_pdu.erl:510: The variable _ can never match since previous clauses completely covered the type 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 -wsp_pdu.erl:512: The variable _ can never match since previous clauses completely covered the type 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 -wsp_pdu.erl:5265: Call to missing or unexported function inet:ip_to_bytes/1 +wsp_pdu.erl:1063:1: The pattern [H | Hs] can never match the type [] +wsp_pdu.erl:1162:40: The call wsp_pdu:parse_push_flag(Value::[any()]) will never return since it differs in the 1st argument from the success typing arguments: (integer()) +wsp_pdu.erl:2400:1: Function decode_retry_after/2 has no local return +wsp_pdu.erl:2403:32: The call wsp_pdu:d_date(Data1::binary()) will never return since it differs in the 1st argument from the success typing arguments: (integer() | {'short',binary()}) +wsp_pdu.erl:2406:12: Guard test is_integer(Sec::{[byte()] | byte() | {'long',binary()} | {'short',binary()},binary()}) can never succeed +wsp_pdu.erl:2408:3: The pattern {'short', Data2} can never match the type {[byte()] | byte() | {'long',binary()} | {'short',binary()},binary()} +wsp_pdu.erl:2755:1: Function parse_push_flag/1 has no local return +wsp_pdu.erl:2756:38: The call erlang:integer_to_list(Value::[any()]) breaks the contract (Integer) -> string() when Integer :: integer() +wsp_pdu.erl:2875:36: The call wsp_pdu:d_text_string(Data::byte()) will never return since it differs in the 1st argument from the success typing arguments: (binary()) +wsp_pdu.erl:2976:32: The call wsp_pdu:d_q_value(QData::byte()) will never return since it differs in the 1st argument from the success typing arguments: (<<_:8,_:_*8>>) +wsp_pdu.erl:3336:31: The call wsp_pdu:encode_typed_field(Ver::any(),'Q-value',ParamValue::any()) will never return since it differs in the 2nd argument from the success typing arguments: (any(),'Constrained-encoding' | 'Date-value' | 'No-value' | 'Short-integer' | 'Text-string' | 'Text-value' | 'Well-known-charset',any()) +wsp_pdu.erl:3342:31: The call wsp_pdu:encode_typed_field(Ver::any(),'Ver-value',ParamValue::any()) will never return since it differs in the 2nd argument from the success typing arguments: (any(),'Constrained-encoding' | 'Date-value' | 'No-value' | 'Short-integer' | 'Text-string' | 'Text-value' | 'Well-known-charset',any()) +wsp_pdu.erl:3349:31: The call wsp_pdu:encode_typed_field(Ver::any(),'Integer-value',ParamValue::any()) will never return since it differs in the 2nd argument from the success typing arguments: (any(),'Constrained-encoding' | 'Date-value' | 'No-value' | 'Short-integer' | 'Text-string' | 'Text-value' | 'Well-known-charset',any()) +wsp_pdu.erl:3367:31: The call wsp_pdu:encode_typed_field(Ver::any(),'Field-name',ParamValue::any()) will never return since it differs in the 2nd argument from the success typing arguments: (any(),'Constrained-encoding' | 'Date-value' | 'No-value' | 'Short-integer' | 'Text-string' | 'Text-value' | 'Well-known-charset',any()) +wsp_pdu.erl:3405:31: The call wsp_pdu:encode_typed_field(Ver::any(),'Delta-seconds-value',ParamValue::any()) will never return since it differs in the 2nd argument from the success typing arguments: (any(),'Constrained-encoding' | 'Date-value' | 'No-value' | 'Short-integer' | 'Text-string' | 'Text-value' | 'Well-known-charset',any()) +wsp_pdu.erl:3437:31: The call wsp_pdu:encode_typed_field(Ver::any(),'Integer-value',ParamValue::any()) will never return since it differs in the 2nd argument from the success typing arguments: (any(),'Constrained-encoding' | 'Date-value' | 'No-value' | 'Short-integer' | 'Text-string' | 'Text-value' | 'Well-known-charset',any()) +wsp_pdu.erl:3455:39: The call wsp_pdu:decode_typed_field('Version-value',Data::binary(),Version::any()) will never return since it differs in the 1st argument from the success typing arguments: ('Constrained-encoding' | 'Date-value' | 'Delta-seconds-value' | 'Field-name' | 'No-value' | 'Q-value' | 'Short-integer' | 'Text-string' | 'Text-value' | 'Well-known-charset',binary(),any()) +wsp_pdu.erl:3459:39: The call wsp_pdu:decode_typed_field('Integer-value',Data::binary(),Version::any()) will never return since it differs in the 1st argument from the success typing arguments: ('Constrained-encoding' | 'Date-value' | 'Delta-seconds-value' | 'Field-name' | 'No-value' | 'Q-value' | 'Short-integer' | 'Text-string' | 'Text-value' | 'Well-known-charset',binary(),any()) +wsp_pdu.erl:3531:39: The call wsp_pdu:decode_typed_field('Integer-value',Data::binary(),Version::any()) will never return since it differs in the 1st argument from the success typing arguments: ('Constrained-encoding' | 'Date-value' | 'Delta-seconds-value' | 'Field-name' | 'No-value' | 'Q-value' | 'Short-integer' | 'Text-string' | 'Text-value' | 'Well-known-charset',binary(),any()) +wsp_pdu.erl:3593:2: The pattern 'Delta-Seconds-value' can never match the type 'Delta-seconds-value' | 'Field-name' | 'Integer-value' | 'No-value' | 'Q-value' | 'Ver-value' +wsp_pdu.erl:4844:36: The call wsp_pdu:d_long('data') will never return since it differs in the 1st argument from the success typing arguments: (binary()) +wsp_pdu.erl:510:2: The variable _ can never match since previous clauses completely covered the type 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 +wsp_pdu.erl:512:2: The variable _ can never match since previous clauses completely covered the type 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 +wsp_pdu.erl:5265:22: Call to missing or unexported function inet:ip_to_bytes/1 diff --git a/lib/edoc/src/edoc_extract.erl b/lib/edoc/src/edoc_extract.erl index e878fc1a39..e821c1931d 100644 --- a/lib/edoc/src/edoc_extract.erl +++ b/lib/edoc/src/edoc_extract.erl @@ -385,7 +385,7 @@ collect([F | Fs], Cs, Ss, Ts, Rs, As, Header, Mod) -> comment -> collect(Fs, [F | Cs], Ss, Ts, Rs, As, Header, Mod); {function, Name} -> - L = erl_syntax:get_pos(F), + L = get_line(F), Export = ordsets:is_element(Name, Mod#module.exports), Args = parameters(erl_syntax:function_clauses(F)), collect(Fs, [], [], [], [], @@ -394,7 +394,7 @@ collect([F | Fs], Cs, Ss, Ts, Rs, As, Header, Mod) -> data = {comment_text(Cs),Ss,Ts,Rs}} | As], Header, Mod); {attribute, {module, _}} when Header =:= undefined -> - L = erl_syntax:get_pos(F), + L = get_line(F), collect(Fs, [], [], [], [], As, #entry{name = module, line = L, data = {comment_text(Cs),Ss,Ts,Rs}}, @@ -441,7 +441,7 @@ comment_text(Cs) -> comment_text(Cs, []). comment_text([C | Cs], Ss) -> - L = erl_syntax:get_pos(C), + L = get_line(C), comment_text(Cs, [#comment{line = L, text = [remove_percent_chars(S) || S <- erl_syntax:comment_text(C)]} @@ -449,6 +449,10 @@ comment_text([C | Cs], Ss) -> comment_text([], Ss) -> Ss. +get_line(Tree) -> + Anno = erl_syntax:get_pos(Tree), + erl_anno:line(Anno). + %% @doc Replaces leading `%' characters by spaces. For example, `"%%% %% foo" -> "\s\s\s foo"', but `"% % foo" -> "\s % foo"', since the %% second `%' is preceded by whitespace. diff --git a/lib/edoc/src/edoc_specs.erl b/lib/edoc/src/edoc_specs.erl index 9b5050a7c2..8c2fb8ee50 100644 --- a/lib/edoc/src/edoc_specs.erl +++ b/lib/edoc/src/edoc_specs.erl @@ -47,8 +47,9 @@ type(Form, TypeDocs) -> case Data0 of {R, Fs} -> record = Name, - L = erl_syntax:get_pos(Form), - {{record, R}, {type, L, record, [{atom,L,R} | Fs]}, [], ""}; + Anno = erl_syntax:get_pos(Form), + {{record, R}, + {type, Anno, record, [{atom,Anno,R} | Fs]}, [], ""}; {N,T,As} -> type = tag(Name), Doc0 = @@ -137,11 +138,11 @@ find_type_docs([F | Fs], Cs, Fun) -> try get_name_and_last_line(F) of {Name, LastTypeLine} -> C0 = erl_syntax:comment(["% @type f(). "]), - C1 = erl_syntax:set_pos(C0, LastTypeLine), + C1 = erl_syntax:set_pos(C0, anno(LastTypeLine)), %% Postcomments before the dot after the typespec are ignored. C2 = [C1 | [C || C <- erl_syntax:get_postcomments(F), - erl_syntax:get_pos(C) >= LastTypeLine]], + get_tree_line(C) >= LastTypeLine]], C3 = collect_comments(Fs, LastTypeLine), #tag{data = Doc0} = Fun(lists:reverse(C2 ++ C3), LastTypeLine), case strip(Doc0) of % Strip away "f(). \n" @@ -158,7 +159,7 @@ find_type_docs([F | Fs], Cs, Fun) -> collect_comments([], _Line) -> []; collect_comments([F | Fs], Line) -> - L1 = erl_syntax:get_pos(F), + L1 = get_tree_line(F), if L1 =:= Line + 1; L1 =:= Line -> % a separate postcomment @@ -175,6 +176,13 @@ collect_comments([F | Fs], Line) -> %% by a -type attribute and the include statement is followed by a %% comment (which is not meant to be documentation of the type). +anno(Location) -> + erl_anno:new(Location). + +get_tree_line(Tree) -> + Anno = erl_syntax:get_pos(Tree), + erl_anno:line(Anno). + is_comment(F) -> erl_syntax_lib:analyze_form(F) =:= comment. @@ -190,7 +198,8 @@ strip([_ | S]) -> get_name_and_last_line(F) -> {Name, Data} = analyze_type_attribute(F), type = edoc_specs:tag(Name), - Attr = {attribute, erl_syntax:get_pos(F), Name, Data}, + Anno = erl_syntax:get_pos(F), + Attr = {attribute, Anno, Name, Data}, Fun = fun(A) -> Line = get_line(A), case get('$max_line') of diff --git a/lib/erl_docgen/priv/bin/specs_gen.escript b/lib/erl_docgen/priv/bin/specs_gen.escript index 5b75a83a7e..4e7c42f189 100644 --- a/lib/erl_docgen/priv/bin/specs_gen.escript +++ b/lib/erl_docgen/priv/bin/specs_gen.escript @@ -82,7 +82,7 @@ call_edoc(FileSpec, InclFs, Dir) -> Fs0 = read_file(File, ReadOpts), clauses(Fs0); {module, Module} -> - [{attribute,0,module,list_to_atom(Module)}] + [{attribute,erl_anno:new(0),module,list_to_atom(Module)}] end, Doc = extract(File, Fs, ExtractOpts), Text = edoc:layout(Doc, LayoutOpts), diff --git a/lib/parsetools/doc/src/yecc.xml b/lib/parsetools/doc/src/yecc.xml index 74fe22a7a5..67847e5cc1 100644 --- a/lib/parsetools/doc/src/yecc.xml +++ b/lib/parsetools/doc/src/yecc.xml @@ -128,6 +128,12 @@ <item> <p>Causes warnings to be treated as errors.</p> </item> + <tag><c>{error_location, column | line}</c>.</tag> + <item>If the value of this flag is <c>line</c>, the location + of warnings and errors is a line number. If the value + is <c>column</c>, the location includes a line number and + a column number. Default is <c>column</c>. + </item> </taglist> <p>Any of the Boolean options can be set to <c>true</c> by stating the name of the option. For example, <c>verbose</c> diff --git a/lib/parsetools/include/yeccpre.hrl b/lib/parsetools/include/yeccpre.hrl index 562f17c19e..6cfdb60078 100644 --- a/lib/parsetools/include/yeccpre.hrl +++ b/lib/parsetools/include/yeccpre.hrl @@ -25,15 +25,15 @@ -spec parse(Tokens :: list()) -> yecc_ret(). parse(Tokens) -> - yeccpars0(Tokens, {no_func, no_line}, 0, [], []). + yeccpars0(Tokens, {no_func, no_location}, 0, [], []). -spec parse_and_scan({function() | {atom(), atom()}, [_]} | {atom(), atom(), [_]}) -> yecc_ret(). parse_and_scan({F, A}) -> - yeccpars0([], {{F, A}, no_line}, 0, [], []); + yeccpars0([], {{F, A}, no_location}, 0, [], []); parse_and_scan({M, F, A}) -> Arity = length(A), - yeccpars0([], {{fun M:F/Arity, A}, no_line}, 0, [], []). + yeccpars0([], {{fun M:F/Arity, A}, no_location}, 0, [], []). -spec format_error(any()) -> [char() | list()]. format_error(Message) -> @@ -47,9 +47,9 @@ format_error(Message) -> %% To be used in grammar files to throw an error message to the parser %% toplevel. Doesn't have to be exported! -compile({nowarn_unused_function, return_error/2}). --spec return_error(integer(), any()) -> no_return(). -return_error(Line, Message) -> - throw({error, {Line, ?MODULE, Message}}). +-spec return_error(erl_anno:location(), any()) -> no_return(). +return_error(Location, Message) -> + throw({error, {Location, ?MODULE, Message}}). -define(CODE_VERSION, "1.4"). @@ -64,7 +64,7 @@ yeccpars0(Tokens, Tzr, State, States, Vstack) -> catch _:_ -> erlang:raise(error, Error, Stacktrace) end; %% Probably thrown from return_error/2: - throw: {error, {_Line, ?MODULE, _M}} = Error -> + throw: {error, {_Location, ?MODULE, _M}} = Error -> Error end. @@ -81,22 +81,22 @@ yecc_error_type(function_clause, [{?MODULE,F,ArityOrArgs,_} | _]) -> yeccpars1([Token | Tokens], Tzr, State, States, Vstack) -> yeccpars2(State, element(1, Token), States, Vstack, Token, Tokens, Tzr); -yeccpars1([], {{F, A},_Line}, State, States, Vstack) -> +yeccpars1([], {{F, A},_Location}, State, States, Vstack) -> case apply(F, A) of - {ok, Tokens, Endline} -> - yeccpars1(Tokens, {{F, A}, Endline}, State, States, Vstack); - {eof, Endline} -> - yeccpars1([], {no_func, Endline}, State, States, Vstack); - {error, Descriptor, _Endline} -> + {ok, Tokens, EndLocation} -> + yeccpars1(Tokens, {{F, A}, EndLocation}, State, States, Vstack); + {eof, EndLocation} -> + yeccpars1([], {no_func, EndLocation}, State, States, Vstack); + {error, Descriptor, _EndLocation} -> {error, Descriptor} end; -yeccpars1([], {no_func, no_line}, State, States, Vstack) -> +yeccpars1([], {no_func, no_location}, State, States, Vstack) -> Line = 999999, yeccpars2(State, '$end', States, Vstack, yecc_end(Line), [], {no_func, Line}); -yeccpars1([], {no_func, Endline}, State, States, Vstack) -> - yeccpars2(State, '$end', States, Vstack, yecc_end(Endline), [], - {no_func, Endline}). +yeccpars1([], {no_func, EndLocation}, State, States, Vstack) -> + yeccpars2(State, '$end', States, Vstack, yecc_end(EndLocation), [], + {no_func, EndLocation}). %% yeccpars1/7 is called from generated code. %% @@ -107,21 +107,19 @@ yeccpars1([], {no_func, Endline}, State, States, Vstack) -> yeccpars1(State1, State, States, Vstack, Token0, [Token | Tokens], Tzr) -> yeccpars2(State, element(1, Token), [State1 | States], [Token0 | Vstack], Token, Tokens, Tzr); -yeccpars1(State1, State, States, Vstack, Token0, [], {{_F,_A}, _Line}=Tzr) -> +yeccpars1(State1, State, States, Vstack, Token0, [], {{_F,_A}, _Location}=Tzr) -> yeccpars1([], Tzr, State, [State1 | States], [Token0 | Vstack]); -yeccpars1(State1, State, States, Vstack, Token0, [], {no_func, no_line}) -> - Line = yecctoken_end_location(Token0), +yeccpars1(State1, State, States, Vstack, Token0, [], {no_func, no_location}) -> + Location = yecctoken_end_location(Token0), yeccpars2(State, '$end', [State1 | States], [Token0 | Vstack], - yecc_end(Line), [], {no_func, Line}); -yeccpars1(State1, State, States, Vstack, Token0, [], {no_func, Line}) -> + yecc_end(Location), [], {no_func, Location}); +yeccpars1(State1, State, States, Vstack, Token0, [], {no_func, Location}) -> yeccpars2(State, '$end', [State1 | States], [Token0 | Vstack], - yecc_end(Line), [], {no_func, Line}). + yecc_end(Location), [], {no_func, Location}). %% For internal use only. -yecc_end({Line,_Column}) -> - {'$end', Line}; -yecc_end(Line) -> - {'$end', Line}. +yecc_end(Location) -> + {'$end', Location}. yecctoken_end_location(Token) -> try erl_anno:end_location(element(2, Token)) of diff --git a/lib/parsetools/src/yecc.erl b/lib/parsetools/src/yecc.erl index 55bc8a20d4..4bee428ac2 100644 --- a/lib/parsetools/src/yecc.erl +++ b/lib/parsetools/src/yecc.erl @@ -81,7 +81,7 @@ -record(rule, { n, % rule n in the grammar file - anno, + location, symbols, % the names of symbols tokens, is_guard, % the action is a guard (not used) @@ -235,7 +235,7 @@ format_error({bad_symbol, String}) -> format_error(cannot_parse) -> io_lib:fwrite("cannot parse; possibly encoding mismatch", []). --type error_info() :: {erl_anno:line() | 'none', +-type error_info() :: {erl_anno:location() | 'none', module(), ErrorDescriptor :: term()}. -type errors() :: [{file:filename(), [error_info()]}]. -type warnings() :: [{file:filename(), [error_info()]}]. @@ -387,11 +387,14 @@ check_options([{Option, FileName0} | Options], AllOptions, L) Filename -> check_options(Options, AllOptions, [{Option, Filename} | L]) end; -check_options([{Option, Boolean} | Options], AllOptions, L) +check_options([{error_location, ELoc}=OptionValue | Options], AllOptions, L) + when ELoc =:= column; ELoc =:= line -> + check_options(Options, AllOptions, [OptionValue | L]); +check_options([{Option, Boolean}=OptionValue | Options], AllOptions, L) when is_boolean(Boolean) -> case lists:member(Option, AllOptions) of true -> - check_options(Options, AllOptions, [{Option, Boolean} | L]); + check_options(Options, AllOptions, [OptionValue | L]); false -> badarg end; @@ -401,10 +404,11 @@ check_options(_Options, _, _L) -> badarg. all_options() -> - [file_attributes, includefile, parserfile, report_errors, - report_warnings, return_errors, return_warnings, time, verbose, - warnings_as_errors]. + [error_location, file_attributes, includefile, parserfile, + report_errors, report_warnings, return_errors, return_warnings, + time, verbose, warnings_as_errors]. +default_option(error_location) -> column; default_option(file_attributes) -> true; default_option(includefile) -> []; default_option(parserfile) -> []; @@ -570,33 +574,40 @@ generate(St0) -> foldl(Fun, St1, Passes). parse_grammar(St) -> - parse_grammar(St#yecc.inport, 1, St). + StartLocation = + case lists:keyfind(error_location, 1, St#yecc.options) of + {error_location, column} -> + {1, 1}; + _ -> + 1 + end, + parse_grammar(St#yecc.inport, StartLocation, St). -parse_grammar(Inport, Line, St) -> - {NextLine, Grammar} = read_grammar(Inport, St, Line), - parse_grammar(Grammar, Inport, NextLine, St). +parse_grammar(Inport, Location, St) -> + {NextLocation, Grammar} = read_grammar(Inport, St, Location), + parse_grammar(Grammar, Inport, NextLocation, St). -parse_grammar(eof, _Inport, _NextLine, St) -> +parse_grammar(eof, _Inport, _NextLocation, St) -> St; -parse_grammar({#symbol{name = 'Header'}, Ss}, Inport, NextLine, St0) -> +parse_grammar({#symbol{name = 'Header'}, Ss}, Inport, NextLocation, St0) -> St1 = St0#yecc{header = [S || {string,_,S} <- Ss]}, - parse_grammar(Inport, NextLine, St1); + parse_grammar(Inport, NextLocation, St1); parse_grammar({#symbol{name = 'Erlang'}, [#symbol{name = code}]}, _Inport, - NextLine, St) -> - St#yecc{erlang_code = NextLine}; -parse_grammar(Grammar, Inport, NextLine, St0) -> + NextLocation, St) -> + St#yecc{erlang_code = line_of_location(NextLocation)}; +parse_grammar(Grammar, Inport, NextLocation, St0) -> St = parse_grammar(Grammar, St0), - parse_grammar(Inport, NextLine, St). + parse_grammar(Inport, NextLocation, St). -parse_grammar({error,ErrorLine,Error}, St) -> - add_error(erl_anno:new(ErrorLine), Error, St); -parse_grammar({rule, Rule, Tokens}, St0) -> +parse_grammar({error,ErrorLocation,Error}, St) -> + add_error(erl_anno:new(ErrorLocation), Error, St); +parse_grammar({rule, Rule, Tokens, AllTokens}, St0) -> NmbrOfDaughters = case Rule of [_, #symbol{name = '$empty'}] -> 0; _ -> length(Rule) - 1 end, {IsGuard, IsWellFormed} = check_action(Tokens), - {Tokens1, St} = subst_pseudo_vars(Tokens, + {Tokens1, St} = subst_pseudo_vars(AllTokens, NmbrOfDaughters, St0), RuleDef = #rule{symbols = Rule, @@ -628,38 +639,48 @@ parse_grammar({#symbol{anno = Anno, name = Name}, Symbols}, St) -> _ -> add_warning(Anno, bad_declaration, St) end. -read_grammar(Inport, St, Line) -> - case yeccscan:scan(Inport, '', Line) of - {eof, NextLine} -> - {NextLine, eof}; - {error, {ErrorLine, Mod, What}, NextLine} -> - {NextLine, {error, ErrorLine, {error, Mod, What}}}; +read_grammar(Inport, St, Location) -> + case yeccscan:scan(Inport, '', Location) of + {eof, NextLocation} -> + {NextLocation, eof}; + {error, {ErrorLocation, Mod, What}, NextLocation} -> + {NextLocation, {error, ErrorLocation, {error, Mod, What}}}; {error, terminated} -> throw(St); {error, _} -> File = St#yecc.infile, throw(add_error(File, none, cannot_parse, St)); - {ok, Input, NextLine} -> - {NextLine, case yeccparser:parse(Input) of - {error, {ErrorLine, Mod, Message}} -> - {error, ErrorLine, {error, Mod, Message}}; - {ok, {rule, Rule, {erlang_code, Tokens}}} -> - {rule, Rule, Tokens}; - {ok, {#symbol{name=P}, - [#symbol{name=I} | OpL]}=Ss} -> - A = precedence(P), - if - A =/= unknown, - is_integer(I), - OpL =/= [] -> - Ps = [{Op, I , A} || Op <- OpL], - {prec, Ps}; - true -> - Ss - end; - {ok, Ss} -> - Ss - end} + {ok, AllInput, Input, NextLocation} -> + {NextLocation, + case yeccparser:parse(Input) of + {error, {ErrorLocation, Mod, Message}} -> + {error, ErrorLocation, {error, Mod, Message}}; + {ok, {rule, Rule, {erlang_code, Tokens}}} -> + AllTokens0 = + lists:dropwhile(fun(T) -> element(1, T) =/= ':' end, + AllInput), + AllTokens = case AllTokens0 of + [] -> + Tokens; + _ -> % Remove ':' and dot. + tl(AllTokens0) -- [last(AllTokens0)] + end, + {rule, Rule, Tokens, AllTokens}; + {ok, {#symbol{name=P}, + [#symbol{name=I} | OpL]}=Ss} -> + A = precedence(P), + if + A =/= unknown, + is_integer(I), + OpL =/= [] -> + Ps = [{Op, I , A} || Op <- OpL], + {prec, Ps}; + true -> + Ss + end; + {ok, Ss} -> + Ss + end} end. precedence('Left') -> left; @@ -787,7 +808,8 @@ check_rule(Rule0, {St0,Rules}) -> {add_error(HeadAnno, {undefined_nonterminal, Head}, St0), Rules}; true -> St = check_rhs(tl(Symbols), St0), - Rule = Rule0#rule{anno = HeadAnno, symbols = names(Symbols)}, + Rule = Rule0#rule{location = location(HeadAnno), + symbols = names(Symbols)}, {St, [Rule | Rules]} end. @@ -797,7 +819,7 @@ check_rules(St0) -> [] -> add_error(no_grammar_rules, St); _ -> - Rule = #rule{anno = none, + Rule = #rule{location = none, symbols = [?ACCEPT, St#yecc.rootsymbol], tokens = []}, Rules1 = [Rule | Rules0], @@ -933,9 +955,9 @@ report_errors(St) -> foreach(fun({File,{none,Mod,E}}) -> io:fwrite(<<"~ts: ~ts\n">>, [File,Mod:format_error(E)]); - ({File,{Line,Mod,E}}) -> - io:fwrite(<<"~ts:~w: ~ts\n">>, - [File,Line,Mod:format_error(E)]) + ({File,{Location,Mod,E}}) -> + io:fwrite(<<"~ts:~s: ~ts\n">>, + [File,pos(Location),Mod:format_error(E)]) end, sort(St#yecc.errors)); false -> ok @@ -954,15 +976,20 @@ report_warnings(St) -> io:fwrite(<<"~ts: ~s~ts\n">>, [File,Prefix, Mod:format_error(W)]); - ({File,{Line,Mod,W}}) -> - io:fwrite(<<"~ts:~w: ~s~ts\n">>, - [File,Line,Prefix, + ({File,{Location,Mod,W}}) -> + io:fwrite(<<"~ts:~s: ~s~ts\n">>, + [File,pos(Location),Prefix, Mod:format_error(W)]) end, sort(St#yecc.warnings)); false -> ok end. +pos(Line) when is_integer(Line) -> + io_lib:format("~w", [Line]); +pos({Line, Column}) when is_integer(Line), is_integer(Column) -> + io_lib:format("~w:~w", [Line, Column]). + add_error(E, St) -> add_error(none, E, St). @@ -1021,6 +1048,9 @@ add_roberts_dot([{'dot', Anno} | _], _) -> add_roberts_dot([Token | Tokens], _) -> [Token | add_roberts_dot(Tokens, element(2, Token))]. +-define(PSEUDO_PREFIX, "___"). +-define(PSEUDO_VAR_1, '___1'). + subst_pseudo_vars([], _, St) -> {[], St}; subst_pseudo_vars([H0 | T0], NmbrOfDaughters, St0) -> @@ -1032,7 +1062,9 @@ subst_pseudo_vars({atom, Anno, Atom}, NmbrOfDaughters, St0) -> [$$ | Rest] -> try list_to_integer(Rest) of N when N > 0, N =< NmbrOfDaughters -> - {{var, Anno, list_to_atom(append("__", Rest))}, St0}; + PseudoVarName = append(?PSEUDO_PREFIX, Rest), + NewAnno = erl_anno:set_text(PseudoVarName, Anno), + {{var, NewAnno, list_to_atom(PseudoVarName)}, St0}; _ -> St = add_error(Anno, {undefined_pseudo_variable, Atom}, @@ -1559,13 +1591,13 @@ compute_parse_actions1([#item{rule_pointer = RulePointer, [] -> Lookahead = decode_terminals(Lookahead0, St#yecc.inv_symbol_tab), case rule(RulePointer, St) of - {[?ACCEPT | _], _RuleLine, _} -> + {[?ACCEPT | _], _RuleLocation, _} -> [{Lookahead, accept} | compute_parse_actions1(Items, N, St)]; %% Head is placed after the daughters when finding the %% precedence. This is how giving precedence to %% non-terminals takes effect. - {[Head | Daughters0], _RuleLine, _} -> + {[Head | Daughters0], _RuleLocation, _} -> Daughters = delete('$empty', Daughters0), [{Lookahead, #reduce{rule_nmbr = RulePointer, head = Head, @@ -1577,7 +1609,7 @@ compute_parse_actions1([#item{rule_pointer = RulePointer, case is_terminal(St#yecc.symbol_tab, Symbol) of true -> DecSymbol = decode_symbol(Symbol, St#yecc.inv_symbol_tab), - {[Head | _], _RuleLine, _} = rule(RulePointer, St), + {[Head | _], _RuleLocation, _} = rule(RulePointer, St), %% A bogus shift-shift conflict can be introduced %% here if some terminal occurs in different rules %% which have been given precedence "one level up". @@ -1912,17 +1944,17 @@ conflict(#shift{prec = Prec1, rule_nmbr = RuleNmbr1}, {Symbol, N, Confl, Confl}; conflict(#reduce{rule_nmbr = RuleNmbr1}, NewAction, Cxt) -> #cxt{terminal = Symbol, state_n = N, yecc = St} = Cxt, - {R1, RuleLine1, RuleN1} = rule(RuleNmbr1, St), + {R1, RuleLocation1, RuleN1} = rule(RuleNmbr1, St), Confl = case NewAction of accept -> {accept, St#yecc.rootsymbol}; #reduce{rule_nmbr = RuleNmbr2} -> - {R2, RuleLine2, RuleN2} = rule(RuleNmbr2, St), - {reduce, R2, RuleN2, RuleLine2}; + {R2, RuleLocation2, RuleN2} = rule(RuleNmbr2, St), + {reduce, R2, RuleN2, RuleLocation2}; #shift{state = NewState} -> {shift, NewState, last(R1)} end, - {Symbol, N, {R1, RuleN1, RuleLine1}, Confl}. + {Symbol, N, {R1, RuleN1, RuleLocation1}, Confl}. format_conflict({Symbol, N, _, {one_level_up, {L1, RuleN1, {P1, Ass1}}, @@ -1930,28 +1962,28 @@ format_conflict({Symbol, N, _, {one_level_up, S1 = io_lib:fwrite(<<"Conflicting precedences of symbols when " "scanning ~ts in state ~w:\n">>, [format_symbol(Symbol), N]), - S2 = io_lib:fwrite(<<" ~s ~w (rule ~w at line ~w)\n" + S2 = io_lib:fwrite(<<" ~s ~w (rule ~w ~s)\n" " vs.\n">>, - [format_assoc(Ass1), P1, RuleN1, L1]), - S3 = io_lib:fwrite(<<" ~s ~w (rule ~w at line ~w)\n">>, - [format_assoc(Ass2), P2, RuleN2, L2]), + [format_assoc(Ass1), P1, RuleN1, rule_pos(L1)]), + S3 = io_lib:fwrite(<<" ~s ~w (rule ~w ~s)\n">>, + [format_assoc(Ass2), P2, RuleN2, rule_pos(L2)]), [S1, S2, S3]; format_conflict({Symbol, N, Reduce, Confl}) -> S1 = io_lib:fwrite(<<"Parse action conflict scanning symbol " "~ts in state ~w:\n">>, [format_symbol(Symbol), N]), S2 = case Reduce of - {[HR | TR], RuleNmbr, RuleLine} -> - io_lib:fwrite(<<" Reduce to ~ts from ~ts (rule ~w at " - "line ~w)\n vs.\n">>, + {[HR | TR], RuleNmbr, RuleLocation} -> + io_lib:fwrite(<<" Reduce to ~ts from ~ts (rule ~w " + "~s)\n vs.\n">>, [format_symbol(HR), format_symbols(TR), - RuleNmbr, RuleLine]) + RuleNmbr, rule_pos(RuleLocation)]) end, S3 = case Confl of - {reduce, [HR2|TR2], RuleNmbr2, RuleLine2} -> + {reduce, [HR2|TR2], RuleNmbr2, RuleLocation2} -> io_lib:fwrite(<<" reduce to ~ts from ~ts " - "(rule ~w at line ~w).">>, + "(rule ~w ~s).">>, [format_symbol(HR2), format_symbols(TR2), - RuleNmbr2, RuleLine2]); + RuleNmbr2, rule_pos(RuleLocation2)]); {shift, NewState, Sym} -> io_lib:fwrite(<<" shift to state ~w, adding right " "sisters to ~ts.">>, @@ -1962,6 +1994,11 @@ format_conflict({Symbol, N, Reduce, Confl}) -> end, [S1, S2, S3]. +rule_pos(Line) when is_integer(Line) -> + io_lib:format("at line ~w", [Line]); +rule_pos({Line, Column}) when is_integer(Line), is_integer(Column) -> + io_lib:format("at location ~w:~w", [Line, Column]). + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Code generation: @@ -2107,7 +2144,7 @@ find_user_code(ParseActions, St) -> {Action, Terminals, RuleNmbr, NmbrOfDaughters} <- find_user_code2(La_actions), case tokens(RuleNmbr, St) of - [{var, _, '__1'}] -> NmbrOfDaughters =/= 1; + [{var, _, ?PSEUDO_VAR_1}] -> NmbrOfDaughters =/= 1; _ -> true end, Terminal <- Terminals]. @@ -2273,7 +2310,7 @@ output_reduce(St0, State, Terminal, fwrite(St20, <<" [~s|Nss] = Ss,\n">>, [Tmp]) end, St40 = case tokens(RuleNmbr, St30) of - [{var, _, '__1'}] when NmbrOfDaughters =:= 1 -> + [{var, _, ?PSEUDO_VAR_1}] when NmbrOfDaughters =:= 1 -> NewStack = "Stack", St30; _ -> @@ -2355,14 +2392,14 @@ output_inlined(St0, FunctionName, Reduce, Infile) -> St30; _ -> Stack = "__Stack", - A = concat(flatmap(fun(I) -> [",__",I] end, + A = concat(flatmap(fun(I) -> [",",?PSEUDO_PREFIX,I] end, lists:seq(N_daughters, 1, -1))), fwrite(St30, <<" ~s = __Stack0,\n">>, [append(["[", tl(A), " | __Stack]"])]) end, St = St40#yecc{line = St40#yecc.line + NLines}, - fwrite(St, <<" [begin\n ~ts\n end | ~s].\n\n">>, - [pp_tokens(Tokens, Line0, St#yecc.encoding), Stack]). + fwrite(St, <<" [begin\n~ts\n end | ~s].\n\n">>, + [pp_tokens(Tokens), Stack]). inlined_function_name(St, State, Terminal) -> End = case Terminal of @@ -2376,9 +2413,9 @@ function_name(St, Name, Suf) -> list_to_atom(concat([Name, '_'] ++ [quoted_atom(St, Suf)])). rule(RulePointer, St) -> - #rule{n = N, anno = Anno, symbols = Symbols} = + #rule{n = N, location = Location, symbols = Symbols} = maps:get(RulePointer, St#yecc.rule_pointer2rule), - {Symbols, Anno, N}. + {Symbols, Location, N}. get_rule(RuleNmbr, St) -> maps:get(RuleNmbr, St#yecc.rule_pointer2rule). @@ -2571,37 +2608,19 @@ parse_file(Epp) -> case epp:parse_erl_form(Epp) of {ok, {function,_Anno,yeccpars1,7,_Clauses}} -> {1,4}; - {eof,_Line} -> + {eof,_Location} -> {1,1}; _Form -> parse_file(Epp) end. -%% Keeps the line breaks of the original code. -pp_tokens(Tokens, Line0, Enc) -> - concat(pp_tokens1(Tokens, Line0, Enc, [])). +%% Keeps the line breaks and the column numbers of the original code. +pp_tokens(Tokens) -> + C = first_column(Tokens), + Indent = lists:duplicate(C - 1, $\s), + Text = lists:append([erl_anno:text(anno(T)) || T <- Tokens]), + [Indent, Text]. -pp_tokens1([], _Line0, _Enc, _T0) -> - []; -pp_tokens1([T | Ts], Line0, Enc, T0) -> - Line = location(anno(T)), - [pp_sep(Line, Line0, T0), pp_symbol(T, Enc)|pp_tokens1(Ts, Line, Enc, T)]. - -pp_symbol({var,_,Var}, _Enc) -> Var; -pp_symbol({string,_,String}, latin1) -> - io_lib:write_string_as_latin1(String); -pp_symbol({string,_,String}, _Enc) -> io_lib:write_string(String); -pp_symbol({_,_,Symbol}, latin1) -> io_lib:fwrite(<<"~p">>, [Symbol]); -pp_symbol({_,_,Symbol}, _Enc) -> io_lib:fwrite(<<"~tp">>, [Symbol]); -pp_symbol({Symbol, _}, _Enc) -> Symbol. - -pp_sep(Line, Line0, T0) when Line > Line0 -> - ["\n " | pp_sep(Line - 1, Line0, T0)]; -pp_sep(_Line, _Line0, {'.',_}) -> - ""; -pp_sep(_Line, _Line0, _T0) -> - " ". - set_encoding(#yecc{encoding = none}, Port) -> ok = io:setopts(Port, [{encoding, epp:default_encoding()}]); set_encoding(#yecc{encoding = E}, Port) -> @@ -2618,15 +2637,26 @@ output_file_directive(St, Filename, Line) when St#yecc.file_attrs -> output_file_directive(St, _Filename, _Line) -> St. +first_column(Tokens) -> + case erl_anno:column(anno(hd(Tokens))) of + undefined -> + 1; + Column -> + Column + end. + first_line(Tokens) -> - location(anno(hd(Tokens))). + line(anno(hd(Tokens))). last_line(Tokens) -> - location(anno(lists:last(Tokens))). + line(anno(lists:last(Tokens))). + +line(Anno) -> + erl_anno:line(Anno). location(none) -> none; location(Anno) -> - erl_anno:line(Anno). + erl_anno:location(Anno). anno(Token) -> element(2, Token). @@ -2683,6 +2713,11 @@ format_symbol(Symbol) -> io_lib:fwrite(<<"~tw">>, [Symbol]) end. +line_of_location(Line) when is_integer(Line) -> + Line; +line_of_location({Line, Column}) when is_integer(Line), is_integer(Column) -> + Line. + inverse(L) -> sort([{A,B} || {B,A} <- L]). diff --git a/lib/parsetools/src/yeccgramm.yrl b/lib/parsetools/src/yeccgramm.yrl index 40aa85a43e..77d9f53688 100644 --- a/lib/parsetools/src/yeccgramm.yrl +++ b/lib/parsetools/src/yeccgramm.yrl @@ -43,7 +43,10 @@ strings -> string : ['$1']. strings -> string strings : ['$1' | '$2']. attached_code -> ':' tokens : {erlang_code, '$2'}. attached_code -> '$empty' : {erlang_code, - [{atom, erl_anno:new(0), '$undefined'}]}. + [{atom, + erl_anno:set_text("'$undefined'", + erl_anno:new(0)), + '$undefined'}]}. tokens -> token : ['$1']. tokens -> token tokens : ['$1' | '$2']. symbol -> var : symbol('$1'). diff --git a/lib/parsetools/src/yeccparser.erl b/lib/parsetools/src/yeccparser.erl index 0deecc7879..3da29e1ec9 100644 --- a/lib/parsetools/src/yeccparser.erl +++ b/lib/parsetools/src/yeccparser.erl @@ -1,6 +1,6 @@ -module(yeccparser). -export([parse/1, parse_and_scan/1, format_error/1]). --file("yeccgramm.yrl", 65). +-file("yeccgramm.yrl", 68). -record(symbol, {anno, name}). @@ -41,15 +41,15 @@ anno_of(Token) -> -spec parse(Tokens :: list()) -> yecc_ret(). parse(Tokens) -> - yeccpars0(Tokens, {no_func, no_line}, 0, [], []). + yeccpars0(Tokens, {no_func, no_location}, 0, [], []). -spec parse_and_scan({function() | {atom(), atom()}, [_]} | {atom(), atom(), [_]}) -> yecc_ret(). parse_and_scan({F, A}) -> - yeccpars0([], {{F, A}, no_line}, 0, [], []); + yeccpars0([], {{F, A}, no_location}, 0, [], []); parse_and_scan({M, F, A}) -> Arity = length(A), - yeccpars0([], {{fun M:F/Arity, A}, no_line}, 0, [], []). + yeccpars0([], {{fun M:F/Arity, A}, no_location}, 0, [], []). -spec format_error(any()) -> [char() | list()]. format_error(Message) -> @@ -63,9 +63,9 @@ format_error(Message) -> %% To be used in grammar files to throw an error message to the parser %% toplevel. Doesn't have to be exported! -compile({nowarn_unused_function, return_error/2}). --spec return_error(integer(), any()) -> no_return(). -return_error(Line, Message) -> - throw({error, {Line, ?MODULE, Message}}). +-spec return_error(erl_anno:location(), any()) -> no_return(). +return_error(Location, Message) -> + throw({error, {Location, ?MODULE, Message}}). -define(CODE_VERSION, "1.4"). @@ -80,7 +80,7 @@ yeccpars0(Tokens, Tzr, State, States, Vstack) -> catch _:_ -> erlang:raise(error, Error, Stacktrace) end; %% Probably thrown from return_error/2: - throw: {error, {_Line, ?MODULE, _M}} = Error -> + throw: {error, {_Location, ?MODULE, _M}} = Error -> Error end. @@ -97,22 +97,22 @@ yecc_error_type(function_clause, [{?MODULE,F,ArityOrArgs,_} | _]) -> yeccpars1([Token | Tokens], Tzr, State, States, Vstack) -> yeccpars2(State, element(1, Token), States, Vstack, Token, Tokens, Tzr); -yeccpars1([], {{F, A},_Line}, State, States, Vstack) -> +yeccpars1([], {{F, A},_Location}, State, States, Vstack) -> case apply(F, A) of - {ok, Tokens, Endline} -> - yeccpars1(Tokens, {{F, A}, Endline}, State, States, Vstack); - {eof, Endline} -> - yeccpars1([], {no_func, Endline}, State, States, Vstack); - {error, Descriptor, _Endline} -> + {ok, Tokens, EndLocation} -> + yeccpars1(Tokens, {{F, A}, EndLocation}, State, States, Vstack); + {eof, EndLocation} -> + yeccpars1([], {no_func, EndLocation}, State, States, Vstack); + {error, Descriptor, _EndLocation} -> {error, Descriptor} end; -yeccpars1([], {no_func, no_line}, State, States, Vstack) -> +yeccpars1([], {no_func, no_location}, State, States, Vstack) -> Line = 999999, yeccpars2(State, '$end', States, Vstack, yecc_end(Line), [], {no_func, Line}); -yeccpars1([], {no_func, Endline}, State, States, Vstack) -> - yeccpars2(State, '$end', States, Vstack, yecc_end(Endline), [], - {no_func, Endline}). +yeccpars1([], {no_func, EndLocation}, State, States, Vstack) -> + yeccpars2(State, '$end', States, Vstack, yecc_end(EndLocation), [], + {no_func, EndLocation}). %% yeccpars1/7 is called from generated code. %% @@ -123,21 +123,19 @@ yeccpars1([], {no_func, Endline}, State, States, Vstack) -> yeccpars1(State1, State, States, Vstack, Token0, [Token | Tokens], Tzr) -> yeccpars2(State, element(1, Token), [State1 | States], [Token0 | Vstack], Token, Tokens, Tzr); -yeccpars1(State1, State, States, Vstack, Token0, [], {{_F,_A}, _Line}=Tzr) -> +yeccpars1(State1, State, States, Vstack, Token0, [], {{_F,_A}, _Location}=Tzr) -> yeccpars1([], Tzr, State, [State1 | States], [Token0 | Vstack]); -yeccpars1(State1, State, States, Vstack, Token0, [], {no_func, no_line}) -> - Line = yecctoken_end_location(Token0), +yeccpars1(State1, State, States, Vstack, Token0, [], {no_func, no_location}) -> + Location = yecctoken_end_location(Token0), yeccpars2(State, '$end', [State1 | States], [Token0 | Vstack], - yecc_end(Line), [], {no_func, Line}); -yeccpars1(State1, State, States, Vstack, Token0, [], {no_func, Line}) -> + yecc_end(Location), [], {no_func, Location}); +yeccpars1(State1, State, States, Vstack, Token0, [], {no_func, Location}) -> yeccpars2(State, '$end', [State1 | States], [Token0 | Vstack], - yecc_end(Line), [], {no_func, Line}). + yecc_end(Location), [], {no_func, Location}). %% For internal use only. -yecc_end({Line,_Column}) -> - {'$end', Line}; -yecc_end(Line) -> - {'$end', Line}. +yecc_end(Location) -> + {'$end', Location}. yecctoken_end_location(Token) -> try erl_anno:end_location(element(2, Token)) of @@ -185,7 +183,7 @@ yecctoken2string(Other) -> --file("yeccgramm.erl", 190). +-file("yeccgramm.erl", 186). -dialyzer({nowarn_function, yeccpars2/7}). yeccpars2(0=S, Cat, Ss, Stack, T, Ts, Tzr) -> @@ -286,10 +284,12 @@ yeccpars2_1(S, string, Ss, Stack, T, Ts, Tzr) -> yeccpars2_1(S, var, Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 9, Ss, Stack, T, Ts, Tzr); yeccpars2_1(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccgoto_head(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). + NewStack = yeccpars2_1_(Stack), + yeccgoto_head(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). yeccpars2_2(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccgoto_grammar(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). + NewStack = yeccpars2_2_(Stack), + yeccgoto_grammar(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). -dialyzer({nowarn_function, yeccpars2_3/7}). yeccpars2_3(S, '->', Ss, Stack, T, Ts, Tzr) -> @@ -304,7 +304,8 @@ yeccpars2_4(_, _, _, _, T, _, _) -> yeccerror(T). yeccpars2_5(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccgoto_grammar(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). + NewStack = yeccpars2_5_(Stack), + yeccgoto_grammar(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). yeccpars2_6(_S, Cat, Ss, Stack, T, Ts, Tzr) -> NewStack = yeccpars2_6_(Stack), @@ -415,16 +416,20 @@ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_token(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). yeccpars2_20(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccgoto_token(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). + NewStack = yeccpars2_20_(Stack), + yeccgoto_token(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccgoto_token(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). + NewStack = yeccpars2_21_(Stack), + yeccgoto_token(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccgoto_token(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). + NewStack = yeccpars2_22_(Stack), + yeccgoto_token(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccgoto_token(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). + NewStack = yeccpars2_23_(Stack), + yeccgoto_token(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr) -> NewStack = yeccpars2_24_(Stack), @@ -435,10 +440,12 @@ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_token(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). yeccpars2_26(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccgoto_token(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). + NewStack = yeccpars2_26_(Stack), + yeccgoto_token(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). yeccpars2_27(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccgoto_token(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). + NewStack = yeccpars2_27_(Stack), + yeccgoto_token(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). yeccpars2_28(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_|Nss] = Ss, @@ -539,157 +546,232 @@ yeccgoto_tokens(15=_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_tokens(17=_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_28(_S, Cat, Ss, Stack, T, Ts, Tzr). +-compile({inline,yeccpars2_1_/1}). +-file("yeccgramm.yrl", 35). +yeccpars2_1_(__Stack0) -> + [___1 | __Stack] = __Stack0, + [begin + ___1 + end | __Stack]. + +-compile({inline,yeccpars2_2_/1}). +-file("yeccgramm.yrl", 31). +yeccpars2_2_(__Stack0) -> + [___1 | __Stack] = __Stack0, + [begin + ___1 + end | __Stack]. + +-compile({inline,yeccpars2_5_/1}). +-file("yeccgramm.yrl", 30). +yeccpars2_5_(__Stack0) -> + [___1 | __Stack] = __Stack0, + [begin + ___1 + end | __Stack]. + -compile({inline,yeccpars2_6_/1}). --file("yeccgramm.yrl", 46). +-file("yeccgramm.yrl", 49). yeccpars2_6_(__Stack0) -> - [__1 | __Stack] = __Stack0, + [___1 | __Stack] = __Stack0, [begin - symbol ( __1 ) + symbol(___1) end | __Stack]. -compile({inline,yeccpars2_7_/1}). --file("yeccgramm.yrl", 47). +-file("yeccgramm.yrl", 50). yeccpars2_7_(__Stack0) -> - [__1 | __Stack] = __Stack0, + [___1 | __Stack] = __Stack0, [begin - symbol ( __1 ) + symbol(___1) end | __Stack]. -compile({inline,yeccpars2_8_/1}). --file("yeccgramm.yrl", 48). +-file("yeccgramm.yrl", 51). yeccpars2_8_(__Stack0) -> - [__1 | __Stack] = __Stack0, + [___1 | __Stack] = __Stack0, [begin - symbol ( __1 ) + symbol(___1) end | __Stack]. -compile({inline,yeccpars2_9_/1}). --file("yeccgramm.yrl", 45). +-file("yeccgramm.yrl", 48). yeccpars2_9_(__Stack0) -> - [__1 | __Stack] = __Stack0, + [___1 | __Stack] = __Stack0, [begin - symbol ( __1 ) + symbol(___1) end | __Stack]. -compile({inline,yeccpars2_11_/1}). -file("yeccgramm.yrl", 41). yeccpars2_11_(__Stack0) -> [begin - { erlang_code , - [ { atom , erl_anno : new ( 0 ) , '$undefined' } ] } + {erlang_code, + [{atom, + erl_anno:set_text("'$undefined'", + erl_anno:new(0)), + '$undefined'}]} end | __Stack0]. -compile({inline,yeccpars2_12_/1}). -file("yeccgramm.yrl", 36). yeccpars2_12_(__Stack0) -> - [__1 | __Stack] = __Stack0, + [___1 | __Stack] = __Stack0, [begin - [ __1 ] + [___1] end | __Stack]. -compile({inline,yeccpars2_13_/1}). -file("yeccgramm.yrl", 37). yeccpars2_13_(__Stack0) -> - [__2,__1 | __Stack] = __Stack0, + [___2,___1 | __Stack] = __Stack0, [begin - [ __1 | __2 ] + [___1 | ___2] end | __Stack]. -compile({inline,yeccpars2_16_/1}). -file("yeccgramm.yrl", 40). yeccpars2_16_(__Stack0) -> - [__2,__1 | __Stack] = __Stack0, + [___2,___1 | __Stack] = __Stack0, [begin - { erlang_code , __2 } + {erlang_code, ___2} end | __Stack]. -compile({inline,yeccpars2_17_/1}). --file("yeccgramm.yrl", 43). +-file("yeccgramm.yrl", 46). yeccpars2_17_(__Stack0) -> - [__1 | __Stack] = __Stack0, + [___1 | __Stack] = __Stack0, [begin - [ __1 ] + [___1] end | __Stack]. -compile({inline,yeccpars2_18_/1}). --file("yeccgramm.yrl", 57). +-file("yeccgramm.yrl", 60). yeccpars2_18_(__Stack0) -> - [__1 | __Stack] = __Stack0, + [___1 | __Stack] = __Stack0, [begin - { '->' , anno_of ( __1 ) } + {'->', anno_of(___1)} end | __Stack]. -compile({inline,yeccpars2_19_/1}). --file("yeccgramm.yrl", 58). +-file("yeccgramm.yrl", 61). yeccpars2_19_(__Stack0) -> - [__1 | __Stack] = __Stack0, + [___1 | __Stack] = __Stack0, [begin - { ':' , anno_of ( __1 ) } + {':', anno_of(___1)} end | __Stack]. --compile({inline,yeccpars2_24_/1}). +-compile({inline,yeccpars2_20_/1}). +-file("yeccgramm.yrl", 53). +yeccpars2_20_(__Stack0) -> + [___1 | __Stack] = __Stack0, + [begin + ___1 + end | __Stack]. + +-compile({inline,yeccpars2_21_/1}). +-file("yeccgramm.yrl", 57). +yeccpars2_21_(__Stack0) -> + [___1 | __Stack] = __Stack0, + [begin + ___1 + end | __Stack]. + +-compile({inline,yeccpars2_22_/1}). +-file("yeccgramm.yrl", 54). +yeccpars2_22_(__Stack0) -> + [___1 | __Stack] = __Stack0, + [begin + ___1 + end | __Stack]. + +-compile({inline,yeccpars2_23_/1}). -file("yeccgramm.yrl", 55). +yeccpars2_23_(__Stack0) -> + [___1 | __Stack] = __Stack0, + [begin + ___1 + end | __Stack]. + +-compile({inline,yeccpars2_24_/1}). +-file("yeccgramm.yrl", 58). yeccpars2_24_(__Stack0) -> - [__1 | __Stack] = __Stack0, + [___1 | __Stack] = __Stack0, [begin - { value_of ( __1 ) , anno_of ( __1 ) } + {value_of(___1), anno_of(___1)} end | __Stack]. -compile({inline,yeccpars2_25_/1}). --file("yeccgramm.yrl", 56). +-file("yeccgramm.yrl", 59). yeccpars2_25_(__Stack0) -> - [__1 | __Stack] = __Stack0, + [___1 | __Stack] = __Stack0, [begin - { value_of ( __1 ) , anno_of ( __1 ) } + {value_of(___1), anno_of(___1)} + end | __Stack]. + +-compile({inline,yeccpars2_26_/1}). +-file("yeccgramm.yrl", 56). +yeccpars2_26_(__Stack0) -> + [___1 | __Stack] = __Stack0, + [begin + ___1 + end | __Stack]. + +-compile({inline,yeccpars2_27_/1}). +-file("yeccgramm.yrl", 52). +yeccpars2_27_(__Stack0) -> + [___1 | __Stack] = __Stack0, + [begin + ___1 end | __Stack]. -compile({inline,yeccpars2_28_/1}). --file("yeccgramm.yrl", 44). +-file("yeccgramm.yrl", 47). yeccpars2_28_(__Stack0) -> - [__2,__1 | __Stack] = __Stack0, + [___2,___1 | __Stack] = __Stack0, [begin - [ __1 | __2 ] + [___1 | ___2] end | __Stack]. -compile({inline,yeccpars2_29_/1}). -file("yeccgramm.yrl", 34). yeccpars2_29_(__Stack0) -> - [__5,__4,__3,__2,__1 | __Stack] = __Stack0, + [___5,___4,___3,___2,___1 | __Stack] = __Stack0, [begin - { rule , [ __1 | __3 ] , __4 } + {rule, [___1 | ___3], ___4} end | __Stack]. -compile({inline,yeccpars2_32_/1}). -file("yeccgramm.yrl", 38). yeccpars2_32_(__Stack0) -> - [__1 | __Stack] = __Stack0, + [___1 | __Stack] = __Stack0, [begin - [ __1 ] + [___1] end | __Stack]. -compile({inline,yeccpars2_33_/1}). -file("yeccgramm.yrl", 39). yeccpars2_33_(__Stack0) -> - [__2,__1 | __Stack] = __Stack0, + [___2,___1 | __Stack] = __Stack0, [begin - [ __1 | __2 ] + [___1 | ___2] end | __Stack]. -compile({inline,yeccpars2_34_/1}). -file("yeccgramm.yrl", 33). yeccpars2_34_(__Stack0) -> - [__3,__2,__1 | __Stack] = __Stack0, + [___3,___2,___1 | __Stack] = __Stack0, [begin - { __1 , __2 } + {___1, ___2} end | __Stack]. -compile({inline,yeccpars2_35_/1}). -file("yeccgramm.yrl", 32). yeccpars2_35_(__Stack0) -> - [__3,__2,__1 | __Stack] = __Stack0, + [___3,___2,___1 | __Stack] = __Stack0, [begin - { __1 , __2 } + {___1, ___2} end | __Stack]. --file("yeccgramm.yrl", 77). +-file("yeccgramm.yrl", 80). diff --git a/lib/parsetools/src/yeccscan.erl b/lib/parsetools/src/yeccscan.erl index 6dbf6872bc..aad6f69de5 100644 --- a/lib/parsetools/src/yeccscan.erl +++ b/lib/parsetools/src/yeccscan.erl @@ -22,44 +22,54 @@ -export([scan/1, scan/3]). scan(Inport) -> - scan(Inport, '', 1). + scan(Inport, '', {1, 1}). -scan(Inport, Prompt, Line1) -> - case catch io:scan_erl_form(Inport, Prompt, Line1) of - {eof, Line2} -> - {eof, Line2}; - {ok, Tokens, Line2} -> - case Tokens of +scan(Inport, Prompt, Location1) -> + case catch io:scan_erl_form(Inport, Prompt, Location1, [text, return]) of + {eof, Location2} -> + {eof, Location2}; + {ok, Tokens, Location2} -> + LexedTokens = lex(Tokens), + ParsableTokens = [Token || Token <- LexedTokens, + element(1, Token) =/= white_space, + element(1, Token) =/= comment], + case ParsableTokens of [] -> - scan(Inport, Prompt, Line2); + scan(Inport, Prompt, Location2); _ -> - {ok, lex(Tokens), Line2} + {ok, LexedTokens, ParsableTokens, Location2} end; {error, Reason} -> {error, Reason}; - {error, Descriptor, Line2} -> - {error, Descriptor, Line2}; + {error, Descriptor, Location2} -> + {error, Descriptor, Location2}; {'EXIT', Why} -> - io:format('yeccscan: Error scanning input line ~w~n', [Line1]), + io:format('yeccscan: Error scanning input line ~s~n', + [pos(Location1)]), exit(Why) end. +pos({Line,Col}) -> + io_lib:format("~w:~w", [Line, Col]); +pos(Line) -> + io_lib:format("~w", [Line]). + lex([]) -> []; lex([Token | Tokens]) -> case Token of - {'dot', Line} -> - [{'dot', Line} | lex(Tokens)]; - {':', Line} -> - [{':', Line} | lex(Tokens)]; - {'->', Line} -> - [{'->', Line} | lex(Tokens)]; - {Category, Line, Symbol} -> - [{Category, Line, Symbol} | lex(Tokens)]; - {Other, Line} -> + {'dot', Location} -> + [{'dot', Location} | lex(Tokens)]; + {':', Location} -> + [{':', Location} | lex(Tokens)]; + {'->', Location} -> + [{'->', Location} | lex(Tokens)]; + {Category, Location, Symbol} -> + [{Category, Location, Symbol} | lex(Tokens)]; + {Other, Location} -> Cat = case erl_scan:reserved_word(Other) of true -> reserved_word; false -> reserved_symbol end, - [{Cat, Line, Other} | lex(Tokens)] + [{Cat, Location, Other} | lex(Tokens)] end. diff --git a/lib/parsetools/test/leex_SUITE.erl b/lib/parsetools/test/leex_SUITE.erl index e8ec376d4b..90ab770138 100644 --- a/lib/parsetools/test/leex_SUITE.erl +++ b/lib/parsetools/test/leex_SUITE.erl @@ -130,8 +130,8 @@ file(Config) when is_list(Config) -> ok = file:write_file(LeexPre, <<"syntax error.\n">>), PreErrors = run_test(Config, Mini, LeexPre), {errors, - [{1,_,["syntax error before: ","error"]}, - {3,_,undefined_module}], + [{{1,8},_,["syntax error before: ","error"]}, + {{3,1},_,undefined_module}], []} = extract(LeexPre, PreErrors), file:delete(LeexPre), @@ -297,8 +297,8 @@ syntax(Config) when is_list(Config) -> "an error.\n">>), % syntax error {ok, _, []} = leex:file(Filename, Ret1), {error, - [{_,[{8,_,["syntax error before: ","error"]}]}, - {_,[{6,_,{unbound_var,'DDDD'}}]}], + [{_,[{{8,4},_,["syntax error before: ","error"]}]}, + {_,[{{6,6},_,{unbound_var,'DDDD'}}]}], []} = compile:file(ErlFile, [basic_validation, return]), diff --git a/lib/parsetools/test/yecc_SUITE.erl b/lib/parsetools/test/yecc_SUITE.erl index 4b0f4d81d1..8ad95f2b7f 100644 --- a/lib/parsetools/test/yecc_SUITE.erl +++ b/lib/parsetools/test/yecc_SUITE.erl @@ -203,22 +203,22 @@ syntax(Config) when is_list(Config) -> %% Nonterminals and terminals not disjoint. ok = file:write_file(Filename, <<"Nonterminals nt 't t'. Terminals t 't t'. Rootsymbol nt.">>), - {error,[{_,[{1,yecc,{symbol_terminal_and_nonterminal,'t t'}}, - {none,yecc,no_grammar_rules}]}], + {error,[{_,[{none,yecc,no_grammar_rules}, + {{1,17},yecc,{symbol_terminal_and_nonterminal,'t t'}}]}], []} = yecc:file(Filename, Ret), %% Rootsymbol is not a nonterminal. ok = file:write_file(Filename, <<"Nonterminals nt. Terminals t. Rootsymbol t. nt -> t.">>), - {error,[{_,[{2,yecc,{bad_rootsymbol,t}}]}],[]} = + {error,[{_,[{{2,24},yecc,{bad_rootsymbol,t}}]}],[]} = yecc:file(Filename, Ret), %% Rootsymbol is not a nonterminal. ok = file:write_file(Filename, <<"Nonterminals nt. Terminals t. Rootsymbol t. nt -> t.">>), - {error,[{_,[{2,yecc,{bad_rootsymbol,t}}]}],[]} = + {error,[{_,[{{2,24},yecc,{bad_rootsymbol,t}}]}],[]} = yecc:file(Filename, Ret), %% Endsymbol is a nonterminal. @@ -226,7 +226,7 @@ syntax(Config) when is_list(Config) -> <<"Nonterminals nt. Terminals t. Rootsymbol nt. Endsymbol nt. nt -> t.">>), - {error,[{_,[{2,yecc,{endsymbol_is_nonterminal,nt}}]}],[]} = + {error,[{_,[{{2,23},yecc,{endsymbol_is_nonterminal,nt}}]}],[]} = yecc:file(Filename, Ret), %% Endsymbol is a terminal. @@ -234,7 +234,7 @@ syntax(Config) when is_list(Config) -> <<"Nonterminals nt. Terminals t. Rootsymbol nt. Endsymbol t. nt -> t.">>), - {error,[{_,[{2,yecc,{endsymbol_is_terminal,t}}]}],[]} = + {error,[{_,[{{2,23},yecc,{endsymbol_is_terminal,t}}]}],[]} = yecc:file(Filename, Ret), %% No grammar rules. @@ -247,7 +247,7 @@ syntax(Config) when is_list(Config) -> ok = file:write_file(Filename, <<"Nonterminals nt. Terminals t. Rootsymbol nt. Endsymbol e. nt -> t. e e.">>), - {ok,_,[{_,[{2,yecc,bad_declaration}]}]} = + {ok,_,[{_,[{{2,22},yecc,bad_declaration}]}]} = yecc:file(Filename, Ret), %% Bad declaration with warnings_as_errors. @@ -256,10 +256,10 @@ syntax(Config) when is_list(Config) -> false = filelib:is_regular(Parserfile), error = yecc:file(Filename, [return_warnings,warnings_as_errors]), false = filelib:is_regular(Parserfile), - {error,_,[{_,[{2,yecc,bad_declaration}]}]} = + {error,_,[{_,[{{2,22},yecc,bad_declaration}]}]} = yecc:file(Filename, [return_errors,warnings_as_errors]), false = filelib:is_regular(Parserfile), - {ok,_,[{_,[{2,yecc,bad_declaration}]}]} = + {ok,_,[{_,[{{2,22},yecc,bad_declaration}]}]} = yecc:file(Filename, [return_warnings]), true = filelib:is_regular(Parserfile), @@ -268,21 +268,25 @@ syntax(Config) when is_list(Config) -> <<"Nonterminals nt. Terminals t. Rootsymbol nt nt. Rootsymbol nt. Endsymbol e. nt -> t.">>), - {ok,_,[{_,[{2,yecc,bad_declaration}]}]} = + {ok,_,[{_,[{{2,13},yecc,bad_declaration}]}]} = yecc:file(Filename, Ret), + ?line {ok,_,[{_,[{2,yecc,bad_declaration}]}]} = + yecc:file(Filename, [{error_location, line} | Ret]), %% Syntax error found by yeccparser. ok = file:write_file(Filename, <<"Nonterminals nt. Terminals t. Rootsymbol nt. Endsymbol e. a - a.">>), - {error,[{_,[{2,yecc,{error,_yeccparser,_}}]}],[]} = + {error,[{_,[{{2,15},yecc,{error,_yeccparser,_}}]}],[]} = yecc:file(Filename, Ret), + ?line {error,[{_,[{2,yecc,{error,_yeccparser,_}}]}],[]} = + yecc:file(Filename, [{error_location, line} | Ret]), %% Syntax error: unknown nonterminal. ok = file:write_file(Filename, <<"Nonterminals nt. Terminals t. Rootsymbol nt. Endsymbol e. 'unknown ' -> t.">>), - {error,[{_,[{2,yecc,{undefined_nonterminal,'unknown '}}]}],[]} = + {error,[{_,[{{2,13},yecc,{undefined_nonterminal,'unknown '}}]}],[]} = yecc:file(Filename, Ret), %% Undefined rhs symbols. Note quotes in output. @@ -294,11 +298,11 @@ syntax(Config) when is_list(Config) -> nt -> Nonterminals. Nonterminals -> Terminals receive foo 45 '17' 'a b'.">>), - {error,[{_,[{6,yecc,{undefined_symbol,45}}, - {6,yecc,{undefined_symbol,foo}}, - {6,yecc,{undefined_symbol,'receive'}}, - {7,yecc,{undefined_symbol,'17'}}, - {7,yecc,{undefined_symbol,'a b'}}]}],[]} = + {error,[{_,[{{6,39},yecc,{undefined_symbol,'receive'}}, + {{6,47},yecc,{undefined_symbol,foo}}, + {{6,51},yecc,{undefined_symbol,45}}, + {{7,29},yecc,{undefined_symbol,'17'}}, + {{7,34},yecc,{undefined_symbol,'a b'}}]}],[]} = yecc:file(Filename, Ret), %% '$empty' used early, before Terminals. OK. @@ -308,7 +312,7 @@ syntax(Config) when is_list(Config) -> Terminals t. Rootsymbol nt. Endsymbol e.">>), - {ok,_,[{_,[{3,yecc,{unused_terminal,t}}]}]} = + {ok,_,[{_,[{{3,23},yecc,{unused_terminal,t}}]}]} = yecc:file(Filename, Ret), %% Illegal use of '$empty'. @@ -319,7 +323,7 @@ syntax(Config) when is_list(Config) -> Endsymbol e. nt -> t. nt2 -> t '$empty'.">>), - {error,[{_,[{6,yecc,illegal_empty}]}],[]} = + {error,[{_,[{{6,22},yecc,illegal_empty}]}],[]} = yecc:file(Filename, Ret), ParserFile3 = [{parserfile, Parserfile1}], @@ -336,10 +340,10 @@ syntax(Config) when is_list(Config) -> SzYeccPre = yeccpre_size(), %% Note: checking the line numbers. Changes when yeccpre.hrl changes. fun() -> - {error,[{_,[{5,_,["syntax error before: ","bad"]}]}, - {_,[{L1,_,{undefined_function,{yeccpars2_2_,1}}}, - {L2,_,{bad_inline,{yeccpars2_2_,1}}}]}], - []} = compile:file(Parserfile1, [basic_validation,return]), + {error,[{_,[{{5,25},_,["syntax error before: ","bad"]}]}, + {_,[{{L1,_},_,{undefined_function,{yeccpars2_2_,1}}}, + {{L2,_},_,{bad_inline,{yeccpars2_2_,1}}}]}], + []} = compile:file(Parserfile1, [basic_validation,return]), L1 = 31 + SzYeccPre, L2 = 39 + SzYeccPre end(), @@ -354,10 +358,10 @@ syntax(Config) when is_list(Config) -> {ok, _, []} = yecc:file(Filename, ParserFile3 ++ Ret), %% Note: checking the line numbers. Changes when yeccpre.hrl changes. fun() -> - {error,[{_,[{5,_,{undefined,'F',1}}]}, - {_,[{L1,_,{undefined_function,{yeccpars2_2_,1}}}, - {L2,_,{bad_inline,{yeccpars2_2_,1}}}]}], - []} = compile:file(Parserfile1, [basic_validation,return]), + {error,[{_,[{{5,24},_,{undefined,'F',1}}]}, + {_,[{{L1,_},_,{undefined_function,{yeccpars2_2_,1}}}, + {{L2,_},_,{bad_inline,{yeccpars2_2_,1}}}]}], + []} = compile:file(Parserfile1, [basic_validation,return]), L1 = 31 + SzYeccPre, L2 = 39 + SzYeccPre end(), @@ -374,8 +378,8 @@ syntax(Config) when is_list(Config) -> t() -> bad().">>), {ok, _, []} = yecc:file(Filename, ParserFile3 ++ Ret), - {error,[{_,[{9,_,{undefined_function,{bad,0}}}]}], - [{_,[{8,_,{unused_function,{t,0}}}]}]} + {error,[{_,[{{9,16},_,{undefined_function,{bad,0}}}]}], + [{_,[{{8,13},_,{unused_function,{t,0}}}]}]} = compile:file(Parserfile1, [basic_validation, return]), %% Terminals defined before nonterminals. (One of many checks...) @@ -398,7 +402,8 @@ syntax(Config) when is_list(Config) -> nt -> t. Right t. Left nt 100.">>), - {ok,_,[{_,[{6,yecc,bad_declaration},{7,yecc,bad_declaration}]}]} = + {ok,_,[{_,[{{6,13},yecc,bad_declaration}, + {{7,13},yecc,bad_declaration}]}]} = yecc:file(Filename, Ret), %% Precedence with unknown operator. @@ -409,7 +414,7 @@ syntax(Config) when is_list(Config) -> Endsymbol e. nt -> t. Unary 100 '-'.">>), - {error,[{_,[{6,yecc,{precedence_op_is_unknown,'-'}}]}],[]} = + {error,[{_,[{{6,23},yecc,{precedence_op_is_unknown,'-'}}]}],[]} = yecc:file(Filename, Ret), %% Precedence with endsymbol operator. @@ -420,7 +425,7 @@ syntax(Config) when is_list(Config) -> Endsymbol e. nt -> t. Unary 100 e.">>), - {error,[{_,[{6,yecc,{precedence_op_is_endsymbol,e}}]}],[]} = + {error,[{_,[{{6,23},yecc,{precedence_op_is_endsymbol,e}}]}],[]} = yecc:file(Filename, Ret), %% Duplicated precedence. @@ -434,18 +439,18 @@ syntax(Config) when is_list(Config) -> Left 200 '+'. Left 200 '+'. Right 200 t.">>), - {error,[{_,[{8,yecc,{duplicate_precedence,'+'}}, - {9,yecc,{duplicate_precedence,'+'}}, - {10,yecc,{duplicate_precedence,t}}]}], + {error,[{_,[{{8,22},yecc,{duplicate_precedence,'+'}}, + {{9,22},yecc,{duplicate_precedence,'+'}}, + {{10,23},yecc,{duplicate_precedence,t}}]}], []} = yecc:file(Filename, Ret), %% Duplicated nonterminal. ok = file:write_file(Filename, <<"Nonterminals 'n t' 'n t'. Terminals t. Rootsymbol 'n t'. 'n t' -> t.">>), - {ok, _, [{_,[{1,yecc,{duplicate_nonterminal,'n t'}}]}]} = + {ok, _, [{_,[{{1,14},yecc,{duplicate_nonterminal,'n t'}}]}]} = yecc:file(Filename, Ret), - {ok, _, [{_,[{1,yecc,{duplicate_nonterminal,'n t'}}]}]} = + {ok, _, [{_,[{{1,14},yecc,{duplicate_nonterminal,'n t'}}]}]} = yecc:file(Filename, [return_warnings, {report, false}]), {ok, _} = yecc:file(Filename), {ok, _} = @@ -455,7 +460,7 @@ syntax(Config) when is_list(Config) -> ok = file:write_file(Filename, <<"Nonterminals nt. Terminals 't t' 't t'. Rootsymbol nt. nt -> 't t'.">>), - {ok, _, [{_,[{1,yecc,{duplicate_terminal,'t t'}}]}]} = + {ok, _, [{_,[{{1,28},yecc,{duplicate_terminal,'t t'}}]}]} = yecc:file(Filename, Ret), %% Two Nonterminals declarations. @@ -463,7 +468,7 @@ syntax(Config) when is_list(Config) -> <<"Nonterminals nt. Terminals t. Nonterminals nt2. Rootsymbol nt2. nt -> t. nt2 -> nt.">>), - {error,[{_,[{2,yecc,{duplicate_declaration,'Nonterminals'}}]}], + {error,[{_,[{{2,13},yecc,{duplicate_declaration,'Nonterminals'}}]}], []} = yecc:file(Filename, Ret), %% Three Terminals declarations. @@ -472,15 +477,15 @@ syntax(Config) when is_list(Config) -> Terminals t1. Terminals t1. Rootsymbol nt. nt -> t t1.">>), - {error,[{_,[{2,yecc,{duplicate_declaration,'Terminals'}}, - {3,yecc,{duplicate_declaration,'Terminals'}}]}], + {error,[{_,[{{2,13},yecc,{duplicate_declaration,'Terminals'}}, + {{3,13},yecc,{duplicate_declaration,'Terminals'}}]}], []} = yecc:file(Filename, Ret), %% Two root symbols. ok = file:write_file(Filename, <<"Nonterminals nt. Terminals t. Rootsymbol t. Rootsymbol nt. nt -> t.">>), - {error,[{_,[{2,yecc,{duplicate_declaration,'Rootsymbol'}}]}],[]} = + {error,[{_,[{{2,13},yecc,{duplicate_declaration,'Rootsymbol'}}]}],[]} = yecc:file(Filename, Ret), %% Two end symbols. @@ -488,7 +493,7 @@ syntax(Config) when is_list(Config) -> <<"Nonterminals nt. Terminals t. Rootsymbol t. Endsymbol e. Endsymbol e. nt -> t.">>), - {error,[{_,[{3,yecc,{duplicate_declaration,'Endsymbol'}}]}],[]} = + {error,[{_,[{{3,13},yecc,{duplicate_declaration,'Endsymbol'}}]}],[]} = yecc:file(Filename, Ret), %% Two end symbols. @@ -497,7 +502,7 @@ syntax(Config) when is_list(Config) -> Expect 1. Expect 0. Endsymbol e. nt -> t.">>), - {error,[{_,[{3,yecc,{duplicate_declaration,'Expect'}}]}],[]} = + {error,[{_,[{{3,13},yecc,{duplicate_declaration,'Expect'}}]}],[]} = yecc:file(Filename, Ret), %% Some words should not be used. @@ -508,10 +513,10 @@ syntax(Config) when is_list(Config) -> Endsymbol '$end'. '$undefined' -> '$empty'. ">>), - {error,[{_,[{2,yecc,{reserved,'$empty'}}, - {2,yecc,{reserved,'$end'}}, - {3,yecc,{reserved,'$undefined'}}, - {5,yecc,{endsymbol_is_terminal,'$end'}}]}],[]} = + {error,[{_,[{{2,23},yecc,{reserved,'$empty'}}, + {{2,32},yecc,{reserved,'$end'}}, + {{3,26},yecc,{reserved,'$undefined'}}, + {{5,23},yecc,{endsymbol_is_terminal,'$end'}}]}],[]} = yecc:file(Filename, Ret), %% Undefined pseudo variable. @@ -521,7 +526,7 @@ syntax(Config) when is_list(Config) -> Rootsymbol nt. nt -> t : '$2'. ">>), - {error,[{_,[{5,yecc,{undefined_pseudo_variable,'$2'}}]}],[]} = + {error,[{_,[{{5,25},yecc,{undefined_pseudo_variable,'$2'}}]}],[]} = yecc:file(Filename, Ret), %% Space in module name. @@ -615,13 +620,13 @@ syntax(Config) when is_list(Config) -> ok = file:write_file(Filename, Quotes), {ok,_,[{_, - [{3,yecc,{unused_nonterminal,42}}, - {3,yecc,{unused_nonterminal,' unused '}}, - {3,yecc,{unused_nonterminal,'42'}}, - {3,yecc,{unused_nonterminal,'Unused'}}, - {3,yecc,{unused_nonterminal,'receive'}}, - {6,yecc,{unused_terminal,'"hi"'}}, - {6,yecc,{unused_terminal,'there\''}}]}]} = + [{{3,25},yecc,{unused_nonterminal,42}}, + {{3,28},yecc,{unused_nonterminal,'Unused'}}, + {{3,35},yecc,{unused_nonterminal,' unused '}}, + {{3,46},yecc,{unused_nonterminal,'42'}}, + {{3,61},yecc,{unused_nonterminal,'receive'}}, + {{6,25},yecc,{unused_terminal,'"hi"'}}, + {{6,32},yecc,{unused_terminal,'there\''}}]}]} = yecc:file(Filename, Ret), Ts = [{quotes, Quotes, default, ok}], @@ -635,7 +640,7 @@ syntax(Config) when is_list(Config) -> nt -> t : something. ">>), - {ok,_,[{_,[{2,yecc,{unused_nonterminal,bad}}]}]} = + {ok,_,[{_,[{{2,31},yecc,{unused_nonterminal,bad}}]}]} = yecc:file(Filename, Ret), %% Non-terminal has no rules and is used. @@ -646,7 +651,7 @@ syntax(Config) when is_list(Config) -> nt -> t bad : something. ">>), - {error,[{_,[{2,yecc,{missing_syntax_rule,bad}}]}],[]} = + {error,[{_,[{{2,31},yecc,{missing_syntax_rule,bad}}]}],[]} = yecc:file(Filename, Ret), %% Warning in Erlang code. With and without file attributes. @@ -666,10 +671,10 @@ syntax(Config) when is_list(Config) -> yecc:file(Filename, [file_attributes | Ret]), Opts = [basic_validation, return], Erlfile = filename:join(Dir, "file.erl"), - {ok,[],[{_,[{10,_,_}]}]} = compile:file(Erlfile, Opts), + {ok,[],[{_,[{{10,17},_,_}]}]} = compile:file(Erlfile, Opts), {ok, _, []} = yecc:file(Filename, [{file_attributes,false} | Ret]), - {ok,[],[{_,[{4,_,_}]}]} = compile:file(Erlfile, Opts), + {ok,[],[{_,[{{4,17},_,_}]}]} = compile:file(Erlfile, Opts), file:delete(Parserfile1 ++ ".erl"), file:delete(Parserfile2 ++ ".erl"), @@ -731,7 +736,7 @@ rules(Config) when is_list(Config) -> nt -> '$empty' : '$1'. nt -> t. ">>), - {error,[{_,[{5,yecc,{undefined_pseudo_variable,'$1'}}]}],[]} = + {error,[{_,[{{5,32},yecc,{undefined_pseudo_variable,'$1'}}]}],[]} = yecc:file(Filename, Ret), ok = file:write_file(Filename,<<" @@ -741,7 +746,7 @@ rules(Config) when is_list(Config) -> nt -> '$empty' : '$0'. nt -> t. ">>), - {error,[{_,[{5,yecc,{undefined_pseudo_variable,'$0'}}]}],[]} = + {error,[{_,[{{5,32},yecc,{undefined_pseudo_variable,'$0'}}]}],[]} = yecc:file(Filename, Ret), file:delete(Filename), @@ -790,7 +795,7 @@ expect(Config) when is_list(Config) -> e -> i e t e. e -> i e t e else e. ">>), - {error,[{_,[{5,yecc,{bad_expect,a}}]}],[]} = + {error,[{_,[{{5,24},yecc,{bad_expect,a}}]}],[]} = yecc:file(Filename, Ret), ok = file:write_file(Filename, <<" @@ -825,7 +830,7 @@ expect(Config) when is_list(Config) -> e -> i e t e. e -> i e t e else e. ">>), - {error,[{_,[{5,yecc,{error,_yeccparser,_}}]}],[]} = + {error,[{_,[{{5,24},yecc,{error,_yeccparser,_}}]}],[]} = yecc:file(Filename, Ret), %% States N. An undocumented declaration used for testing. @@ -844,7 +849,7 @@ expect(Config) when is_list(Config) -> Rootsymbol nt. States bad. nt -> t.">>), - {error,[{_,[{5,yecc,{bad_states,bad}}]}],[]} = + {error,[{_,[{{5,24},yecc,{bad_states,bad}}]}],[]} = yecc:file(Filename, Ret), file:delete(Filename), @@ -1543,10 +1548,17 @@ otp_8483(Config) when is_list(Config) -> ok = file:write_file(Input, Bug1), Ret = [return, {report, true}], {error,[{_,[{none,yecc,{conflict,_}}, - {none,yecc,{conflict,_}}, + {none,yecc,{conflict,{'$end',4,{[seq,elem],3,{6,15}}, + {reduce,[seq,seq,elem],4,{7,15}}}}}, {none,yecc,{conflict,_}}]}], [{_,[{none,yecc,{conflicts,1,3}}]}]} = yecc:file(Input, Ret), + {error,[{_,[{none,yecc,{conflict,_}}, + {none,yecc,{conflict,{'$end',4,{[seq,elem],3,6}, + {reduce,[seq,seq,elem],4,7}}}}, + {none,yecc,{conflict,_}}]}], + [{_,[{none,yecc,{conflicts,1,3}}]}]} = + yecc:file(Input, [{error_location, line} | Ret]), file:delete(Input), ok. @@ -1616,10 +1628,10 @@ otp_7292(Config) when is_list(Config) -> fun() -> SzYeccPre = yeccpre_size(), {error, - [{_,[{5,_,["syntax error before: ","bad"]}]}, - {_,[{L1,_,{undefined_function,{yeccpars2_2_,1}}}, - {L2,_,{bad_inline,{yeccpars2_2_,1}}}]}], - [{_,[{16,_,{unused_function,{foo,0}}}]}]} = + [{_,[{{5,32},_,["syntax error before: ","bad"]}]}, + {_,[{{L1,_},_,{undefined_function,{yeccpars2_2_,1}}}, + {{L2,_},_,{bad_inline,{yeccpars2_2_,1}}}]}], + [{_,[{{16,20},_,{unused_function,{foo,0}}}]}]} = compile:file(Parserfile1, [basic_validation, return]), L1 = 41 + SzYeccPre, L2 = 49 + SzYeccPre @@ -1634,10 +1646,10 @@ otp_7292(Config) when is_list(Config) -> fun() -> SzYeccPre = yeccpre_size(YeccPre), {error, - [{_,[{5,_,["syntax error before: ","bad"]}]}, - {_,[{L1,_,{undefined_function,{yeccpars2_2_,1}}}, - {L2,_,{bad_inline,{yeccpars2_2_,1}}}]}], - [{_,[{16,_,{unused_function,{foo,0}}}]}]} = + [{_,[{{5,32},_,["syntax error before: ","bad"]}]}, + {_,[{{L1,_},_,{undefined_function,{yeccpars2_2_,1}}}, + {{L2,_},_,{bad_inline,{yeccpars2_2_,1}}}]}], + [{_,[{{16,20},_,{unused_function,{foo,0}}}]}]} = compile:file(Parserfile1, [basic_validation, return]), L1 = 40 + SzYeccPre, L2 = 48 + SzYeccPre @@ -1775,15 +1787,15 @@ otp_7969(suite) -> []; otp_7969(Config) when is_list(Config) -> {ok,Ts1,_} = erl_scan:string("'foo\nbar'", {1,1}, [text]), - {error,{2,_,["syntax error before: ",[]]}} = erl_parse:parse(Ts1), + {error,{{2,5},_,["syntax error before: ",[]]}} = erl_parse:parse(Ts1), {ok,Ts1_1,_} = erl_scan:string("'foo\nbar'", 1, [text]), {error,{2,_,["syntax error before: ",[]]}} = erl_parse:parse(Ts1_1), {ok,Ts2,_EndLocation} = erl_scan:string("'foo\nbar'", {1,1}, []), - %% Can't do better than report possibly wrong line: - {error,{1,_,["syntax error before: ",[]]}} = erl_parse:parse(Ts2), + %% Can't do better than report possibly wrong location: + {error,{{1,1},_,["syntax error before: ",[]]}} = erl_parse:parse(Ts2), {ok, Ts11, _}=R1 = erl_scan:string("f() -> a."), F1 = fun() -> {ok,Ts11 ++ [{'$end',2}],2} end, @@ -1832,7 +1844,7 @@ otp_10302(Config) when is_list(Config) -> nt -> t.">>, ok = file:write_file(Filename, Mini1), %% This could (and should) be refined: - {error,[{Filename,[{2,Mod1,Err1}]}],[]} = + {error,[{Filename,[{{2,29},Mod1,Err1}]}],[]} = yecc:file(Filename, Ret), "cannot translate from UTF-8" = Mod1:format_error(Err1), @@ -1876,7 +1888,7 @@ otp_10302(Config) when is_list(Config) -> Terminals t. Rootsymbol \"örn_Ð\". Hopp -> t : '$1'.">>), - {error,[{Filename,[{4,yecc,{bad_symbol,"örn_"++[1024]}}]}],[]} = + {error,[{Filename,[{{4,20},yecc,{bad_symbol,"örn_"++[1024]}}]}],[]} = yecc:file(Filename, Ret), ok = file:write_file(Filename, @@ -1886,7 +1898,7 @@ otp_10302(Config) when is_list(Config) -> Rootsymbol Hopp. Endsymbol \"örn_Ð\". Hopp -> t : '$1'.">>), - {error,[{Filename,[{5,yecc,{bad_symbol,"örn_"++[1024]}}]}],[]} = + {error,[{Filename,[{{5,19},yecc,{bad_symbol,"örn_"++[1024]}}]}],[]} = yecc:file(Filename, Ret), ok = file:write_file(Filename, @@ -1896,7 +1908,7 @@ otp_10302(Config) when is_list(Config) -> Rootsymbol Hopp. Expect \"örn_Ð\". Hopp -> t : '$1'.">>), - {error,[{Filename,[{5,yecc,{bad_symbol,"örn_"++[1024]}}]}],[]} = + {error,[{Filename,[{{5,16},yecc,{bad_symbol,"örn_"++[1024]}}]}],[]} = yecc:file(Filename, Ret), ok = file:write_file(Filename, @@ -1906,7 +1918,7 @@ otp_10302(Config) when is_list(Config) -> Rootsymbol Hopp. States \"örn_Ð\". Hopp -> t : '$1'.">>), - {error,[{Filename,[{5,yecc,{bad_symbol,"örn_"++[1024]}}]}],[]} = + {error,[{Filename,[{{5,16},yecc,{bad_symbol,"örn_"++[1024]}}]}],[]} = yecc:file(Filename, Ret), Ts = [{otp_10302_1,<<" @@ -2144,7 +2156,7 @@ otp_17023(Config) -> Rootsymbol nt. nt -> t : '$2'. ">>), - {error,[{_,[{5,yecc,{undefined_pseudo_variable,'$2'}}]}],[]} = + {error,[{_,[{{5,25},yecc,{undefined_pseudo_variable,'$2'}}]}],[]} = yecc:file(Filename, Ret), true = os:putenv("ERL_COMPILER_OPTIONS", "{return, false}"), error = yecc:file(Filename, Ret), diff --git a/lib/stdlib/doc/src/epp.xml b/lib/stdlib/doc/src/epp.xml index 29d3a488c8..1c5fefe559 100644 --- a/lib/stdlib/doc/src/epp.xml +++ b/lib/stdlib/doc/src/epp.xml @@ -132,6 +132,9 @@ <c><anno>Options</anno></c>, the return value is <c>{ok, <anno>Epp</anno>, <anno>Extra</anno>}</c> instead of <c>{ok, <anno>Epp</anno>}</c>.</p> + <p>The option <c>location</c> is forwarded + to the Erlang token scanner, see + <seemfa marker="erl_scan#tokens/3"><c>erl_scan:tokens/3,4</c></seemfa>.</p> </desc> </func> @@ -160,8 +163,8 @@ <type name="warning_info"/> <desc> <p>Returns the next Erlang form from the opened Erlang source file. - Tuple <c>{eof, <anno>Line</anno>}</c> is returned at the end of the - file. The first form corresponds to an implicit attribute + Tuple <c>{eof, <anno>Location</anno>}</c> is returned at the end + of the file. The first form corresponds to an implicit attribute <c>-file(File,1).</c>, where <c>File</c> is the file name.</p> </desc> </func> @@ -171,7 +174,7 @@ <fsummary>Preprocess and parse an Erlang source file.</fsummary> <desc> <p>Preprocesses and parses an Erlang source file. - Notice that tuple <c>{eof, <anno>Line</anno>}</c> returned at the + Notice that tuple <c>{eof, <anno>Location</anno>}</c> returned at the end of the file is included as a "form".</p> <p>If you want to change the file name of the implicit -file() attributes inserted during preprocessing, you can do with @@ -181,6 +184,9 @@ <c><anno>Options</anno></c>, the return value is <c>{ok, [<anno>Form</anno>], <anno>Extra</anno>}</c> instead of <c>{ok, [<anno>Form</anno>]}</c>.</p> + <p>The option <c>location</c> is forwarded + to the Erlang token scanner, see + <seemfa marker="erl_scan#tokens/3"><c>erl_scan:tokens/3,4</c></seemfa>.</p> </desc> </func> diff --git a/lib/stdlib/doc/src/erl_id_trans.xml b/lib/stdlib/doc/src/erl_id_trans.xml index 337cb6215f..82308a2c87 100644 --- a/lib/stdlib/doc/src/erl_id_trans.xml +++ b/lib/stdlib/doc/src/erl_id_trans.xml @@ -42,6 +42,14 @@ parse transformers. If option <c>{parse_transform,Module}</c> is passed to the compiler, a user-written function <c>parse_transform/2</c> is called by the compiler before the code is checked for errors.</p> + <p>Before the function <c>parse_transform</c> is called, the Erlang + Compiler checks if the parse transformation can handle abstract code + with column numbers: If the function <c>parse_transform_info/0</c> + is implemented and returns a map where the key <c>error_location</c> is + associated with the value <c>line</c>, the compiler removes + column numbers from the abstract code before calling the parse + transform. Otherwise, the compiler passes the abstract code on + without modification.</p> </description> <funcs> @@ -58,6 +66,18 @@ </p> </desc> </func> + + <func> + <name since="OTP-24">parse_transform_info() -> Info</name> + <fsummary>Return information about the parse transform itself.</fsummary> + <type> + <v>Info = #{'error_location' => 'column' | 'line'}</v> + </type> + <desc> + <p>Returns information about the parse transform itself.</p> + </desc> + </func> + </funcs> <section> diff --git a/lib/stdlib/doc/src/shell.xml b/lib/stdlib/doc/src/shell.xml index 62ce63ec33..dc68af4328 100644 --- a/lib/stdlib/doc/src/shell.xml +++ b/lib/stdlib/doc/src/shell.xml @@ -353,7 +353,7 @@ ok</pre> <pre> 12> <input>P.</input> -* 1: variable 'P' is unbound +* 1:1: variable 'P' is unbound 13> <input>Descriptor.</input> {4,abcd}</pre> @@ -418,7 +418,7 @@ worked <pre> 23> <input>Z.</input> -* 1: variable 'Z' is unbound +* 1:1: variable 'Z' is unbound 24> <input>get(aa).</input> hello</pre> @@ -520,7 +520,7 @@ ok</pre> <pre> 39> <input>rd(rec, {c}), A.</input> -* 1: variable 'A' is unbound +* 1:15: variable 'A' is unbound 40> <input>#rec{}.</input> #rec{c = undefined} ok</pre> diff --git a/lib/stdlib/examples/erl_id_trans.erl b/lib/stdlib/examples/erl_id_trans.erl index f18e13a565..0aa23fb8b3 100644 --- a/lib/stdlib/examples/erl_id_trans.erl +++ b/lib/stdlib/examples/erl_id_trans.erl @@ -25,11 +25,14 @@ %% N.B. if this module is to be used as a basis for transforms then %% all the error cases must be handled otherwise this module just crashes! --export([parse_transform/2]). +-export([parse_transform/2, parse_transform_info/0]). parse_transform(Forms, _Options) -> forms(Forms). +parse_transform_info() -> + #{columns => true}. + %% forms(Fs) -> lists:map(fun (F) -> form(F) end, Fs). forms([F0|Fs0]) -> @@ -43,60 +46,60 @@ forms([]) -> []. %% that the ordering is correct! %% First the various attributes. -form({attribute,Line,module,Mod}) -> - {attribute,Line,module,Mod}; -form({attribute,Line,file,{File,Line}}) -> %This is valid anywhere. - {attribute,Line,file,{File,Line}}; -form({attribute,Line,export,Es0}) -> +form({attribute,Anno,module,Mod}) -> + {attribute,Anno,module,Mod}; +form({attribute,Anno,file,{File,Line}}) -> %This is valid anywhere. + {attribute,Anno,file,{File,Line}}; +form({attribute,Anno,export,Es0}) -> Es1 = farity_list(Es0), - {attribute,Line,export,Es1}; -form({attribute,Line,import,{Mod,Is0}}) -> + {attribute,Anno,export,Es1}; +form({attribute,Anno,import,{Mod,Is0}}) -> Is1 = farity_list(Is0), - {attribute,Line,import,{Mod,Is1}}; -form({attribute,Line,export_type,Es0}) -> + {attribute,Anno,import,{Mod,Is1}}; +form({attribute,Anno,export_type,Es0}) -> Es1 = farity_list(Es0), - {attribute,Line,export_type,Es1}; -form({attribute,Line,optional_callbacks,Es0}) -> + {attribute,Anno,export_type,Es1}; +form({attribute,Anno,optional_callbacks,Es0}) -> try farity_list(Es0) of Es1 -> - {attribute,Line,optional_callbacks,Es1} + {attribute,Anno,optional_callbacks,Es1} catch _:_ -> - {attribute,Line,optional_callbacks,Es0} + {attribute,Anno,optional_callbacks,Es0} end; -form({attribute,Line,compile,C}) -> - {attribute,Line,compile,C}; -form({attribute,Line,record,{Name,Defs0}}) -> +form({attribute,Anno,compile,C}) -> + {attribute,Anno,compile,C}; +form({attribute,Anno,record,{Name,Defs0}}) -> Defs1 = record_defs(Defs0), - {attribute,Line,record,{Name,Defs1}}; -form({attribute,Line,asm,{function,N,A,Code}}) -> - {attribute,Line,asm,{function,N,A,Code}}; -form({attribute,Line,type,{N,T,Vs}}) -> + {attribute,Anno,record,{Name,Defs1}}; +form({attribute,Anno,asm,{function,N,A,Code}}) -> + {attribute,Anno,asm,{function,N,A,Code}}; +form({attribute,Anno,type,{N,T,Vs}}) -> T1 = type(T), Vs1 = variable_list(Vs), - {attribute,Line,type,{N,T1,Vs1}}; -form({attribute,Line,opaque,{N,T,Vs}}) -> + {attribute,Anno,type,{N,T1,Vs1}}; +form({attribute,Anno,opaque,{N,T,Vs}}) -> T1 = type(T), Vs1 = variable_list(Vs), - {attribute,Line,opaque,{N,T1,Vs1}}; -form({attribute,Line,spec,{{N,A},FTs}}) -> + {attribute,Anno,opaque,{N,T1,Vs1}}; +form({attribute,Anno,spec,{{N,A},FTs}}) -> FTs1 = function_type_list(FTs), - {attribute,Line,spec,{{N,A},FTs1}}; -form({attribute,Line,spec,{{M,N,A},FTs}}) -> + {attribute,Anno,spec,{{N,A},FTs1}}; +form({attribute,Anno,spec,{{M,N,A},FTs}}) -> FTs1 = function_type_list(FTs), - {attribute,Line,spec,{{M,N,A},FTs1}}; -form({attribute,Line,callback,{{N,A},FTs}}) -> + {attribute,Anno,spec,{{M,N,A},FTs1}}; +form({attribute,Anno,callback,{{N,A},FTs}}) -> FTs1 = function_type_list(FTs), - {attribute,Line,callback,{{N,A},FTs1}}; -form({attribute,Line,Attr,Val}) -> %The general attribute. - {attribute,Line,Attr,Val}; -form({function,Line,Name0,Arity0,Clauses0}) -> + {attribute,Anno,callback,{{N,A},FTs1}}; +form({attribute,Anno,Attr,Val}) -> %The general attribute. + {attribute,Anno,Attr,Val}; +form({function,Anno,Name0,Arity0,Clauses0}) -> {Name,Arity,Clauses} = function(Name0, Arity0, Clauses0), - {function,Line,Name,Arity,Clauses}; + {function,Anno,Name,Arity,Clauses}; %% Extra forms from the parser. form({error,E}) -> {error,E}; form({warning,W}) -> {warning,W}; -form({eof,Line}) -> {eof,Line}. +form({eof,Location}) -> {eof,Location}. %% -type farity_list([Farity]) -> [Farity] when Farity <= {atom(),integer()}. @@ -106,28 +109,28 @@ farity_list([]) -> []. %% -type variable_list([Var]) -> [Var] -variable_list([{var,Line,Var}|Vs]) -> - [{var,Line,Var}|variable_list(Vs)]; +variable_list([{var,Anno,Var}|Vs]) -> + [{var,Anno,Var}|variable_list(Vs)]; variable_list([]) -> []. %% -type record_defs([RecDef]) -> [RecDef]. %% N.B. Field names are full expressions here but only atoms are allowed %% by the *parser*! -record_defs([{record_field,Line,{atom,La,A},Val0}|Is]) -> +record_defs([{record_field,Anno,{atom,Aa,A},Val0}|Is]) -> Val1 = expr(Val0), - [{record_field,Line,{atom,La,A},Val1}|record_defs(Is)]; -record_defs([{record_field,Line,{atom,La,A}}|Is]) -> - [{record_field,Line,{atom,La,A}}|record_defs(Is)]; -record_defs([{typed_record_field,{record_field,Line,{atom,La,A},Val0},Type}| + [{record_field,Anno,{atom,Aa,A},Val1}|record_defs(Is)]; +record_defs([{record_field,Anno,{atom,Aa,A}}|Is]) -> + [{record_field,Anno,{atom,Aa,A}}|record_defs(Is)]; +record_defs([{typed_record_field,{record_field,Anno,{atom,Aa,A},Val0},Type}| Is]) -> Val1 = expr(Val0), Type1 = type(Type), - [{typed_record_field,{record_field,Line,{atom,La,A},Val1},Type1}| + [{typed_record_field,{record_field,Anno,{atom,Aa,A},Val1},Type1}| record_defs(Is)]; -record_defs([{typed_record_field,{record_field,Line,{atom,La,A}},Type}|Is]) -> +record_defs([{typed_record_field,{record_field,Anno,{atom,Aa,A}},Type}|Is]) -> Type1 = type(Type), - [{typed_record_field,{record_field,Line,{atom,La,A}},Type1}| + [{typed_record_field,{record_field,Anno,{atom,Aa,A}},Type1}| record_defs(Is)]; record_defs([]) -> []. @@ -146,11 +149,11 @@ clauses([]) -> []. %% -type clause(Clause) -> Clause. -clause({clause,Line,H0,G0,B0}) -> +clause({clause,Anno,H0,G0,B0}) -> H1 = head(H0), G1 = guard(G0), B1 = exprs(B0), - {clause,Line,H1,G1,B1}. + {clause,Anno,H1,G1,B1}. %% -type head([Pattern]) -> [Pattern]. @@ -168,54 +171,54 @@ patterns([]) -> []. %% -type pattern(Pattern) -> Pattern. %% N.B. Only valid patterns are included here. -pattern({var,Line,V}) -> {var,Line,V}; -pattern({match,Line,L0,R0}) -> +pattern({var,Anno,V}) -> {var,Anno,V}; +pattern({match,Anno,L0,R0}) -> L1 = pattern(L0), R1 = pattern(R0), - {match,Line,L1,R1}; -pattern({integer,Line,I}) -> {integer,Line,I}; -pattern({char,Line,C}) -> {char,Line,C}; -pattern({float,Line,F}) -> {float,Line,F}; -pattern({atom,Line,A}) -> {atom,Line,A}; -pattern({string,Line,S}) -> {string,Line,S}; -pattern({nil,Line}) -> {nil,Line}; -pattern({cons,Line,H0,T0}) -> + {match,Anno,L1,R1}; +pattern({integer,Anno,I}) -> {integer,Anno,I}; +pattern({char,Anno,C}) -> {char,Anno,C}; +pattern({float,Anno,F}) -> {float,Anno,F}; +pattern({atom,Anno,A}) -> {atom,Anno,A}; +pattern({string,Anno,S}) -> {string,Anno,S}; +pattern({nil,Anno}) -> {nil,Anno}; +pattern({cons,Anno,H0,T0}) -> H1 = pattern(H0), T1 = pattern(T0), - {cons,Line,H1,T1}; -pattern({tuple,Line,Ps0}) -> + {cons,Anno,H1,T1}; +pattern({tuple,Anno,Ps0}) -> Ps1 = pattern_list(Ps0), - {tuple,Line,Ps1}; -pattern({map,Line,Ps0}) -> + {tuple,Anno,Ps1}; +pattern({map,Anno,Ps0}) -> Ps1 = pattern_list(Ps0), - {map,Line,Ps1}; -pattern({map_field_exact,Line,K,V}) -> + {map,Anno,Ps1}; +pattern({map_field_exact,Anno,K,V}) -> Ke = expr(K), Ve = pattern(V), - {map_field_exact,Line,Ke,Ve}; -pattern({record,Line,Name,Pfs0}) -> + {map_field_exact,Anno,Ke,Ve}; +pattern({record,Anno,Name,Pfs0}) -> Pfs1 = pattern_fields(Pfs0), - {record,Line,Name,Pfs1}; -pattern({record_index,Line,Name,Field0}) -> + {record,Anno,Name,Pfs1}; +pattern({record_index,Anno,Name,Field0}) -> Field1 = pattern(Field0), - {record_index,Line,Name,Field1}; -pattern({record_field,Line,Rec0,Name,Field0}) -> + {record_index,Anno,Name,Field1}; +pattern({record_field,Anno,Rec0,Name,Field0}) -> Rec1 = expr(Rec0), Field1 = expr(Field0), - {record_field,Line,Rec1,Name,Field1}; -pattern({record_field,Line,Rec0,Field0}) -> + {record_field,Anno,Rec1,Name,Field1}; +pattern({record_field,Anno,Rec0,Field0}) -> Rec1 = expr(Rec0), Field1 = expr(Field0), - {record_field,Line,Rec1,Field1}; -pattern({bin,Line,Fs}) -> + {record_field,Anno,Rec1,Field1}; +pattern({bin,Anno,Fs}) -> Fs2 = pattern_grp(Fs), - {bin,Line,Fs2}; -pattern({op,Line,Op,A}) -> - {op,Line,Op,A}; -pattern({op,Line,Op,L,R}) -> - {op,Line,Op,L,R}. + {bin,Anno,Fs2}; +pattern({op,Anno,Op,A}) -> + {op,Anno,Op,A}; +pattern({op,Anno,Op,L,R}) -> + {op,Anno,Op,L,R}. -pattern_grp([{bin_element,L1,E1,S1,T1} | Fs]) -> +pattern_grp([{bin_element,Anno,E1,S1,T1} | Fs]) -> S2 = case S1 of default -> default; @@ -228,7 +231,7 @@ pattern_grp([{bin_element,L1,E1,S1,T1} | Fs]) -> _ -> bit_types(T1) end, - [{bin_element,L1,expr(E1),S2,T2} | pattern_grp(Fs)]; + [{bin_element,Anno,expr(E1),S2,T2} | pattern_grp(Fs)]; pattern_grp([]) -> []. @@ -254,12 +257,12 @@ pattern_list([]) -> []. %% N.B. Field names are full expressions here but only atoms are allowed %% by the *linter*!. -pattern_fields([{record_field,Lf,{atom,La,F},P0}|Pfs]) -> +pattern_fields([{record_field,Af,{atom,Aa,F},P0}|Pfs]) -> P1 = pattern(P0), - [{record_field,Lf,{atom,La,F},P1}|pattern_fields(Pfs)]; -pattern_fields([{record_field,Lf,{var,La,'_'},P0}|Pfs]) -> + [{record_field,Af,{atom,Aa,F},P1}|pattern_fields(Pfs)]; +pattern_fields([{record_field,Af,{var,Aa,'_'},P0}|Pfs]) -> P1 = pattern(P0), - [{record_field,Lf,{var,La,'_'},P1}|pattern_fields(Pfs)]; + [{record_field,Af,{var,Aa,'_'},P1}|pattern_fields(Pfs)]; pattern_fields([]) -> []. %% -type guard([GuardTest]) -> [GuardTest]. @@ -274,11 +277,11 @@ guard0([G0|Gs]) -> [G1|guard0(Gs)]; guard0([]) -> []. -guard_test(Expr={call,Line,{atom,La,F},As0}) -> +guard_test(Expr={call,Anno,{atom,Aa,F},As0}) -> case erl_internal:type_test(F, length(As0)) of true -> As1 = gexpr_list(As0), - {call,Line,{atom,La,F},As1}; + {call,Anno,{atom,Aa,F},As1}; _ -> gexpr(Expr) end; @@ -290,80 +293,80 @@ guard_test(Any) -> %% there is no need for a special clause for the toplevel expressions. %% -type gexpr(GuardExpr) -> GuardExpr. -gexpr({var,Line,V}) -> {var,Line,V}; -gexpr({integer,Line,I}) -> {integer,Line,I}; -gexpr({char,Line,C}) -> {char,Line,C}; -gexpr({float,Line,F}) -> {float,Line,F}; -gexpr({atom,Line,A}) -> {atom,Line,A}; -gexpr({string,Line,S}) -> {string,Line,S}; -gexpr({nil,Line}) -> {nil,Line}; -gexpr({map,Line,Map0,Es0}) -> +gexpr({var,Anno,V}) -> {var,Anno,V}; +gexpr({integer,Anno,I}) -> {integer,Anno,I}; +gexpr({char,Anno,C}) -> {char,Anno,C}; +gexpr({float,Anno,F}) -> {float,Anno,F}; +gexpr({atom,Anno,A}) -> {atom,Anno,A}; +gexpr({string,Anno,S}) -> {string,Anno,S}; +gexpr({nil,Anno}) -> {nil,Anno}; +gexpr({map,Anno,Map0,Es0}) -> [Map1|Es1] = gexpr_list([Map0|Es0]), - {map,Line,Map1,Es1}; -gexpr({map,Line,Es0}) -> + {map,Anno,Map1,Es1}; +gexpr({map,Anno,Es0}) -> Es1 = gexpr_list(Es0), - {map,Line,Es1}; -gexpr({map_field_assoc,Line,K,V}) -> + {map,Anno,Es1}; +gexpr({map_field_assoc,Anno,K,V}) -> Ke = gexpr(K), Ve = gexpr(V), - {map_field_assoc,Line,Ke,Ve}; -gexpr({map_field_exact,Line,K,V}) -> + {map_field_assoc,Anno,Ke,Ve}; +gexpr({map_field_exact,Anno,K,V}) -> Ke = gexpr(K), Ve = gexpr(V), - {map_field_exact,Line,Ke,Ve}; -gexpr({cons,Line,H0,T0}) -> + {map_field_exact,Anno,Ke,Ve}; +gexpr({cons,Anno,H0,T0}) -> H1 = gexpr(H0), T1 = gexpr(T0), %They see the same variables - {cons,Line,H1,T1}; -gexpr({tuple,Line,Es0}) -> + {cons,Anno,H1,T1}; +gexpr({tuple,Anno,Es0}) -> Es1 = gexpr_list(Es0), - {tuple,Line,Es1}; -gexpr({record_index,Line,Name,Field0}) -> + {tuple,Anno,Es1}; +gexpr({record_index,Anno,Name,Field0}) -> Field1 = gexpr(Field0), - {record_index,Line,Name,Field1}; -gexpr({record_field,Line,Rec0,Name,Field0}) -> + {record_index,Anno,Name,Field1}; +gexpr({record_field,Anno,Rec0,Name,Field0}) -> Rec1 = gexpr(Rec0), Field1 = gexpr(Field0), - {record_field,Line,Rec1,Name,Field1}; -gexpr({record,Line,Name,Inits0}) -> + {record_field,Anno,Rec1,Name,Field1}; +gexpr({record,Anno,Name,Inits0}) -> Inits1 = grecord_inits(Inits0), - {record,Line,Name,Inits1}; -gexpr({call,Line,{atom,La,F},As0}) -> + {record,Anno,Name,Inits1}; +gexpr({call,Anno,{atom,Aa,F},As0}) -> case erl_internal:guard_bif(F, length(As0)) of true -> As1 = gexpr_list(As0), - {call,Line,{atom,La,F},As1} + {call,Anno,{atom,Aa,F},As1} end; % Guard bif's can be remote, but only in the module erlang... -gexpr({call,Line,{remote,La,{atom,Lb,erlang},{atom,Lc,F}},As0}) -> +gexpr({call,Anno,{remote,Aa,{atom,Ab,erlang},{atom,Ac,F}},As0}) -> case erl_internal:guard_bif(F, length(As0)) or erl_internal:arith_op(F, length(As0)) or erl_internal:comp_op(F, length(As0)) or erl_internal:bool_op(F, length(As0)) of true -> As1 = gexpr_list(As0), - {call,Line,{remote,La,{atom,Lb,erlang},{atom,Lc,F}},As1} + {call,Anno,{remote,Aa,{atom,Ab,erlang},{atom,Ac,F}},As1} end; -gexpr({bin,Line,Fs}) -> +gexpr({bin,Anno,Fs}) -> Fs2 = pattern_grp(Fs), - {bin,Line,Fs2}; -gexpr({op,Line,Op,A0}) -> + {bin,Anno,Fs2}; +gexpr({op,Anno,Op,A0}) -> case erl_internal:arith_op(Op, 1) or erl_internal:bool_op(Op, 1) of true -> A1 = gexpr(A0), - {op,Line,Op,A1} + {op,Anno,Op,A1} end; -gexpr({op,Line,Op,L0,R0}) when Op =:= 'andalso'; Op =:= 'orelse' -> +gexpr({op,Anno,Op,L0,R0}) when Op =:= 'andalso'; Op =:= 'orelse' -> %% R11B: andalso/orelse are now allowed in guards. L1 = gexpr(L0), R1 = gexpr(R0), %They see the same variables - {op,Line,Op,L1,R1}; -gexpr({op,Line,Op,L0,R0}) -> + {op,Anno,Op,L1,R1}; +gexpr({op,Anno,Op,L0,R0}) -> case erl_internal:arith_op(Op, 2) or erl_internal:bool_op(Op, 2) or erl_internal:comp_op(Op, 2) of true -> L1 = gexpr(L0), R1 = gexpr(R0), %They see the same variables - {op,Line,Op,L1,R1} + {op,Anno,Op,L1,R1} end. %% -type gexpr_list([GuardExpr]) -> [GuardExpr]. @@ -375,12 +378,12 @@ gexpr_list([E0|Es]) -> [E1|gexpr_list(Es)]; gexpr_list([]) -> []. -grecord_inits([{record_field,Lf,{atom,La,F},Val0}|Is]) -> +grecord_inits([{record_field,Af,{atom,Aa,F},Val0}|Is]) -> Val1 = gexpr(Val0), - [{record_field,Lf,{atom,La,F},Val1}|grecord_inits(Is)]; -grecord_inits([{record_field,Lf,{var,La,'_'},Val0}|Is]) -> + [{record_field,Af,{atom,Aa,F},Val1}|grecord_inits(Is)]; +grecord_inits([{record_field,Af,{var,Aa,'_'},Val0}|Is]) -> Val1 = gexpr(Val0), - [{record_field,Lf,{var,La,'_'},Val1}|grecord_inits(Is)]; + [{record_field,Af,{var,Aa,'_'},Val1}|grecord_inits(Is)]; grecord_inits([]) -> []. %% -type exprs([Expression]) -> [Expression]. @@ -394,130 +397,130 @@ exprs([]) -> []. %% -type expr(Expression) -> Expression. -expr({var,Line,V}) -> {var,Line,V}; -expr({integer,Line,I}) -> {integer,Line,I}; -expr({float,Line,F}) -> {float,Line,F}; -expr({atom,Line,A}) -> {atom,Line,A}; -expr({string,Line,S}) -> {string,Line,S}; -expr({char,Line,C}) -> {char,Line,C}; -expr({nil,Line}) -> {nil,Line}; -expr({cons,Line,H0,T0}) -> +expr({var,Anno,V}) -> {var,Anno,V}; +expr({integer,Anno,I}) -> {integer,Anno,I}; +expr({float,Anno,F}) -> {float,Anno,F}; +expr({atom,Anno,A}) -> {atom,Anno,A}; +expr({string,Anno,S}) -> {string,Anno,S}; +expr({char,Anno,C}) -> {char,Anno,C}; +expr({nil,Anno}) -> {nil,Anno}; +expr({cons,Anno,H0,T0}) -> H1 = expr(H0), T1 = expr(T0), %They see the same variables - {cons,Line,H1,T1}; -expr({lc,Line,E0,Qs0}) -> + {cons,Anno,H1,T1}; +expr({lc,Anno,E0,Qs0}) -> Qs1 = lc_bc_quals(Qs0), E1 = expr(E0), - {lc,Line,E1,Qs1}; -expr({bc,Line,E0,Qs0}) -> + {lc,Anno,E1,Qs1}; +expr({bc,Anno,E0,Qs0}) -> Qs1 = lc_bc_quals(Qs0), E1 = expr(E0), - {bc,Line,E1,Qs1}; -expr({tuple,Line,Es0}) -> + {bc,Anno,E1,Qs1}; +expr({tuple,Anno,Es0}) -> Es1 = expr_list(Es0), - {tuple,Line,Es1}; -expr({map,Line,Map0,Es0}) -> + {tuple,Anno,Es1}; +expr({map,Anno,Map0,Es0}) -> [Map1|Es1] = exprs([Map0|Es0]), - {map,Line,Map1,Es1}; -expr({map,Line,Es0}) -> + {map,Anno,Map1,Es1}; +expr({map,Anno,Es0}) -> Es1 = exprs(Es0), - {map,Line,Es1}; -expr({map_field_assoc,Line,K,V}) -> + {map,Anno,Es1}; +expr({map_field_assoc,Anno,K,V}) -> Ke = expr(K), Ve = expr(V), - {map_field_assoc,Line,Ke,Ve}; -expr({map_field_exact,Line,K,V}) -> + {map_field_assoc,Anno,Ke,Ve}; +expr({map_field_exact,Anno,K,V}) -> Ke = expr(K), Ve = expr(V), - {map_field_exact,Line,Ke,Ve}; -expr({record_index,Line,Name,Field0}) -> + {map_field_exact,Anno,Ke,Ve}; +expr({record_index,Anno,Name,Field0}) -> Field1 = expr(Field0), - {record_index,Line,Name,Field1}; -expr({record,Line,Name,Inits0}) -> + {record_index,Anno,Name,Field1}; +expr({record,Anno,Name,Inits0}) -> Inits1 = record_inits(Inits0), - {record,Line,Name,Inits1}; -expr({record_field,Line,Rec0,Name,Field0}) -> + {record,Anno,Name,Inits1}; +expr({record_field,Anno,Rec0,Name,Field0}) -> Rec1 = expr(Rec0), Field1 = expr(Field0), - {record_field,Line,Rec1,Name,Field1}; -expr({record,Line,Rec0,Name,Upds0}) -> + {record_field,Anno,Rec1,Name,Field1}; +expr({record,Anno,Rec0,Name,Upds0}) -> Rec1 = expr(Rec0), Upds1 = record_updates(Upds0), - {record,Line,Rec1,Name,Upds1}; -expr({record_field,Line,Rec0,Field0}) -> + {record,Anno,Rec1,Name,Upds1}; +expr({record_field,Anno,Rec0,Field0}) -> Rec1 = expr(Rec0), Field1 = expr(Field0), - {record_field,Line,Rec1,Field1}; -expr({block,Line,Es0}) -> + {record_field,Anno,Rec1,Field1}; +expr({block,Anno,Es0}) -> %% Unfold block into a sequence. Es1 = exprs(Es0), - {block,Line,Es1}; -expr({'if',Line,Cs0}) -> + {block,Anno,Es1}; +expr({'if',Anno,Cs0}) -> Cs1 = icr_clauses(Cs0), - {'if',Line,Cs1}; -expr({'case',Line,E0,Cs0}) -> + {'if',Anno,Cs1}; +expr({'case',Anno,E0,Cs0}) -> E1 = expr(E0), Cs1 = icr_clauses(Cs0), - {'case',Line,E1,Cs1}; -expr({'receive',Line,Cs0}) -> + {'case',Anno,E1,Cs1}; +expr({'receive',Anno,Cs0}) -> Cs1 = icr_clauses(Cs0), - {'receive',Line,Cs1}; -expr({'receive',Line,Cs0,To0,ToEs0}) -> + {'receive',Anno,Cs1}; +expr({'receive',Anno,Cs0,To0,ToEs0}) -> To1 = expr(To0), ToEs1 = exprs(ToEs0), Cs1 = icr_clauses(Cs0), - {'receive',Line,Cs1,To1,ToEs1}; -expr({'try',Line,Es0,Scs0,Ccs0,As0}) -> + {'receive',Anno,Cs1,To1,ToEs1}; +expr({'try',Anno,Es0,Scs0,Ccs0,As0}) -> Es1 = exprs(Es0), Scs1 = icr_clauses(Scs0), Ccs1 = icr_clauses(Ccs0), As1 = exprs(As0), - {'try',Line,Es1,Scs1,Ccs1,As1}; -expr({'fun',Line,Body}) -> + {'try',Anno,Es1,Scs1,Ccs1,As1}; +expr({'fun',Anno,Body}) -> case Body of {clauses,Cs0} -> Cs1 = fun_clauses(Cs0), - {'fun',Line,{clauses,Cs1}}; + {'fun',Anno,{clauses,Cs1}}; {function,F,A} -> - {'fun',Line,{function,F,A}}; + {'fun',Anno,{function,F,A}}; {function,M0,F0,A0} -> M = expr(M0), F = expr(F0), A = expr(A0), - {'fun',Line,{function,M,F,A}} + {'fun',Anno,{function,M,F,A}} end; -expr({named_fun,Loc,Name,Cs}) -> - {named_fun,Loc,Name,fun_clauses(Cs)}; -expr({call,Line,F0,As0}) -> +expr({named_fun,Anno,Name,Cs}) -> + {named_fun,Anno,Name,fun_clauses(Cs)}; +expr({call,Anno,F0,As0}) -> %% N.B. If F an atom then call to local function or BIF, if F a %% remote structure (see below) then call to other module, %% otherwise apply to "function". F1 = expr(F0), As1 = expr_list(As0), - {call,Line,F1,As1}; -expr({'catch',Line,E0}) -> + {call,Anno,F1,As1}; +expr({'catch',Anno,E0}) -> %% No new variables added. E1 = expr(E0), - {'catch',Line,E1}; -expr({match,Line,P0,E0}) -> + {'catch',Anno,E1}; +expr({match,Anno,P0,E0}) -> E1 = expr(E0), P1 = pattern(P0), - {match,Line,P1,E1}; -expr({bin,Line,Fs}) -> + {match,Anno,P1,E1}; +expr({bin,Anno,Fs}) -> Fs2 = pattern_grp(Fs), - {bin,Line,Fs2}; -expr({op,Line,Op,A0}) -> + {bin,Anno,Fs2}; +expr({op,Anno,Op,A0}) -> A1 = expr(A0), - {op,Line,Op,A1}; -expr({op,Line,Op,L0,R0}) -> + {op,Anno,Op,A1}; +expr({op,Anno,Op,L0,R0}) -> L1 = expr(L0), R1 = expr(R0), %They see the same variables - {op,Line,Op,L1,R1}; + {op,Anno,Op,L1,R1}; %% The following are not allowed to occur anywhere! -expr({remote,Line,M0,F0}) -> +expr({remote,Anno,M0,F0}) -> M1 = expr(M0), F1 = expr(F0), - {remote,Line,M1,F1}. + {remote,Anno,M1,F1}. %% -type expr_list([Expression]) -> [Expression]. %% These expressions are processed "in parallel" for purposes of variable @@ -532,21 +535,21 @@ expr_list([]) -> []. %% N.B. Field names are full expressions here but only atoms are allowed %% by the *linter*!. -record_inits([{record_field,Lf,{atom,La,F},Val0}|Is]) -> +record_inits([{record_field,Af,{atom,Aa,F},Val0}|Is]) -> Val1 = expr(Val0), - [{record_field,Lf,{atom,La,F},Val1}|record_inits(Is)]; -record_inits([{record_field,Lf,{var,La,'_'},Val0}|Is]) -> + [{record_field,Af,{atom,Aa,F},Val1}|record_inits(Is)]; +record_inits([{record_field,Af,{var,Aa,'_'},Val0}|Is]) -> Val1 = expr(Val0), - [{record_field,Lf,{var,La,'_'},Val1}|record_inits(Is)]; + [{record_field,Af,{var,Aa,'_'},Val1}|record_inits(Is)]; record_inits([]) -> []. %% -type record_updates([RecordUpd]) -> [RecordUpd]. %% N.B. Field names are full expressions here but only atoms are allowed %% by the *linter*!. -record_updates([{record_field,Lf,{atom,La,F},Val0}|Us]) -> +record_updates([{record_field,Af,{atom,Aa,F},Val0}|Us]) -> Val1 = expr(Val0), - [{record_field,Lf,{atom,La,F},Val1}|record_updates(Us)]; + [{record_field,Af,{atom,Aa,F},Val1}|record_updates(Us)]; record_updates([]) -> []. %% -type icr_clauses([Clause]) -> [Clause]. @@ -559,14 +562,14 @@ icr_clauses([]) -> []. %% -type lc_bc_quals([Qualifier]) -> [Qualifier]. %% Allow filters to be both guard tests and general expressions. -lc_bc_quals([{generate,Line,P0,E0}|Qs]) -> +lc_bc_quals([{generate,Anno,P0,E0}|Qs]) -> E1 = expr(E0), P1 = pattern(P0), - [{generate,Line,P1,E1}|lc_bc_quals(Qs)]; -lc_bc_quals([{b_generate,Line,P0,E0}|Qs]) -> + [{generate,Anno,P1,E1}|lc_bc_quals(Qs)]; +lc_bc_quals([{b_generate,Anno,P0,E0}|Qs]) -> E1 = expr(E0), P1 = pattern(P0), - [{b_generate,Line,P1,E1}|lc_bc_quals(Qs)]; + [{b_generate,Anno,P1,E1}|lc_bc_quals(Qs)]; lc_bc_quals([E0|Qs]) -> E1 = expr(E0), [E1|lc_bc_quals(Qs)]; @@ -579,97 +582,97 @@ fun_clauses([C0|Cs]) -> [C1|fun_clauses(Cs)]; fun_clauses([]) -> []. -function_type_list([{type,Line,bounded_fun,[Ft,Fc]}|Fts]) -> +function_type_list([{type,Anno,bounded_fun,[Ft,Fc]}|Fts]) -> Ft1 = function_type(Ft), Fc1 = function_constraint(Fc), - [{type,Line,bounded_fun,[Ft1,Fc1]}|function_type_list(Fts)]; + [{type,Anno,bounded_fun,[Ft1,Fc1]}|function_type_list(Fts)]; function_type_list([Ft|Fts]) -> [function_type(Ft)|function_type_list(Fts)]; function_type_list([]) -> []. -function_type({type,Line,'fun',[{type,Lt,product,As},B]}) -> +function_type({type,Anno,'fun',[{type,At,product,As},B]}) -> As1 = type_list(As), B1 = type(B), - {type,Line,'fun',[{type,Lt,product,As1},B1]}. + {type,Anno,'fun',[{type,At,product,As1},B1]}. function_constraint([C|Cs]) -> C1 = constraint(C), [C1|function_constraint(Cs)]; function_constraint([]) -> []. -constraint({type,Line,constraint,[{atom,L,A},[V,T]]}) -> +constraint({type,Anno,constraint,[{atom,Annoa,A},[V,T]]}) -> V1 = type(V), T1 = type(T), - {type,Line,constraint,[{atom,L,A},[V1,T1]]}. + {type,Anno,constraint,[{atom,Annoa,A},[V1,T1]]}. -type({ann_type,Line,[{var,Lv,V},T]}) -> +type({ann_type,Anno,[{var,Av,V},T]}) -> T1 = type(T), - {ann_type,Line,[{var,Lv,V},T1]}; -type({atom,Line,A}) -> - {atom,Line,A}; -type({integer,Line,I}) -> - {integer,Line,I}; -type({op,Line,Op,T}) -> + {ann_type,Anno,[{var,Av,V},T1]}; +type({atom,Anno,A}) -> + {atom,Anno,A}; +type({integer,Anno,I}) -> + {integer,Anno,I}; +type({op,Anno,Op,T}) -> T1 = type(T), - {op,Line,Op,T1}; -type({op,Line,Op,L,R}) -> + {op,Anno,Op,T1}; +type({op,Anno,Op,L,R}) -> L1 = type(L), R1 = type(R), - {op,Line,Op,L1,R1}; -type({type,Line,binary,[M,N]}) -> + {op,Anno,Op,L1,R1}; +type({type,Anno,binary,[M,N]}) -> M1 = type(M), N1 = type(N), - {type,Line,binary,[M1,N1]}; -type({type,Line,'fun',[]}) -> - {type,Line,'fun',[]}; -type({type,Line,'fun',[{type,Lt,any},B]}) -> + {type,Anno,binary,[M1,N1]}; +type({type,Anno,'fun',[]}) -> + {type,Anno,'fun',[]}; +type({type,Anno,'fun',[{type,At,any},B]}) -> B1 = type(B), - {type,Line,'fun',[{type,Lt,any},B1]}; -type({type,Line,range,[L,H]}) -> + {type,Anno,'fun',[{type,At,any},B1]}; +type({type,Anno,range,[L,H]}) -> L1 = type(L), H1 = type(H), - {type,Line,range,[L1,H1]}; -type({type,Line,map,any}) -> - {type,Line,map,any}; -type({type,Line,map,Ps}) -> + {type,Anno,range,[L1,H1]}; +type({type,Anno,map,any}) -> + {type,Anno,map,any}; +type({type,Anno,map,Ps}) -> Ps1 = map_pair_types(Ps), - {type,Line,map,Ps1}; -type({type,Line,record,[{atom,La,N}|Fs]}) -> + {type,Anno,map,Ps1}; +type({type,Anno,record,[{atom,Aa,N}|Fs]}) -> Fs1 = field_types(Fs), - {type,Line,record,[{atom,La,N}|Fs1]}; -type({remote_type,Line,[{atom,Lm,M},{atom,Ln,N},As]}) -> + {type,Anno,record,[{atom,Aa,N}|Fs1]}; +type({remote_type,Anno,[{atom,Am,M},{atom,An,N},As]}) -> As1 = type_list(As), - {remote_type,Line,[{atom,Lm,M},{atom,Ln,N},As1]}; -type({type,Line,tuple,any}) -> - {type,Line,tuple,any}; -type({type,Line,tuple,Ts}) -> + {remote_type,Anno,[{atom,Am,M},{atom,An,N},As1]}; +type({type,Anno,tuple,any}) -> + {type,Anno,tuple,any}; +type({type,Anno,tuple,Ts}) -> Ts1 = type_list(Ts), - {type,Line,tuple,Ts1}; -type({type,Line,union,Ts}) -> + {type,Anno,tuple,Ts1}; +type({type,Anno,union,Ts}) -> Ts1 = type_list(Ts), - {type,Line,union,Ts1}; -type({var,Line,V}) -> - {var,Line,V}; -type({user_type,Line,N,As}) -> + {type,Anno,union,Ts1}; +type({var,Anno,V}) -> + {var,Anno,V}; +type({user_type,Anno,N,As}) -> As1 = type_list(As), - {user_type,Line,N,As1}; -type({type,Line,N,As}) -> + {user_type,Anno,N,As1}; +type({type,Anno,N,As}) -> As1 = type_list(As), - {type,Line,N,As1}. + {type,Anno,N,As1}. -map_pair_types([{type,Line,map_field_assoc,[K,V]}|Ps]) -> +map_pair_types([{type,Anno,map_field_assoc,[K,V]}|Ps]) -> K1 = type(K), V1 = type(V), - [{type,Line,map_field_assoc,[K1,V1]}|map_pair_types(Ps)]; -map_pair_types([{type,Line,map_field_exact,[K,V]}|Ps]) -> + [{type,Anno,map_field_assoc,[K1,V1]}|map_pair_types(Ps)]; +map_pair_types([{type,Anno,map_field_exact,[K,V]}|Ps]) -> K1 = type(K), V1 = type(V), - [{type,Line,map_field_exact,[K1,V1]}|map_pair_types(Ps)]; + [{type,Anno,map_field_exact,[K1,V1]}|map_pair_types(Ps)]; map_pair_types([]) -> []. -field_types([{type,Line,field_type,[{atom,La,A},T]}|Fs]) -> +field_types([{type,Anno,field_type,[{atom,Aa,A},T]}|Fs]) -> T1 = type(T), - [{type,Line,field_type,[{atom,La,A},T1]}|field_types(Fs)]; + [{type,Anno,field_type,[{atom,Aa,A},T1]}|field_types(Fs)]; field_types([]) -> []. type_list([T|Ts]) -> diff --git a/lib/stdlib/src/epp.erl b/lib/stdlib/src/epp.erl index 92b43a89ce..b390697a56 100644 --- a/lib/stdlib/src/epp.erl +++ b/lib/stdlib/src/epp.erl @@ -21,7 +21,7 @@ %% An Erlang code preprocessor. --export([open/1, open/2,open/3,open/5,close/1,format_error/1]). +-export([open/1,open/2,open/3,close/1,format_error/1]). -export([scan_erl_form/1,parse_erl_form/1,macro_defs/1]). -export([parse_file/1, parse_file/2, parse_file/3]). -export([default_encoding/0, encoding_to_string/1, @@ -34,7 +34,7 @@ -export_type([source_encoding/0]). --type macros() :: [atom() | {atom(), term()}]. +-type macros() :: [atom() | {atom(), term()} | {atom(), term(), 'redefine'}]. -type epp_handle() :: pid(). -type source_encoding() :: latin1 | utf8. @@ -73,13 +73,12 @@ :: #{name() => [{argspec(), [used()]}]}, default_encoding = ?DEFAULT_ENCODING :: source_encoding(), pre_opened = false :: boolean(), - fname = [] :: function_name_type() + fname = [] :: function_name_type() }). %% open(Options) %% open(FileName, IncludePath) %% open(FileName, IncludePath, PreDefMacros) -%% open(FileName, IoDevice, StartLocation, IncludePath, PreDefMacros) %% close(Epp) %% scan_erl_form(Epp) %% parse_erl_form(Epp) @@ -107,11 +106,7 @@ open(Name, Path) -> ErrorDescriptor :: term(). open(Name, Path, Pdm) -> - internal_open([{name, Name}, {includes, Path}, {macros, Pdm}], #epp{}). - -open(Name, File, StartLocation, Path, Pdm) -> - internal_open([{name, Name}, {includes, Path}, {macros, Pdm}], - #epp{file=File, pre_opened=true, location=StartLocation}). + open([{name, Name}, {includes, Path}, {macros, Pdm}]). -spec open(Options) -> {'ok', Epp} | {'ok', Epp, Extra} | {'error', ErrorDescriptor} when @@ -120,21 +115,20 @@ open(Name, File, StartLocation, Path, Pdm) -> {'source_name', SourceName :: file:name()} | {'macros', PredefMacros :: macros()} | {'name',FileName :: file:name()} | + {'location',StartLocation :: erl_anno:location()} | + {'fd',FileDescriptor :: file:io_device()} | 'extra'], Epp :: epp_handle(), Extra :: [{'encoding', source_encoding() | 'none'}], ErrorDescriptor :: term(). open(Options) -> - internal_open(Options, #epp{}). - -internal_open(Options, St) -> case proplists:get_value(name, Options) of undefined -> erlang:error(badarg); Name -> Self = self(), - Epp = spawn(fun() -> server(Self, Name, Options, St) end), + Epp = spawn(fun() -> server(Self, Name, Options) end), case epp_request(Epp) of {ok, Pid, Encoding} -> case proplists:get_bool(extra, Options) of @@ -162,10 +156,10 @@ scan_erl_form(Epp) -> -spec parse_erl_form(Epp) -> {'ok', AbsForm} | {error, ErrorInfo} | - {'warning',WarningInfo} | {'eof',Line} when + {'warning',WarningInfo} | {'eof',Location} when Epp :: epp_handle(), AbsForm :: erl_parse:abstract_form(), - Line :: erl_anno:line(), + Location :: erl_anno:location(), ErrorInfo :: erl_scan:error_info() | erl_parse:error_info(), WarningInfo :: warning_info(). @@ -190,8 +184,12 @@ format_error(cannot_parse) -> io_lib:format("cannot parse file, giving up", []); format_error({bad,W}) -> io_lib:format("badly formed '~s'", [W]); +format_error({duplicated_argument, Arg}) -> + io_lib:format("argument '~ts' already used", [Arg]); format_error(missing_parenthesis) -> io_lib:format("badly formed define: missing closing right parenthesis",[]); +format_error(missing_comma) -> + io_lib:format("badly formed define: missing comma",[]); format_error(premature_end) -> "premature end"; format_error({call,What}) -> @@ -236,9 +234,11 @@ format_error(E) -> file:format_error(E). {'ok', [Form]} | {error, OpenError} when FileName :: file:name(), IncludePath :: [DirectoryName :: file:name()], - Form :: erl_parse:abstract_form() | {'error', ErrorInfo} | {'eof',Line}, + Form :: erl_parse:abstract_form() + | {'error', ErrorInfo} + | {'eof',Location}, PredefMacros :: macros(), - Line :: erl_anno:line(), + Location :: erl_anno:location(), ErrorInfo :: erl_scan:error_info() | erl_parse:error_info(), OpenError :: file:posix() | badarg | system_limit. @@ -252,15 +252,18 @@ parse_file(Ifile, Path, Predefs) -> {'source_name', SourceName :: file:name()} | {'macros', PredefMacros :: macros()} | {'default_encoding', DefEncoding :: source_encoding()} | + {'location',StartLocation :: erl_anno:location()} | 'extra'], - Form :: erl_parse:abstract_form() | {'error', ErrorInfo} | {'eof',Line}, - Line :: erl_anno:line(), + Form :: erl_parse:abstract_form() + | {'error', ErrorInfo} + | {'eof',Location}, + Location :: erl_anno:location(), ErrorInfo :: erl_scan:error_info() | erl_parse:error_info(), Extra :: [{'encoding', source_encoding() | 'none'}], OpenError :: file:posix() | badarg | system_limit. parse_file(Ifile, Options) -> - case internal_open([{name, Ifile} | Options], #epp{}) of + case open([{name, Ifile} | Options]) of {ok,Epp} -> Forms = parse_file(Epp), close(Epp), @@ -276,8 +279,8 @@ parse_file(Ifile, Options) -> -spec parse_file(Epp) -> [Form] when Epp :: epp_handle(), Form :: erl_parse:abstract_form() | {'error', ErrorInfo} | - {'warning',WarningInfo} | {'eof',Line}, - Line :: erl_anno:line(), + {'warning',WarningInfo} | {'eof',Location}, + Location :: erl_anno:location(), ErrorInfo :: erl_scan:error_info() | erl_parse:error_info(), WarningInfo :: warning_info(). @@ -514,32 +517,33 @@ normalize_typed_record_fields([Field|Rest], NewFields, Typed) -> restore_typed_record_fields([]) -> []; -restore_typed_record_fields([{attribute,La,record,{Record,_NewFields}}, - {attribute,La,type,{{record,Record},Fields,[]}}| +restore_typed_record_fields([{attribute,A,record,{Record,_NewFields}}, + {attribute,A,type,{{record,Record},Fields,[]}}| Forms]) -> - [{attribute,La,record,{Record,Fields}}| + [{attribute,A,record,{Record,Fields}}| restore_typed_record_fields(Forms)]; -restore_typed_record_fields([{attribute,La,type,{{record,Record},Fields,[]}}| +restore_typed_record_fields([{attribute,A,type,{{record,Record},Fields,[]}}| Forms]) -> %% This clause is due to the compiler's 'E' option. %% Record information kept by erl_expand_records. - [{attribute,La,record,{Record,Fields}}| + [{attribute,A,record,{Record,Fields}}| restore_typed_record_fields(Forms)]; restore_typed_record_fields([Form|Forms]) -> [Form|restore_typed_record_fields(Forms)]. -server(Pid, Name, Options, #epp{pre_opened=PreOpened}=St) -> +server(Pid, Name, Options) -> process_flag(trap_exit, true), - case PreOpened of - false -> + St = #epp{}, + case proplists:get_value(fd, Options) of + undefined -> case file:open(Name, [read]) of {ok,File} -> init_server(Pid, Name, Options, St#epp{file = File}); {error,E} -> epp_reply(Pid, {error,E}) end; - true -> - init_server(Pid, Name, Options, St) + Fd -> + init_server(Pid, Name, Options, St#epp{file = Fd, pre_opened=true}) end. init_server(Pid, FileName, Options, St0) -> @@ -548,17 +552,18 @@ init_server(Pid, FileName, Options, St0) -> Ms0 = predef_macros(FileName), case user_predef(Pdm, Ms0) of {ok,Ms1} -> - #epp{file = File, location = AtLocation} = St0, DefEncoding = proplists:get_value(default_encoding, Options, ?DEFAULT_ENCODING), - Encoding = set_encoding(File, DefEncoding), + Encoding = set_encoding(St0#epp.file, DefEncoding), epp_reply(Pid, {ok,self(),Encoding}), %% ensure directory of current source file is %% first in path Path = [filename:dirname(FileName) | proplists:get_value(includes, Options, [])], + %% the default location is 1 for backwards compatibility, not {1,1} + AtLocation = proplists:get_value(location, Options, 1), St = St0#epp{delta=0, name=SourceName, name2=SourceName, - path=Path, macs=Ms1, + path=Path, location=AtLocation, macs=Ms1, default_encoding=DefEncoding}, From = wait_request(St), Anno = erl_anno:new(AtLocation), @@ -680,7 +685,8 @@ enter_file(NewName, Inc, From, St) -> enter_file2(NewF, Pname, From, St0, AtLocation) -> Anno = erl_anno:new(AtLocation), enter_file_reply(From, Pname, Anno, AtLocation, code), - Ms0 = St0#epp.macs, + #epp{macs = Ms0, + default_encoding = DefEncoding} = St0, Ms = Ms0#{'FILE':={none,[{string,Anno,Pname}]}}, %% update the head of the include path to be the directory of the new %% source file, so that an included file can always include other files @@ -689,14 +695,13 @@ enter_file2(NewF, Pname, From, St0, AtLocation) -> %% the path) must be dropped, otherwise the path used within the current %% file will depend on the order of file inclusions in the parent files Path = [filename:dirname(Pname) | tl(St0#epp.path)], - DefEncoding = St0#epp.default_encoding, _ = set_encoding(NewF, DefEncoding), #epp{file=NewF,location=AtLocation,name=Pname,name2=Pname,delta=0, sstk=[St0|St0#epp.sstk],path=Path,macs=Ms, default_encoding=DefEncoding}. enter_file_reply(From, Name, LocationAnno, AtLocation, Where) -> - Anno0 = loc_anno(AtLocation), + Anno0 = erl_anno:new(AtLocation), Anno = case Where of code -> Anno0; generated -> erl_anno:set_generated(true, Anno0) @@ -812,25 +817,25 @@ scan_toks(Toks0, From, St) -> wait_req_scan(St) end. -scan_module([{'-',_Lh},{atom,_Lm,module},{'(',_Ll}|Ts], Ms) -> +scan_module([{'-',_Ah},{atom,_Am,module},{'(',_Al}|Ts], Ms) -> scan_module_1(Ts, Ms); -scan_module([{'-',_Lh},{atom,_Lm,extends},{'(',_Ll}|Ts], Ms) -> +scan_module([{'-',_Ah},{atom,_Am,extends},{'(',_Al}|Ts], Ms) -> scan_extends(Ts, Ms); scan_module(_Ts, Ms) -> Ms. -scan_module_1([{atom,_,_}=A,{',',L}|Ts], Ms) -> +scan_module_1([{atom,_,_}=A,{',',Anno}|Ts], Ms) -> %% Parameterized modules. - scan_module_1([A,{')',L}|Ts], Ms); -scan_module_1([{atom,Ln,A}=ModAtom,{')',_Lr}|_Ts], Ms0) -> + scan_module_1([A,{')',Anno}|Ts], Ms); +scan_module_1([{atom,Anno,A}=ModAtom,{')',_Ar}|_Ts], Ms0) -> ModString = atom_to_list(A), Ms = Ms0#{'MODULE':={none,[ModAtom]}}, - Ms#{'MODULE_STRING':={none,[{string,Ln,ModString}]}}; + Ms#{'MODULE_STRING':={none,[{string,Anno,ModString}]}}; scan_module_1(_Ts, Ms) -> Ms. -scan_extends([{atom,Ln,A}=ModAtom,{')',_Lr}|_Ts], Ms0) -> +scan_extends([{atom,Anno,A}=ModAtom,{')',_Ar}|_Ts], Ms0) -> ModString = atom_to_list(A), Ms = Ms0#{'BASE_MODULE':={none,[ModAtom]}}, - Ms#{'BASE_MODULE_STRING':={none,[{string,Ln,ModString}]}}; + Ms#{'BASE_MODULE_STRING':={none,[{string,Anno,ModString}]}}; scan_extends(_Ts, Ms) -> Ms. scan_err_warn([{'(',_}|_]=Toks0, {atom,_,Tag}=Token, From, St) -> @@ -847,17 +852,19 @@ scan_err_warn([{'(',_}|_]=Toks0, {atom,_,Tag}=Token, From, St) -> epp_reply(From, {error,{loc(Token),epp,{bad,Tag}}}) end, wait_req_scan(St); -scan_err_warn(_Toks, {atom,_,Tag}=Token, From, St) -> - epp_reply(From, {error,{loc(Token),epp,{bad,Tag}}}), +scan_err_warn(Toks, {atom,_,Tag}=Token, From, St) -> + T = no_match(Toks, Token), + epp_reply(From, {error,{loc(T),epp,{bad,Tag}}}), wait_req_scan(St). %% scan_define(Tokens, DefineToken, From, EppState) -scan_define([{'(',_Lp},{Type,_Lm,_}=Mac|Toks], Def, From, St) +scan_define([{'(',_Ap},{Type,_Am,_}=Mac|Toks], Def, From, St) when Type =:= atom; Type =:= var -> scan_define_1(Toks, Mac, Def, From, St); -scan_define(_Toks, Def, From, St) -> - epp_reply(From, {error,{loc(Def),epp,{bad,define}}}), +scan_define(Toks, Def, From, St) -> + T = find_mismatch(['(', var_or_atom], Toks, Def), + epp_reply(From, {error,{loc(T),epp,{bad,define}}}), wait_req_scan(St). scan_define_1([{',',_}=Comma|Toks], Mac,_Def, From, St) -> @@ -868,20 +875,18 @@ scan_define_1([{',',_}=Comma|Toks], Mac,_Def, From, St) -> epp_reply(From, {error,{ErrL,epp,What}}), wait_req_scan(St) end; -scan_define_1([{'(',_Lc}|Toks], Mac, Def, From, St) -> - case catch macro_pars(Toks, []) of +scan_define_1([{'(',_Ac}=T|Toks], Mac, _Def, From, St) -> + case catch macro_pars(Toks, [], T) of {ok,{As,_}=MacroDef} -> Len = length(As), scan_define_2(Len, MacroDef, Mac, From, St); {error,ErrL,What} -> epp_reply(From, {error,{ErrL,epp,What}}), - wait_req_scan(St); - _ -> - epp_reply(From, {error,{loc(Def),epp,{bad,define}}}), wait_req_scan(St) end; -scan_define_1(_Toks, _Mac, Def, From, St) -> - epp_reply(From, {error,{loc(Def),epp,{bad,define}}}), +scan_define_1(Toks, _Mac, Def, From, St) -> + T = no_match(Toks, Def), + epp_reply(From, {error,{loc(T),epp,{bad,define}}}), wait_req_scan(St). scan_define_2(Arity, Def, {_,_,Key}=Mac, From, #epp{macs=Ms}=St) -> @@ -924,8 +929,8 @@ scan_define_cont(F, #epp{macs=Ms0}=St, M, Defs, Arity, Def) -> Uses = Uses0#{M=>Val}, scan_toks(F, St#epp{uses=Uses,macs=Ms}) catch - {error, Line, Reason} -> - epp_reply(F, {error,{Line,epp,Reason}}), + {error, Location, Reason} -> + epp_reply(F, {error,{Location,epp,Reason}}), wait_req_scan(St) end. @@ -950,16 +955,17 @@ macro_ref([_Token | Rest]) -> %% scan_undef(Tokens, UndefToken, From, EppState) -scan_undef([{'(',_Llp},{atom,_Lm,M},{')',_Lrp},{dot,_Ld}], _Undef, From, St) -> +scan_undef([{'(',_Alp},{atom,_Am,M},{')',_Arp},{dot,_Ad}], _Undef, From, St) -> Macs = maps:remove(M, St#epp.macs), Uses = maps:remove(M, St#epp.uses), scan_toks(From, St#epp{macs=Macs, uses=Uses}); -scan_undef([{'(',_Llp},{var,_Lm,M},{')',_Lrp},{dot,_Ld}], _Undef, From,St) -> +scan_undef([{'(',_Alp},{var,_Am,M},{')',_Arp},{dot,_Ad}], _Undef, From,St) -> Macs = maps:remove(M, St#epp.macs), Uses = maps:remove(M, St#epp.uses), scan_toks(From, St#epp{macs=Macs, uses=Uses}); -scan_undef(_Toks, Undef, From, St) -> - epp_reply(From, {error,{loc(Undef),epp,{bad,undef}}}), +scan_undef(Toks, Undef, From, St) -> + T = find_mismatch(['(',var_or_atom,')',dot], Toks, Undef), + epp_reply(From, {error,{loc(T),epp,{bad,undef}}}), wait_req_scan(St). %% scan_include(Tokens, IncludeToken, From, St) @@ -968,12 +974,13 @@ scan_include(Tokens0, Inc, From, St) -> Tokens = coalesce_strings(Tokens0), scan_include1(Tokens, Inc, From, St). -scan_include1([{'(',_Llp},{string,_Lf,NewName0},{')',_Lrp},{dot,_Ld}], Inc, - From, St) -> +scan_include1([{'(',_Alp},{string,_Af,NewName0}=StringT,{')',_Arp},{dot,_Ad}], + _Inc, From, St) -> NewName = expand_var(NewName0), - enter_file(NewName, Inc, From, St); -scan_include1(_Toks, Inc, From, St) -> - epp_reply(From, {error,{loc(Inc),epp,{bad,include}}}), + enter_file(NewName, StringT, From, St); +scan_include1(Toks, Inc, From, St) -> + T = find_mismatch(['(',string,')',dot], Toks, Inc), + epp_reply(From, {error,{loc(T),epp,{bad,include}}}), wait_req_scan(St). %% scan_include_lib(Tokens, IncludeToken, From, EppState) @@ -995,13 +1002,13 @@ scan_include_lib(Tokens0, Inc, From, St) -> Tokens = coalesce_strings(Tokens0), scan_include_lib1(Tokens, Inc, From, St). -scan_include_lib1([{'(',_Llp},{string,_Lf,_NewName0},{')',_Lrp},{dot,_Ld}], +scan_include_lib1([{'(',_Alp},{string,_Af,_NewName0},{')',_Arp},{dot,_Ad}], Inc, From, St) when length(St#epp.sstk) >= 8 -> epp_reply(From, {error,{loc(Inc),epp,{depth,"include_lib"}}}), wait_req_scan(St); -scan_include_lib1([{'(',_Llp},{string,_Lf,NewName0},{')',_Lrp},{dot,_Ld}], - Inc, From, St) -> +scan_include_lib1([{'(',_Alp},{string,_Af,NewName0}=N,{')',_Arp},{dot,_Ad}], + _Inc, From, St) -> NewName = expand_var(NewName0), Loc = start_loc(St#epp.location), case file:path_open(St#epp.path, NewName, [read]) of @@ -1016,18 +1023,19 @@ scan_include_lib1([{'(',_Llp},{string,_Lf,NewName0},{')',_Lrp},{dot,_Ld}], St, Loc)); {error,_E2} -> epp_reply(From, - {error,{loc(Inc),epp, + {error,{loc(N),epp, {include,lib,NewName}}}), wait_req_scan(St) end; error -> - epp_reply(From, {error,{loc(Inc),epp, + epp_reply(From, {error,{loc(N),epp, {include,lib,NewName}}}), wait_req_scan(St) end end; -scan_include_lib1(_Toks, Inc, From, St) -> - epp_reply(From, {error,{loc(Inc),epp,{bad,include_lib}}}), +scan_include_lib1(Toks, Inc, From, St) -> + T = find_mismatch(['(',string,')',dot], Toks, Inc), + epp_reply(From, {error,{loc(T),epp,{bad,include_lib}}}), wait_req_scan(St). %% scan_ifdef(Tokens, IfdefToken, From, EppState) @@ -1035,47 +1043,49 @@ scan_include_lib1(_Toks, Inc, From, St) -> %% Handle the conditional parsing of a file. %% Report a badly formed if[n]def test and then treat as undefined macro. -scan_ifdef([{'(',_Llp},{atom,_Lm,M},{')',_Lrp},{dot,_Ld}], _IfD, From, St) -> +scan_ifdef([{'(',_Alp},{atom,_Am,M},{')',_Arp},{dot,_Ad}], _IfD, From, St) -> case St#epp.macs of #{M:=_Def} -> scan_toks(From, St#epp{istk=[ifdef|St#epp.istk]}); _ -> skip_toks(From, St, [ifdef]) end; -scan_ifdef([{'(',_Llp},{var,_Lm,M},{')',_Lrp},{dot,_Ld}], _IfD, From, St) -> +scan_ifdef([{'(',_Alp},{var,_Am,M},{')',_Arp},{dot,_Ad}], _IfD, From, St) -> case St#epp.macs of #{M:=_Def} -> scan_toks(From, St#epp{istk=[ifdef|St#epp.istk]}); _ -> skip_toks(From, St, [ifdef]) end; -scan_ifdef(_Toks, IfDef, From, St) -> - epp_reply(From, {error,{loc(IfDef),epp,{bad,ifdef}}}), +scan_ifdef(Toks, IfDef, From, St) -> + T = find_mismatch(['(',var_or_atom,')',dot], Toks, IfDef), + epp_reply(From, {error,{loc(T),epp,{bad,ifdef}}}), wait_req_skip(St, [ifdef]). -scan_ifndef([{'(',_Llp},{atom,_Lm,M},{')',_Lrp},{dot,_Ld}], _IfnD, From, St) -> +scan_ifndef([{'(',_Alp},{atom,_Am,M},{')',_Arp},{dot,_Ad}], _IfnD, From, St) -> case St#epp.macs of #{M:=_Def} -> skip_toks(From, St, [ifndef]); _ -> scan_toks(From, St#epp{istk=[ifndef|St#epp.istk]}) end; -scan_ifndef([{'(',_Llp},{var,_Lm,M},{')',_Lrp},{dot,_Ld}], _IfnD, From, St) -> +scan_ifndef([{'(',_Alp},{var,_Am,M},{')',_Arp},{dot,_Ad}], _IfnD, From, St) -> case St#epp.macs of #{M:=_Def} -> skip_toks(From, St, [ifndef]); _ -> scan_toks(From, St#epp{istk=[ifndef|St#epp.istk]}) end; -scan_ifndef(_Toks, IfnDef, From, St) -> - epp_reply(From, {error,{loc(IfnDef),epp,{bad,ifndef}}}), +scan_ifndef(Toks, IfnDef, From, St) -> + T = find_mismatch(['(',var_or_atom,')',dot], Toks, IfnDef), + epp_reply(From, {error,{loc(T),epp,{bad,ifndef}}}), wait_req_skip(St, [ifndef]). %% scan_else(Tokens, ElseToken, From, EppState) %% If we are in an if body then convert to else and skip, if we are in an %% else or not in anything report an error. -scan_else([{dot,_Ld}], Else, From, St) -> +scan_else([{dot,_Ad}], Else, From, St) -> case St#epp.istk of ['else'|Cis] -> epp_reply(From, {error,{loc(Else), @@ -1088,8 +1098,9 @@ scan_else([{dot,_Ld}], Else, From, St) -> {illegal,"unbalanced",'else'}}}), wait_req_scan(St) end; -scan_else(_Toks, Else, From, St) -> - epp_reply(From, {error,{loc(Else),epp,{bad,'else'}}}), +scan_else(Toks, Else, From, St) -> + T = no_match(Toks, Else), + epp_reply(From, {error,{loc(T),epp,{bad,'else'}}}), wait_req_scan(St). %% scan_if(Tokens, IfToken, From, EppState) @@ -1114,8 +1125,9 @@ scan_if([{'(',_}|_]=Toks, If, From, St) -> epp_reply(From, Error), wait_req_skip(St, ['if']) end; -scan_if(_Toks, If, From, St) -> - epp_reply(From, {error,{loc(If),epp,{bad,'if'}}}), +scan_if(Toks, If, From, St) -> + T = no_match(Toks, If), + epp_reply(From, {error,{loc(T),epp,{bad,'if'}}}), wait_req_skip(St, ['if']). eval_if(Toks0, St) -> @@ -1210,7 +1222,7 @@ scan_elif(_Toks, Elif, From, St) -> %% scan_endif(Tokens, EndifToken, From, EppState) %% If we are in an if body then exit it, else report an error. -scan_endif([{dot,_Ld}], Endif, From, St) -> +scan_endif([{dot,_Ad}], Endif, From, St) -> case St#epp.istk of [_I|Cis] -> scan_toks(From, St#epp{istk=Cis}); @@ -1219,8 +1231,9 @@ scan_endif([{dot,_Ld}], Endif, From, St) -> {illegal,"unbalanced",endif}}}), wait_req_scan(St) end; -scan_endif(_Toks, Endif, From, St) -> - epp_reply(From, {error,{loc(Endif),epp,{bad,endif}}}), +scan_endif(Toks, Endif, From, St) -> + T = no_match(Toks, Endif), + epp_reply(From, {error,{loc(T),epp,{bad,endif}}}), wait_req_scan(St). %% scan_file(Tokens, FileToken, From, EppState) @@ -1231,8 +1244,8 @@ scan_file(Tokens0, Tf, From, St) -> Tokens = coalesce_strings(Tokens0), scan_file1(Tokens, Tf, From, St). -scan_file1([{'(',_Llp},{string,_Ls,Name},{',',_Lc},{integer,_Li,Ln},{')',_Lrp}, - {dot,_Ld}], Tf, From, St) -> +scan_file1([{'(',_Alp},{string,_As,Name},{',',_Ac},{integer,_Ai,Ln},{')',_Arp}, + {dot,_Ad}], Tf, From, St) -> Anno = erl_anno:new(Ln), enter_file_reply(From, Name, Anno, loc(Tf), generated), Ms0 = St#epp.macs, @@ -1241,8 +1254,9 @@ scan_file1([{'(',_Llp},{string,_Ls,Name},{',',_Lc},{integer,_Li,Ln},{')',_Lrp}, NewLoc = new_location(Ln, St#epp.location, Locf), Delta = get_line(element(2, Tf))-Ln + St#epp.delta, wait_req_scan(St#epp{name2=Name,location=NewLoc,delta=Delta,macs=Ms}); -scan_file1(_Toks, Tf, From, St) -> - epp_reply(From, {error,{loc(Tf),epp,{bad,file}}}), +scan_file1(Toks, Tf, From, St) -> + T = find_mismatch(['(', string, ',', integer, ')', dot], Toks, Tf), + epp_reply(From, {error,{loc(T),epp,{bad,file}}}), wait_req_scan(St). new_location(Ln, Le, Lf) when is_integer(Lf) -> @@ -1256,17 +1270,17 @@ new_location(Ln, {Le,_}, {Lf,_}) -> skip_toks(From, St, [I|Sis]) -> case io:scan_erl_form(St#epp.file, '', St#epp.location) of - {ok,[{'-',_Lh},{atom,_Li,ifdef}|_Toks],Cl} -> + {ok,[{'-',_Ah},{atom,_Ai,ifdef}|_Toks],Cl} -> skip_toks(From, St#epp{location=Cl}, [ifdef,I|Sis]); - {ok,[{'-',_Lh},{atom,_Li,ifndef}|_Toks],Cl} -> + {ok,[{'-',_Ah},{atom,_Ai,ifndef}|_Toks],Cl} -> skip_toks(From, St#epp{location=Cl}, [ifndef,I|Sis]); - {ok,[{'-',_Lh},{'if',_Li}|_Toks],Cl} -> + {ok,[{'-',_Ah},{'if',_Ai}|_Toks],Cl} -> skip_toks(From, St#epp{location=Cl}, ['if',I|Sis]); - {ok,[{'-',_Lh},{atom,_Le,'else'}=Else|_Toks],Cl}-> + {ok,[{'-',_Ah},{atom,_Ae,'else'}=Else|_Toks],Cl}-> skip_else(Else, From, St#epp{location=Cl}, [I|Sis]); - {ok,[{'-',_Lh},{atom,_Le,'elif'}=Elif|Toks],Cl}-> + {ok,[{'-',_Ah},{atom,_Ae,'elif'}=Elif|Toks],Cl}-> skip_elif(Toks, Elif, From, St#epp{location=Cl}, [I|Sis]); - {ok,[{'-',_Lh},{atom,_Le,endif}|_Toks],Cl} -> + {ok,[{'-',_Ah},{atom,_Ae,endif}|_Toks],Cl} -> skip_toks(From, St#epp{location=Cl}, Sis); {ok,_Toks,Cl} -> skip_toks(From, St#epp{location=Cl}, [I|Sis]); @@ -1311,44 +1325,66 @@ skip_elif(Toks, Elif, From, St, [_I]) -> skip_elif(_Toks, _Elif, From, St, Sis) -> skip_toks(From, St, Sis). -%% macro_pars(Tokens, ArgStack) -%% macro_expansion(Tokens, Anno) +%% macro_pars(Tokens, ArgStack, Token) +%% macro_expansion(Tokens, Token) %% Extract the macro parameters and the expansion from a macro definition. -macro_pars([{')',_Lp}, {',',_Ld}=Comma|Ex], Args) -> - {ok, {lists:reverse(Args), macro_expansion(Ex, Comma)}}; -macro_pars([{var,_,Name}, {')',_Lp}, {',',_Ld}=Comma|Ex], Args) -> - false = lists:member(Name, Args), %Prolog is nice - {ok, {lists:reverse([Name|Args]), macro_expansion(Ex, Comma)}}; -macro_pars([{var,_L,Name}, {',',_}|Ts], Args) -> - false = lists:member(Name, Args), - macro_pars(Ts, [Name|Args]). - -macro_expansion([{')',_Lp},{dot,_Ld}], _T0) -> []; +macro_pars([{')',_Ap}=Par|Ex], Args, _T0) -> + {ok, {lists:reverse(Args), macro_pars_end(Ex, Par)}}; +macro_pars([{var,_,Name}=T|Ex], Args, _T0) -> + check_macro_arg(Name, Args, T), + macro_pars_cont(Ex, [Name|Args], T); +macro_pars(Toks, _Args, T0) -> + T = no_match(Toks, T0), + throw({error,loc(T),{bad,define}}). + +macro_pars_cont([{')',_Ap}=Par|Ex], Args, _T0) -> + {ok, {lists:reverse(Args), macro_pars_end(Ex, Par)}}; +macro_pars_cont([{',',_Ad},{var,_,Name}=T|Ex], Args, _T0) -> + check_macro_arg(Name, Args, T), + macro_pars_cont(Ex, [Name|Args], T); +macro_pars_cont(Toks, _Args, T0) -> + T = no_match(Toks, T0), + throw({error,loc(T),{bad,define}}). + +macro_pars_end([{',',_Ad}=Comma|Ex], _T0) -> + macro_expansion(Ex, Comma); +macro_pars_end(Toks, T0) -> + T = no_match(Toks, T0), + throw({error,loc(T),missing_comma}). + +macro_expansion([{')',_Ap},{dot,_Ad}], _T0) -> []; macro_expansion([{dot,_}=Dot], _T0) -> throw({error,loc(Dot),missing_parenthesis}); macro_expansion([T|Ts], _T0) -> [T|macro_expansion(Ts, T)]; macro_expansion([], T0) -> throw({error,loc(T0),premature_end}). +check_macro_arg(Name, Args, T) -> + case lists:member(Name, Args) of + true -> + throw({error,loc(T),{duplicated_argument,Name}}); + false -> + ok + end. + %% expand_macros(Tokens, St) -%% expand_macro(Tokens, MacroToken, RestTokens) %% Expand the macros in a list of tokens, making sure that an expansion %% gets the same location as the macro call. expand_macros(MacT, M, Toks, St) -> #epp{macs=Ms,uses=U} = St, Lm = loc(MacT), - Tinfo = element(2, MacT), + Anno = element(2, MacT), case expand_macro1(Lm, M, Toks, Ms) of {ok,{none,Exp}} -> check_uses([{M,none}], [], U, Lm), - Toks1 = expand_macros(expand_macro(Exp, Tinfo, [], #{}), St), + Toks1 = expand_macros(expand_macro(Exp, Anno, [], #{}), St), expand_macros(Toks1++Toks, St); {ok,{As,Exp}} -> check_uses([{M,length(As)}], [], U, Lm), {Bs,Toks1} = bind_args(Toks, Lm, M, As, #{}), - expand_macros(expand_macro(Exp, Tinfo, Toks1, Bs), St) + expand_macros(expand_macro(Exp, Anno, Toks1, Bs), St) end. expand_macro1(Lm, M, Toks, Ms) -> @@ -1397,32 +1433,32 @@ get_macro_uses({M,Arity}, U) -> %% Macro expansion %% Note: io:scan_erl_form() does not return comments or white spaces. -expand_macros([{'?',_Lq},{atom,_Lm,M}=MacT|Toks], St) -> +expand_macros([{'?',_Aq},{atom,_Am,M}=MacT|Toks], St) -> expand_macros(MacT, M, Toks, St); %% Special macros -expand_macros([{'?',_Lq},{var,Lm,'FUNCTION_NAME'}=Token|Toks], St0) -> +expand_macros([{'?',_Aq},{var,Lm,'FUNCTION_NAME'}=Token|Toks], St0) -> St = update_fun_name(Token, St0), case St#epp.fname of undefined -> - [{'?',_Lq},Token]; + [{'?',_Aq},Token]; {Name,_} -> [{atom,Lm,Name}] end ++ expand_macros(Toks, St); -expand_macros([{'?',_Lq},{var,Lm,'FUNCTION_ARITY'}=Token|Toks], St0) -> +expand_macros([{'?',_Aq},{var,Lm,'FUNCTION_ARITY'}=Token|Toks], St0) -> St = update_fun_name(Token, St0), case St#epp.fname of undefined -> - [{'?',_Lq},Token]; + [{'?',_Aq},Token]; {_,Arity} -> [{integer,Lm,Arity}] end ++ expand_macros(Toks, St); -expand_macros([{'?',_Lq},{var,Lm,'LINE'}=Tok|Toks], St) -> +expand_macros([{'?',_Aq},{var,Lm,'LINE'}=Tok|Toks], St) -> Line = erl_scan:line(Tok), [{integer,Lm,Line}|expand_macros(Toks, St)]; -expand_macros([{'?',_Lq},{var,_Lm,M}=MacT|Toks], St) -> +expand_macros([{'?',_Aq},{var,_Am,M}=MacT|Toks], St) -> expand_macros(MacT, M, Toks, St); %% Illegal macros -expand_macros([{'?',_Lq},Token|_Toks], _St) -> +expand_macros([{'?',_Aq},Token|_Toks], _St) -> T = case erl_scan:text(Token) of Text when is_list(Text) -> Text; @@ -1438,17 +1474,17 @@ expand_macros([], _St) -> []. %% bind_args(Tokens, MacroLocation, MacroName, ArgumentVars, Bindings) %% Collect the arguments to a macro call. -bind_args([{'(',_Llp},{')',_Lrp}|Toks], _Lm, _M, [], Bs) -> +bind_args([{'(',_Alp},{')',_Arp}|Toks], _Lm, _M, [], Bs) -> {Bs,Toks}; -bind_args([{'(',_Llp}|Toks0], Lm, M, [A|As], Bs) -> +bind_args([{'(',_Alp}|Toks0], Lm, M, [A|As], Bs) -> {Arg,Toks1} = macro_arg(Toks0, [], []), macro_args(Toks1, Lm, M, As, store_arg(Lm, M, A, Arg, Bs)); bind_args(_Toks, Lm, M, _As, _Bs) -> throw({error,Lm,{mismatch,M}}). % Cannot happen. -macro_args([{')',_Lrp}|Toks], _Lm, _M, [], Bs) -> +macro_args([{')',_Arp}|Toks], _Lm, _M, [], Bs) -> {Bs,Toks}; -macro_args([{',',_Lc}|Toks0], Lm, M, [A|As], Bs) -> +macro_args([{',',_Ac}|Toks0], Lm, M, [A|As], Bs) -> {Arg,Toks1} = macro_arg(Toks0, [], []), macro_args(Toks1, Lm, M, As, store_arg(Lm, M, A, Arg, Bs)); macro_args([], Lm, M, _As, _Bs) -> @@ -1463,21 +1499,21 @@ store_arg(_L, _M, A, Arg, Bs) -> %% count_args(Tokens, MacroLine, MacroName) %% Count the number of arguments in a macro call. -count_args([{'(', _Llp},{')',_Lrp}|_Toks], _Lm, _M) -> +count_args([{'(', _Alp},{')',_Arp}|_Toks], _Lm, _M) -> 0; -count_args([{'(', _Llp},{',',_Lc}|_Toks], Lm, M) -> +count_args([{'(', _Alp},{',',_Ac}|_Toks], Lm, M) -> throw({error,Lm,{arg_error,M}}); -count_args([{'(',_Llp}|Toks0], Lm, M) -> +count_args([{'(',_Alp}|Toks0], Lm, M) -> {_Arg,Toks1} = macro_arg(Toks0, [], []), count_args(Toks1, Lm, M, 1); count_args(_Toks, _Lm, _M) -> none. -count_args([{')',_Lrp}|_Toks], _Lm, _M, NbArgs) -> +count_args([{')',_Arp}|_Toks], _Lm, _M, NbArgs) -> NbArgs; -count_args([{',',_Lc},{')',_Lrp}|_Toks], Lm, M, _NbArgs) -> +count_args([{',',_Ac},{')',_Arp}|_Toks], Lm, M, _NbArgs) -> throw({error,Lm,{arg_error,M}}); -count_args([{',',_Lc}|Toks0], Lm, M, NbArgs) -> +count_args([{',',_Ac}|Toks0], Lm, M, NbArgs) -> {_Arg,Toks1} = macro_arg(Toks0, [], []), count_args(Toks1, Lm, M, NbArgs+1); count_args([], Lm, M, _NbArgs) -> @@ -1525,36 +1561,37 @@ macro_arg([T|Toks], E, Arg) -> macro_arg([], _E, Arg) -> {lists:reverse(Arg),[]}. -%% expand_macro(MacroDef, MacroTokenInfo, RestTokens, Bindings) -%% expand_arg(Argtokens, MacroTokens, MacroLocation, RestTokens, Bindings) +%% expand_macro(MacroDef, MacroTokenAnno, RestTokens, Bindings) +%% expand_arg(Argtokens, MacroTokens, TokenAnno, RestTokens, Bindings) %% Insert the macro expansion replacing macro parameters with their %% argument values, inserting the location of first the macro call %% and then the macro arguments, i.e. simulate textual expansion. -expand_macro([{var,_Lv,V}|Ts], L, Rest, Bs) -> +expand_macro([{var,_Av,V}|Ts], Anno, Rest, Bs) -> case Bs of #{V:=Val} -> - expand_arg(Val, Ts, L, Rest, Bs); + expand_arg(Val, Ts, Anno, Rest, Bs); _ -> - [{var,L,V}|expand_macro(Ts, L, Rest, Bs)] + [{var,Anno,V}|expand_macro(Ts, Anno, Rest, Bs)] end; -expand_macro([{'?', _}, {'?', _}, {var,_Lv,V}|Ts], L, Rest, Bs) -> +expand_macro([{'?', _}, {'?', _}, {var,_Av,V}|Ts], Anno, Rest, Bs) -> case Bs of #{V:=Val} -> - expand_arg(stringify(Val, L), Ts, L, Rest, Bs); + expand_arg(stringify(Val, Anno), Ts, Anno, Rest, Bs); _ -> - [{var,L,V}|expand_macro(Ts, L, Rest, Bs)] + [{var,Anno,V}|expand_macro(Ts, Anno, Rest, Bs)] end; -expand_macro([T|Ts], L, Rest, Bs) -> - [setelement(2, T, L)|expand_macro(Ts, L, Rest, Bs)]; -expand_macro([], _L, Rest, _Bs) -> Rest. - -expand_arg([A|As], Ts, _L, Rest, Bs) -> - %% It is not obvious that the location of arguments should replace L. - NextL = element(2, A), - [A|expand_arg(As, Ts, NextL, Rest, Bs)]; -expand_arg([], Ts, L, Rest, Bs) -> - expand_macro(Ts, L, Rest, Bs). +expand_macro([T|Ts], Anno, Rest, Bs) -> + [setelement(2, T, Anno)|expand_macro(Ts, Anno, Rest, Bs)]; +expand_macro([], _Anno, Rest, _Bs) -> Rest. + +expand_arg([A|As], Ts, _Anno, Rest, Bs) -> + %% It is not obvious that the annotation of arguments should + %% replace _Anno. + NextAnno = element(2, A), + [A|expand_arg(As, Ts, NextAnno, Rest, Bs)]; +expand_arg([], Ts, Anno, Rest, Bs) -> + expand_macro(Ts, Anno, Rest, Bs). %%% %%% Here follows support for the ?FUNCTION_NAME and ?FUNCTION_ARITY @@ -1643,7 +1680,7 @@ classify_token_1('>>') -> right; classify_token_1(_) -> other. -%%% stringify(Ts, L) returns a list of one token: a string which when +%%% stringify(Ts, Anno) returns a list of one token: a string which when %%% tokenized would yield the token list Ts. %% erl_scan:text(T) is not backward compatible with this. @@ -1666,9 +1703,9 @@ stringify1([]) -> stringify1([T | Tokens]) -> [io_lib:format(" ~ts", [token_src(T)]) | stringify1(Tokens)]. -stringify(Ts, L) -> +stringify(Ts, Anno) -> [$\s | S] = lists:flatten(stringify1(Ts)), - [{string, L, S}]. + [{string, Anno, S}]. coalesce_strings([{string,A,S} | Tokens]) -> coalesce_strings(Tokens, A, [S]); @@ -1682,6 +1719,22 @@ coalesce_strings([{string,_,S}|Tokens], A, S0) -> coalesce_strings(Tokens, A, S) -> [{string,A,lists:append(lists:reverse(S))} | coalesce_strings(Tokens)]. +find_mismatch([Tag|Tags], [{Tag,_A}=T|Ts], _T0) -> + find_mismatch(Tags, Ts, T); +find_mismatch([Tag|Tags], [{Tag,_A,_V}=T|Ts], _T0) -> + find_mismatch(Tags, Ts, T); +find_mismatch([var_or_atom|Tags], [{var,_A,_V}=T|Ts], _T0) -> + find_mismatch(Tags, Ts, T); +find_mismatch([var_or_atom|Tags], [{atom,_A,_N}=T|Ts], _T0) -> + find_mismatch(Tags, Ts, T); +find_mismatch(_, Ts, T0) -> + no_match(Ts, T0). + +no_match([T|_], _T0) -> + T; +no_match(_, T0) -> + T0. + %% epp_request(Epp) %% epp_request(Epp, Request) %% epp_reply(From, Reply) @@ -1730,12 +1783,6 @@ fname_join(["." | [_|_]=Rest]) -> fname_join(Components) -> filename:join(Components). -%% The line only. (Other tokens may have the column and text as well...) -loc_anno(Line) when is_integer(Line) -> - erl_anno:new(Line); -loc_anno({Line,_Column}) -> - erl_anno:new(Line). - loc(Token) -> erl_scan:location(Token). @@ -1770,7 +1817,7 @@ get_line(Anno) -> %% of the abstract code would then point into different windows %% depending on the -file attribute. [Note that if, as is the case for %% yecc, code has been copied into the file, then it is possible that -%% the copied code differ from the one referred to by the -file +%% the copied code differs from the one referred to by the -file %% attribute, which means that line numbers can mismatch.] In practice %% however it is very rare with Erlang functions in included files, so %% only one window is used per module. This means that the line @@ -1784,11 +1831,8 @@ get_line(Anno) -> %% %% It turns out to be difficult to distinguish -file attributes in the %% input file from the ones added by epp unless some action is taken. -%% The (less than perfect) solution employed is to let epp assign -%% negative line numbers to user supplied -file attributes. - -%% Note: it is assumed that the second element is a line or a key-list -%% where 'line' can be found. +%% The solution employed is to let epp label the annotation of user +%% supplied -file attributes as 'generated'. interpret_file_attribute(Forms) -> interpret_file_attr(Forms, 0, []). diff --git a/lib/stdlib/src/erl_eval.erl b/lib/stdlib/src/erl_eval.erl index 0534a93f9a..e9afe464bb 100644 --- a/lib/stdlib/src/erl_eval.erl +++ b/lib/stdlib/src/erl_eval.erl @@ -90,7 +90,7 @@ exprs(Exprs, Bs) -> case check_command(Exprs, Bs) of ok -> exprs(Exprs, Bs, none, none, none); - {error,{_Line,_Mod,Error}} -> + {error,{_Location,_Mod,Error}} -> erlang:raise(error, Error, ?STACKTRACE) end. @@ -141,7 +141,7 @@ expr(E, Bs) -> case check_command([E], Bs) of ok -> expr(E, Bs, none, none, none); - {error,{_Line,_Mod,Error}} -> + {error,{_Location,_Mod,Error}} -> erlang:raise(error, Error, ?STACKTRACE) end. @@ -276,14 +276,14 @@ expr({'receive',_,Cs}, Bs, Lf, Ef, RBs) -> expr({'receive',_, Cs, E, TB}, Bs0, Lf, Ef, RBs) -> {value,T,Bs} = expr(E, Bs0, Lf, Ef, none), receive_clauses(T, Cs, {TB,Bs}, Bs0, Lf, Ef, RBs); -expr({'fun',_Line,{function,Mod0,Name0,Arity0}}, Bs0, Lf, Ef, RBs) -> +expr({'fun',_Anno,{function,Mod0,Name0,Arity0}}, Bs0, Lf, Ef, RBs) -> {[Mod,Name,Arity],Bs} = expr_list([Mod0,Name0,Arity0], Bs0, Lf, Ef), F = erlang:make_fun(Mod, Name, Arity), ret_expr(F, Bs, RBs); -expr({'fun',_Line,{function,Name,Arity}}, _Bs0, _Lf, _Ef, _RBs) -> % R8 +expr({'fun',_Anno,{function,Name,Arity}}, _Bs0, _Lf, _Ef, _RBs) -> % R8 %% Don't know what to do... erlang:raise(error, undef, [{?MODULE,Name,Arity}|?STACKTRACE]); -expr({'fun',Line,{clauses,Cs}} = Ex, Bs, Lf, Ef, RBs) -> +expr({'fun',Anno,{clauses,Cs}} = Ex, Bs, Lf, Ef, RBs) -> %% Save only used variables in the function environment. %% {value,L,V} are hidden while lint finds used variables. {Ex1, _} = hide_calls(Ex, 0), @@ -326,12 +326,12 @@ expr({'fun',Line,{clauses,Cs}} = Ex, Bs, Lf, Ef, RBs) -> 20 -> fun (A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T) -> eval_fun([A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T], Info) end; _Other -> - L = erl_anno:location(Line), + L = erl_anno:location(Anno), erlang:raise(error, {'argument_limit',{'fun',L,to_terms(Cs)}}, ?STACKTRACE) end, ret_expr(F, Bs, RBs); -expr({named_fun,Line,Name,Cs} = Ex, Bs, Lf, Ef, RBs) -> +expr({named_fun,Anno,Name,Cs} = Ex, Bs, Lf, Ef, RBs) -> %% Save only used variables in the function environment. %% {value,L,V} are hidden while lint finds used variables. {Ex1, _} = hide_calls(Ex, 0), @@ -379,7 +379,7 @@ expr({named_fun,Line,Name,Cs} = Ex, Bs, Lf, Ef, RBs) -> eval_named_fun([A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T], RF, Info) end; _Other -> - L = erl_anno:location(Line), + L = erl_anno:location(Anno), erlang:raise(error, {'argument_limit', {named_fun,L,Name,to_terms(Cs)}}, ?STACKTRACE) @@ -391,17 +391,17 @@ expr({call,_,{remote,_,{atom,_,qlc},{atom,_,q}},[{lc,_,_E,_Qs}=LC | As0]}, MaxLine = find_maxline(LC), {LC1, D} = hide_calls(LC, MaxLine), case qlc:transform_from_evaluator(LC1, Bs0) of - {ok,{call,L,Remote,[QLC]}} -> + {ok,{call,A,Remote,[QLC]}} -> QLC1 = unhide_calls(QLC, MaxLine, D), - expr({call,L,Remote,[QLC1 | As0]}, Bs0, Lf, Ef, RBs); + expr({call,A,Remote,[QLC1 | As0]}, Bs0, Lf, Ef, RBs); {not_ok,Error} -> ret_expr(Error, Bs0, RBs) end; -expr({call,L1,{remote,L2,{record_field,_,{atom,_,''},{atom,_,qlc}=Mod}, +expr({call,A1,{remote,A2,{record_field,_,{atom,_,''},{atom,_,qlc}=Mod}, {atom,_,q}=Func}, [{lc,_,_E,_Qs} | As0]=As}, Bs, Lf, Ef, RBs) when length(As0) =< 1 -> - expr({call,L1,{remote,L2,Mod,Func},As}, Bs, Lf, Ef, RBs); + expr({call,A1,{remote,A2,Mod,Func},As}, Bs, Lf, Ef, RBs); expr({call,_,{remote,_,Mod,Func},As0}, Bs0, Lf, Ef, RBs) -> {value,M,Bs1} = expr(Mod, Bs0, Lf, Ef, none), {value,F,Bs2} = expr(Func, Bs0, Lf, Ef, none), @@ -488,11 +488,18 @@ expr({value,_,Val}, Bs, _Lf, _Ef, RBs) -> % Special case straight values. find_maxline(LC) -> put('$erl_eval_max_line', 0), F = fun(A) -> - L = erl_anno:line(A), - case is_integer(L) and (L > get('$erl_eval_max_line')) of - true -> put('$erl_eval_max_line', L); + case erl_anno:is_anno(A) of + true -> + L = erl_anno:line(A), + case + is_integer(L) and (L > get('$erl_eval_max_line')) + of + true -> put('$erl_eval_max_line', L); + false -> ok + end; false -> ok - end end, + end + end, _ = erl_parse:map_anno(F, LC), erase('$erl_eval_max_line'). @@ -505,14 +512,14 @@ hide_calls(LC, MaxLine) -> hide({value,L,V}, Id, D) -> A = erl_anno:new(Id), {{atom,A,ok}, Id+1, maps:put(Id, {value,L,V}, D)}; -hide({call,L,{atom,_,N}=Atom,Args}, Id0, D0) -> +hide({call,A,{atom,_,N}=Atom,Args}, Id0, D0) -> {NArgs, Id, D} = hide(Args, Id0, D0), C = case erl_internal:bif(N, length(Args)) of true -> - {call,L,Atom,NArgs}; + {call,A,Atom,NArgs}; false -> - A = erl_anno:new(Id), - {call,A,{remote,L,{atom,L,m},{atom,L,f}},NArgs} + Anno = erl_anno:new(Id), + {call,Anno,{remote,A,{atom,A,m},{atom,A,f}},NArgs} end, {C, Id+1, maps:put(Id, {call,Atom}, D)}; hide(T0, Id0, D0) when is_tuple(T0) -> @@ -533,14 +540,15 @@ unhide_calls({atom,A,ok}=E, MaxLine, D) -> true -> E end; -unhide_calls({call,A,{remote,L,{atom,L,m},{atom,L,f}}=F,Args}, MaxLine, D) -> - Line = erl_anno:line(A), +unhide_calls({call,Anno,{remote,A,{atom,A,m},{atom,A,f}}=F,Args}, + MaxLine, D) -> + Line = erl_anno:line(Anno), if Line > MaxLine -> {call,Atom} = map_get(Line, D), - {call,L,Atom,unhide_calls(Args, MaxLine, D)}; + {call,A,Atom,unhide_calls(Args, MaxLine, D)}; true -> - {call,A,F,unhide_calls(Args, MaxLine, D)} + {call,Anno,F,unhide_calls(Args, MaxLine, D)} end; unhide_calls(T, MaxLine, D) when is_tuple(T) -> list_to_tuple(unhide_calls(tuple_to_list(T), MaxLine, D)); @@ -1045,14 +1053,14 @@ guard0([], _Bs, _Lf, _Ef) -> true. %% {value,bool(),NewBindings}. %% Evaluate one guard test. Never fails, returns bool(). -guard_test({call,L,{atom,Ln,F},As0}, Bs0, Lf, Ef) -> +guard_test({call,A,{atom,Ln,F},As0}, Bs0, Lf, Ef) -> TT = type_test(F), - G = {call,L,{atom,Ln,TT},As0}, + G = {call,A,{atom,Ln,TT},As0}, expr_guard_test(G, Bs0, Lf, Ef); -guard_test({call,L,{remote,Lr,{atom,Lm,erlang},{atom,Lf,F}},As0}, +guard_test({call,A,{remote,Ar,{atom,Am,erlang},{atom,Af,F}},As0}, Bs0, Lf, Ef) -> TT = type_test(F), - G = {call,L,{remote,Lr,{atom,Lm,erlang},{atom,Lf,TT}},As0}, + G = {call,A,{remote,Ar,{atom,Am,erlang},{atom,Af,TT}},As0}, expr_guard_test(G, Bs0, Lf, Ef); guard_test(G, Bs0, Lf, Ef) -> expr_guard_test(G, Bs0, Lf, Ef). @@ -1098,8 +1106,8 @@ match(Pat, Term, Bs, BBs) -> end. string_to_conses([], _, Tail) -> Tail; -string_to_conses([E|Rest], Line, Tail) -> - {cons, Line, {integer, Line, E}, string_to_conses(Rest, Line, Tail)}. +string_to_conses([E|Rest], Anno, Tail) -> + {cons, Anno, {integer, Anno, E}, string_to_conses(Rest, Anno, Tail)}. match1({atom,_,A0}, A, Bs, _BBs) -> case A of @@ -1177,22 +1185,22 @@ match1({bin,_,_}, _, _Bs, _BBs) -> throw(nomatch); match1({op,_,'++',{nil,_},R}, Term, Bs, BBs) -> match1(R, Term, Bs, BBs); -match1({op,_,'++',{cons,Li,{integer,L2,I},T},R}, Term, Bs, BBs) -> - match1({cons,Li,{integer,L2,I},{op,Li,'++',T,R}}, Term, Bs, BBs); -match1({op,_,'++',{cons,Li,{char,L2,C},T},R}, Term, Bs, BBs) -> - match1({cons,Li,{char,L2,C},{op,Li,'++',T,R}}, Term, Bs, BBs); -match1({op,_,'++',{string,Li,L},R}, Term, Bs, BBs) -> - match1(string_to_conses(L, Li, R), Term, Bs, BBs); -match1({op,Line,Op,A}, Term, Bs, BBs) -> - case partial_eval({op,Line,Op,A}) of - {op,Line,Op,A} -> +match1({op,_,'++',{cons,Ai,{integer,A2,I},T},R}, Term, Bs, BBs) -> + match1({cons,Ai,{integer,A2,I},{op,Ai,'++',T,R}}, Term, Bs, BBs); +match1({op,_,'++',{cons,Ai,{char,A2,C},T},R}, Term, Bs, BBs) -> + match1({cons,Ai,{char,A2,C},{op,Ai,'++',T,R}}, Term, Bs, BBs); +match1({op,_,'++',{string,Ai,L},R}, Term, Bs, BBs) -> + match1(string_to_conses(L, Ai, R), Term, Bs, BBs); +match1({op,Anno,Op,A}, Term, Bs, BBs) -> + case partial_eval({op,Anno,Op,A}) of + {op,Anno,Op,A} -> throw(invalid); X -> match1(X, Term, Bs, BBs) end; -match1({op,Line,Op,L,R}, Term, Bs, BBs) -> - case partial_eval({op,Line,Op,L,R}) of - {op,Line,Op,L,R} -> +match1({op,Anno,Op,L,R}, Term, Bs, BBs) -> + case partial_eval({op,Anno,Op,L,R}) of + {op,Anno,Op,L,R} -> throw(invalid); X -> match1(X, Term, Bs, BBs) @@ -1547,11 +1555,11 @@ eval_expr(Expr) -> end. partial_eval(Expr) -> - Line = line(Expr), + Anno = anno(Expr), case catch ev_expr(Expr) of - X when is_integer(X) -> ret_expr(Expr,{integer,Line,X}); - X when is_float(X) -> ret_expr(Expr,{float,Line,X}); - X when is_atom(X) -> ret_expr(Expr,{atom,Line,X}); + X when is_integer(X) -> ret_expr(Expr,{integer,Anno,X}); + X when is_float(X) -> ret_expr(Expr,{float,Anno,X}); + X when is_atom(X) -> ret_expr(Expr,{atom,Anno,X}); _ -> Expr end. @@ -1566,10 +1574,10 @@ ev_expr({tuple,_,Es}) -> list_to_tuple([ev_expr(X) || X <- Es]); ev_expr({nil,_}) -> []; ev_expr({cons,_,H,T}) -> [ev_expr(H) | ev_expr(T)]. -%%ev_expr({call,Line,{atom,_,F},As}) -> +%%ev_expr({call,Anno,{atom,_,F},As}) -> %% true = erl_internal:guard_bif(F, length(As)), %% apply(erlang, F, [ev_expr(X) || X <- As]); -%%ev_expr({call,Line,{remote,_,{atom,_,erlang},{atom,_,F}},As}) -> +%%ev_expr({call,Anno,{remote,_,{atom,_,erlang},{atom,_,F}},As}) -> %% true = erl_internal:guard_bif(F, length(As)), %% apply(erlang, F, [ev_expr(X) || X <- As]); @@ -1599,7 +1607,7 @@ eval_str(Str) when is_list(Str) -> Other -> {error, ?result("*** eval: ~p", [Other])} end; - {error, {_Line, Mod, Args}} -> + {error, {_Location, Mod, Args}} -> Msg = ?result("*** ~ts",[Mod:format_error(Args)]), {error, Msg} end; @@ -1622,4 +1630,4 @@ ret_expr(_Old, New) -> %% [line(Old), erl_pp:expr(Old), erl_pp:expr(New)]), New. -line(Expr) -> element(2, Expr). +anno(Expr) -> element(2, Expr). diff --git a/lib/stdlib/src/erl_expand_records.erl b/lib/stdlib/src/erl_expand_records.erl index 6200978d4d..ad824dae3a 100644 --- a/lib/stdlib/src/erl_expand_records.erl +++ b/lib/stdlib/src/erl_expand_records.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2005-2017. All Rights Reserved. +%% Copyright Ericsson AB 2005-2020. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -31,7 +31,8 @@ calltype=#{}, % Call types records=#{}, % Record definitions strict_ra=[], % strict record accesses - checked_ra=[] % successfully accessed records + checked_ra=[], % successfully accessed records + dialyzer=false % Cached value of compile flag 'dialyzer' }). -spec(module(AbsForms, CompileOptions) -> AbsForms2 when @@ -43,8 +44,9 @@ %% erl_lint without errors. module(Fs0, Opts0) -> Opts = compiler_options(Fs0) ++ Opts0, + Dialyzer = lists:member(dialyzer, Opts), Calltype = init_calltype(Fs0), - St0 = #exprec{compile = Opts, calltype = Calltype}, + St0 = #exprec{compile = Opts, dialyzer = Dialyzer, calltype = Calltype}, {Fs,_St} = forms(Fs0, St0), Fs. @@ -71,22 +73,22 @@ forms([{attribute,_,record,{Name,Defs}}=Attr | Fs], St0) -> St = St0#exprec{records=maps:put(Name, NDefs, St0#exprec.records)}, {Fs1, St1} = forms(Fs, St), {[Attr | Fs1], St1}; -forms([{function,L,N,A,Cs0} | Fs0], St0) -> +forms([{function,Anno,N,A,Cs0} | Fs0], St0) -> {Cs,St1} = clauses(Cs0, St0), {Fs,St2} = forms(Fs0, St1), - {[{function,L,N,A,Cs} | Fs],St2}; + {[{function,Anno,N,A,Cs} | Fs],St2}; forms([F | Fs0], St0) -> {Fs,St} = forms(Fs0, St0), {[F | Fs], St}; forms([], St) -> {[],St}. -clauses([{clause,Line,H0,G0,B0} | Cs0], St0) -> +clauses([{clause,Anno,H0,G0,B0} | Cs0], St0) -> {H1,St1} = head(H0, St0), {G1,St2} = guard(G0, St1), {H,G} = optimize_is_record(H1, G1, St2), {B,St3} = exprs(B0, St2), {Cs,St4} = clauses(Cs0, St3), - {[{clause,Line,H,G,B} | Cs],St4}; + {[{clause,Anno,H,G,B} | Cs],St4}; clauses([], St) -> {[],St}. head(As, St) -> pattern_list(As, St). @@ -107,41 +109,41 @@ pattern({string,_,_}=String, St) -> {String,St}; pattern({nil,_}=Nil, St) -> {Nil,St}; -pattern({cons,Line,H,T}, St0) -> +pattern({cons,Anno,H,T}, St0) -> {TH,St1} = pattern(H, St0), {TT,St2} = pattern(T, St1), - {{cons,Line,TH,TT},St2}; -pattern({tuple,Line,Ps}, St0) -> + {{cons,Anno,TH,TT},St2}; +pattern({tuple,Anno,Ps}, St0) -> {TPs,St1} = pattern_list(Ps, St0), - {{tuple,Line,TPs},St1}; -pattern({map,Line,Ps}, St0) -> + {{tuple,Anno,TPs},St1}; +pattern({map,Anno,Ps}, St0) -> {TPs,St1} = pattern_list(Ps, St0), - {{map,Line,TPs},St1}; -pattern({map_field_exact,Line,K0,V0}, St0) -> + {{map,Anno,TPs},St1}; +pattern({map_field_exact,Anno,K0,V0}, St0) -> {K,St1} = expr(K0, St0), {V,St2} = pattern(V0, St1), - {{map_field_exact,Line,K,V},St2}; -pattern({record_index,Line,Name,Field}, St) -> - {index_expr(Line, Field, Name, record_fields(Name, St)),St}; -pattern({record,Line0,Name,Pfs}, St0) -> - Fs = record_fields(Name, St0), + {{map_field_exact,Anno,K,V},St2}; +pattern({record_index,Anno,Name,Field}, St) -> + {index_expr(Anno, Field, Name, record_fields(Name, Anno, St)),St}; +pattern({record,Anno0,Name,Pfs}, St0) -> + Fs = record_fields(Name, Anno0, St0), {TMs,St1} = pattern_list(pattern_fields(Fs, Pfs), St0), - Line = mark_record(Line0, St1), - {{tuple,Line,[{atom,Line0,Name} | TMs]},St1}; -pattern({bin,Line,Es0}, St0) -> + Anno = mark_record(Anno0, St1), + {{tuple,Anno,[{atom,Anno0,Name} | TMs]},St1}; +pattern({bin,Anno,Es0}, St0) -> {Es1,St1} = pattern_bin(Es0, St0), - {{bin,Line,Es1},St1}; -pattern({match,Line,Pat1, Pat2}, St0) -> + {{bin,Anno,Es1},St1}; +pattern({match,Anno,Pat1, Pat2}, St0) -> {TH,St1} = pattern(Pat2, St0), {TT,St2} = pattern(Pat1, St1), - {{match,Line,TT,TH},St2}; -pattern({op,Line,Op,A0}, St0) -> + {{match,Anno,TT,TH},St2}; +pattern({op,Anno,Op,A0}, St0) -> {A,St1} = pattern(A0, St0), - {{op,Line,Op,A},St1}; -pattern({op,Line,Op,L0,R0}, St0) -> + {{op,Anno,Op,A},St1}; +pattern({op,Anno,Op,L0,R0}, St0) -> {L,St1} = pattern(L0, St0), {R,St2} = pattern(R0, St1), - {{op,Line,Op,L,R},St2}. + {{op,Anno,Op,L,R},St2}. pattern_list([P0 | Ps0], St0) -> {P,St1} = pattern(P0, St0), @@ -173,9 +175,9 @@ guard_test(G0, St0) -> %% Normalising guard tests ensures that none of the Boolean operands %% created by strict_record_access/2 calls any of the old guard tests. -guard_test1({call,Line,{atom,Lt,Tname},As}, St) -> - Test = {atom,Lt,normalise_test(Tname, length(As))}, - expr({call,Line,Test,As}, St); +guard_test1({call,Anno,{atom,Tanno,Tname},As}, St) -> + Test = {atom,Tanno,normalise_test(Tname, length(As))}, + expr({call,Anno,Test,As}, St); guard_test1(Test, St) -> expr(Test, St). @@ -202,27 +204,27 @@ in_guard(F) -> true = erase(erl_expand_records_in_guard), Res. -%% record_test(Line, Term, Name, Vs, St) -> TransformedExpr +%% record_test(Anno, Term, Name, Vs, St) -> TransformedExpr %% Generate code for is_record/1. -record_test(Line, Term, Name, St) -> +record_test(Anno, Term, Name, St) -> case is_in_guard() of false -> - record_test_in_body(Line, Term, Name, St); + record_test_in_body(Anno, Term, Name, St); true -> - record_test_in_guard(Line, Term, Name, St) + record_test_in_guard(Anno, Term, Name, St) end. -record_test_in_guard(Line, Term, Name, St) -> +record_test_in_guard(Anno, Term, Name, St) -> case not_a_tuple(Term) of true -> %% In case that later optimization passes have been turned off. - expr({atom,Line,false}, St); + expr({atom,Anno,false}, St); false -> - Fs = record_fields(Name, St), - NLine = no_compiler_warning(Line), - expr({call,NLine,{remote,NLine,{atom,NLine,erlang},{atom,NLine,is_record}}, - [Term,{atom,Line,Name},{integer,Line,length(Fs)+1}]}, + Fs = record_fields(Name, Anno, St), + NAnno = no_compiler_warning(Anno), + expr({call,NAnno,{remote,NAnno,{atom,NAnno,erlang},{atom,NAnno,is_record}}, + [Term,{atom,Anno,Name},{integer,Anno,length(Fs)+1}]}, St) end. @@ -239,19 +241,19 @@ not_a_tuple({op,_,_,_}) -> true; not_a_tuple({op,_,_,_,_}) -> true; not_a_tuple(_) -> false. -record_test_in_body(Line, Expr, Name, St0) -> +record_test_in_body(Anno, Expr, Name, St0) -> %% As Expr may have side effects, we must evaluate it %% first and bind the value to a new variable. %% We must use also handle the case that Expr does not %% evaluate to a tuple properly. - Fs = record_fields(Name, St0), - {Var,St} = new_var(Line, St0), - NLine = no_compiler_warning(Line), - expr({block,Line, - [{match,Line,Var,Expr}, - {call,NLine,{remote,NLine,{atom,NLine,erlang}, - {atom,NLine,is_record}}, - [Var,{atom,Line,Name},{integer,Line,length(Fs)+1}]}]}, St). + Fs = record_fields(Name, Anno, St0), + {Var,St} = new_var(Anno, St0), + NAnno = no_compiler_warning(Anno), + expr({block,Anno, + [{match,Anno,Var,Expr}, + {call,NAnno,{remote,NAnno,{atom,NAnno,erlang}, + {atom,NAnno,is_record}}, + [Var,{atom,Anno,Name},{integer,Anno,length(Fs)+1}]}]}, St). exprs([E0 | Es0], St0) -> {E,St1} = expr(E0, St0), @@ -273,160 +275,160 @@ expr({string,_,_}=String, St) -> {String,St}; expr({nil,_}=Nil, St) -> {Nil,St}; -expr({cons,Line,H0,T0}, St0) -> +expr({cons,Anno,H0,T0}, St0) -> {H,St1} = expr(H0, St0), {T,St2} = expr(T0, St1), - {{cons,Line,H,T},St2}; -expr({lc,Line,E0,Qs0}, St0) -> - {Qs1,St1} = lc_tq(Line, Qs0, St0), + {{cons,Anno,H,T},St2}; +expr({lc,Anno,E0,Qs0}, St0) -> + {Qs1,St1} = lc_tq(Anno, Qs0, St0), {E1,St2} = expr(E0, St1), - {{lc,Line,E1,Qs1},St2}; -expr({bc,Line,E0,Qs0}, St0) -> - {Qs1,St1} = lc_tq(Line, Qs0, St0), + {{lc,Anno,E1,Qs1},St2}; +expr({bc,Anno,E0,Qs0}, St0) -> + {Qs1,St1} = lc_tq(Anno, Qs0, St0), {E1,St2} = expr(E0, St1), - {{bc,Line,E1,Qs1},St2}; -expr({tuple,Line,Es0}, St0) -> + {{bc,Anno,E1,Qs1},St2}; +expr({tuple,Anno,Es0}, St0) -> {Es1,St1} = expr_list(Es0, St0), - {{tuple,Line,Es1},St1}; -expr({map,Line,Es0}, St0) -> + {{tuple,Anno,Es1},St1}; +expr({map,Anno,Es0}, St0) -> {Es1,St1} = expr_list(Es0, St0), - {{map,Line,Es1},St1}; -expr({map,Line,Arg0,Es0}, St0) -> + {{map,Anno,Es1},St1}; +expr({map,Anno,Arg0,Es0}, St0) -> {Arg1,St1} = expr(Arg0, St0), {Es1,St2} = expr_list(Es0, St1), - {{map,Line,Arg1,Es1},St2}; -expr({map_field_assoc,Line,K0,V0}, St0) -> + {{map,Anno,Arg1,Es1},St2}; +expr({map_field_assoc,Anno,K0,V0}, St0) -> {K,St1} = expr(K0, St0), {V,St2} = expr(V0, St1), - {{map_field_assoc,Line,K,V},St2}; -expr({map_field_exact,Line,K0,V0}, St0) -> + {{map_field_assoc,Anno,K,V},St2}; +expr({map_field_exact,Anno,K0,V0}, St0) -> {K,St1} = expr(K0, St0), {V,St2} = expr(V0, St1), - {{map_field_exact,Line,K,V},St2}; -expr({record_index,Line,Name,F}, St) -> - I = index_expr(Line, F, Name, record_fields(Name, St)), + {{map_field_exact,Anno,K,V},St2}; +expr({record_index,Anno,Name,F}, St) -> + I = index_expr(Anno, F, Name, record_fields(Name, Anno, St)), expr(I, St); -expr({record,Line0,Name,Is}, St) -> - Line = mark_record(Line0, St), - expr({tuple,Line,[{atom,Line0,Name} | - record_inits(record_fields(Name, St), Is)]}, +expr({record,Anno0,Name,Is}, St) -> + Anno = mark_record(Anno0, St), + expr({tuple,Anno,[{atom,Anno0,Name} | + record_inits(record_fields(Name, Anno0, St), Is)]}, St); -expr({record_field,Line,R,Name,F}, St) -> - get_record_field(Line, R, F, Name, St); -expr({record,_,R,Name,Us}, St0) -> - {Ue,St1} = record_update(R, Name, record_fields(Name, St0), Us, St0), +expr({record_field,Anno,R,Name,F}, St) -> + get_record_field(Anno, R, F, Name, St); +expr({record,Anno,R,Name,Us}, St0) -> + {Ue,St1} = record_update(R, Name, record_fields(Name, Anno, St0), Us, St0), expr(Ue, St1); -expr({bin,Line,Es0}, St0) -> +expr({bin,Anno,Es0}, St0) -> {Es1,St1} = expr_bin(Es0, St0), - {{bin,Line,Es1},St1}; -expr({block,Line,Es0}, St0) -> + {{bin,Anno,Es1},St1}; +expr({block,Anno,Es0}, St0) -> {Es,St1} = exprs(Es0, St0), - {{block,Line,Es},St1}; -expr({'if',Line,Cs0}, St0) -> + {{block,Anno,Es},St1}; +expr({'if',Anno,Cs0}, St0) -> {Cs,St1} = clauses(Cs0, St0), - {{'if',Line,Cs},St1}; -expr({'case',Line,E0,Cs0}, St0) -> + {{'if',Anno,Cs},St1}; +expr({'case',Anno,E0,Cs0}, St0) -> {E,St1} = expr(E0, St0), {Cs,St2} = clauses(Cs0, St1), - {{'case',Line,E,Cs},St2}; -expr({'receive',Line,Cs0}, St0) -> + {{'case',Anno,E,Cs},St2}; +expr({'receive',Anno,Cs0}, St0) -> {Cs,St1} = clauses(Cs0, St0), - {{'receive',Line,Cs},St1}; -expr({'receive',Line,Cs0,To0,ToEs0}, St0) -> + {{'receive',Anno,Cs},St1}; +expr({'receive',Anno,Cs0,To0,ToEs0}, St0) -> {To,St1} = expr(To0, St0), {ToEs,St2} = exprs(ToEs0, St1), {Cs,St3} = clauses(Cs0, St2), - {{'receive',Line,Cs,To,ToEs},St3}; -expr({'fun',Lf,{function,F,A}}=Fun0, St0) -> + {{'receive',Anno,Cs,To,ToEs},St3}; +expr({'fun',Anno,{function,F,A}}=Fun0, St0) -> case erl_internal:bif(F, A) of true -> - {As,St1} = new_vars(A, Lf, St0), - Cs = [{clause,Lf,As,[],[{call,Lf,{atom,Lf,F},As}]}], - Fun = {'fun',Lf,{clauses,Cs}}, + {As,St1} = new_vars(A, Anno, St0), + Cs = [{clause,Anno,As,[],[{call,Anno,{atom,Anno,F},As}]}], + Fun = {'fun',Anno,{clauses,Cs}}, expr(Fun, St1); false -> {Fun0,St0} end; expr({'fun',_,{function,_M,_F,_A}}=Fun, St) -> {Fun,St}; -expr({'fun',Line,{clauses,Cs0}}, St0) -> +expr({'fun',Anno,{clauses,Cs0}}, St0) -> {Cs,St1} = clauses(Cs0, St0), - {{'fun',Line,{clauses,Cs}},St1}; -expr({named_fun,Line,Name,Cs0}, St0) -> + {{'fun',Anno,{clauses,Cs}},St1}; +expr({named_fun,Anno,Name,Cs0}, St0) -> {Cs,St1} = clauses(Cs0, St0), - {{named_fun,Line,Name,Cs},St1}; -expr({call,Line,{atom,_,is_record},[A,{atom,_,Name}]}, St) -> - record_test(Line, A, Name, St); -expr({call,Line,{remote,_,{atom,_,erlang},{atom,_,is_record}}, + {{named_fun,Anno,Name,Cs},St1}; +expr({call,Anno,{atom,_,is_record},[A,{atom,_,Name}]}, St) -> + record_test(Anno, A, Name, St); +expr({call,Anno,{remote,_,{atom,_,erlang},{atom,_,is_record}}, [A,{atom,_,Name}]}, St) -> - record_test(Line, A, Name, St); -expr({call,Line,{tuple,_,[{atom,_,erlang},{atom,_,is_record}]}, + record_test(Anno, A, Name, St); +expr({call,Anno,{tuple,_,[{atom,_,erlang},{atom,_,is_record}]}, [A,{atom,_,Name}]}, St) -> - record_test(Line, A, Name, St); -expr({call,Line,{atom,_La,record_info},[_,_]=As0}, St0) -> + record_test(Anno, A, Name, St); +expr({call,Anno,{atom,_AnnoA,record_info},[_,_]=As0}, St0) -> {As,St1} = expr_list(As0, St0), - record_info_call(Line, As, St1); -expr({call,Line,{atom,_La,N}=Atom,As0}, St0) -> + record_info_call(Anno, As, St1); +expr({call,Anno,{atom,_AnnoA,N}=Atom,As0}, St0) -> {As,St1} = expr_list(As0, St0), Ar = length(As), NA = {N,Ar}, case St0#exprec.calltype of #{NA := local} -> - {{call,Line,Atom,As},St1}; + {{call,Anno,Atom,As},St1}; #{NA := {imported,Module}} -> - ModAtom = {atom,Line,Module}, - {{call,Line,{remote,Line,ModAtom,Atom},As},St1}; + ModAtom = {atom,Anno,Module}, + {{call,Anno,{remote,Anno,ModAtom,Atom},As},St1}; _ -> case erl_internal:bif(N, Ar) of true -> - ModAtom = {atom,Line,erlang}, - {{call,Line,{remote,Line,ModAtom,Atom},As},St1}; + ModAtom = {atom,Anno,erlang}, + {{call,Anno,{remote,Anno,ModAtom,Atom},As},St1}; false -> %% Call to a module_info/0,1 or one of the %% pseudo-functions in the shell. Leave it as %% a local call. - {{call,Line,Atom,As},St1} + {{call,Anno,Atom,As},St1} end end; -expr({call,Line,{remote,Lr,M,F},As0}, St0) -> +expr({call,Anno,{remote,AnnoR,M,F},As0}, St0) -> {[M1,F1 | As1],St1} = expr_list([M,F | As0], St0), - {{call,Line,{remote,Lr,M1,F1},As1},St1}; -expr({call,Line,F,As0}, St0) -> + {{call,Anno,{remote,AnnoR,M1,F1},As1},St1}; +expr({call,Anno,F,As0}, St0) -> {[Fun1 | As1],St1} = expr_list([F | As0], St0), - {{call,Line,Fun1,As1},St1}; -expr({'try',Line,Es0,Scs0,Ccs0,As0}, St0) -> + {{call,Anno,Fun1,As1},St1}; +expr({'try',Anno,Es0,Scs0,Ccs0,As0}, St0) -> {Es1,St1} = exprs(Es0, St0), {Scs1,St2} = clauses(Scs0, St1), {Ccs1,St3} = clauses(Ccs0, St2), {As1,St4} = exprs(As0, St3), - {{'try',Line,Es1,Scs1,Ccs1,As1},St4}; -expr({'catch',Line,E0}, St0) -> + {{'try',Anno,Es1,Scs1,Ccs1,As1},St4}; +expr({'catch',Anno,E0}, St0) -> {E,St1} = expr(E0, St0), - {{'catch',Line,E},St1}; -expr({match,Line,P0,E0}, St0) -> + {{'catch',Anno,E},St1}; +expr({match,Anno,P0,E0}, St0) -> {E,St1} = expr(E0, St0), {P,St2} = pattern(P0, St1), - {{match,Line,P,E},St2}; -expr({op,Line,'not',A0}, St0) -> + {{match,Anno,P,E},St2}; +expr({op,Anno,'not',A0}, St0) -> {A,St1} = bool_operand(A0, St0), - {{op,Line,'not',A},St1}; -expr({op,Line,Op,A0}, St0) -> + {{op,Anno,'not',A},St1}; +expr({op,Anno,Op,A0}, St0) -> {A,St1} = expr(A0, St0), - {{op,Line,Op,A},St1}; -expr({op,Line,Op,L0,R0}, St0) when Op =:= 'and'; + {{op,Anno,Op,A},St1}; +expr({op,Anno,Op,L0,R0}, St0) when Op =:= 'and'; Op =:= 'or' -> {L,St1} = bool_operand(L0, St0), {R,St2} = bool_operand(R0, St1), - {{op,Line,Op,L,R},St2}; -expr({op,Line,Op,L0,R0}, St0) when Op =:= 'andalso'; + {{op,Anno,Op,L,R},St2}; +expr({op,Anno,Op,L0,R0}, St0) when Op =:= 'andalso'; Op =:= 'orelse' -> {L,St1} = bool_operand(L0, St0), {R,St2} = bool_operand(R0, St1), - {{op,Line,Op,L,R},St2#exprec{checked_ra = St1#exprec.checked_ra}}; -expr({op,Line,Op,L0,R0}, St0) -> + {{op,Anno,Op,L,R},St2#exprec{checked_ra = St1#exprec.checked_ra}}; +expr({op,Anno,Op,L0,R0}, St0) -> {L,St1} = expr(L0, St0), {R,St2} = expr(R0, St1), - {{op,Line,Op,L,R},St2}. + {{op,Anno,Op,L,R},St2}. expr_list([E0 | Es0], St0) -> {E,St1} = expr(E0, St0), @@ -442,7 +444,7 @@ strict_record_access(E, #exprec{strict_ra = []} = St) -> {E, St}; strict_record_access(E0, St0) -> #exprec{strict_ra = StrictRA, checked_ra = CheckedRA} = St0, - {New,NC} = lists:foldl(fun ({Key,_L,_R,_Sz}=A, {L,C}) -> + {New,NC} = lists:foldl(fun ({Key,_Anno,_R,_Sz}=A, {L,C}) -> case lists:keymember(Key, 1, C) of true -> {L,C}; false -> {[A|L],[A|C]} @@ -456,16 +458,16 @@ strict_record_access(E0, St0) -> %% ('and'/2 is left recursive). conj([], _E) -> empty; -conj([{{Name,_Rp},L,R,Sz} | AL], E) -> - NL = no_compiler_warning(L), - T1 = {op,NL,'orelse', - {call,NL, - {remote,NL,{atom,NL,erlang},{atom,NL,is_record}}, - [R,{atom,NL,Name},{integer,NL,Sz}]}, - {atom,NL,fail}}, +conj([{{Name,_Rp},Anno,R,Sz} | AL], E) -> + NAnno = no_compiler_warning(Anno), + T1 = {op,NAnno,'orelse', + {call,NAnno, + {remote,NAnno,{atom,NAnno,erlang},{atom,NAnno,is_record}}, + [R,{atom,NAnno,Name},{integer,NAnno,Sz}]}, + {atom,NAnno,fail}}, T2 = case conj(AL, none) of empty -> T1; - C -> {op,NL,'and',C,T1} + C -> {op,NAnno,'and',C,T1} end, case E of none -> @@ -478,26 +480,26 @@ conj([{{Name,_Rp},L,R,Sz} | AL], E) -> %% expression returns 'fail'. ('orelse' used to verify %% that its right operand was a boolean, but that is no %% longer the case.) - {op,NL,'and',T2,{atom,NL,true}} + {op,NAnno,'and',T2,{atom,NAnno,true}} end; _ -> - {op,NL,'and',T2,E} + {op,NAnno,'and',T2,E} end. -%% lc_tq(Line, Qualifiers, State) -> +%% lc_tq(Anno, Qualifiers, State) -> %% {[TransQual],State'} -lc_tq(Line, [{generate,Lg,P0,G0} | Qs0], St0) -> +lc_tq(Anno, [{generate,AnnoG,P0,G0} | Qs0], St0) -> {G1,St1} = expr(G0, St0), {P1,St2} = pattern(P0, St1), - {Qs1,St3} = lc_tq(Line, Qs0, St2), - {[{generate,Lg,P1,G1} | Qs1],St3}; -lc_tq(Line, [{b_generate,Lg,P0,G0} | Qs0], St0) -> + {Qs1,St3} = lc_tq(Anno, Qs0, St2), + {[{generate,AnnoG,P1,G1} | Qs1],St3}; +lc_tq(Anno, [{b_generate,AnnoG,P0,G0} | Qs0], St0) -> {G1,St1} = expr(G0, St0), {P1,St2} = pattern(P0, St1), - {Qs1,St3} = lc_tq(Line, Qs0, St2), - {[{b_generate,Lg,P1,G1} | Qs1],St3}; -lc_tq(Line, [F0 | Qs0], #exprec{calltype=Calltype}=St0) -> + {Qs1,St3} = lc_tq(Anno, Qs0, St2), + {[{b_generate,AnnoG,P1,G1} | Qs1],St3}; +lc_tq(Anno, [F0 | Qs0], #exprec{calltype=Calltype}=St0) -> %% Allow record/2 and expand out as guard test. IsOverriden = fun(FA) -> case Calltype of @@ -509,14 +511,14 @@ lc_tq(Line, [F0 | Qs0], #exprec{calltype=Calltype}=St0) -> case erl_lint:is_guard_test(F0, [], IsOverriden) of true -> {F1,St1} = guard_test(F0, St0), - {Qs1,St2} = lc_tq(Line, Qs0, St1), + {Qs1,St2} = lc_tq(Anno, Qs0, St1), {[F1|Qs1],St2}; false -> {F1,St1} = expr(F0, St0), - {Qs1,St2} = lc_tq(Line, Qs0, St1), + {Qs1,St2} = lc_tq(Anno, Qs0, St1), {[F1 | Qs1],St2} end; -lc_tq(_Line, [], St0) -> +lc_tq(_Anno, [], St0) -> {[],St0#exprec{checked_ra = []}}. %% normalise_fields([RecDef]) -> [Field]. @@ -524,96 +526,110 @@ lc_tq(_Line, [], St0) -> %% none has been given then use 'undefined'. normalise_fields(Fs) -> - map(fun ({record_field,Lf,Field}) -> - {record_field,Lf,Field,{atom,Lf,undefined}}; - ({typed_record_field,{record_field,Lf,Field},_Type}) -> - {record_field,Lf,Field,{atom,Lf,undefined}}; + map(fun ({record_field,Anno,Field}) -> + {record_field,Anno,Field,{atom,Anno,undefined}}; + ({typed_record_field,{record_field,Anno,Field},_Type}) -> + {record_field,Anno,Field,{atom,Anno,undefined}}; ({typed_record_field,Field,_Type}) -> Field; (F) -> F end, Fs). -%% record_fields(RecordName, State) +%% record_fields(RecordName, Anno, State) %% find_field(FieldName, Fields) -record_fields(R, St) -> maps:get(R, St#exprec.records). +record_fields(R, Anno, St) -> + Fields = maps:get(R, St#exprec.records), + case St#exprec.dialyzer of + true -> + [{record_field,Anno,{atom,Anno,F},copy_expr(Di, Anno)} || + {record_field,_Anno,{atom,_AnnoA,F},Di} <- Fields]; + false -> + Fields + end. find_field(F, [{record_field,_,{atom,_,F},Val} | _]) -> {ok,Val}; find_field(F, [_ | Fs]) -> find_field(F, Fs); find_field(_, []) -> error. +%% copy_expr(Expr, Anno) -> Expr. +%% Make a copy of Expr converting all annotations to Anno. + +copy_expr(Expr, Anno) -> + erl_parse:map_anno(fun(_A) -> Anno end, Expr). + %% field_names(RecFields) -> [Name]. %% Return a list of the field names structures. field_names(Fs) -> map(fun ({record_field,_,Field,_Val}) -> Field end, Fs). -%% index_expr(Line, FieldExpr, Name, Fields) -> IndexExpr. +%% index_expr(Anno, FieldExpr, Name, Fields) -> IndexExpr. %% Return an expression which evaluates to the index of a %% field. Currently only handle the case where the field is an %% atom. This expansion must be passed through expr again. -index_expr(Line, {atom,_,F}, _Name, Fs) -> - {integer,Line,index_expr(F, Fs, 2)}. +index_expr(Anno, {atom,_,F}, _Name, Fs) -> + {integer,Anno,index_expr(F, Fs, 2)}. index_expr(F, [{record_field,_,{atom,_,F},_} | _], I) -> I; index_expr(F, [_ | Fs], I) -> index_expr(F, Fs, I+1). -%% get_record_field(Line, RecExpr, FieldExpr, Name, St) -> {Expr,St'}. +%% get_record_field(Anno, RecExpr, FieldExpr, Name, St) -> {Expr,St'}. %% Return an expression which verifies that the type of record %% is correct and then returns the value of the field. %% This expansion must be passed through expr again. -get_record_field(Line, R, Index, Name, St) -> +get_record_field(Anno, R, Index, Name, St) -> case strict_record_tests(St#exprec.compile) of false -> - sloppy_get_record_field(Line, R, Index, Name, St); + sloppy_get_record_field(Anno, R, Index, Name, St); true -> - strict_get_record_field(Line, R, Index, Name, St) + strict_get_record_field(Anno, R, Index, Name, St) end. -strict_get_record_field(Line, R, {atom,_,F}=Index, Name, St0) -> +strict_get_record_field(Anno, R, {atom,_,F}=Index, Name, St0) -> case is_in_guard() of false -> %Body context. - {Var,St} = new_var(Line, St0), - Fs = record_fields(Name, St), + {Var,St} = new_var(Anno, St0), + Fs = record_fields(Name, Anno, St), I = index_expr(F, Fs, 2), - P = record_pattern(2, I, Var, length(Fs)+1, Line, [{atom,Line,Name}]), - NLine = no_compiler_warning(Line), - RLine = mark_record(NLine, St), - E = {'case',NLine,R, - [{clause,NLine,[{tuple,RLine,P}],[],[Var]}, - {clause,NLine,[{var,NLine,'_'}],[], - [{call,NLine,{remote,NLine, - {atom,NLine,erlang}, - {atom,NLine,error}}, - [{tuple,NLine,[{atom,NLine,badrecord},{atom,NLine,Name}]}]}]}]}, + P = record_pattern(2, I, Var, length(Fs)+1, Anno, [{atom,Anno,Name}]), + NAnno = no_compiler_warning(Anno), + RAnno = mark_record(NAnno, St), + E = {'case',Anno,R, + [{clause,NAnno,[{tuple,RAnno,P}],[],[Var]}, + {clause,NAnno,[{var,NAnno,'_'}],[], + [{call,NAnno,{remote,NAnno, + {atom,NAnno,erlang}, + {atom,NAnno,error}}, + [{tuple,NAnno,[{atom,NAnno,badrecord},{atom,NAnno,Name}]}]}]}]}, expr(E, St); true -> %In a guard. - Fs = record_fields(Name, St0), - I = index_expr(Line, Index, Name, Fs), + Fs = record_fields(Name, Anno, St0), + I = index_expr(Anno, Index, Name, Fs), {ExpR,St1} = expr(R, St0), %% Just to make comparison simple: A0 = erl_anno:new(0), ExpRp = erl_parse:map_anno(fun(_A) -> A0 end, ExpR), - RA = {{Name,ExpRp},Line,ExpR,length(Fs)+1}, + RA = {{Name,ExpRp},Anno,ExpR,length(Fs)+1}, St2 = St1#exprec{strict_ra = [RA | St1#exprec.strict_ra]}, - {{call,Line, - {remote,Line,{atom,Line,erlang},{atom,Line,element}}, + {{call,Anno, + {remote,Anno,{atom,Anno,erlang},{atom,Anno,element}}, [I,ExpR]},St2} end. -record_pattern(I, I, Var, Sz, Line, Acc) -> - record_pattern(I+1, I, Var, Sz, Line, [Var | Acc]); -record_pattern(Cur, I, Var, Sz, Line, Acc) when Cur =< Sz -> - record_pattern(Cur+1, I, Var, Sz, Line, [{var,Line,'_'} | Acc]); +record_pattern(I, I, Var, Sz, Anno, Acc) -> + record_pattern(I+1, I, Var, Sz, Anno, [Var | Acc]); +record_pattern(Cur, I, Var, Sz, Anno, Acc) when Cur =< Sz -> + record_pattern(Cur+1, I, Var, Sz, Anno, [{var,Anno,'_'} | Acc]); record_pattern(_, _, _, _, _, Acc) -> reverse(Acc). -sloppy_get_record_field(Line, R, Index, Name, St) -> - Fs = record_fields(Name, St), - I = index_expr(Line, Index, Name, Fs), - expr({call,Line, - {remote,Line,{atom,Line,erlang},{atom,Line,element}}, +sloppy_get_record_field(Anno, R, Index, Name, St) -> + Fs = record_fields(Name, Anno, St), + I = index_expr(Anno, Index, Name, Fs), + expr({call,Anno, + {remote,Anno,{atom,Anno,erlang},{atom,Anno,element}}, [I,R]}, St). strict_record_tests([strict_record_tests | _]) -> true; @@ -633,10 +649,10 @@ strict_record_updates([]) -> false. %Default. pattern_fields(Fs, Ms) -> Wildcard = record_wildcard_init(Ms), - map(fun ({record_field,L,{atom,_,F},_}) -> + map(fun ({record_field,Anno,{atom,_,F},_}) -> case find_field(F, Ms) of {ok,Match} -> Match; - error when Wildcard =:= none -> {var,L,'_'}; + error when Wildcard =:= none -> {var,Anno,'_'}; error -> Wildcard end end, Fs). @@ -667,7 +683,7 @@ record_wildcard_init([]) -> none. %% passed through expr again. record_update(R, Name, Fs, Us0, St0) -> - Line = element(2, R), + Anno = element(2, R), {Pre,Us,St1} = record_exprs(Us0, St0), Nf = length(Fs), %# of record fields Nu = length(Us), %# of update fields @@ -675,7 +691,7 @@ record_update(R, Name, Fs, Us0, St0) -> %% We need a new variable for the record expression %% to guarantee that it is only evaluated once. - {Var,St2} = new_var(Line, St1), + {Var,St2} = new_var(Anno, St1), StrictUpdates = strict_record_updates(St2#exprec.compile), @@ -683,31 +699,31 @@ record_update(R, Name, Fs, Us0, St0) -> {Update,St} = if Nu =:= 0 -> - record_match(Var, Name, Line, Fs, Us, St2); + record_match(Var, Name, Anno, Fs, Us, St2); Nu =< Nc, not StrictUpdates -> %Few fields updated {record_setel(Var, Name, Fs, Us), St2}; true -> %The wide area inbetween - record_match(Var, Name, element(2, hd(Us)), Fs, Us, St2) + record_match(Var, Name, Anno, Fs, Us, St2) end, - {{block,Line,Pre ++ [{match,Line,Var,R},Update]},St}. + {{block,Anno,Pre ++ [{match,Anno,Var,R},Update]},St}. %% record_match(Record, RecordName, [RecDefField], [Update], State) %% Build a 'case' expression to modify record fields. -record_match(R, Name, Lr, Fs, Us, St0) -> +record_match(R, Name, AnnoR, Fs, Us, St0) -> {Ps,News,St1} = record_upd_fs(Fs, Us, St0), - NLr = no_compiler_warning(Lr), - RLine = mark_record(Lr, St1), - {{'case',Lr,R, - [{clause,Lr,[{tuple,RLine,[{atom,Lr,Name} | Ps]}],[], - [{tuple,RLine,[{atom,Lr,Name} | News]}]}, - {clause,NLr,[{var,NLr,'_'}],[], - [call_error(NLr, {tuple,NLr,[{atom,NLr,badrecord},{atom,NLr,Name}]})]} + NAnnoR = no_compiler_warning(AnnoR), + RAnno = mark_record(AnnoR, St1), + {{'case',AnnoR,R, + [{clause,AnnoR,[{tuple,RAnno,[{atom,AnnoR,Name} | Ps]}],[], + [{tuple,RAnno,[{atom,AnnoR,Name} | News]}]}, + {clause,NAnnoR,[{var,NAnnoR,'_'}],[], + [call_error(NAnnoR, {tuple,NAnnoR,[{atom,NAnnoR,badrecord},{atom,NAnnoR,Name}]})]} ]}, St1}. -record_upd_fs([{record_field,Lf,{atom,_La,F},_Val} | Fs], Us, St0) -> - {P,St1} = new_var(Lf, St0), +record_upd_fs([{record_field,Anno,{atom,_AnnoA,F},_Val} | Fs], Us, St0) -> + {P,St1} = new_var(Anno, St0), {Ps,News,St2} = record_upd_fs(Fs, Us, St1), case find_field(F, Us) of {ok,New} -> {[P | Ps],[New | News],St2}; @@ -720,37 +736,37 @@ record_upd_fs([], _, St) -> {[],[],St}. %% updated record tuple. record_setel(R, Name, Fs, Us0) -> - Us1 = foldl(fun ({record_field,Lf,Field,Val}, Acc) -> - {integer,_,FieldIndex} = I = index_expr(Lf, Field, Name, Fs), - [{FieldIndex,{I,Lf,Val}} | Acc] + Us1 = foldl(fun ({record_field,Anno,Field,Val}, Acc) -> + {integer,_,FieldIndex} = I = index_expr(Anno, Field, Name, Fs), + [{FieldIndex,{I,Anno,Val}} | Acc] end, [], Us0), Us2 = sort(Us1), Us = [T || {_,T} <- Us2], - Lr = element(2, hd(Us)), - Wildcards = duplicate(length(Fs), {var,Lr,'_'}), - NLr = no_compiler_warning(Lr), + AnnoR = element(2, hd(Us)), + Wildcards = duplicate(length(Fs), {var,AnnoR,'_'}), + NAnnoR = no_compiler_warning(AnnoR), %% Note: calling mark_record() here is not necessary since it is %% targeted at Dialyzer which always calls the compiler with %% 'strict_record_updates' meaning that record_setel() will never %% be called. - {'case',Lr,R, - [{clause,Lr,[{tuple,Lr,[{atom,Lr,Name} | Wildcards]}],[], - [foldr(fun ({I,Lf,Val}, Acc) -> - {call,Lf,{remote,Lf,{atom,Lf,erlang}, - {atom,Lf,setelement}},[I,Acc,Val]} end, + {'case',AnnoR,R, + [{clause,AnnoR,[{tuple,AnnoR,[{atom,AnnoR,Name} | Wildcards]}],[], + [foldr(fun ({I,Anno,Val}, Acc) -> + {call,Anno,{remote,Anno,{atom,Anno,erlang}, + {atom,Anno,setelement}},[I,Acc,Val]} end, R, Us)]}, - {clause,NLr,[{var,NLr,'_'}],[], - [call_error(NLr, {tuple,NLr,[{atom,NLr,badrecord},{atom,NLr,Name}]})]}]}. + {clause,NAnnoR,[{var,NAnnoR,'_'}],[], + [call_error(NAnnoR, {tuple,NAnnoR,[{atom,NAnnoR,badrecord},{atom,NAnnoR,Name}]})]}]}. %% Expand a call to record_info/2. We have checked that it is not %% shadowed by an import. -record_info_call(Line, [{atom,_Li,Info},{atom,_Ln,Name}], St) -> +record_info_call(Anno, [{atom,_AnnoI,Info},{atom,_AnnoN,Name}], St) -> case Info of size -> - {{integer,Line,1+length(record_fields(Name, St))},St}; + {{integer,Anno,1+length(record_fields(Name, Anno, St))},St}; fields -> - {make_list(field_names(record_fields(Name, St)), Line),St} + {make_list(field_names(record_fields(Name, Anno, St)), Anno),St} end. %% Break out expressions from an record update list and bind to new @@ -760,14 +776,14 @@ record_info_call(Line, [{atom,_Li,Info},{atom,_Ln,Name}], St) -> record_exprs(Us, St) -> record_exprs(Us, St, [], []). -record_exprs([{record_field,Lf,{atom,_La,_F}=Name,Val}=Field0 | Us], St0, Pre, Fs) -> +record_exprs([{record_field,Anno,{atom,_AnnoA,_F}=Name,Val}=Field0 | Us], St0, Pre, Fs) -> case is_simple_val(Val) of true -> record_exprs(Us, St0, Pre, [Field0 | Fs]); false -> - {Var,St} = new_var(Lf, St0), - Bind = {match,Lf,Var,Val}, - Field = {record_field,Lf,Name,Var}, + {Var,St} = new_var(Anno, St0), + Bind = {match,Anno,Var,Val}, + Field = {record_field,Anno,Name,Var}, record_exprs(Us, St, [Bind | Pre], [Field | Fs]) end; record_exprs([], St, Pre, Fs) -> @@ -787,57 +803,57 @@ is_simple_val(Val) -> pattern_bin(Es0, St) -> foldr(fun (E, Acc) -> pattern_element(E, Acc) end, {[],St}, Es0). -pattern_element({bin_element,Line,Expr0,Size0,Type}, {Es,St0}) -> +pattern_element({bin_element,Anno,Expr0,Size0,Type}, {Es,St0}) -> {Expr,St1} = pattern(Expr0, St0), {Size,St2} = case Size0 of default -> {Size0,St1}; _ -> expr(Size0, St1) end, - {[{bin_element,Line,Expr,Size,Type} | Es],St2}. + {[{bin_element,Anno,Expr,Size,Type} | Es],St2}. %% expr_bin([Element], State) -> {[Element],State}. expr_bin(Es0, St) -> foldr(fun (E, Acc) -> bin_element(E, Acc) end, {[],St}, Es0). -bin_element({bin_element,Line,Expr,Size,Type}, {Es,St0}) -> +bin_element({bin_element,Anno,Expr,Size,Type}, {Es,St0}) -> {Expr1,St1} = expr(Expr, St0), {Size1,St2} = if Size =:= default -> {default,St1}; true -> expr(Size, St1) end, - {[{bin_element,Line,Expr1,Size1,Type} | Es],St2}. + {[{bin_element,Anno,Expr1,Size1,Type} | Es],St2}. -new_vars(N, L, St) -> new_vars(N, L, St, []). +new_vars(N, Anno, St) -> new_vars(N, Anno, St, []). -new_vars(N, L, St0, Vs) when N > 0 -> - {V,St1} = new_var(L, St0), - new_vars(N-1, L, St1, [V|Vs]); -new_vars(0, _L, St, Vs) -> {Vs,St}. +new_vars(N, Anno, St0, Vs) when N > 0 -> + {V,St1} = new_var(Anno, St0), + new_vars(N-1, Anno, St1, [V|Vs]); +new_vars(0, _Anno, St, Vs) -> {Vs,St}. -new_var(L, St0) -> +new_var(Anno, St0) -> {New,St1} = new_var_name(St0), - {{var,L,New},St1}. + {{var,Anno,New},St1}. new_var_name(St) -> C = St#exprec.vcount, {list_to_atom("rec" ++ integer_to_list(C)),St#exprec{vcount=C+1}}. -make_list(Ts, Line) -> - foldr(fun (H, T) -> {cons,Line,H,T} end, {nil,Line}, Ts). +make_list(Ts, Anno) -> + foldr(fun (H, T) -> {cons,Anno,H,T} end, {nil,Anno}, Ts). -call_error(L, R) -> - {call,L,{remote,L,{atom,L,erlang},{atom,L,error}},[R]}. +call_error(Anno, R) -> + {call,Anno,{remote,Anno,{atom,Anno,erlang},{atom,Anno,error}},[R]}. %%% %%% Replace is_record/3 in guards with matching if possible. %%% -optimize_is_record(H0, G0, #exprec{compile=Opts}) -> +optimize_is_record(H0, G0, #exprec{dialyzer=Dialyzer}) -> case opt_rec_vars(G0) of [] -> {H0,G0}; Rs0 -> - case lists:member(dialyzer, Opts) of % no_is_record_optimization + case Dialyzer of % no_is_record_optimization true -> {H0,G0}; false -> @@ -913,22 +929,22 @@ opt_pattern({var,_,V}=Var, Rs0) -> _ -> {Var,Rs0} end; -opt_pattern({cons,Line,H0,T0}, Rs0) -> +opt_pattern({cons,Anno,H0,T0}, Rs0) -> {H,Rs1} = opt_pattern(H0, Rs0), {T,Rs} = opt_pattern(T0, Rs1), - {{cons,Line,H,T},Rs}; -opt_pattern({tuple,Line,Es0}, Rs0) -> + {{cons,Anno,H,T},Rs}; +opt_pattern({tuple,Anno,Es0}, Rs0) -> {Es,Rs} = opt_pattern_list(Es0, Rs0), - {{tuple,Line,Es},Rs}; -opt_pattern({match,Line,Pa0,Pb0}, Rs0) -> + {{tuple,Anno,Es},Rs}; +opt_pattern({match,Anno,Pa0,Pb0}, Rs0) -> {Pa,Rs1} = opt_pattern(Pa0, Rs0), {Pb,Rs} = opt_pattern(Pb0, Rs1), - {{match,Line,Pa,Pb},Rs}; + {{match,Anno,Pa,Pb},Rs}; opt_pattern(P, Rs) -> {P,Rs}. -opt_var({var,Line,_}=Var, Tag, Sz) -> - Rp = record_pattern(2, -1, ignore, Sz, Line, [{atom,Line,Tag}]), - {match,Line,{tuple,Line,Rp},Var}. +opt_var({var,Anno,_}=Var, Tag, Sz) -> + Rp = record_pattern(2, -1, ignore, Sz, Anno, [{atom,Anno,Tag}]), + {match,Anno,{tuple,Anno,Rp},Var}. opt_remove(Gs, Rs) -> [opt_remove_1(G, Rs) || G <- Gs]. @@ -936,25 +952,25 @@ opt_remove(Gs, Rs) -> opt_remove_1(Ts, Rs) -> [opt_remove_2(T, Rs) || T <- Ts]. -opt_remove_2({op,L,'and'=Op,A1,A2}, Rs) -> - {op,L,Op,opt_remove_2(A1, Rs),opt_remove_2(A2, Rs)}; -opt_remove_2({op,L,'andalso'=Op,A1,A2}, Rs) -> - {op,L,Op,opt_remove_2(A1, Rs),opt_remove_2(A2, Rs)}; -opt_remove_2({op,L,'orelse',A1,A2}, Rs) -> - {op,L,'orelse',opt_remove_2(A1, Rs),A2}; -opt_remove_2({call,Line,{remote,_,{atom,_,erlang},{atom,_,is_record}}, +opt_remove_2({op,Anno,'and'=Op,A1,A2}, Rs) -> + {op,Anno,Op,opt_remove_2(A1, Rs),opt_remove_2(A2, Rs)}; +opt_remove_2({op,Anno,'andalso'=Op,A1,A2}, Rs) -> + {op,Anno,Op,opt_remove_2(A1, Rs),opt_remove_2(A2, Rs)}; +opt_remove_2({op,Anno,'orelse',A1,A2}, Rs) -> + {op,Anno,'orelse',opt_remove_2(A1, Rs),A2}; +opt_remove_2({call,Anno,{remote,_,{atom,_,erlang},{atom,_,is_record}}, [{var,_,V},{atom,_,Tag},{integer,_,Sz}]}=A, Rs) -> case orddict:find(V, Rs) of {ok,{remove,Tag,Sz}} -> - {atom,Line,true}; + {atom,Anno,true}; _ -> A end; -opt_remove_2({call,Line,{atom,_,is_record}, +opt_remove_2({call,Anno,{atom,_,is_record}, [{var,_,V},{atom,_,Tag},{integer,_,Sz}]}=A, Rs) -> case orddict:find(V, Rs) of {ok,{remove,Tag,Sz}} -> - {atom,Line,true}; + {atom,Anno,true}; _ -> A end; @@ -964,7 +980,7 @@ no_compiler_warning(Anno) -> erl_anno:set_generated(true, Anno). mark_record(Anno, St) -> - case lists:member(dialyzer, St#exprec.compile) of + case St#exprec.dialyzer of true -> erl_anno:set_record(true, Anno); false -> Anno end. diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl index bd2cd2e697..d54f71be59 100644 --- a/lib/stdlib/src/erl_lint.erl +++ b/lib/stdlib/src/erl_lint.erl @@ -67,7 +67,7 @@ value_option(Flag, Default, On, OnVal, Off, OffVal, Opts) -> -define(MAX_ARGUMENTS, 255). -%% The error and warning info structures, {Line,Module,Descriptor}, +%% The error and warning info structures, {Location,Module,Descriptor}, %% are kept in their seperate fields in the lint state record together %% with the name of the file (when a new file is entered, marked by %% the 'file' attribute, then the field 'file' of the lint record is @@ -79,7 +79,7 @@ value_option(Flag, Default, On, OnVal, Off, OffVal, Opts) -> %%-define(DEBUGF(X,Y), io:format(X, Y)). -define(DEBUGF(X,Y), void). --type line() :: erl_anno:anno(). % a convenient alias +-type anno() :: erl_anno:anno(). % a convenient alias -type fa() :: {atom(), arity()}. % function+arity -type ta() :: {atom(), arity()}. % type+arity @@ -87,7 +87,7 @@ value_option(Flag, Default, On, OnVal, Off, OffVal, Opts) -> -type gexpr_context() :: 'guard' | 'bin_seg_size' | 'map_key'. --record(typeinfo, {attr, line}). +-record(typeinfo, {attr, anno}). %% Usage of records, functions, and imports. The variable table, which %% is passed on as an argument, holds the usage of variables. @@ -97,12 +97,12 @@ value_option(Flag, Default, On, OnVal, Off, OffVal, Opts) -> used_records = gb_sets:new() %Used record definitions :: gb_sets:set(atom()), used_types = maps:new() %Used type definitions - :: #{ta() := line()} + :: #{ta() := anno()} }). %% Define the lint state record. -%% 'called' and 'exports' contain {Line, {Function, Arity}}, +%% 'called' and 'exports' contain {Anno, {Function, Arity}}, %% the other function collections contain {Function, Arity}. -record(lint, {state=start :: 'start' | 'attribute' | 'function', module='', %Module @@ -111,7 +111,7 @@ value_option(Flag, Default, On, OnVal, Off, OffVal, Opts) -> imports=[] :: orddict:orddict(fa(), module()),%Imports compile=[], %Compile flags records=maps:new() %Record definitions - :: #{atom() => {line(),Fields :: term()}}, + :: #{atom() => {anno(),Fields :: term()}}, locals=gb_sets:empty() %All defined functions (prescanned) :: gb_sets:set(fa()), no_auto=gb_sets:empty() %Functions explicitly not autoimported @@ -119,7 +119,7 @@ value_option(Flag, Default, On, OnVal, Off, OffVal, Opts) -> defined=gb_sets:empty() %Defined fuctions :: gb_sets:set(fa()), on_load=[] :: [fa()], %On-load function - on_load_line=erl_anno:new(0) %Line for on_load + on_load_anno=erl_anno:new(0) %Location for on_load :: erl_anno:anno(), clashes=[], %Exported functions named as BIFs not_deprecated=[], %Not considered deprecated @@ -135,14 +135,14 @@ value_option(Flag, Default, On, OnVal, Off, OffVal, Opts) -> recdef_top=false :: boolean(), %true in record initialisation %outside any fun or lc xqlc= false :: boolean(), %true if qlc.hrl included - called= [] :: [{fa(),line()}], %Called functions + called= [] :: [{fa(),anno()}], %Called functions usage = #usage{} :: #usage{}, specs = maps:new() %Type specifications - :: #{mfa() => line()}, + :: #{mfa() => anno()}, callbacks = maps:new() %Callback types - :: #{mfa() => line()}, + :: #{mfa() => anno()}, optional_callbacks = maps:new() %Optional callbacks - :: #{mfa() => line()}, + :: #{mfa() => anno()}, types = maps:new() %Type definitions :: #{ta() => #typeinfo{}}, exp_types=gb_sets:empty() %Exported types @@ -154,7 +154,7 @@ value_option(Flag, Default, On, OnVal, Off, OffVal, Opts) -> -type lint_state() :: #lint{}. -type error_description() :: term(). --type error_info() :: {erl_anno:line(), module(), error_description()}. +-type error_info() :: {erl_anno:location(), module(), error_description()}. %% format_error(Error) %% Return a string describing the error. @@ -675,9 +675,9 @@ pack_warnings(Ws) -> File <- lists:usort([F || {F,_} <- Ws])]. %% add_error(ErrorDescriptor, State) -> State' -%% add_error(Line, Error, State) -> State' +%% add_error(Anno, Error, State) -> State' %% add_warning(ErrorDescriptor, State) -> State' -%% add_warning(Line, Error, State) -> State' +%% add_warning(Anno, Error, State) -> State' add_error(E, St) -> add_lint_error(E, St#lint.file, St). @@ -697,8 +697,8 @@ add_lint_error(E, File, St) -> add_warning(W, St) -> add_lint_warning(W, St#lint.file, St). -add_warning(FileLine, W, St) -> - {File,Location} = loc(FileLine, St), +add_warning(Anno, W, St) -> + {File,Location} = loc(Anno, St), add_lint_warning({Location,erl_lint,W}, File, St). add_lint_warning(W, File, St) -> @@ -727,11 +727,11 @@ forms(Forms0, St0) -> St5 = foldl(fun form/2, pre_scan(Forms, St4), Forms), post_traversal_check(Forms, St5). -pre_scan([{attribute,L,compile,C} | Fs], St) -> +pre_scan([{attribute,A,compile,C} | Fs], St) -> case is_warn_enabled(export_all, St) andalso member(export_all, lists:flatten([C])) of true -> - pre_scan(Fs, add_warning(L, export_all, St)); + pre_scan(Fs, add_warning(A, export_all, St)); false -> pre_scan(Fs, St) end; @@ -750,7 +750,7 @@ includes_qlc_hrl(Forms, St) -> eval_file_attribute(Forms, St) -> eval_file_attr(Forms, St#lint.file). -eval_file_attr([{attribute,_L,file,{File,_Line}}=Form | Forms], _File) -> +eval_file_attr([{attribute,_A,file,{File,_Line}}=Form | Forms], _File) -> [Form | eval_file_attr(Forms, File)]; eval_file_attr([Form0 | Forms], File) -> Form = set_form_file(Form0, File), @@ -761,10 +761,10 @@ eval_file_attr([], _File) -> %% Sets the file only on the form. This is used on post-traversal. %% For the remaining of the AST we rely on #lint.file. -set_form_file({attribute,L,K,V}, File) -> - {attribute,erl_anno:set_file(File, L),K,V}; -set_form_file({function,L,N,A,C}, File) -> - {function,erl_anno:set_file(File, L),N,A,C}; +set_form_file({attribute,A,K,V}, File) -> + {attribute,erl_anno:set_file(File, A),K,V}; +set_form_file({function,Anno,N,A,C}, File) -> + {function,erl_anno:set_file(File, Anno),N,A,C}; set_form_file(Form, _File) -> Form. @@ -782,9 +782,9 @@ anno_set_file(T, File) -> form({error,E}, St) -> add_error(E, St); form({warning,W}, St) -> add_warning(W, St); -form({attribute,_L,file,{File,_Line}}, St) -> +form({attribute,_A,file,{File,_Line}}, St) -> St#lint{file = File}; -form({attribute,_L,compile,_}, St) -> +form({attribute,_A,compile,_}, St) -> St; form(Form, #lint{state=State}=St) -> case State of @@ -795,16 +795,16 @@ form(Form, #lint{state=State}=St) -> %% start_state(Form, State) -> State' -start_state({attribute,Line,module,{_,_}}=Form, St0) -> - St1 = add_error(Line, pmod_unsupported, St0), +start_state({attribute,Anno,module,{_,_}}=Form, St0) -> + St1 = add_error(Anno, pmod_unsupported, St0), attribute_state(Form, St1#lint{state=attribute}); -start_state({attribute,Line,module,M}, St0) -> +start_state({attribute,Anno,module,M}, St0) -> St1 = St0#lint{module=M}, St2 = St1#lint{state=attribute}, - check_module_name(M, Line, St2); + check_module_name(M, Anno, St2); start_state(Form, St) -> Anno = case Form of - {eof, L} -> erl_anno:new(L); + {eof, Location} -> erl_anno:new(Location); %% {warning, Warning} and {error, Error} not possible here. _ -> element(2, Form) end, @@ -814,35 +814,35 @@ start_state(Form, St) -> %% attribute_state(Form, State) -> %% State' -attribute_state({attribute,_L,module,_M}, #lint{module=''}=St) -> +attribute_state({attribute,_A,module,_M}, #lint{module=''}=St) -> St; -attribute_state({attribute,L,module,_M}, St) -> - add_error(L, redefine_module, St); -attribute_state({attribute,L,export,Es}, St) -> - export(L, Es, St); -attribute_state({attribute,L,export_type,Es}, St) -> - export_type(L, Es, St); -attribute_state({attribute,L,import,Is}, St) -> - import(L, Is, St); -attribute_state({attribute,L,record,{Name,Fields}}, St) -> - record_def(L, Name, Fields, St); -attribute_state({attribute,La,behaviour,Behaviour}, St) -> - St#lint{behaviour=St#lint.behaviour ++ [{La,Behaviour}]}; -attribute_state({attribute,La,behavior,Behaviour}, St) -> - St#lint{behaviour=St#lint.behaviour ++ [{La,Behaviour}]}; -attribute_state({attribute,L,type,{TypeName,TypeDef,Args}}, St) -> - type_def(type, L, TypeName, TypeDef, Args, St); -attribute_state({attribute,L,opaque,{TypeName,TypeDef,Args}}, St) -> - type_def(opaque, L, TypeName, TypeDef, Args, St); -attribute_state({attribute,L,spec,{Fun,Types}}, St) -> - spec_decl(L, Fun, Types, St); -attribute_state({attribute,L,callback,{Fun,Types}}, St) -> - callback_decl(L, Fun, Types, St); -attribute_state({attribute,L,optional_callbacks,Es}, St) -> - optional_callbacks(L, Es, St); -attribute_state({attribute,L,on_load,Val}, St) -> - on_load(L, Val, St); -attribute_state({attribute,_L,_Other,_Val}, St) -> % Ignore others +attribute_state({attribute,A,module,_M}, St) -> + add_error(A, redefine_module, St); +attribute_state({attribute,A,export,Es}, St) -> + export(A, Es, St); +attribute_state({attribute,A,export_type,Es}, St) -> + export_type(A, Es, St); +attribute_state({attribute,A,import,Is}, St) -> + import(A, Is, St); +attribute_state({attribute,A,record,{Name,Fields}}, St) -> + record_def(A, Name, Fields, St); +attribute_state({attribute,Aa,behaviour,Behaviour}, St) -> + St#lint{behaviour=St#lint.behaviour ++ [{Aa,Behaviour}]}; +attribute_state({attribute,Aa,behavior,Behaviour}, St) -> + St#lint{behaviour=St#lint.behaviour ++ [{Aa,Behaviour}]}; +attribute_state({attribute,A,type,{TypeName,TypeDef,Args}}, St) -> + type_def(type, A, TypeName, TypeDef, Args, St); +attribute_state({attribute,A,opaque,{TypeName,TypeDef,Args}}, St) -> + type_def(opaque, A, TypeName, TypeDef, Args, St); +attribute_state({attribute,A,spec,{Fun,Types}}, St) -> + spec_decl(A, Fun, Types, St); +attribute_state({attribute,A,callback,{Fun,Types}}, St) -> + callback_decl(A, Fun, Types, St); +attribute_state({attribute,A,optional_callbacks,Es}, St) -> + optional_callbacks(A, Es, St); +attribute_state({attribute,A,on_load,Val}, St) -> + on_load(A, Val, St); +attribute_state({attribute,_A,_Other,_Val}, St) -> % Ignore others St; attribute_state(Form, St) -> function_state(Form, St#lint{state=function}). @@ -853,32 +853,32 @@ attribute_state(Form, St) -> %% declarations to be intersperced within function definitions. %% Dialyzer attributes are also allowed everywhere. -function_state({attribute,L,record,{Name,Fields}}, St) -> - record_def(L, Name, Fields, St); -function_state({attribute,L,type,{TypeName,TypeDef,Args}}, St) -> - type_def(type, L, TypeName, TypeDef, Args, St); -function_state({attribute,L,opaque,{TypeName,TypeDef,Args}}, St) -> - type_def(opaque, L, TypeName, TypeDef, Args, St); -function_state({attribute,L,spec,{Fun,Types}}, St) -> - spec_decl(L, Fun, Types, St); -function_state({attribute,_L,dialyzer,_Val}, St) -> +function_state({attribute,A,record,{Name,Fields}}, St) -> + record_def(A, Name, Fields, St); +function_state({attribute,A,type,{TypeName,TypeDef,Args}}, St) -> + type_def(type, A, TypeName, TypeDef, Args, St); +function_state({attribute,A,opaque,{TypeName,TypeDef,Args}}, St) -> + type_def(opaque, A, TypeName, TypeDef, Args, St); +function_state({attribute,A,spec,{Fun,Types}}, St) -> + spec_decl(A, Fun, Types, St); +function_state({attribute,_A,dialyzer,_Val}, St) -> St; -function_state({attribute,La,Attr,_Val}, St) -> - add_error(La, {attribute,Attr}, St); -function_state({function,L,N,A,Cs}, St) -> - function(L, N, A, Cs, St); -function_state({eof,L}, St) -> eof(L, St). +function_state({attribute,Aa,Attr,_Val}, St) -> + add_error(Aa, {attribute,Attr}, St); +function_state({function,Anno,N,A,Cs}, St) -> + function(Anno, N, A, Cs, St); +function_state({eof,Location}, St) -> eof(Location, St). -%% eof(LastLine, State) -> +%% eof(LastLocation, State) -> %% State' -eof(_Line, St0) -> +eof(_Location, St0) -> St0. %% bif_clashes(Forms, State0) -> State. bif_clashes(Forms, #lint{nowarn_bif_clash=Nowarn} = St) -> - Clashes0 = [{Name,Arity} || {function,_L,Name,Arity,_Cs} <- Forms, + Clashes0 = [{Name,Arity} || {function,_A,Name,Arity,_Cs} <- Forms, erl_internal:bif(Name, Arity)], Clashes = ordsets:subtract(ordsets:from_list(Clashes0), Nowarn), St#lint{clashes=Clashes}. @@ -887,35 +887,35 @@ bif_clashes(Forms, #lint{nowarn_bif_clash=Nowarn} = St) -> not_deprecated(Forms, #lint{compile=Opts}=St0) -> %% There are no line numbers in St0#lint.compile. - MFAsL = [{MFA,L} || - {attribute, L, compile, Args} <- Forms, + MFAsAnno = [{MFA,Anno} || + {attribute, Anno, compile, Args} <- Forms, {nowarn_deprecated_function, MFAs0} <- lists:flatten([Args]), MFA <- lists:flatten([MFAs0])], Nowarn = [MFA || {nowarn_deprecated_function, MFAs0} <- Opts, MFA <- lists:flatten([MFAs0])], - ML = [{M,L} || {{M,_F,_A},L} <- MFAsL, is_atom(M)], - St1 = foldl(fun ({M,L}, St2) -> - check_module_name(M, L, St2) - end, St0, ML), + MAnno = [{M,Anno} || {{M,_F,_A},Anno} <- MFAsAnno, is_atom(M)], + St1 = foldl(fun ({M,Anno}, St2) -> + check_module_name(M, Anno, St2) + end, St0, MAnno), St1#lint{not_deprecated = ordsets:from_list(Nowarn)}. %% not_removed(Forms, State0) -> State not_removed(Forms, #lint{compile=Opts}=St0) -> %% There are no line numbers in St0#lint.compile. - MFAsL = [{MFA,L} || - {attribute, L, compile, Args} <- Forms, + MFAsAnno = [{MFA,Anno} || + {attribute, Anno, compile, Args} <- Forms, {nowarn_removed, MFAs0} <- lists:flatten([Args]), MFA <- lists:flatten([MFAs0])], Nowarn = [MFA || {nowarn_removed, MFAs0} <- Opts, MFA <- lists:flatten([MFAs0])], - St1 = foldl(fun ({{M, _F, _A}, L}, St2) -> - check_module_name(M, L, St2); - ({M,L}, St2) -> - check_module_name(M, L, St2) - end, St0, MFAsL), + St1 = foldl(fun ({{M, _F, _A}, Anno}, St2) -> + check_module_name(M, Anno, St2); + ({M,Anno}, St2) -> + check_module_name(M, Anno, St2) + end, St0, MFAsAnno), St1#lint{not_removed = gb_sets:from_list(Nowarn)}. %% The nowarn_bif_clash directive is not only deprecated, it's actually an error from R14A @@ -968,7 +968,7 @@ post_traversal_check(Forms, St0) -> check_behaviour(St0) -> behaviour_check(St0#lint.behaviour, St0). -%% behaviour_check([{Line,Behaviour}], State) -> State' +%% behaviour_check([{Anno,Behaviour}], State) -> State' %% Check behaviours for existence and defined functions. behaviour_check(Bs, St0) -> @@ -984,15 +984,15 @@ behaviour_check(Bs, St0) -> AllBfs = [{Item,F(Bfs0, OBfs0)} || {Item,Bfs0,OBfs0} <- AllBfs0], behaviour_conflicting(AllBfs, St). -all_behaviour_callbacks([{Line,B}|Bs], Acc, St0) -> - {Bfs0,OBfs0,St} = behaviour_callbacks(Line, B, St0), - all_behaviour_callbacks(Bs, [{{Line,B},Bfs0,OBfs0}|Acc], St); +all_behaviour_callbacks([{Anno,B}|Bs], Acc, St0) -> + {Bfs0,OBfs0,St} = behaviour_callbacks(Anno, B, St0), + all_behaviour_callbacks(Bs, [{{Anno,B},Bfs0,OBfs0}|Acc], St); all_behaviour_callbacks([], Acc, St) -> {reverse(Acc),St}. -behaviour_callbacks(Line, B, St0) -> +behaviour_callbacks(Anno, B, St0) -> try B:behaviour_info(callbacks) of undefined -> - St1 = add_warning(Line, {undefined_behaviour_callbacks, B}, St0), + St1 = add_warning(Anno, {undefined_behaviour_callbacks, B}, St0), {[], [], St1}; Funcs -> case is_fa_list(Funcs) of @@ -1008,7 +1008,7 @@ behaviour_callbacks(Line, B, St0) -> {Funcs, OptFuncs, St0}; false -> W = {ill_defined_optional_callbacks, B}, - St1 = add_warning(Line, W, St0), + St1 = add_warning(Anno, W, St0), {Funcs, [], St1} end catch @@ -1016,19 +1016,19 @@ behaviour_callbacks(Line, B, St0) -> {Funcs, [], St0} end; false -> - St1 = add_warning(Line, + St1 = add_warning(Anno, {ill_defined_behaviour_callbacks, B}, St0), {[], [], St1} end catch _:_ -> - St1 = add_warning(Line, {undefined_behaviour, B}, St0), - St2 = check_module_name(B, Line, St1), + St1 = add_warning(Anno, {undefined_behaviour, B}, St0), + St2 = check_module_name(B, Anno, St1), {[], [], St2} end. -behaviour_missing_callbacks([{{Line,B},Bfs0,OBfs}|T], St0) -> +behaviour_missing_callbacks([{{Anno,B},Bfs0,OBfs}|T], St0) -> Bfs = ordsets:subtract(ordsets:from_list(Bfs0), ordsets:from_list(OBfs)), Exports = gb_sets:to_list(exports(St0)), Missing = ordsets:subtract(Bfs, Exports), @@ -1036,7 +1036,7 @@ behaviour_missing_callbacks([{{Line,B},Bfs0,OBfs}|T], St0) -> case is_fa(F) of true -> M = {undefined_behaviour_func,F,B}, - add_warning(Line, M, S0); + add_warning(Anno, M, S0); false -> S0 % ill_defined_behaviour_callbacks end @@ -1053,14 +1053,14 @@ behaviour_conflicting(AllBfs, St) -> R = sofs:to_external(R4), behaviour_add_conflicts(R, St). -behaviour_add_conflicts([{Cb,[{FirstLoc,FirstB}|Cs]}|T], St0) -> - FirstL = element(2, loc(FirstLoc, St0)), +behaviour_add_conflicts([{Cb,[{FirstAnno,FirstB}|Cs]}|T], St0) -> + FirstL = element(2, loc(FirstAnno, St0)), St = behaviour_add_conflict(Cs, Cb, FirstL, FirstB, St0), behaviour_add_conflicts(T, St); behaviour_add_conflicts([], St) -> St. -behaviour_add_conflict([{Line,B}|Cs], Cb, FirstL, FirstB, St0) -> - St = add_warning(Line, {conflicting_behaviours,Cb,B,FirstL,FirstB}, St0), +behaviour_add_conflict([{Anno,B}|Cs], Cb, FirstL, FirstB, St0) -> + St = add_warning(Anno, {conflicting_behaviours,Cb,B,FirstL,FirstB}, St0), behaviour_add_conflict(Cs, Cb, FirstL, FirstB, St); behaviour_add_conflict([], _, _, _, St) -> St. @@ -1074,11 +1074,11 @@ check_deprecated(Forms, St0) -> end, X = ignore_predefined_funcs(gb_sets:to_list(Exports)), #lint{module = Mod} = St0, - Bad = [{E,L} || {attribute, L, deprecated, Depr} <- Forms, + Bad = [{E,Anno} || {attribute, Anno, deprecated, Depr} <- Forms, D <- lists:flatten([Depr]), E <- depr_cat(D, X, Mod)], - foldl(fun ({E,L}, St1) -> - add_error(L, E, St1) + foldl(fun ({E,Anno}, St1) -> + add_error(Anno, E, St1) end, St0, Bad). depr_cat({F, A, Flg}=D, X, Mod) -> @@ -1132,11 +1132,11 @@ check_removed(Forms, St0) -> end, X = ignore_predefined_funcs(gb_sets:to_list(Exports)), #lint{module = Mod} = St0, - Bad = [{E,L} || {attribute, L, removed, Removed} <- Forms, + Bad = [{E,Anno} || {attribute, Anno, removed, Removed} <- Forms, R <- lists:flatten([Removed]), E <- removed_cat(R, X, Mod)], - foldl(fun ({E,L}, St1) -> - add_error(L, E, St1) + foldl(fun ({E,Anno}, St1) -> + add_error(Anno, E, St1) end, St0, Bad). removed_cat({F, A, Desc}=R, X, Mod) -> @@ -1200,11 +1200,11 @@ check_imports(Forms, St0) -> true -> Usage = St0#lint.usage, Unused = ordsets:subtract(St0#lint.imports, Usage#usage.imported), - Imports = [{{FA,Mod},L} || - {attribute,L,import,{Mod,Fs}} <- Forms, + Imports = [{{FA,Mod},Anno} || + {attribute,Anno,import,{Mod,Fs}} <- Forms, FA <- lists:usort(Fs)], - Bad = [{FM,L} || FM <- Unused, {FM2,L} <- Imports, FM =:= FM2], - func_line_warning(unused_import, Bad, St0) + Bad = [{FM,Anno} || FM <- Unused, {FM2,Anno} <- Imports, FM =:= FM2], + func_location_warning(unused_import, Bad, St0) end. %% check_inlines(Forms, State0) -> State @@ -1230,9 +1230,9 @@ check_unused_functions(Forms, St0) -> UsedOrNowarn = ordsets:union(Used, Nowarn), Unused = ordsets:subtract(gb_sets:to_list(St1#lint.defined), UsedOrNowarn), - Functions = [{{N,A},L} || {function,L,N,A,_} <- Forms], - Bad = [{FA,L} || FA <- Unused, {FA2,L} <- Functions, FA =:= FA2], - func_line_warning(unused_function, Bad, St1) + Functions = [{{N,A},Anno} || {function,Anno,N,A,_} <- Forms], + Bad = [{FA,Anno} || FA <- Unused, {FA2,Anno} <- Functions, FA =:= FA2], + func_location_warning(unused_function, Bad, St1) end. initially_reached(#lint{exports=Exp,on_load=OnLoad}) -> @@ -1264,8 +1264,8 @@ check_undefined_functions(#lint{called=Called0,defined=Def0}=St0) -> Called = sofs:relation(Called0, [{func,location}]), Def = sofs:from_external(gb_sets:to_list(Def0), [func]), Undef = sofs:to_external(sofs:drestriction(Called, Def)), - foldl(fun ({NA,L}, St) -> - add_error(L, {undefined_function,NA}, St) + foldl(fun ({NA,Anno}, St) -> + add_error(Anno, {undefined_function,NA}, St) end, St0, Undef). %% check_undefined_types(State0) -> State @@ -1277,8 +1277,8 @@ check_undefined_types(#lint{usage=Usage,types=Def}=St0) -> TA <- UTAs, not is_map_key(TA, Def), not is_default_type(TA)], - foldl(fun ({TA,L}, St) -> - add_error(L, {undefined_type,TA}, St) + foldl(fun ({TA,Anno}, St) -> + add_error(Anno, {undefined_type,TA}, St) end, St0, Undef). %% check_bif_clashes(Forms, State0) -> State @@ -1290,25 +1290,25 @@ check_bif_clashes(Forms, St0) -> check_option_functions(Forms, Tag0, Type, St0) -> %% There are no line numbers in St0#lint.compile. - FAsL = [{FA,L} || {attribute, L, compile, Args} <- Forms, + FAsAnno = [{FA,Anno} || {attribute, Anno, compile, Args} <- Forms, {Tag, FAs0} <- lists:flatten([Args]), Tag0 =:= Tag, FA <- lists:flatten([FAs0])], DefFunctions = (gb_sets:to_list(St0#lint.defined) -- pseudolocals()) ++ [{F,A} || {{F,A},_} <- orddict:to_list(St0#lint.imports)], - Bad = [{FA,L} || {FA,L} <- FAsL, not member(FA, DefFunctions)], - func_line_error(Type, Bad, St0). + Bad = [{FA,Anno} || {FA,Anno} <- FAsAnno, not member(FA, DefFunctions)], + func_location_error(Type, Bad, St0). nowarn_function(Tag, Opts) -> ordsets:from_list([FA || {Tag1,FAs} <- Opts, Tag1 =:= Tag, FA <- lists:flatten([FAs])]). -func_line_warning(Type, Fs, St) -> - foldl(fun ({F,Line}, St0) -> add_warning(Line, {Type,F}, St0) end, St, Fs). +func_location_warning(Type, Fs, St) -> + foldl(fun ({F,Anno}, St0) -> add_warning(Anno, {Type,F}, St0) end, St, Fs). -func_line_error(Type, Fs, St) -> - foldl(fun ({F,Line}, St0) -> add_error(Line, {Type,F}, St0) end, St, Fs). +func_location_error(Type, Fs, St) -> + foldl(fun ({F,Anno}, St0) -> add_error(Anno, {Type,F}, St0) end, St, Fs). check_untyped_records(Forms, St0) -> case is_warn_enabled(untyped_record, St0) of @@ -1322,10 +1322,10 @@ check_untyped_records(Forms, St0) -> (_) -> false end, Fields)], foldl(fun (N, St) -> - {L, Fields} = map_get(N, St0#lint.records), + {Anno, Fields} = map_get(N, St0#lint.records), case Fields of [] -> St; % exclude records with no fields - [_|_] -> add_warning(L, {untyped_record, N}, St) + [_|_] -> add_warning(Anno, {untyped_record, N}, St) end end, St0, ordsets:subtract(ordsets:from_list(RecNames), ordsets:from_list(TRecNames))); @@ -1334,7 +1334,7 @@ check_untyped_records(Forms, St0) -> end. check_unused_records(Forms, St0) -> - AttrFiles = [File || {attribute,_L,file,{File,_Line}} <- Forms], + AttrFiles = [File || {attribute,_A,file,{File,_Line}} <- Forms], case {is_warn_enabled(unused_record, St0),AttrFiles} of {true,[FirstFile|_]} -> %% The check is a bit imprecise in that uses from unused @@ -1344,11 +1344,11 @@ check_unused_records(Forms, St0) -> URecs = gb_sets:fold(fun (Used, Recs) -> maps:remove(Used, Recs) end, St0#lint.records, UsedRecords), - Unused = [{Name,FileLine} || - {Name,{FileLine,_Fields}} <- maps:to_list(URecs), - element(1, loc(FileLine, St0)) =:= FirstFile], - foldl(fun ({N,L}, St) -> - add_warning(L, {unused_record, N}, St) + Unused = [{Name,Anno} || + {Name,{Anno,_Fields}} <- maps:to_list(URecs), + element(1, loc(Anno, St0)) =:= FirstFile], + foldl(fun ({N,Anno}, St) -> + add_warning(Anno, {unused_record, N}, St) end, St0, Unused); _ -> St0 @@ -1357,12 +1357,12 @@ check_unused_records(Forms, St0) -> check_callback_information(#lint{callbacks = Callbacks, optional_callbacks = OptionalCbs, defined = Defined} = St0) -> - OptFun = fun(MFA, Line, St) -> + OptFun = fun(MFA, Anno, St) -> case is_map_key(MFA, Callbacks) of true -> St; false -> - add_error(Line, {undefined_callback, MFA}, St) + add_error(Anno, {undefined_callback, MFA}, St) end end, St1 = maps:fold(OptFun, St0, OptionalCbs), @@ -1373,8 +1373,8 @@ check_callback_information(#lint{callbacks = Callbacks, 0 -> St1; _ -> FoldFun = - fun(Fa, Line, St) -> - add_error(Line, {behaviour_info, Fa}, St) + fun(Fa, Anno, St) -> + add_error(Anno, {behaviour_info, Fa}, St) end, maps:fold(FoldFun, St1, Callbacks) end @@ -1383,45 +1383,45 @@ check_callback_information(#lint{callbacks = Callbacks, %% For storing the import list we use the orddict module. %% We know an empty set is []. --spec export(line(), [fa()], lint_state()) -> lint_state(). +-spec export(anno(), [fa()], lint_state()) -> lint_state(). %% Mark functions as exported, also as called from the export line. -export(Line, Es, #lint{exports = Es0, called = Called} = St0) -> +export(Anno, Es, #lint{exports = Es0, called = Called} = St0) -> {Es1,C1,St1} = foldl(fun (NA, {E,C,St2}) -> St = case gb_sets:is_element(NA, E) of true -> Warn = {duplicated_export,NA}, - add_warning(Line, Warn, St2); + add_warning(Anno, Warn, St2); false -> St2 end, - {gb_sets:add_element(NA, E), [{NA,Line}|C], St} + {gb_sets:add_element(NA, E), [{NA,Anno}|C], St} end, {Es0,Called,St0}, Es), St1#lint{exports = Es1, called = C1}. --spec export_type(line(), [ta()], lint_state()) -> lint_state(). +-spec export_type(anno(), [ta()], lint_state()) -> lint_state(). %% Mark types as exported; also mark them as used from the export line. -export_type(Line, ETs, #lint{usage = Usage, exp_types = ETs0} = St0) -> +export_type(Anno, ETs, #lint{usage = Usage, exp_types = ETs0} = St0) -> UTs0 = Usage#usage.used_types, try foldl(fun ({T,A}=TA, {E,U,St2}) when is_atom(T), is_integer(A) -> St = case gb_sets:is_element(TA, E) of true -> Warn = {duplicated_export_type,TA}, - add_warning(Line, Warn, St2); + add_warning(Anno, Warn, St2); false -> St2 end, - {gb_sets:add_element(TA, E), maps:put(TA, Line, U), St} + {gb_sets:add_element(TA, E), maps:put(TA, Anno, U), St} end, {ETs0,UTs0,St0}, ETs) of {ETs1,UTs1,St1} -> St1#lint{usage = Usage#usage{used_types = UTs1}, exp_types = ETs1} catch error:_ -> - add_error(Line, {bad_export_type, ETs}, St0) + add_error(Anno, {bad_export_type, ETs}, St0) end. -spec exports(lint_state()) -> gb_sets:set(fa()). @@ -1433,12 +1433,12 @@ exports(#lint{compile = Opts, defined = Defs, exports = Es}) -> end. -type import() :: {module(), [fa()]} | module(). --spec import(line(), import(), lint_state()) -> lint_state(). +-spec import(anno(), import(), lint_state()) -> lint_state(). -import(Line, {Mod,Fs}, St00) -> - St = check_module_name(Mod, Line, St00), +import(Anno, {Mod,Fs}, St00) -> + St = check_module_name(Mod, Anno, St00), Mfs = ordsets:from_list(Fs), - case check_imports(Line, Mfs, St#lint.imports) of + case check_imports(Anno, Mfs, St#lint.imports) of [] -> St#lint{imports=add_imports(Mod, Mfs, St#lint.imports)}; @@ -1453,19 +1453,19 @@ import(Line, {Mod,Fs}, St00) -> {Err,if Warn and (not AutoImpSup) and OldBif -> add_error - (Line, + (Anno, {redefine_old_bif_import, {F,A}}, St0); Warn and (not AutoImpSup) -> add_warning - (Line, + (Anno, {redefine_bif_import, {F,A}}, St0); true -> St0 end}; (Ef, {_Err,St0}) -> - {true,add_error(Line, + {true,add_error(Anno, {redefine_import,Ef}, St0)} end, @@ -1479,7 +1479,7 @@ import(Line, {Mod,Fs}, St00) -> end end. -check_imports(_Line, Fs, Is) -> +check_imports(_Anno, Fs, Is) -> foldl(fun (F, Efs) -> case orddict:find(F, Is) of {ok,Mod} -> [{F,Mod}|Efs]; @@ -1507,11 +1507,11 @@ imported(F, A, St) -> -spec on_load(erl_anno:anno(), fa(), lint_state()) -> lint_state(). %% Check an on_load directive and remember it. -on_load(Line, {Name,Arity}=Fa, #lint{on_load=OnLoad0}=St0) +on_load(Anno, {Name,Arity}=Fa, #lint{on_load=OnLoad0}=St0) when is_atom(Name), is_integer(Arity) -> %% Always add the function name (even if there is a problem), %% to avoid irrelevant warnings for unused functions. - St = St0#lint{on_load=[Fa|OnLoad0],on_load_line=Line}, + St = St0#lint{on_load=[Fa|OnLoad0],on_load_anno=Anno}, case St of #lint{on_load=[{_,0}]} -> %% This is the first on_load attribute seen in the module @@ -1519,62 +1519,62 @@ on_load(Line, {Name,Arity}=Fa, #lint{on_load=OnLoad0}=St0) St; #lint{on_load=[{_,_}]} -> %% Wrong arity. - add_error(Line, {bad_on_load_arity,Fa}, St); + add_error(Anno, {bad_on_load_arity,Fa}, St); #lint{on_load=[_,_|_]} -> %% Multiple on_load attributes. - add_error(Line, multiple_on_loads, St) + add_error(Anno, multiple_on_loads, St) end; -on_load(Line, Val, St) -> +on_load(Anno, Val, St) -> %% Bad syntax. - add_error(Line, {bad_on_load,Val}, St). + add_error(Anno, {bad_on_load,Val}, St). check_on_load(#lint{defined=Defined,on_load=[{_,0}=Fa], - on_load_line=Line}=St) -> + on_load_anno=Anno}=St) -> case gb_sets:is_member(Fa, Defined) of true -> St; - false -> add_error(Line, {undefined_on_load,Fa}, St) + false -> add_error(Anno, {undefined_on_load,Fa}, St) end; check_on_load(St) -> St. --spec call_function(line(), atom(), arity(), lint_state()) -> lint_state(). +-spec call_function(anno(), atom(), arity(), lint_state()) -> lint_state(). %% Add to both called and calls. -call_function(Line, F, A, #lint{usage=Usage0,called=Cd,func=Func,file=File}=St) -> +call_function(Anno0, F, A, #lint{usage=Usage0,called=Cd,func=Func,file=File}=St) -> #usage{calls = Cs} = Usage0, NA = {F,A}, Usage = case Cs of undefined -> Usage0; _ -> Usage0#usage{calls=maps_prepend(Func, NA, Cs)} end, - Anno = erl_anno:set_file(File, Line), + Anno = erl_anno:set_file(File, Anno0), St#lint{called=[{NA,Anno}|Cd], usage=Usage}. -%% function(Line, Name, Arity, Clauses, State) -> State. +%% function(Anno, Name, Arity, Clauses, State) -> State. -function(Line, Name, Arity, Cs, St0) -> +function(Anno, Name, Arity, Cs, St0) -> St1 = St0#lint{func={Name,Arity}}, - St2 = define_function(Line, Name, Arity, St1), + St2 = define_function(Anno, Name, Arity, St1), clauses(Cs, St2). --spec define_function(line(), atom(), arity(), lint_state()) -> lint_state(). +-spec define_function(anno(), atom(), arity(), lint_state()) -> lint_state(). -define_function(Line, Name, Arity, St0) -> - St1 = keyword_warning(Line, Name, St0), +define_function(Anno, Name, Arity, St0) -> + St1 = keyword_warning(Anno, Name, St0), NA = {Name,Arity}, case gb_sets:is_member(NA, St1#lint.defined) of true -> - add_error(Line, {redefine_function,NA}, St1); + add_error(Anno, {redefine_function,NA}, St1); false -> - St2 = function_check_max_args(Line, Arity, St1), + St2 = function_check_max_args(Anno, Arity, St1), St3 = St2#lint{defined=gb_sets:add_element(NA, St2#lint.defined)}, case imported(Name, Arity, St3) of - {yes,_M} -> add_error(Line, {define_import,NA}, St3); + {yes,_M} -> add_error(Anno, {define_import,NA}, St3); no -> St3 end end. -function_check_max_args(Line, Arity, St) when Arity > ?MAX_ARGUMENTS -> - add_error(Line, {too_many_arguments,Arity}, St); +function_check_max_args(Anno, Arity, St) when Arity > ?MAX_ARGUMENTS -> + add_error(Anno, {too_many_arguments,Arity}, St); function_check_max_args(_, _, St) -> St. %% clauses([Clause], State) -> {VarTable, State}. @@ -1585,7 +1585,7 @@ clauses(Cs, St) -> St1 end, St, Cs). -clause({clause,_Line,H,G,B}, St0) -> +clause({clause,_Anno,H,G,B}, St0) -> Vt0 = [], {Hvt,Hnew,St1} = head(H, Vt0, St0), Vt1 = vtupdate(Hvt, vtupdate(Hnew, Vt0)), @@ -1627,51 +1627,51 @@ head([], _Vt, _Env, St) -> {[],[],St}. pattern(P, Vt, St) -> pattern(P, Vt, Vt, St). % Old = Vt -pattern({var,_Line,'_'}, _Vt, _Old, St) -> +pattern({var,_Anno,'_'}, _Vt, _Old, St) -> {[],[],St}; %Ignore anonymous variable -pattern({var,Line,V}, _Vt, Old, St) -> - pat_var(V, Line, Old, [], St); -pattern({char,_Line,_C}, _Vt, _Old, St) -> {[],[],St}; -pattern({integer,_Line,_I}, _Vt, _Old, St) -> {[],[],St}; -pattern({float,_Line,_F}, _Vt, _Old, St) -> {[],[],St}; -pattern({atom,Line,A}, _Vt, _Old, St) -> - {[],[],keyword_warning(Line, A, St)}; -pattern({string,_Line,_S}, _Vt, _Old, St) -> {[],[],St}; -pattern({nil,_Line}, _Vt, _Old, St) -> {[],[],St}; -pattern({cons,_Line,H,T}, Vt, Old, St0) -> +pattern({var,Anno,V}, _Vt, Old, St) -> + pat_var(V, Anno, Old, [], St); +pattern({char,_Anno,_C}, _Vt, _Old, St) -> {[],[],St}; +pattern({integer,_Anno,_I}, _Vt, _Old, St) -> {[],[],St}; +pattern({float,_Anno,_F}, _Vt, _Old, St) -> {[],[],St}; +pattern({atom,Anno,A}, _Vt, _Old, St) -> + {[],[],keyword_warning(Anno, A, St)}; +pattern({string,_Anno,_S}, _Vt, _Old, St) -> {[],[],St}; +pattern({nil,_Anno}, _Vt, _Old, St) -> {[],[],St}; +pattern({cons,_Anno,H,T}, Vt, Old, St0) -> {Hvt,Hnew,St1} = pattern(H, Vt, Old, St0), {Tvt,Tnew,St2} = pattern(T, Vt, Old, St1), {vtmerge_pat(Hvt, Tvt),vtmerge_pat(Hnew,Tnew),St2}; -pattern({tuple,_Line,Ps}, Vt, Old, St) -> +pattern({tuple,_Anno,Ps}, Vt, Old, St) -> pattern_list(Ps, Vt, Old, St); -pattern({map,_Line,Ps}, Vt, Old, St) -> +pattern({map,_Anno,Ps}, Vt, Old, St) -> pattern_map(Ps, Vt, Old, St); -pattern({record_index,Line,Name,Field}, _Vt, _Old, St) -> +pattern({record_index,Anno,Name,Field}, _Vt, _Old, St) -> {Vt1,St1} = - check_record(Line, Name, St, + check_record(Anno, Name, St, fun (Dfs, St1) -> pattern_field(Field, Name, Dfs, St1) end), {Vt1,[],St1}; -pattern({record,Line,Name,Pfs}, Vt, Old, St) -> +pattern({record,Anno,Name,Pfs}, Vt, Old, St) -> case maps:find(Name, St#lint.records) of - {ok,{_Line,Fields}} -> + {ok,{_Anno,Fields}} -> St1 = used_record(Name, St), - St2 = check_multi_field_init(Pfs, Line, Fields, St1), + St2 = check_multi_field_init(Pfs, Anno, Fields, St1), pattern_fields(Pfs, Name, Fields, Vt, Old, St2); - error -> {[],[],add_error(Line, {undefined_record,Name}, St)} + error -> {[],[],add_error(Anno, {undefined_record,Name}, St)} end; pattern({bin,_,Fs}, Vt, Old, St) -> pattern_bin(Fs, Vt, Old, St); -pattern({op,_Line,'++',{nil,_},R}, Vt, Old, St) -> +pattern({op,_Anno,'++',{nil,_},R}, Vt, Old, St) -> pattern(R, Vt, Old, St); -pattern({op,_Line,'++',{cons,Li,{char,_L2,_C},T},R}, Vt, Old, St) -> - pattern({op,Li,'++',T,R}, Vt, Old, St); %Char unimportant here -pattern({op,_Line,'++',{cons,Li,{integer,_L2,_I},T},R}, Vt, Old, St) -> - pattern({op,Li,'++',T,R}, Vt, Old, St); %Weird, but compatible! -pattern({op,_Line,'++',{string,_Li,_S},R}, Vt, Old, St) -> +pattern({op,_Anno,'++',{cons,Ai,{char,_A2,_C},T},R}, Vt, Old, St) -> + pattern({op,Ai,'++',T,R}, Vt, Old, St); %Char unimportant here +pattern({op,_Anno,'++',{cons,Ai,{integer,_A2,_I},T},R}, Vt, Old, St) -> + pattern({op,Ai,'++',T,R}, Vt, Old, St); %Weird, but compatible! +pattern({op,_Anno,'++',{string,_Ai,_S},R}, Vt, Old, St) -> pattern(R, Vt, Old, St); %String unimportant here -pattern({match,_Line,Pat1,Pat2}, Vt, Old, St0) -> +pattern({match,_Anno,Pat1,Pat2}, Vt, Old, St0) -> {Lvt,Lnew,St1} = pattern(Pat1, Vt, Old, St0), {Rvt,Rnew,St2} = pattern(Pat2, Vt, Old, St1), St3 = reject_invalid_alias(Pat1, Pat2, Vt, St2), @@ -1690,11 +1690,13 @@ pattern_list(Ps, Vt, Old, St) -> end, {[],[],St}, Ps). %% Check for '_' initializing no fields. -check_multi_field_init(Fs, Line, Fields, St) -> - case - has_wildcard_field(Fs) andalso init_fields(Fs, Line, Fields) =:= [] - of - true -> add_error(Line, bad_multi_field_init, St); +check_multi_field_init(Fs, Anno, Fields, St) -> + case init_fields(Fs, Anno, Fields) =:= [] of + true -> + case has_wildcard_field(Fs) of + no -> St; + WildAnno -> add_error(WildAnno, bad_multi_field_init, St) + end; false -> St end. @@ -1725,17 +1727,17 @@ reject_invalid_alias_expr(_, _, _, St) -> St. %% error. %% Maps should reject unbound variables here. -reject_invalid_alias({bin,Line,_}, {bin,_,_}, _, St) -> - add_error(Line, illegal_bin_pattern, St); -reject_invalid_alias({map,_Line,Ps1}, {map,_,Ps2}, Vt, St0) -> - Fun = fun ({map_field_exact,L,{var,_,K},_V}, Sti) -> +reject_invalid_alias({bin,Anno,_}, {bin,_,_}, _, St) -> + add_error(Anno, illegal_bin_pattern, St); +reject_invalid_alias({map,_Anno,Ps1}, {map,_,Ps2}, Vt, St0) -> + Fun = fun ({map_field_exact,_,{var,A,K},_V}, Sti) -> case is_var_bound(K,Vt) of true -> Sti; false -> - add_error(L, {unbound_var,K}, Sti) + add_error(A, {unbound_var,K}, Sti) end; - ({map_field_exact,_L,_K,_V}, Sti) -> + ({map_field_exact,_A,_K,_V}, Sti) -> Sti end, foldl(Fun, foldl(Fun, St0, Ps1), Ps2); @@ -1747,7 +1749,7 @@ reject_invalid_alias({tuple,_,Es1}, {tuple,_,Es2}, Vt, St) -> reject_invalid_alias({record,_,Name1,Pfs1}, {record,_,Name2,Pfs2}, Vt, #lint{records=Recs}=St) -> case Recs of - #{Name1 := {_Line1,Fields1}, Name2 := {_Line2,Fields2}} -> + #{Name1 := {_Anno1,Fields1}, Name2 := {_Anno2,Fields2}} -> reject_invalid_alias_rec(Pfs1, Pfs2, Fields1, Fields2, Vt, St); #{} -> %% One or more non-existing records. (An error messages has @@ -1811,25 +1813,25 @@ is_pattern_expr(Expr) -> end end. -is_pattern_expr_1({char,_Line,_C}) -> true; -is_pattern_expr_1({integer,_Line,_I}) -> true; -is_pattern_expr_1({float,_Line,_F}) -> true; -is_pattern_expr_1({atom,_Line,_A}) -> true; -is_pattern_expr_1({tuple,_Line,Es}) -> +is_pattern_expr_1({char,_Anno,_C}) -> true; +is_pattern_expr_1({integer,_Anno,_I}) -> true; +is_pattern_expr_1({float,_Anno,_F}) -> true; +is_pattern_expr_1({atom,_Anno,_A}) -> true; +is_pattern_expr_1({tuple,_Anno,Es}) -> all(fun is_pattern_expr/1, Es); -is_pattern_expr_1({nil,_Line}) -> true; -is_pattern_expr_1({cons,_Line,H,T}) -> +is_pattern_expr_1({nil,_Anno}) -> true; +is_pattern_expr_1({cons,_Anno,H,T}) -> is_pattern_expr_1(H) andalso is_pattern_expr_1(T); -is_pattern_expr_1({op,_Line,Op,A}) -> +is_pattern_expr_1({op,_Anno,Op,A}) -> erl_internal:arith_op(Op, 1) andalso is_pattern_expr_1(A); -is_pattern_expr_1({op,_Line,Op,A1,A2}) -> +is_pattern_expr_1({op,_Anno,Op,A1,A2}) -> erl_internal:arith_op(Op, 2) andalso all(fun is_pattern_expr/1, [A1,A2]); is_pattern_expr_1(_Other) -> false. pattern_map(Ps, Vt, Old, St) -> - foldl(fun({map_field_assoc,L,_,_}, {Psvt,Psnew,St0}) -> - {Psvt,Psnew,add_error(L, illegal_pattern, St0)}; - ({map_field_exact,_L,K,V}, {Psvt,Psnew,St0}) -> + foldl(fun({map_field_assoc,A,_,_}, {Psvt,Psnew,St0}) -> + {Psvt,Psnew,add_error(A, illegal_pattern, St0)}; + ({map_field_exact,_A,K,V}, {Psvt,Psnew,St0}) -> St1 = St0#lint{gexpr_context=map_key}, {Kvt,St2} = gexpr(K, Vt, St1), {Vvt,Vnew,St3} = pattern(V, Vt, Old, St2), @@ -1843,35 +1845,38 @@ pattern_map(Ps, Vt, Old, St) -> %% Check a pattern group. pattern_bin(Es, Vt, Old, St0) -> - {_Sz,Esvt,Esnew,St1} = foldl(fun (E, Acc) -> - pattern_element(E, Vt, Old, Acc) - end, - {0,[],[],St0}, Es), + {_,Esvt,Esnew,St1} = foldl(fun (E, Acc) -> + pattern_element(E, Vt, Old, Acc) + end, {{0,0},[],[],St0}, Es), {Esvt,Esnew,St1}. -pattern_element({bin_element,Line,{string,_,_},Size,Ts}=Be, Vt, +pattern_element({bin_element,Anno,{string,_,_},Size,Ts}=Be, Vt, Old, {Sz,Esvt,Esnew,St0}=Acc) -> case good_string_size_type(Size, Ts) of true -> pattern_element_1(Be, Vt, Old, Acc); false -> - St = add_error(Line, typed_literal_string, St0), + St = add_error(Anno, typed_literal_string, St0), {Sz,Esvt,Esnew,St} end; pattern_element(Be, Vt, Old, Acc) -> pattern_element_1(Be, Vt, Old, Acc). -pattern_element_1({bin_element,Line,E,Sz0,Ts}, Vt, Old, {Size0,Esvt,Esnew,St0}) -> +pattern_element_1({bin_element,Anno,E,Sz0,Ts}, Vt, Old, + {{PrevSize,PrevAnno},Esvt,Esnew,St0}) -> {Pevt,Penew,St1} = pat_bit_expr(E, Old, Esnew, St0), {Sz1,Szvt,Sznew,St2} = pat_bit_size(Sz0, Vt, Esnew, St1), - {Sz2,Bt,St3} = bit_type(Line, Sz1, Ts, St2), - {Sz3,St4} = bit_size_check(Line, Sz2, Bt, St3), + {Sz2,Bt,St3} = bit_type(Anno, Sz1, Ts, St2), + {Sz3,St4} = bit_size_check(Anno, Sz2, Bt, St3), Sz4 = case {E,Sz3} of {{string,_,S},all} -> 8*length(S); {_,_} -> Sz3 end, - {Size1,St5} = add_bit_size(Line, Sz4, Size0, false, St4), - {Size1,vtmerge(Szvt,vtmerge(Pevt, Esvt)), + St5 = case PrevSize of + all -> add_error(PrevAnno, unsized_binary_not_at_end, St4); + _ -> St4 + end, + {{Sz4,Anno},vtmerge(Szvt,vtmerge(Pevt, Esvt)), vtmerge(Sznew,vtmerge(Esnew, Penew)), St5}. good_string_size_type(default, default) -> @@ -1889,10 +1894,10 @@ good_string_size_type(_, _) -> false. %% Check pattern bit expression, only allow really valid patterns! pat_bit_expr({var,_,'_'}, _Old, _New, St) -> {[],[],St}; -pat_bit_expr({var,Ln,V}, Old, New, St) -> pat_var(V, Ln, Old, New, St); +pat_bit_expr({var,Anno,V}, Old, New, St) -> pat_var(V, Anno, Old, New, St); pat_bit_expr({string,_,_}, _Old, _new, St) -> {[],[],St}; -pat_bit_expr({bin,L,_}, _Old, _New, St) -> - {[],[],add_error(L, illegal_pattern, St)}; +pat_bit_expr({bin,A,_}, _Old, _New, St) -> + {[],[],add_error(A, illegal_pattern, St)}; pat_bit_expr(P, _Old, _New, St) -> case is_pattern_expr(P) of true -> {[],[],St}; @@ -1904,13 +1909,13 @@ pat_bit_expr(P, _Old, _New, St) -> %% Check pattern size expression, only allow really valid sizes! pat_bit_size(default, _Vt, _New, St) -> {default,[],[],St}; -pat_bit_size({var,Lv,V}, Vt0, New0, St0) -> - {Vt,New,St1} = pat_binsize_var(V, Lv, Vt0, New0, St0), +pat_bit_size({var,Anno,V}, Vt0, New0, St0) -> + {Vt,New,St1} = pat_binsize_var(V, Anno, Vt0, New0, St0), {unknown,Vt,New,St1}; pat_bit_size(Size, Vt0, New0, St0) -> - Line = element(2, Size), + Anno = element(2, Size), case erl_eval:partial_eval(Size) of - {integer,Line,I} -> {I,[],[],St0}; + {integer,Anno,I} -> {I,[],[],St0}; Expr -> %% The size is an expression using operators %% and/or guard BIFs calls. If the expression @@ -1924,7 +1929,7 @@ pat_bit_size(Size, Vt0, New0, St0) -> %% The size is a non-integer literal or a simple %% expression that does not evaluate to an %% integer value. Issue a warning. - add_warning(Line, non_integer_bitsize, St3); + add_warning(Anno, non_integer_bitsize, St3); false -> St3 end, {unknown,Vt,New,St} @@ -1939,24 +1944,24 @@ is_bit_size_illegal({nil,_}) -> true; is_bit_size_illegal({tuple,_,_}) -> true; is_bit_size_illegal(_) -> false. -%% expr_bin(Line, [Element], VarTable, State, CheckFun) -> {UpdVarTable,State}. +%% expr_bin([Element], VarTable, State, CheckFun) -> {UpdVarTable,State}. %% Check an expression group. expr_bin(Es, Vt, St0, Check) -> - {_Sz,Esvt,St1} = foldl(fun (E, Acc) -> bin_element(E, Vt, Acc, Check) end, - {0,[],St0}, Es), + {Esvt,St1} = foldl(fun (E, Acc) -> + bin_element(E, Vt, Acc, Check) + end, {[],St0}, Es), {Esvt,St1}. -bin_element({bin_element,Line,E,Sz0,Ts}, Vt, {Size0,Esvt,St0}, Check) -> +bin_element({bin_element,Anno,E,Sz0,Ts}, Vt, {Esvt,St0}, Check) -> {Vt1,St1} = Check(E, Vt, St0), {Sz1,Vt2,St2} = bit_size(Sz0, Vt, St1, Check), - {Sz2,Bt,St3} = bit_type(Line, Sz1, Ts, St2), - {Sz3,St4} = bit_size_check(Line, Sz2, Bt, St3), - {Size1,St5} = add_bit_size(Line, Sz3, Size0, true, St4), - {Size1,vtmerge([Vt2,Vt1,Esvt]),St5}. + {Sz2,Bt,St3} = bit_type(Anno, Sz1, Ts, St2), + {_Sz3,St4} = bit_size_check(Anno, Sz2, Bt, St3), + {vtmerge([Vt2,Vt1,Esvt]),St4}. bit_size(default, _Vt, St, _Check) -> {default,[],St}; -bit_size({atom,_Line,all}, _Vt, St, _Check) -> {all,[],St}; +bit_size({atom,_Anno,all}, _Vt, St, _Check) -> {all,[],St}; bit_size(Size, Vt, St, Check) -> %% Try to safely evaluate Size if constant to get size, %% otherwise just treat it as an expression. @@ -1974,56 +1979,42 @@ bit_size(Size, Vt, St, Check) -> {unknown,Evt,St1} end. -%% bit_type(Line, Size, TypeList, State) -> {Size,#bittype,St}. +%% bit_type(Anno, Size, TypeList, State) -> {Size,#bittype,St}. %% Perform warning check on type and size. -bit_type(Line, Size0, Type, St) -> +bit_type(Anno, Size0, Type, St) -> case erl_bits:set_bit_type(Size0, Type) of {ok,Size1,Bt} -> {Size1,Bt,St}; {error,What} -> %% Flag error and generate a default. {ok,Size1,Bt} = erl_bits:set_bit_type(default, []), - {Size1,Bt,add_error(Line, What, St)} + {Size1,Bt,add_error(Anno, What, St)} end. -%% bit_size_check(Line, Size, BitType, State) -> {BitSize,State}. +%% bit_size_check(Anno, Size, BitType, State) -> {BitSize,State}. %% Do some checking & warnings on types %% float == 32 or 64 -bit_size_check(_Line, unknown, _, St) -> {unknown,St}; -bit_size_check(_Line, undefined, #bittype{type=Type}, St) -> +bit_size_check(_Anno, unknown, _, St) -> {unknown,St}; +bit_size_check(_Anno, undefined, #bittype{type=Type}, St) -> true = (Type =:= utf8) or (Type =:= utf16) or (Type =:= utf32), %Assertion. {undefined,St}; -bit_size_check(Line, all, #bittype{type=Type}, St) -> +bit_size_check(Anno, all, #bittype{type=Type}, St) -> case Type of binary -> {all,St}; - _ -> {unknown,add_error(Line, illegal_bitsize, St)} + _ -> {unknown,add_error(Anno, illegal_bitsize, St)} end; -bit_size_check(Line, Size, #bittype{type=Type,unit=Unit}, St) -> +bit_size_check(Anno, Size, #bittype{type=Type,unit=Unit}, St) -> Sz = Unit * Size, %Total number of bits! - St2 = elemtype_check(Line, Type, Sz, St), + St2 = elemtype_check(Anno, Type, Sz, St), {Sz,St2}. -elemtype_check(_Line, float, 32, St) -> St; -elemtype_check(_Line, float, 64, St) -> St; -elemtype_check(Line, float, _Size, St) -> - add_warning(Line, {bad_bitsize,"float"}, St); -elemtype_check(_Line, _Type, _Size, St) -> St. - +elemtype_check(_Anno, float, 32, St) -> St; +elemtype_check(_Anno, float, 64, St) -> St; +elemtype_check(Anno, float, _Size, St) -> + add_warning(Anno, {bad_bitsize,"float"}, St); +elemtype_check(_Anno, _Type, _Size, St) -> St. -%% add_bit_size(Line, ElementSize, BinSize, Build, State) -> {Size,State}. -%% Add bits to group size. - -add_bit_size(Line, _Sz1, all, false, St) -> - {all,add_error(Line, unsized_binary_not_at_end, St)}; -add_bit_size(_Line, _Sz1, all, true, St) -> - {all,St}; -add_bit_size(_Line, all, _Sz2, _B, St) -> {all,St}; -add_bit_size(_Line, undefined, _Sz2, _B, St) -> {undefined,St}; -add_bit_size(_Line, unknown, _Sz2, _B, St) -> {unknown,St}; -add_bit_size(_Line, _Sz1, undefined, _B, St) -> {unknown,St}; -add_bit_size(_Line, _Sz1, unknown, _B, St) -> {unknown,St}; -add_bit_size(_Line, Sz1, Sz2, _B, St) -> {Sz1 + Sz2,St}. %% guard([GuardTest], VarTable, State) -> %% {UsedVarTable,State} @@ -2055,16 +2046,16 @@ guard_test(G, Vt, St0) -> guard_test2(G, Vt, St1). %% Specially handle record type test here. -guard_test2({call,Line,{atom,Lr,record},[E,A]}, Vt, St0) -> - gexpr({call,Line,{atom,Lr,is_record},[E,A]}, Vt, St0); -guard_test2({call,Line,{atom,_La,F},As}=G, Vt, St0) -> +guard_test2({call,Anno,{atom,Ar,record},[E,A]}, Vt, St0) -> + gexpr({call,Anno,{atom,Ar,is_record},[E,A]}, Vt, St0); +guard_test2({call,Anno,{atom,_Aa,F},As}=G, Vt, St0) -> {Asvt,St1} = gexpr_list(As, Vt, St0), %Always check this. A = length(As), case erl_internal:type_test(F, A) of true when F =/= is_record, A =/= 2 -> case no_guard_bif_clash(St1, {F,A}) of false -> - {Asvt,add_error(Line, {illegal_guard_local_call,{F,A}}, St1)}; + {Asvt,add_error(Anno, {illegal_guard_local_call,{F,A}}, St1)}; true -> {Asvt,St1} end; @@ -2079,67 +2070,67 @@ guard_test2(G, Vt, St) -> %% {UsedVarTable,State'} %% Check a guard expression, returns NewVariables. -gexpr({var,Line,V}, Vt, St) -> - expr_var(V, Line, Vt, St); -gexpr({char,_Line,_C}, _Vt, St) -> {[],St}; -gexpr({integer,_Line,_I}, _Vt, St) -> {[],St}; -gexpr({float,_Line,_F}, _Vt, St) -> {[],St}; -gexpr({atom,Line,A}, _Vt, St) -> - {[],keyword_warning(Line, A, St)}; -gexpr({string,_Line,_S}, _Vt, St) -> {[],St}; -gexpr({nil,_Line}, _Vt, St) -> {[],St}; -gexpr({cons,_Line,H,T}, Vt, St) -> +gexpr({var,Anno,V}, Vt, St) -> + expr_var(V, Anno, Vt, St); +gexpr({char,_Anno,_C}, _Vt, St) -> {[],St}; +gexpr({integer,_Anno,_I}, _Vt, St) -> {[],St}; +gexpr({float,_Anno,_F}, _Vt, St) -> {[],St}; +gexpr({atom,Anno,A}, _Vt, St) -> + {[],keyword_warning(Anno, A, St)}; +gexpr({string,_Anno,_S}, _Vt, St) -> {[],St}; +gexpr({nil,_Anno}, _Vt, St) -> {[],St}; +gexpr({cons,_Anno,H,T}, Vt, St) -> gexpr_list([H,T], Vt, St); -gexpr({tuple,_Line,Es}, Vt, St) -> +gexpr({tuple,_Anno,Es}, Vt, St) -> gexpr_list(Es, Vt, St); -gexpr({map,_Line,Es}, Vt, St) -> +gexpr({map,_Anno,Es}, Vt, St) -> map_fields(Es, Vt, check_assoc_fields(Es, St), fun gexpr_list/3); -gexpr({map,_Line,Src,Es}, Vt, St) -> +gexpr({map,_Anno,Src,Es}, Vt, St) -> {Svt,St1} = gexpr(Src, Vt, St), {Fvt,St2} = map_fields(Es, Vt, St1, fun gexpr_list/3), {vtmerge(Svt, Fvt),St2}; -gexpr({record_index,Line,Name,Field}, _Vt, St) -> - check_record(Line, Name, St, +gexpr({record_index,Anno,Name,Field}, _Vt, St) -> + check_record(Anno, Name, St, fun (Dfs, St1) -> record_field(Field, Name, Dfs, St1) end ); -gexpr({record_field,Line,Rec,Name,Field}, Vt, St0) -> +gexpr({record_field,Anno,Rec,Name,Field}, Vt, St0) -> {Rvt,St1} = gexpr(Rec, Vt, St0), - {Fvt,St2} = check_record(Line, Name, St1, + {Fvt,St2} = check_record(Anno, Name, St1, fun (Dfs, St) -> record_field(Field, Name, Dfs, St) end), {vtmerge(Rvt, Fvt),St2}; -gexpr({record,Line,Name,Inits}, Vt, St) -> - check_record(Line, Name, St, +gexpr({record,Anno,Name,Inits}, Vt, St) -> + check_record(Anno, Name, St, fun (Dfs, St1) -> - ginit_fields(Inits, Line, Name, Dfs, Vt, St1) + ginit_fields(Inits, Anno, Name, Dfs, Vt, St1) end); -gexpr({bin,_Line,Fs}, Vt,St) -> +gexpr({bin,_Anno,Fs}, Vt,St) -> expr_bin(Fs, Vt, St, fun gexpr/3); -gexpr({call,_Line,{atom,_Lr,is_record},[E,{atom,Ln,Name}]}, Vt, St0) -> +gexpr({call,_Anno,{atom,_Ar,is_record},[E,{atom,An,Name}]}, Vt, St0) -> {Rvt,St1} = gexpr(E, Vt, St0), - {Rvt,exist_record(Ln, Name, St1)}; -gexpr({call,Line,{atom,_Lr,is_record},[E,R]}, Vt, St0) -> + {Rvt,exist_record(An, Name, St1)}; +gexpr({call,Anno,{atom,_Ar,is_record},[E,R]}, Vt, St0) -> {Asvt,St1} = gexpr_list([E,R], Vt, St0), - {Asvt,add_error(Line, illegal_guard_expr, St1)}; -gexpr({call,Line,{remote,_Lr,{atom,_Lm,erlang},{atom,Lf,is_record}},[E,A]}, + {Asvt,add_error(Anno, illegal_guard_expr, St1)}; +gexpr({call,Anno,{remote,_Ar,{atom,_Am,erlang},{atom,Af,is_record}},[E,A]}, Vt, St0) -> - gexpr({call,Line,{atom,Lf,is_record},[E,A]}, Vt, St0); -gexpr({call,Line,{atom,_Lr,is_record},[E0,{atom,_,_Name},{integer,_,_}]}, + gexpr({call,Anno,{atom,Af,is_record},[E,A]}, Vt, St0); +gexpr({call,Anno,{atom,_Ar,is_record},[E0,{atom,_,_Name},{integer,_,_}]}, Vt, St0) -> {E,St1} = gexpr(E0, Vt, St0), case no_guard_bif_clash(St0, {is_record,3}) of true -> {E,St1}; false -> - {E,add_error(Line, {illegal_guard_local_call,{is_record,3}}, St1)} + {E,add_error(Anno, {illegal_guard_local_call,{is_record,3}}, St1)} end; -gexpr({call,Line,{atom,_Lr,is_record},[_,_,_]=Asvt0}, Vt, St0) -> +gexpr({call,Anno,{atom,_Ar,is_record},[_,_,_]=Asvt0}, Vt, St0) -> {Asvt,St1} = gexpr_list(Asvt0, Vt, St0), - {Asvt,add_error(Line, illegal_guard_expr, St1)}; -gexpr({call,Line,{remote,_,{atom,_,erlang},{atom,_,is_record}=Isr},[_,_,_]=Args}, + {Asvt,add_error(Anno, illegal_guard_expr, St1)}; +gexpr({call,Anno,{remote,_,{atom,_,erlang},{atom,_,is_record}=Isr},[_,_,_]=Args}, Vt, St0) -> - gexpr({call,Line,Isr,Args}, Vt, St0); -gexpr({call,Line,{atom,_La,F},As}, Vt, St0) -> + gexpr({call,Anno,Isr,Args}, Vt, St0); +gexpr({call,Anno,{atom,_Aa,F},As}, Vt, St0) -> {Asvt,St1} = gexpr_list(As, Vt, St0), A = length(As), %% BifClash - Function called in guard @@ -2152,33 +2143,33 @@ gexpr({call,Line,{atom,_La,F},As}, Vt, St0) -> case is_local_function(St1#lint.locals,{F,A}) orelse is_imported_function(St1#lint.imports,{F,A}) of true -> - {Asvt,add_error(Line, {illegal_guard_local_call,{F,A}}, St1)}; + {Asvt,add_error(Anno, {illegal_guard_local_call,{F,A}}, St1)}; _ -> - {Asvt,add_error(Line, illegal_guard_expr, St1)} + {Asvt,add_error(Anno, illegal_guard_expr, St1)} end end; -gexpr({call,Line,{remote,_Lr,{atom,_Lm,erlang},{atom,_Lf,F}},As}, Vt, St0) -> +gexpr({call,Anno,{remote,_Ar,{atom,_Am,erlang},{atom,_Af,F}},As}, Vt, St0) -> {Asvt,St1} = gexpr_list(As, Vt, St0), A = length(As), case erl_internal:guard_bif(F, A) orelse is_gexpr_op(F, A) of true -> {Asvt,St1}; - false -> {Asvt,add_error(Line, illegal_guard_expr, St1)} + false -> {Asvt,add_error(Anno, illegal_guard_expr, St1)} end; -gexpr({op,Line,Op,A}, Vt, St0) -> +gexpr({op,Anno,Op,A}, Vt, St0) -> {Avt,St1} = gexpr(A, Vt, St0), case is_gexpr_op(Op, 1) of true -> {Avt,St1}; - false -> {Avt,add_error(Line, illegal_guard_expr, St1)} + false -> {Avt,add_error(Anno, illegal_guard_expr, St1)} end; gexpr({op,_,'andalso',L,R}, Vt, St) -> gexpr_list([L,R], Vt, St); gexpr({op,_,'orelse',L,R}, Vt, St) -> gexpr_list([L,R], Vt, St); -gexpr({op,Line,Op,L,R}, Vt, St0) -> +gexpr({op,Anno,Op,L,R}, Vt, St0) -> {Avt,St1} = gexpr_list([L,R], Vt, St0), case is_gexpr_op(Op, 2) of true -> {Avt,St1}; - false -> {Avt,add_error(Line, illegal_guard_expr, St1)} + false -> {Avt,add_error(Anno, illegal_guard_expr, St1)} end; %% Everything else is illegal! You could put explicit tests here to %% better error diagnostics. @@ -2236,9 +2227,9 @@ is_guard_test(Expression, Forms, IsOverridden) -> {St0#lint.records,IsOverridden}). %% is_guard_test2(Expression, RecordDefs :: dict:dict()) -> boolean(). -is_guard_test2({call,Line,{atom,Lr,record},[E,A]}, Info) -> - is_gexpr({call,Line,{atom,Lr,is_record},[E,A]}, Info); -is_guard_test2({call,_Line,{atom,_La,Test},As}=Call, {_,IsOverridden}=Info) -> +is_guard_test2({call,Anno,{atom,Ar,record},[E,A]}, Info) -> + is_gexpr({call,Anno,{atom,Ar,is_record},[E,A]}, Info); +is_guard_test2({call,_Anno,{atom,_Aa,Test},As}=Call, {_,IsOverridden}=Info) -> A = length(As), not IsOverridden({Test,A}) andalso case erl_internal:type_test(Test, A) of @@ -2254,46 +2245,46 @@ is_guard_test2(G, Info) -> is_guard_expr(E) -> is_gexpr(E, {[],fun({_,_}) -> false end}). -is_gexpr({var,_L,_V}, _Info) -> true; -is_gexpr({char,_L,_C}, _Info) -> true; -is_gexpr({integer,_L,_I}, _Info) -> true; -is_gexpr({float,_L,_F}, _Info) -> true; -is_gexpr({atom,_L,_A}, _Info) -> true; -is_gexpr({string,_L,_S}, _Info) -> true; -is_gexpr({nil,_L}, _Info) -> true; -is_gexpr({cons,_L,H,T}, Info) -> is_gexpr_list([H,T], Info); -is_gexpr({tuple,_L,Es}, Info) -> is_gexpr_list(Es, Info); -is_gexpr({map,_L,Es}, Info) -> +is_gexpr({var,_A,_V}, _Info) -> true; +is_gexpr({char,_A,_C}, _Info) -> true; +is_gexpr({integer,_A,_I}, _Info) -> true; +is_gexpr({float,_A,_F}, _Info) -> true; +is_gexpr({atom,_A,_Atom}, _Info) -> true; +is_gexpr({string,_A,_S}, _Info) -> true; +is_gexpr({nil,_A}, _Info) -> true; +is_gexpr({cons,_A,H,T}, Info) -> is_gexpr_list([H,T], Info); +is_gexpr({tuple,_A,Es}, Info) -> is_gexpr_list(Es, Info); +is_gexpr({map,_A,Es}, Info) -> is_map_fields(Es, Info); -is_gexpr({map,_L,Src,Es}, Info) -> +is_gexpr({map,_A,Src,Es}, Info) -> is_gexpr(Src, Info) andalso is_map_fields(Es, Info); -is_gexpr({record_index,_L,_Name,Field}, Info) -> +is_gexpr({record_index,_A,_Name,Field}, Info) -> is_gexpr(Field, Info); -is_gexpr({record_field,_L,Rec,_Name,Field}, Info) -> +is_gexpr({record_field,_A,Rec,_Name,Field}, Info) -> is_gexpr_list([Rec,Field], Info); -is_gexpr({record,L,Name,Inits}, Info) -> - is_gexpr_fields(Inits, L, Name, Info); -is_gexpr({bin,_L,Fs}, Info) -> - all(fun ({bin_element,_Line,E,Sz,_Ts}) -> +is_gexpr({record,A,Name,Inits}, Info) -> + is_gexpr_fields(Inits, A, Name, Info); +is_gexpr({bin,_A,Fs}, Info) -> + all(fun ({bin_element,_Anno,E,Sz,_Ts}) -> is_gexpr(E, Info) and (Sz =:= default orelse is_gexpr(Sz, Info)) end, Fs); -is_gexpr({call,_L,{atom,_Lf,F},As}, {_,IsOverridden}=Info) -> +is_gexpr({call,_A,{atom,_Af,F},As}, {_,IsOverridden}=Info) -> A = length(As), not IsOverridden({F,A}) andalso erl_internal:guard_bif(F, A) andalso is_gexpr_list(As, Info); -is_gexpr({call,_L,{remote,_Lr,{atom,_Lm,erlang},{atom,_Lf,F}},As}, Info) -> +is_gexpr({call,_A,{remote,_Ar,{atom,_Am,erlang},{atom,_Af,F}},As}, Info) -> A = length(As), (erl_internal:guard_bif(F, A) orelse is_gexpr_op(F, A)) andalso is_gexpr_list(As, Info); -is_gexpr({call,L,{tuple,Lt,[{atom,Lm,erlang},{atom,Lf,F}]},As}, Info) -> - is_gexpr({call,L,{remote,Lt,{atom,Lm,erlang},{atom,Lf,F}},As}, Info); -is_gexpr({op,_L,Op,A}, Info) -> +is_gexpr({call,A,{tuple,At,[{atom,Am,erlang},{atom,Af,F}]},As}, Info) -> + is_gexpr({call,A,{remote,At,{atom,Am,erlang},{atom,Af,F}},As}, Info); +is_gexpr({op,_A,Op,A}, Info) -> is_gexpr_op(Op, 1) andalso is_gexpr(A, Info); -is_gexpr({op,_L,'andalso',A1,A2}, Info) -> +is_gexpr({op,_A,'andalso',A1,A2}, Info) -> is_gexpr_list([A1,A2], Info); -is_gexpr({op,_L,'orelse',A1,A2}, Info) -> +is_gexpr({op,_A,'orelse',A1,A2}, Info) -> is_gexpr_list([A1,A2], Info); -is_gexpr({op,_L,Op,A1,A2}, Info) -> +is_gexpr({op,_A,Op,A1,A2}, Info) -> is_gexpr_op(Op, 2) andalso is_gexpr_list([A1,A2], Info); is_gexpr(_Other, _Info) -> false. @@ -2317,12 +2308,12 @@ is_map_fields([{Tag,_,K,V}|Fs], Info) when Tag =:= map_field_assoc; is_map_fields([], _Info) -> true; is_map_fields(_T, _Info) -> false. -is_gexpr_fields(Fs, L, Name, {RDs,_}=Info) -> +is_gexpr_fields(Fs, A, Name, {RDs,_}=Info) -> IFs = case maps:find(Name, RDs) of - {ok,{_Line,Fields}} -> Fs ++ init_fields(Fs, L, Fields); + {ok,{_Anno,Fields}} -> Fs ++ init_fields(Fs, A, Fields); error -> Fs end, - all(fun ({record_field,_Lf,_Name,V}) -> is_gexpr(V, Info); + all(fun ({record_field,_Af,_Name,V}) -> is_gexpr(V, Info); (_Other) -> false end, IFs). %% exprs(Sequence, VarTable, State) -> @@ -2341,84 +2332,84 @@ exprs([], _Vt, St) -> {[],St}. %% mark illegally exported variables, e.g. from catch, as unsafe to better %% show why unbound. -expr({var,Line,V}, Vt, St) -> - expr_var(V, Line, Vt, St); -expr({char,_Line,_C}, _Vt, St) -> {[],St}; -expr({integer,_Line,_I}, _Vt, St) -> {[],St}; -expr({float,_Line,_F}, _Vt, St) -> {[],St}; -expr({atom,Line,A}, _Vt, St) -> - {[],keyword_warning(Line, A, St)}; -expr({string,_Line,_S}, _Vt, St) -> {[],St}; -expr({nil,_Line}, _Vt, St) -> {[],St}; -expr({cons,_Line,H,T}, Vt, St) -> +expr({var,Anno,V}, Vt, St) -> + expr_var(V, Anno, Vt, St); +expr({char,_Anno,_C}, _Vt, St) -> {[],St}; +expr({integer,_Anno,_I}, _Vt, St) -> {[],St}; +expr({float,_Anno,_F}, _Vt, St) -> {[],St}; +expr({atom,Anno,A}, _Vt, St) -> + {[],keyword_warning(Anno, A, St)}; +expr({string,_Anno,_S}, _Vt, St) -> {[],St}; +expr({nil,_Anno}, _Vt, St) -> {[],St}; +expr({cons,_Anno,H,T}, Vt, St) -> expr_list([H,T], Vt, St); -expr({lc,_Line,E,Qs}, Vt, St) -> +expr({lc,_Anno,E,Qs}, Vt, St) -> handle_comprehension(E, Qs, Vt, St); -expr({bc,_Line,E,Qs}, Vt, St) -> +expr({bc,_Anno,E,Qs}, Vt, St) -> handle_comprehension(E, Qs, Vt, St); -expr({tuple,_Line,Es}, Vt, St) -> +expr({tuple,_Anno,Es}, Vt, St) -> expr_list(Es, Vt, St); -expr({map,_Line,Es}, Vt, St) -> +expr({map,_Anno,Es}, Vt, St) -> map_fields(Es, Vt, check_assoc_fields(Es, St), fun expr_list/3); -expr({map,_Line,Src,Es}, Vt, St) -> +expr({map,_Anno,Src,Es}, Vt, St) -> {Svt,St1} = expr(Src, Vt, St), {Fvt,St2} = map_fields(Es, Vt, St1, fun expr_list/3), {vtupdate(Svt, Fvt),St2}; -expr({record_index,Line,Name,Field}, _Vt, St) -> - check_record(Line, Name, St, +expr({record_index,Anno,Name,Field}, _Vt, St) -> + check_record(Anno, Name, St, fun (Dfs, St1) -> record_field(Field, Name, Dfs, St1) end); -expr({record,Line,Name,Inits}, Vt, St) -> - check_record(Line, Name, St, +expr({record,Anno,Name,Inits}, Vt, St) -> + check_record(Anno, Name, St, fun (Dfs, St1) -> - init_fields(Inits, Line, Name, Dfs, Vt, St1) + init_fields(Inits, Anno, Name, Dfs, Vt, St1) end); -expr({record_field,Line,Rec,Name,Field}, Vt, St0) -> - {Rvt,St1} = record_expr(Line, Rec, Vt, St0), - {Fvt,St2} = check_record(Line, Name, St1, +expr({record_field,Anno,Rec,Name,Field}, Vt, St0) -> + {Rvt,St1} = record_expr(Anno, Rec, Vt, St0), + {Fvt,St2} = check_record(Anno, Name, St1, fun (Dfs, St) -> record_field(Field, Name, Dfs, St) end), {vtmerge(Rvt, Fvt),St2}; -expr({record,Line,Rec,Name,Upds}, Vt, St0) -> - {Rvt,St1} = record_expr(Line, Rec, Vt, St0), - {Usvt,St2} = check_record(Line, Name, St1, +expr({record,Anno,Rec,Name,Upds}, Vt, St0) -> + {Rvt,St1} = record_expr(Anno, Rec, Vt, St0), + {Usvt,St2} = check_record(Anno, Name, St1, fun (Dfs, St) -> update_fields(Upds, Name, Dfs, Vt, St) end ), case has_wildcard_field(Upds) of - true -> {[],add_error(Line, {wildcard_in_update,Name}, St2)}; - false -> {vtmerge(Rvt, Usvt),St2} + no -> {vtmerge(Rvt, Usvt),St2}; + WildAnno -> {[],add_error(WildAnno, {wildcard_in_update,Name}, St2)} end; -expr({bin,_Line,Fs}, Vt, St) -> +expr({bin,_Anno,Fs}, Vt, St) -> expr_bin(Fs, Vt, St, fun expr/3); -expr({block,_Line,Es}, Vt, St) -> +expr({block,_Anno,Es}, Vt, St) -> %% Unfold block into a sequence. exprs(Es, Vt, St); -expr({'if',Line,Cs}, Vt, St) -> - icrt_clauses(Cs, {'if',Line}, Vt, St); -expr({'case',Line,E,Cs}, Vt, St0) -> +expr({'if',Anno,Cs}, Vt, St) -> + icrt_clauses(Cs, {'if',Anno}, Vt, St); +expr({'case',Anno,E,Cs}, Vt, St0) -> {Evt,St1} = expr(E, Vt, St0), - {Cvt,St2} = icrt_clauses(Cs, {'case',Line}, vtupdate(Evt, Vt), St1), + {Cvt,St2} = icrt_clauses(Cs, {'case',Anno}, vtupdate(Evt, Vt), St1), {vtmerge(Evt, Cvt),St2}; -expr({'receive',Line,Cs}, Vt, St) -> - icrt_clauses(Cs, {'receive',Line}, Vt, St); -expr({'receive',Line,Cs,To,ToEs}, Vt, St0) -> +expr({'receive',Anno,Cs}, Vt, St) -> + icrt_clauses(Cs, {'receive',Anno}, Vt, St); +expr({'receive',Anno,Cs,To,ToEs}, Vt, St0) -> %% Are variables from the timeout expression visible in the clauses? NO! {Tvt,St1} = expr(To, Vt, St0), {Tevt,St2} = exprs(ToEs, Vt, St1), {Cvt,St3} = icrt_clauses(Cs, Vt, St2), %% Csvts = [vtnew(Tevt, Vt)|Cvt], %This is just NEW variables! Csvts = [Tevt|Cvt], - Rvt = icrt_export(Csvts, Vt, {'receive',Line}, St3), + Rvt = icrt_export(Csvts, Vt, {'receive',Anno}, St3), {vtmerge([Tvt,Tevt,Rvt]),St3}; -expr({'fun',Line,Body}, Vt, St) -> +expr({'fun',Anno,Body}, Vt, St) -> %%No one can think funs export! case Body of {clauses,Cs} -> fun_clauses(Cs, Vt, St); {function,record_info,2} -> %% It is illegal to call record_info/2 with unknown arguments. - {[],add_error(Line, illegal_record_info, St)}; + {[],add_error(Anno, illegal_record_info, St)}; {function,F,A} -> %% BifClash - Fun expression %% N.B. Only allows BIFs here as well, NO IMPORTS!! @@ -2426,45 +2417,45 @@ expr({'fun',Line,Body}, Vt, St) -> (erl_internal:bif(F, A) andalso (not is_autoimport_suppressed(St#lint.no_auto,{F,A})))) of true -> {[],St}; - false -> {[],call_function(Line, F, A, St)} + false -> {[],call_function(Anno, F, A, St)} end; {function,M,F,A} -> expr_list([M,F,A], Vt, St) end; expr({named_fun,_,'_',Cs}, Vt, St) -> fun_clauses(Cs, Vt, St); -expr({named_fun,Line,Name,Cs}, Vt, St0) -> - Nvt0 = [{Name,{bound,unused,[Line]}}], +expr({named_fun,Anno,Name,Cs}, Vt, St0) -> + Nvt0 = [{Name,{bound,unused,[Anno]}}], St1 = shadow_vars(Nvt0, Vt, 'named fun', St0), Nvt1 = vtupdate(vtsubtract(Vt, Nvt0), Nvt0), {Csvt,St2} = fun_clauses(Cs, Nvt1, St1), {_,St3} = check_unused_vars(vtupdate(Csvt, Nvt0), [], St2), {vtold(Csvt, Vt),St3}; -expr({call,_Line,{atom,_Lr,is_record},[E,{atom,Ln,Name}]}, Vt, St0) -> +expr({call,_Anno,{atom,_Ar,is_record},[E,{atom,An,Name}]}, Vt, St0) -> {Rvt,St1} = expr(E, Vt, St0), - {Rvt,exist_record(Ln, Name, St1)}; -expr({call,Line,{remote,_Lr,{atom,_Lm,erlang},{atom,Lf,is_record}},[E,A]}, + {Rvt,exist_record(An, Name, St1)}; +expr({call,Anno,{remote,_Ar,{atom,_Am,erlang},{atom,Af,is_record}},[E,A]}, Vt, St0) -> - expr({call,Line,{atom,Lf,is_record},[E,A]}, Vt, St0); -expr({call,L,{tuple,Lt,[{atom,Lm,erlang},{atom,Lf,is_record}]},As}, Vt, St) -> - expr({call,L,{remote,Lt,{atom,Lm,erlang},{atom,Lf,is_record}},As}, Vt, St); -expr({call,Line,{remote,_Lr,{atom,_Lm,M},{atom,Lf,F}},As}, Vt, St0) -> - St1 = keyword_warning(Lf, F, St0), - St2 = check_remote_function(Line, M, F, As, St1), - St3 = check_module_name(M, Line, St2), + expr({call,Anno,{atom,Af,is_record},[E,A]}, Vt, St0); +expr({call,A,{tuple,At,[{atom,Am,erlang},{atom,Af,is_record}]},As}, Vt, St) -> + expr({call,A,{remote,At,{atom,Am,erlang},{atom,Af,is_record}},As}, Vt, St); +expr({call,Anno,{remote,_Ar,{atom,_Am,M},{atom,Af,F}},As}, Vt, St0) -> + St1 = keyword_warning(Af, F, St0), + St2 = check_remote_function(Anno, M, F, As, St1), + St3 = check_module_name(M, Anno, St2), expr_list(As, Vt, St3); -expr({call,Line,{remote,_Lr,M,F},As}, Vt, St0) -> - St1 = keyword_warning(Line, M, St0), - St2 = keyword_warning(Line, F, St1), +expr({call,Anno,{remote,_Ar,M,F},As}, Vt, St0) -> + St1 = keyword_warning(Anno, M, St0), + St2 = keyword_warning(Anno, F, St1), St3 = case M of - {atom,Lm,Mod} -> - check_module_name(Mod, Lm, St2); + {atom,Am,Mod} -> + check_module_name(Mod, Am, St2); _ -> St2 end, expr_list([M,F|As], Vt, St3); -expr({call,Line,{atom,La,F},As}, Vt, St0) -> - St1 = keyword_warning(La, F, St0), +expr({call,Anno,{atom,Aa,F},As}, Vt, St0) -> + St1 = keyword_warning(Aa, F, St0), {Asvt,St2} = expr_list(As, Vt, St1), A = length(As), IsLocal = is_local_function(St2#lint.locals,{F,A}), @@ -2475,19 +2466,19 @@ expr({call,Line,{atom,La,F},As}, Vt, St0) -> case ((not IsLocal) andalso (Imported =:= no) andalso IsAutoBif andalso (not AutoSuppressed)) of true -> - St3 = deprecated_function(Line, erlang, F, As, St2), + St3 = deprecated_function(Anno, erlang, F, As, St2), {Asvt,St3}; false -> {Asvt,case Imported of {yes,M} -> - St3 = check_remote_function(Line, M, F, As, St2), + St3 = check_remote_function(Anno, M, F, As, St2), U0 = St3#lint.usage, Imp = ordsets:add_element({{F,A},M},U0#usage.imported), St3#lint{usage=U0#usage{imported = Imp}}; no -> case {F,A} of {record_info,2} -> - check_record_info_call(Line,La,As,St2); + check_record_info_call(Anno,Aa,As,St2); N -> %% BifClash - function call %% Issue these warnings/errors even if it's a recursive call @@ -2496,12 +2487,12 @@ expr({call,Line,{atom,La,F},As}, Vt, St0) -> case erl_internal:old_bif(F,A) of true -> add_error - (Line, + (Anno, {call_to_redefined_old_bif, {F,A}}, St2); false -> add_warning - (Line, + (Anno, {call_to_redefined_bif, {F,A}}, St2) end; @@ -2513,53 +2504,53 @@ expr({call,Line,{atom,La,F},As}, Vt, St0) -> N =:= St3#lint.func -> St3; true -> - call_function(Line, F, A, St3) + call_function(Anno, F, A, St3) end end end} end; -expr({call,Line,F,As}, Vt, St0) -> - St = warn_invalid_call(Line,F,St0), +expr({call,Anno,F,As}, Vt, St0) -> + St = warn_invalid_call(Anno,F,St0), expr_list([F|As], Vt, St); %They see the same variables -expr({'try',Line,Es,Scs,Ccs,As}, Vt, St0) -> +expr({'try',Anno,Es,Scs,Ccs,As}, Vt, St0) -> %% The only exports we allow are from the try expressions to the %% success clauses. {Evt0,St1} = exprs(Es, Vt, St0), - TryLine = {'try',Line}, - Uvt = vtunsafe(TryLine, Evt0, Vt), - {Sccs,St2} = try_clauses(Scs, Ccs, TryLine, + TryAnno = {'try',Anno}, + Uvt = vtunsafe(TryAnno, Evt0, Vt), + {Sccs,St2} = try_clauses(Scs, Ccs, TryAnno, vtupdate(Evt0, Vt), Uvt, St1), Evt1 = vtupdate(Uvt, Evt0), Rvt0 = Sccs, - Rvt1 = vtupdate(vtunsafe(TryLine, Rvt0, Vt), Rvt0), + Rvt1 = vtupdate(vtunsafe(TryAnno, Rvt0, Vt), Rvt0), Evt2 = vtmerge(Evt1, Rvt1), {Avt0,St} = exprs(As, vtupdate(Evt2, Vt), St2), - Avt1 = vtupdate(vtunsafe(TryLine, Avt0, Vt), Avt0), + Avt1 = vtupdate(vtunsafe(TryAnno, Avt0, Vt), Avt0), Avt = vtmerge(Evt2, Avt1), {Avt,St}; -expr({'catch',Line,E}, Vt, St0) -> +expr({'catch',Anno,E}, Vt, St0) -> %% No new variables added, flag new variables as unsafe. {Evt,St} = expr(E, Vt, St0), - {vtupdate(vtunsafe({'catch',Line}, Evt, Vt), Evt),St}; -expr({match,_Line,P,E}, Vt, St0) -> + {vtupdate(vtunsafe({'catch',Anno}, Evt, Vt), Evt),St}; +expr({match,_Anno,P,E}, Vt, St0) -> {Evt,St1} = expr(E, Vt, St0), {Pvt,Pnew,St2} = pattern(P, vtupdate(Evt, Vt), St1), St = reject_invalid_alias_expr(P, E, Vt, St2), {vtupdate(Pnew, vtmerge(Evt, Pvt)),St}; %% No comparison or boolean operators yet. -expr({op,_Line,_Op,A}, Vt, St) -> +expr({op,_Anno,_Op,A}, Vt, St) -> expr(A, Vt, St); -expr({op,Line,Op,L,R}, Vt, St0) when Op =:= 'orelse'; Op =:= 'andalso' -> +expr({op,Anno,Op,L,R}, Vt, St0) when Op =:= 'orelse'; Op =:= 'andalso' -> {Evt1,St1} = expr(L, Vt, St0), Vt1 = vtupdate(Evt1, Vt), {Evt2,St2} = expr(R, Vt1, St1), - Evt3 = vtupdate(vtunsafe({Op,Line}, Evt2, Vt1), Evt2), + Evt3 = vtupdate(vtunsafe({Op,Anno}, Evt2, Vt1), Evt2), {vtmerge(Evt1, Evt3),St2}; -expr({op,_Line,_Op,L,R}, Vt, St) -> +expr({op,_Anno,_Op,L,R}, Vt, St) -> expr_list([L,R], Vt, St); %They see the same variables %% The following are not allowed to occur anywhere! -expr({remote,Line,_M,_F}, _Vt, St) -> - {[],add_error(Line, illegal_expr, St)}. +expr({remote,Anno,_M,_F}, _Vt, St) -> + {[],add_error(Anno, illegal_expr, St)}. %% expr_list(Expressions, Variables, State) -> %% {UsedVarTable,State} @@ -2570,12 +2561,12 @@ expr_list(Es, Vt, St) -> {vtmerge_pat(Evt, Esvt),St1} end, {[],St}, Es). -record_expr(Line, Rec, Vt, St0) -> - St1 = warn_invalid_record(Line, Rec, St0), +record_expr(Anno, Rec, Vt, St0) -> + St1 = warn_invalid_record(Anno, Rec, St0), expr(Rec, Vt, St1). -check_assoc_fields([{map_field_exact,Line,_,_}|Fs], St) -> - check_assoc_fields(Fs, add_error(Line, illegal_map_construction, St)); +check_assoc_fields([{map_field_exact,Anno,_,_}|Fs], St) -> + check_assoc_fields(Fs, add_error(Anno, illegal_map_construction, St)); check_assoc_fields([{map_field_assoc,_,_,_}|Fs], St) -> check_assoc_fields(Fs, St); check_assoc_fields([], St) -> @@ -2589,13 +2580,13 @@ map_fields([{Tag,_,K,V}|Fs], Vt, St, F) when Tag =:= map_field_assoc; map_fields([], _, St, _) -> {[],St}. -%% warn_invalid_record(Line, Record, State0) -> State +%% warn_invalid_record(Anno, Record, State0) -> State %% Adds warning if the record is invalid. -warn_invalid_record(Line, R, St) -> +warn_invalid_record(Anno, R, St) -> case is_valid_record(R) of true -> St; - false -> add_warning(Line, invalid_record, St) + false -> add_warning(Anno, invalid_record, St) end. %% is_valid_record(Record) -> boolean(). @@ -2616,13 +2607,13 @@ is_valid_record(Rec) -> _ -> true end. -%% warn_invalid_call(Line, Call, State0) -> State +%% warn_invalid_call(Anno, Call, State0) -> State %% Adds warning if the call is invalid. -warn_invalid_call(Line, F, St) -> +warn_invalid_call(Anno, F, St) -> case is_valid_call(F) of true -> St; - false -> add_warning(Line, invalid_call, St) + false -> add_warning(Anno, invalid_call, St) end. %% is_valid_call(Call) -> boolean(). @@ -2641,17 +2632,17 @@ is_valid_call(Call) -> _ -> true end. -%% record_def(Line, RecordName, [RecField], State) -> State. +%% record_def(Anno, RecordName, [RecField], State) -> State. %% Add a record definition if it does not already exist. Normalise %% so that all fields have explicit initial value. -record_def(Line, Name, Fs0, St0) -> +record_def(Anno, Name, Fs0, St0) -> case is_map_key(Name, St0#lint.records) of - true -> add_error(Line, {redefine_record,Name}, St0); + true -> add_error(Anno, {redefine_record,Name}, St0); false -> {Fs1,St1} = def_fields(normalise_fields(Fs0), Name, St0), - St2 = St1#lint{records=maps:put(Name, {Line,Fs1}, - St1#lint.records)}, + St2 = St1#lint{records=maps:put(Name, {Anno,Fs1}, + St1#lint.records)}, Types = [T || {typed_record_field, _, T} <- Fs0], check_type({type, nowarn(), product, Types}, St2) end. @@ -2661,9 +2652,9 @@ record_def(Line, Name, Fs0, St0) -> %% record and set State. def_fields(Fs0, Name, St0) -> - foldl(fun ({record_field,Lf,{atom,La,F},V}, {Fs,St}) -> + foldl(fun ({record_field,Af,{atom,Aa,F},V}, {Fs,St}) -> case exist_field(F, Fs) of - true -> {Fs,add_error(Lf, {redefine_field,Name,F}, St)}; + true -> {Fs,add_error(Af, {redefine_field,Name,F}, St)}; false -> St1 = St#lint{recdef_top = true}, {_,St2} = expr(V, [], St1), @@ -2677,9 +2668,9 @@ def_fields(Fs0, Name, St0) -> %% "recursive" definitions. NV = case St2#lint.errors =:= St1#lint.errors of true -> V; - false -> {atom,La,undefined} + false -> {atom,Aa,undefined} end, - {[{record_field,Lf,{atom,La,F},NV}|Fs],St3} + {[{record_field,Af,{atom,Aa,F},NV}|Fs],St3} end end, {[],St0}, Fs0). @@ -2689,24 +2680,24 @@ def_fields(Fs0, Name, St0) -> %% Also, strip type information from typed record fields. normalise_fields(Fs) -> - map(fun ({record_field,Lf,Field}) -> - {record_field,Lf,Field,{atom,Lf,undefined}}; - ({typed_record_field,{record_field,Lf,Field},_Type}) -> - {record_field,Lf,Field,{atom,Lf,undefined}}; + map(fun ({record_field,Af,Field}) -> + {record_field,Af,Field,{atom,Af,undefined}}; + ({typed_record_field,{record_field,Af,Field},_Type}) -> + {record_field,Af,Field,{atom,Af,undefined}}; ({typed_record_field,Field,_Type}) -> Field; (F) -> F end, Fs). -%% exist_record(Line, RecordName, State) -> State. +%% exist_record(Anno, RecordName, State) -> State. %% Check if a record exists. Set State. -exist_record(Line, Name, St) -> +exist_record(Anno, Name, St) -> case is_map_key(Name, St#lint.records) of true -> used_record(Name, St); - false -> add_error(Line, {undefined_record,Name}, St) + false -> add_error(Anno, {undefined_record,Name}, St) end. -%% check_record(Line, RecordName, State, CheckFun) -> +%% check_record(Anno, RecordName, State, CheckFun) -> %% {UpdVarTable, State}. %% The generic record checking function, first checks that the record %% exists then calls the specific check function. N.B. the check @@ -2717,10 +2708,10 @@ exist_record(Line, Name, St) -> %% and must return %% {UpdatedVarTable,State} -check_record(Line, Name, St, CheckFun) -> +check_record(Anno, Name, St, CheckFun) -> case maps:find(Name, St#lint.records) of - {ok,{_Line,Fields}} -> CheckFun(Fields, used_record(Name, St)); - error -> {[],add_error(Line, {undefined_record,Name}, St)} + {ok,{_Anno,Fields}} -> CheckFun(Fields, used_record(Name, St)); + error -> {[],add_error(Anno, {undefined_record,Name}, St)} end. used_record(Name, #lint{usage=Usage}=St) -> @@ -2741,35 +2732,35 @@ check_fields(Fs, Name, Fields, Vt, St0, CheckFun) -> end, {[],[],St0}, Fs), {Uvt,St1}. -check_field({record_field,Lf,{atom,La,F},Val}, Name, Fields, +check_field({record_field,Af,{atom,Aa,F},Val}, Name, Fields, Vt, St, Sfs, CheckFun) -> case member(F, Sfs) of - true -> {Sfs,{[],add_error(Lf, {redefine_field,Name,F}, St)}}; + true -> {Sfs,{[],add_error(Af, {redefine_field,Name,F}, St)}}; false -> {[F|Sfs], case find_field(F, Fields) of {ok,_I} -> CheckFun(Val, Vt, St); - error -> {[],add_error(La, {undefined_field,Name,F}, St)} + error -> {[],add_error(Aa, {undefined_field,Name,F}, St)} end} end; -check_field({record_field,_Lf,{var,La,'_'=F},Val}, _Name, _Fields, +check_field({record_field,_Af,{var,Aa,'_'=F},Val}, _Name, _Fields, Vt, St, Sfs, CheckFun) -> case member(F, Sfs) of - true -> {Sfs,{[],add_error(La, bad_multi_field_init, St)}}; + true -> {Sfs,{[],add_error(Aa, bad_multi_field_init, St)}}; false -> {[F|Sfs],CheckFun(Val, Vt, St)} end; -check_field({record_field,_Lf,{var,La,V},_Val}, Name, _Fields, +check_field({record_field,_Af,{var,Aa,V},_Val}, Name, _Fields, Vt, St, Sfs, _CheckFun) -> - {Sfs,{Vt,add_error(La, {field_name_is_variable,Name,V}, St)}}. + {Sfs,{Vt,add_error(Aa, {field_name_is_variable,Name,V}, St)}}. %% pattern_field(Field, RecordName, [RecDefField], State) -> %% {UpdVarTable,State}. %% Test if record RecordName has field Field. Set State. -pattern_field({atom,La,F}, Name, Fields, St) -> +pattern_field({atom,Aa,F}, Name, Fields, St) -> case find_field(F, Fields) of {ok,_I} -> {[],St}; - error -> {[],add_error(La, {undefined_field,Name,F}, St)} + error -> {[],add_error(Aa, {undefined_field,Name,F}, St)} end. %% pattern_fields([PatField],RecordName,[RecDefField], @@ -2795,15 +2786,15 @@ pattern_fields(Fs, Name, Fields, Vt0, Old, St0) -> %% {UpdVarTable,State}. %% Test if record RecordName has field Field. Set State. -record_field({atom,La,F}, Name, Fields, St) -> +record_field({atom,Aa,F}, Name, Fields, St) -> case find_field(F, Fields) of {ok,_I} -> {[],St}; - error -> {[],add_error(La, {undefined_field,Name,F}, St)} + error -> {[],add_error(Aa, {undefined_field,Name,F}, St)} end. -%% init_fields([InitField], InitLine, RecordName, [DefField], VarTable, State) -> +%% init_fields([InitField], InitAnno, RecordName, [DefField], VarTable, State) -> %% {UpdVarTable,State}. -%% ginit_fields([InitField], InitLine, RecordName, [DefField], VarTable, State) -> +%% ginit_fields([InitField], InitAnno, RecordName, [DefField], VarTable, State) -> %% {UpdVarTable,State}. %% Check record initialisation. Explicit initialisations are checked %% as is, while default values are checked only if there are no @@ -2813,26 +2804,26 @@ record_field({atom,La,F}, Name, Fields, St) -> %% record definitions were checked. Usage of records, imports, and %% functions is collected. -init_fields(Ifs, Line, Name, Dfs, Vt0, St0) -> +init_fields(Ifs, Anno, Name, Dfs, Vt0, St0) -> {Vt1,St1} = check_fields(Ifs, Name, Dfs, Vt0, St0, fun expr/3), - Defs = init_fields(Ifs, Line, Dfs), + Defs = init_fields(Ifs, Anno, Dfs), {_,St2} = check_fields(Defs, Name, Dfs, Vt1, St1, fun expr/3), {Vt1,St1#lint{usage = St2#lint.usage}}. -ginit_fields(Ifs, Line, Name, Dfs, Vt0, St0) -> +ginit_fields(Ifs, Anno, Name, Dfs, Vt0, St0) -> {Vt1,St1} = check_fields(Ifs, Name, Dfs, Vt0, St0, fun gexpr/3), - Defs = init_fields(Ifs, Line, Dfs), + Defs = init_fields(Ifs, Anno, Dfs), St2 = St1#lint{errors = []}, {_,St3} = check_fields(Defs, Name, Dfs, Vt1, St2, fun gexpr/3), #lint{usage = Usage, errors = Errors} = St3, - IllErrs = [E || {_File,{_Line,erl_lint,illegal_guard_expr}}=E <- Errors], + IllErrs = [E || {_File,{_Anno,erl_lint,illegal_guard_expr}}=E <- Errors], St4 = St1#lint{usage = Usage, errors = IllErrs ++ St1#lint.errors}, {Vt1,St4}. %% Default initializations to be carried out -init_fields(Ifs, Line, Dfs) -> - [ {record_field,Lf,{atom,La,F},copy_expr(Di, Line)} || - {record_field,Lf,{atom,La,F},Di} <- Dfs, +init_fields(Ifs, Anno, Dfs) -> + [ {record_field,Af,{atom,Aa,F},copy_expr(Di, Anno)} || + {record_field,Af,{atom,Aa,F},Di} <- Dfs, not exist_field(F, Ifs) ]. %% update_fields(UpdFields, RecordName, RecDefFields, VarTable, State) -> @@ -2844,28 +2835,28 @@ update_fields(Ufs, Name, Dfs, Vt, St) -> %% exist_field(FieldName, [Field]) -> boolean(). %% Find a record field in a field list. -exist_field(F, [{record_field,_Lf,{atom,_La,F},_Val}|_Fs]) -> true; +exist_field(F, [{record_field,_Af,{atom,_Aa,F},_Val}|_Fs]) -> true; exist_field(F, [_|Fs]) -> exist_field(F, Fs); exist_field(_F, []) -> false. %% find_field(FieldName, [Field]) -> {ok,Val} | error. %% Find a record field in a field list. -find_field(_F, [{record_field,_Lf,{atom,_La,_F},Val}|_Fs]) -> {ok,Val}; +find_field(_F, [{record_field,_Af,{atom,_Aa,_F},Val}|_Fs]) -> {ok,Val}; find_field(F, [_|Fs]) -> find_field(F, Fs); find_field(_F, []) -> error. -%% type_def(Attr, Line, TypeName, PatField, Args, State) -> State. +%% type_def(Attr, Anno, TypeName, PatField, Args, State) -> State. %% Attr :: 'type' | 'opaque' %% Checks that a type definition is valid. -dialyzer({no_match, type_def/6}). -type_def(Attr, Line, TypeName, ProtoType, Args, St0) -> +type_def(Attr, Anno, TypeName, ProtoType, Args, St0) -> TypeDefs = St0#lint.types, Arity = length(Args), TypePair = {TypeName, Arity}, - Info = #typeinfo{attr = Attr, line = Line}, + Info = #typeinfo{attr = Attr, anno = Anno}, StoreType = fun(St) -> NewDefs = maps:put(TypePair, Info, TypeDefs), @@ -2881,16 +2872,16 @@ type_def(Attr, Line, TypeName, ProtoType, Args, St0) -> %% allow some types just for bootstrapping true -> Warn = {new_builtin_type, TypePair}, - St1 = add_warning(Line, Warn, St0), + St1 = add_warning(Anno, Warn, St0), StoreType(St1); false -> - add_error(Line, {builtin_type, TypePair}, St0) + add_error(Anno, {builtin_type, TypePair}, St0) end end; false -> case is_map_key(TypePair, TypeDefs) of true -> - add_error(Line, {redefine_type, TypePair}, St0); + add_error(Anno, {redefine_type, TypePair}, St0); false -> St1 = case Attr =:= opaque andalso @@ -2898,7 +2889,7 @@ type_def(Attr, Line, TypeName, ProtoType, Args, St0) -> of true -> Warn = {underspecified_opaque, TypePair}, - add_warning(Line, Warn, St0); + add_warning(Anno, Warn, St0); false -> St0 end, StoreType(St1) @@ -2911,89 +2902,89 @@ is_underspecified(_ProtType, _Arity) -> false. check_type(Types, St) -> {SeenVars, St1} = check_type(Types, maps:new(), St), - maps:fold(fun(Var, {seen_once, Line}, AccSt) -> + maps:fold(fun(Var, {seen_once, Anno}, AccSt) -> case atom_to_list(Var) of "_"++_ -> AccSt; - _ -> add_error(Line, {singleton_typevar, Var}, AccSt) + _ -> add_error(Anno, {singleton_typevar, Var}, AccSt) end; (_Var, seen_multiple, AccSt) -> AccSt end, St1, SeenVars). -check_type({ann_type, _L, [_Var, Type]}, SeenVars, St) -> +check_type({ann_type, _A, [_Var, Type]}, SeenVars, St) -> check_type(Type, SeenVars, St); -check_type({remote_type, L, [{atom, _, Mod}, {atom, _, Name}, Args]}, +check_type({remote_type, A, [{atom, _, Mod}, {atom, _, Name}, Args]}, SeenVars, St00) -> - St0 = check_module_name(Mod, L, St00), - St = deprecated_type(L, Mod, Name, Args, St0), + St0 = check_module_name(Mod, A, St00), + St = deprecated_type(A, Mod, Name, Args, St0), CurrentMod = St#lint.module, case Mod =:= CurrentMod of - true -> check_type({user_type, L, Name, Args}, SeenVars, St); + true -> check_type({user_type, A, Name, Args}, SeenVars, St); false -> lists:foldl(fun(T, {AccSeenVars, AccSt}) -> check_type(T, AccSeenVars, AccSt) end, {SeenVars, St}, Args) end; -check_type({integer, _L, _}, SeenVars, St) -> {SeenVars, St}; -check_type({atom, _L, _}, SeenVars, St) -> {SeenVars, St}; -check_type({var, _L, '_'}, SeenVars, St) -> {SeenVars, St}; -check_type({var, L, Name}, SeenVars, St) -> +check_type({integer, _A, _}, SeenVars, St) -> {SeenVars, St}; +check_type({atom, _A, _}, SeenVars, St) -> {SeenVars, St}; +check_type({var, _A, '_'}, SeenVars, St) -> {SeenVars, St}; +check_type({var, A, Name}, SeenVars, St) -> NewSeenVars = case maps:find(Name, SeenVars) of {ok, {seen_once, _}} -> maps:put(Name, seen_multiple, SeenVars); {ok, seen_multiple} -> SeenVars; - error -> maps:put(Name, {seen_once, L}, SeenVars) + error -> maps:put(Name, {seen_once, A}, SeenVars) end, {NewSeenVars, St}; -check_type({type, L, bool, []}, SeenVars, St) -> - {SeenVars, add_warning(L, {renamed_type, bool, boolean}, St)}; -check_type({type, L, 'fun', [Dom, Range]}, SeenVars, St) -> +check_type({type, A, bool, []}, SeenVars, St) -> + {SeenVars, add_warning(A, {renamed_type, bool, boolean}, St)}; +check_type({type, A, 'fun', [Dom, Range]}, SeenVars, St) -> St1 = case Dom of {type, _, product, _} -> St; {type, _, any} -> St; - _ -> add_error(L, {type_syntax, 'fun'}, St) + _ -> add_error(A, {type_syntax, 'fun'}, St) end, check_type({type, nowarn(), product, [Dom, Range]}, SeenVars, St1); -check_type({type, L, range, [From, To]}, SeenVars, St) -> +check_type({type, A, range, [From, To]}, SeenVars, St) -> St1 = case {erl_eval:partial_eval(From), erl_eval:partial_eval(To)} of {{integer, _, X}, {integer, _, Y}} when X < Y -> St; - _ -> add_error(L, {type_syntax, range}, St) + _ -> add_error(A, {type_syntax, range}, St) end, {SeenVars, St1}; -check_type({type, _L, map, any}, SeenVars, St) -> +check_type({type, _A, map, any}, SeenVars, St) -> {SeenVars, St}; -check_type({type, _L, map, Pairs}, SeenVars, St) -> +check_type({type, _A, map, Pairs}, SeenVars, St) -> lists:foldl(fun(Pair, {AccSeenVars, AccSt}) -> check_type(Pair, AccSeenVars, AccSt) end, {SeenVars, St}, Pairs); -check_type({type, _L, map_field_assoc, [Dom, Range]}, SeenVars, St) -> +check_type({type, _A, map_field_assoc, [Dom, Range]}, SeenVars, St) -> check_type({type, nowarn(), product, [Dom, Range]}, SeenVars, St); -check_type({type, _L, tuple, any}, SeenVars, St) -> {SeenVars, St}; -check_type({type, _L, any}, SeenVars, St) -> {SeenVars, St}; -check_type({type, L, binary, [Base, Unit]}, SeenVars, St) -> +check_type({type, _A, tuple, any}, SeenVars, St) -> {SeenVars, St}; +check_type({type, _A, any}, SeenVars, St) -> {SeenVars, St}; +check_type({type, A, binary, [Base, Unit]}, SeenVars, St) -> St1 = case {erl_eval:partial_eval(Base), erl_eval:partial_eval(Unit)} of {{integer, _, BaseVal}, {integer, _, UnitVal}} when BaseVal >= 0, UnitVal >= 0 -> St; - _ -> add_error(L, {type_syntax, binary}, St) + _ -> add_error(A, {type_syntax, binary}, St) end, {SeenVars, St1}; -check_type({type, L, record, [Name|Fields]}, SeenVars, St) -> +check_type({type, A, record, [Name|Fields]}, SeenVars, St) -> case Name of {atom, _, Atom} -> St1 = used_record(Atom, St), - check_record_types(L, Atom, Fields, SeenVars, St1); - _ -> {SeenVars, add_error(L, {type_syntax, record}, St)} + check_record_types(A, Atom, Fields, SeenVars, St1); + _ -> {SeenVars, add_error(A, {type_syntax, record}, St)} end; -check_type({type, _L, Tag, Args}, SeenVars, St) when Tag =:= product; +check_type({type, _A, Tag, Args}, SeenVars, St) when Tag =:= product; Tag =:= union; Tag =:= tuple -> lists:foldl(fun(T, {AccSeenVars, AccSt}) -> check_type(T, AccSeenVars, AccSt) end, {SeenVars, St}, Args); -check_type({type, La, TypeName, Args}, SeenVars, St) -> +check_type({type, Anno, TypeName, Args}, SeenVars, St) -> #lint{module = Module, types=Types} = St, Arity = length(Args), TypePair = {TypeName, Arity}, @@ -3003,20 +2994,20 @@ check_type({type, La, TypeName, Args}, SeenVars, St) -> {deprecated, Repl, _} when element(1, Repl) =/= Module -> case maps:find(TypePair, Types) of {ok, _} -> - used_type(TypePair, La, St); + used_type(TypePair, Anno, St); error -> {deprecated, Replacement, Rel} = Obsolete, Tag = deprecated_builtin_type, W = {Tag, TypePair, Replacement, Rel}, - add_warning(La, W, St) + add_warning(Anno, W, St) end; _ -> St end, check_type({type, nowarn(), product, Args}, SeenVars, St1); -check_type({user_type, L, TypeName, Args}, SeenVars, St) -> +check_type({user_type, A, TypeName, Args}, SeenVars, St) -> Arity = length(Args), TypePair = {TypeName, Arity}, - St1 = used_type(TypePair, L, St), + St1 = used_type(TypePair, A, St), lists:foldl(fun(T, {AccSeenVars, AccSt}) -> check_type(T, AccSeenVars, AccSt) end, {SeenVars, St1}, Args); @@ -3024,36 +3015,36 @@ check_type([{typed_record_field,Field,_T}|_], SeenVars, St) -> {SeenVars, add_error(element(2, Field), old_abstract_code, St)}; check_type(I, SeenVars, St) -> case erl_eval:partial_eval(I) of - {integer,_ILn,_Integer} -> {SeenVars, St}; + {integer,_A,_Integer} -> {SeenVars, St}; _Other -> {SeenVars, add_error(element(2, I), {type_syntax, integer}, St)} end. -check_record_types(Line, Name, Fields, SeenVars, St) -> +check_record_types(Anno, Name, Fields, SeenVars, St) -> case maps:find(Name, St#lint.records) of - {ok,{_L,DefFields}} -> + {ok,{_A,DefFields}} -> case lists:all(fun({type, _, field_type, _}) -> true; (_) -> false end, Fields) of true -> check_record_types(Fields, Name, DefFields, SeenVars, St, []); false -> - {SeenVars, add_error(Line, {type_syntax, record}, St)} + {SeenVars, add_error(Anno, {type_syntax, record}, St)} end; error -> - {SeenVars, add_error(Line, {undefined_record, Name}, St)} + {SeenVars, add_error(Anno, {undefined_record, Name}, St)} end. -check_record_types([{type, _, field_type, [{atom, AL, FName}, Type]}|Left], +check_record_types([{type, _, field_type, [{atom, Anno, FName}, Type]}|Left], Name, DefFields, SeenVars, St, SeenFields) -> %% Check that the field name is valid St1 = case exist_field(FName, DefFields) of true -> St; - false -> add_error(AL, {undefined_field, Name, FName}, St) + false -> add_error(Anno, {undefined_field, Name, FName}, St) end, %% Check for duplicates St2 = case ordsets:is_element(FName, SeenFields) of - true -> add_error(AL, {redefine_field, Name, FName}, St1); + true -> add_error(Anno, {redefine_field, Name, FName}, St1); false -> St1 end, %% Check Type @@ -3063,9 +3054,9 @@ check_record_types([{type, _, field_type, [{atom, AL, FName}, Type]}|Left], check_record_types([], _Name, _DefFields, SeenVars, St, _SeenFields) -> {SeenVars, St}. -used_type(TypePair, L, #lint{usage = Usage, file = File} = St) -> +used_type(TypePair, Anno, #lint{usage = Usage, file = File} = St) -> OldUsed = Usage#usage.used_types, - UsedTypes = maps:put(TypePair, erl_anno:set_file(File, L), OldUsed), + UsedTypes = maps:put(TypePair, erl_anno:set_file(File, Anno), OldUsed), St#lint{usage=Usage#usage{used_types=UsedTypes}}. is_default_type({Name, NumberOfTypeVariables}) -> @@ -3081,68 +3072,68 @@ obsolete_builtin_type({1, 255}) -> {deprecated, {2, 255}, ""}; obsolete_builtin_type({Name, A}) when is_atom(Name), is_integer(A) -> no. -%% spec_decl(Line, Fun, Types, State) -> State. +%% spec_decl(Anno, Fun, Types, State) -> State. -spec_decl(Line, MFA0, TypeSpecs, St00 = #lint{specs = Specs, module = Mod}) -> +spec_decl(Anno, MFA0, TypeSpecs, St00 = #lint{specs = Specs, module = Mod}) -> MFA = case MFA0 of {F, Arity} -> {Mod, F, Arity}; {_M, _F, Arity} -> MFA0 end, - St0 = check_module_name(element(1, MFA), Line, St00), - St1 = St0#lint{specs = maps:put(MFA, Line, Specs)}, + St0 = check_module_name(element(1, MFA), Anno, St00), + St1 = St0#lint{specs = maps:put(MFA, Anno, Specs)}, case is_map_key(MFA, Specs) of - true -> add_error(Line, {redefine_spec, MFA0}, St1); + true -> add_error(Anno, {redefine_spec, MFA0}, St1); false -> case MFA of {Mod, _, _} -> check_specs(TypeSpecs, spec_wrong_arity, Arity, St1); _ -> - add_error(Line, {bad_module, MFA}, St1) + add_error(Anno, {bad_module, MFA}, St1) end end. -%% callback_decl(Line, Fun, Types, State) -> State. +%% callback_decl(Anno, Fun, Types, State) -> State. -callback_decl(Line, MFA0, TypeSpecs, +callback_decl(Anno, MFA0, TypeSpecs, St0 = #lint{callbacks = Callbacks, module = Mod}) -> case MFA0 of {M, _F, _A} -> - St1 = check_module_name(M, Line, St0), - add_error(Line, {bad_callback, MFA0}, St1); + St1 = check_module_name(M, Anno, St0), + add_error(Anno, {bad_callback, MFA0}, St1); {F, Arity} -> MFA = {Mod, F, Arity}, - St1 = St0#lint{callbacks = maps:put(MFA, Line, Callbacks)}, + St1 = St0#lint{callbacks = maps:put(MFA, Anno, Callbacks)}, case is_map_key(MFA, Callbacks) of - true -> add_error(Line, {redefine_callback, MFA0}, St1); + true -> add_error(Anno, {redefine_callback, MFA0}, St1); false -> check_specs(TypeSpecs, callback_wrong_arity, Arity, St1) end end. -%% optional_callbacks(Line, FAs, State) -> State. +%% optional_callbacks(Anno, FAs, State) -> State. -optional_callbacks(Line, Term, St0) -> +optional_callbacks(Anno, Term, St0) -> try true = is_fa_list(Term), Term of FAs -> - optional_cbs(Line, FAs, St0) + optional_cbs(Anno, FAs, St0) catch _:_ -> St0 % ignore others end. -optional_cbs(_Line, [], St) -> +optional_cbs(_Anno, [], St) -> St; -optional_cbs(Line, [{F,A}|FAs], St0) -> +optional_cbs(Anno, [{F,A}|FAs], St0) -> #lint{optional_callbacks = OptionalCbs, module = Mod} = St0, MFA = {Mod, F, A}, - St1 = St0#lint{optional_callbacks = maps:put(MFA, Line, OptionalCbs)}, + St1 = St0#lint{optional_callbacks = maps:put(MFA, Anno, OptionalCbs)}, St2 = case is_map_key(MFA, OptionalCbs) of true -> - add_error(Line, {redefine_optional_callback, {F,A}}, St1); + add_error(Anno, {redefine_optional_callback, {F,A}}, St1); false -> St1 end, - optional_cbs(Line, FAs, St2). + optional_cbs(Anno, FAs, St2). is_fa_list([E|L]) -> is_fa(E) andalso is_fa_list(L); is_fa_list([]) -> true; @@ -3152,11 +3143,11 @@ is_fa({FuncName, Arity}) when is_atom(FuncName), is_integer(Arity), Arity >= 0 -> true; is_fa(_) -> false. -check_module_name(M, Line, St) -> +check_module_name(M, Anno, St) -> case is_latin1_name(M) of true -> St; false -> - add_error(Line, non_latin1_module_unsupported, St) + add_error(Anno, non_latin1_module_unsupported, St) end. is_latin1_name(Name) -> @@ -3170,12 +3161,12 @@ check_specs([FunType|Left], ETag, Arity, St0) -> {FT, lists:append(Types0)}; {type, _, 'fun', _} = FT -> {FT, []} end, - {type, L, 'fun', [{type, _, product, D}, _]} = FunType1, + {type, A, 'fun', [{type, _, product, D}, _]} = FunType1, SpecArity = length(D), St1 = case Arity =:= SpecArity of true -> St0; false -> %% Cannot happen if called from the compiler. - add_error(L, ETag, St0) + add_error(A, ETag, St0) end, St2 = check_type({type, nowarn(), product, [FunType1|CTypes]}, St1), check_specs(Left, ETag, Arity, St2); @@ -3188,13 +3179,13 @@ nowarn() -> erl_anno:set_file("", A1). check_specs_without_function(#lint{module=Mod,defined=Funcs,specs=Specs}=St) -> - Fun = fun({M, F, A}, Line, AccSt) when M =:= Mod -> + Fun = fun({M, F, A}, Anno, AccSt) when M =:= Mod -> FA = {F, A}, case gb_sets:is_element(FA, Funcs) of true -> AccSt; - false -> add_error(Line, {spec_fun_undefined, FA}, AccSt) + false -> add_error(Anno, {spec_fun_undefined, FA}, AccSt) end; - ({_M, _F, _A}, _Line, AccSt) -> AccSt + ({_M, _F, _A}, _Anno, AccSt) -> AccSt end, maps:fold(Fun, St, Specs). @@ -3218,16 +3209,16 @@ add_missing_spec_warnings(Forms, St0, Type) -> Warns = %% functions + line numbers for which we should warn case Type of all -> - [{FA,L} || {function,L,F,A,_} <- Forms, + [{FA,Anno} || {function,Anno,F,A,_} <- Forms, not lists:member(FA = {F,A}, Specs)]; exported -> Exps0 = gb_sets:to_list(St0#lint.exports) -- pseudolocals(), Exps = Exps0 -- Specs, - [{FA,L} || {function,L,F,A,_} <- Forms, + [{FA,Anno} || {function,Anno,F,A,_} <- Forms, member(FA = {F,A}, Exps)] end, - foldl(fun ({FA,L}, St) -> - add_warning(L, {missing_spec,FA}, St) + foldl(fun ({FA,Anno}, St) -> + add_warning(Anno, {missing_spec,FA}, St) end, St0, Warns). check_unused_types(Forms, St) -> @@ -3237,7 +3228,7 @@ check_unused_types(Forms, St) -> end. check_unused_types_1(Forms, #lint{usage=Usage, types=Ts, exp_types=ExpTs}=St) -> - case [File || {attribute,_L,file,{File,_Line}} <- Forms] of + case [File || {attribute,_A,file,{File,_Anno}} <- Forms] of [FirstFile|_] -> D = Usage#usage.used_types, L = gb_sets:to_list(ExpTs) ++ maps:keys(D), @@ -3245,14 +3236,14 @@ check_unused_types_1(Forms, #lint{usage=Usage, types=Ts, exp_types=ExpTs}=St) -> FoldFun = fun({{record, _}=_Type, 0}, _, AccSt) -> AccSt; % Before Erlang/OTP 19.0 - (Type, #typeinfo{line = FileLine}, AccSt) -> - case loc(FileLine, AccSt) of + (Type, #typeinfo{anno = Anno}, AccSt) -> + case loc(Anno, AccSt) of {FirstFile, _} -> case gb_sets:is_member(Type, UsedTypes) of true -> AccSt; false -> Warn = {unused_type,Type}, - add_warning(FileLine, Warn, AccSt) + add_warning(Anno, Warn, AccSt) end; _ -> %% No warns about unused types in include files @@ -3269,19 +3260,19 @@ check_local_opaque_types(St) -> FoldFun = fun(_Type, #typeinfo{attr = type}, AccSt) -> AccSt; - (Type, #typeinfo{attr = opaque, line = FileLine}, AccSt) -> + (Type, #typeinfo{attr = opaque, anno = Anno}, AccSt) -> case gb_sets:is_element(Type, ExpTs) of true -> AccSt; false -> Warn = {not_exported_opaque,Type}, - add_warning(FileLine, Warn, AccSt) + add_warning(Anno, Warn, AccSt) end end, maps:fold(FoldFun, St, Ts). check_dialyzer_attribute(Forms, St0) -> - Vals = [{L,V} || - {attribute,L,dialyzer,Val} <- Forms, + Vals = [{Anno,V} || + {attribute,Anno,dialyzer,Val} <- Forms, V0 <- lists:flatten([Val]), V <- case V0 of {O,F} -> @@ -3296,26 +3287,26 @@ check_dialyzer_attribute(Forms, St0) -> ({_,Option}) when is_atom(Option) -> true; (_) -> false end, Vals), - St1 = foldl(fun ({L,Term}, St) -> - add_error(L, {bad_dialyzer_attribute,Term}, St) + St1 = foldl(fun ({Anno,Term}, St) -> + add_error(Anno, {bad_dialyzer_attribute,Term}, St) end, St0, Bad), DefFunctions = (gb_sets:to_list(St0#lint.defined) -- pseudolocals()), - Fun = fun ({L,{Option,FA}}, St) -> + Fun = fun ({Anno,{Option,FA}}, St) -> case is_function_dialyzer_option(Option) of true -> case lists:member(FA, DefFunctions) of true -> St; false -> - add_error(L, {undefined_function,FA}, St) + add_error(Anno, {undefined_function,FA}, St) end; false -> - add_error(L, {bad_dialyzer_option,Option}, St) + add_error(Anno, {bad_dialyzer_option,Option}, St) end; - ({L,Option}, St) -> + ({Anno,Option}, St) -> case is_module_dialyzer_option(Option) of true -> St; false -> - add_error(L, {bad_dialyzer_option,Option}, St) + add_error(Anno, {bad_dialyzer_option,Option}, St) end end, foldl(Fun, St1, Wellformed). @@ -3356,7 +3347,7 @@ icrt_clauses(Cs, In, Vt, St0) -> icrt_clauses(Cs, Vt, St) -> mapfoldl(fun (C, St0) -> icrt_clause(C, Vt, St0) end, St, Cs). -icrt_clause({clause,_Line,H,G,B}, Vt0, St0) -> +icrt_clause({clause,_Anno,H,G,B}, Vt0, St0) -> {Hvt,Hnew,St1} = head(H, Vt0, St0), Vt1 = vtupdate(Hvt, Hnew), {Gvt,St2} = guard(G, vtupdate(Vt1, Vt0), St1), @@ -3367,7 +3358,7 @@ icrt_clause({clause,_Line,H,G,B}, Vt0, St0) -> catch_clauses(Cs, Vt, St) -> mapfoldl(fun(C, St0) -> catch_clause(C, Vt, St0) end, St, Cs). -catch_clause({clause,_Line,H,G,B}, Vt0, St0) -> +catch_clause({clause,_Anno,H,G,B}, Vt0, St0) -> [{tuple,_,[_,_,Stack]}] = H, {Hvt,Hnew,St1} = head(H, Vt0, St0), Vt1 = vtupdate(Hvt, Hnew), @@ -3378,17 +3369,17 @@ catch_clause({clause,_Line,H,G,B}, Vt0, St0) -> {Bvt,St4} = exprs(B, vtupdate(Vt2, Vt0), St3), {vtupdate(Bvt, Vt2),St4}. -taint_stack_var({var,L,V}, Vt, St) when V =/= '_' -> +taint_stack_var({var,Anno,V}, Vt, St) when V =/= '_' -> St1 = case orddict:find(V, Vt) of {ok,{_,used,_}} -> %% the stack var must be unused after processing the pattern; %% it can be used either if bound/unsafe before the try, or %% if it occurs in the class or term part of the pattern - add_error(L, {stacktrace_bound,V}, St); + add_error(Anno, {stacktrace_bound,V}, St); _ -> St end, - {vtupdate([{V,{stacktrace,unused,[L]}}], Vt), St1}; + {vtupdate([{V,{stacktrace,unused,[Anno]}}], Vt), St1}; taint_stack_var(_, Vt, St) -> {Vt, St}. @@ -3396,28 +3387,28 @@ icrt_export(Vts, Vt, {Tag,Attrs}, St) -> {_File,Loc} = loc(Attrs, St), icrt_export(lists:merge(Vts), Vt, {Tag,Loc}, length(Vts), []). -icrt_export([{V,{{export,_},_,_}}|Vs0], [{V,{{export,_}=S0,_,Ls}}|Vt], +icrt_export([{V,{{export,_},_,_}}|Vs0], [{V,{{export,_}=S0,_,As}}|Vt], In, I, Acc) -> %% V was an exported variable and has been used in an expression in at least %% one clause. Its state needs to be merged from all clauses to silence any %% exported var warning already emitted. {VVs,Vs} = lists:partition(fun ({K,_}) -> K =:= V end, Vs0), S = foldl(fun ({_,{S1,_,_}}, AccS) -> merge_state(AccS, S1) end, S0, VVs), - icrt_export(Vs, Vt, In, I, [{V,{S,used,Ls}}|Acc]); -icrt_export([{V,_}|Vs0], [{V,{_,_,Ls}}|Vt], In, I, Acc) -> + icrt_export(Vs, Vt, In, I, [{V,{S,used,As}}|Acc]); +icrt_export([{V,_}|Vs0], [{V,{_,_,As}}|Vt], In, I, Acc) -> %% V was either unsafe or bound and has now been reused. It may also have %% been an export but as it was not matched by the previous clause, it means %% it has been changed to 'bound' in at least one clause because it was used %% in a pattern. Vs = lists:dropwhile(fun ({K,_}) -> K =:= V end, Vs0), - icrt_export(Vs, Vt, In, I, [{V,{bound,used,Ls}}|Acc]); + icrt_export(Vs, Vt, In, I, [{V,{bound,used,As}}|Acc]); icrt_export([{V1,_}|_]=Vs, [{V2,_}|Vt], In, I, Acc) when V1 > V2 -> %% V2 was already in scope and has not been reused in any clause. icrt_export(Vs, Vt, In, I, Acc); icrt_export([{V,_}|_]=Vs0, Vt, In, I, Acc) -> %% V is a new variable. {VVs,Vs} = lists:partition(fun ({K,_}) -> K =:= V end, Vs0), - F = fun ({_,{S,U,Ls}}, {AccI,AccS0,AccLs0}) -> + F = fun ({_,{S,U,As}}, {AccI,AccS0,AccAs0}) -> AccS = case {S,AccS0} of {{unsafe,_},{unsafe,_}} -> %% V was found unsafe in a previous clause, mark @@ -3433,14 +3424,14 @@ icrt_export([{V,_}|_]=Vs0, Vt, In, I, Acc) -> %% state. AccS0 end, - AccLs = case U of - used -> AccLs0; - unused -> merge_lines(AccLs0, Ls) + AccAs = case U of + used -> AccAs0; + unused -> merge_annos(AccAs0, As) end, - {AccI + 1,AccS,AccLs} + {AccI + 1,AccS,AccAs} end, %% Initial state is exported from the current expression. - {Count,S1,Ls} = foldl(F, {0,{export,In},[]}, VVs), + {Count,S1,As} = foldl(F, {0,{export,In},[]}, VVs), S = case Count of I -> %% V was found in all clauses, keep computed state. @@ -3449,8 +3440,8 @@ icrt_export([{V,_}|_]=Vs0, Vt, In, I, Acc) -> %% V was not bound in some clauses, mark as unsafe. {unsafe,In} end, - U = case Ls of [] -> used; _ -> unused end, - icrt_export(Vs, Vt, In, I, [{V,{S,U,Ls}}|Acc]); + U = case As of [] -> used; _ -> unused end, + icrt_export(Vs, Vt, In, I, [{V,{S,U,As}}|Acc]); icrt_export([], _, _, _, Acc) -> reverse(Acc). @@ -3489,10 +3480,10 @@ lc_quals(Qs, Vt0, St0) -> {Vt,Uvt,St} = lc_quals(Qs, Vt0, [], St0#lint{recdef_top = false}), {Vt,Uvt,St#lint{recdef_top = OldRecDef}}. -lc_quals([{generate,_Line,P,E} | Qs], Vt0, Uvt0, St0) -> +lc_quals([{generate,_Anno,P,E} | Qs], Vt0, Uvt0, St0) -> {Vt,Uvt,St} = handle_generator(P,E,Vt0,Uvt0,St0), lc_quals(Qs, Vt, Uvt, St); -lc_quals([{b_generate,_Line,P,E} | Qs], Vt0, Uvt0, St0) -> +lc_quals([{b_generate,_Anno,P,E} | Qs], Vt0, Uvt0, St0) -> St1 = handle_bitstring_gen_pat(P,St0), {Vt,Uvt,St} = handle_generator(P,E,Vt0,Uvt0,St1), lc_quals(Qs, Vt, Uvt, St); @@ -3531,11 +3522,11 @@ handle_generator(P,E,Vt,Uvt,St0) -> handle_bitstring_gen_pat({bin,_,Segments=[_|_]},St) -> case lists:last(Segments) of - {bin_element,Line,_,default,Flags} when is_list(Flags) -> + {bin_element,Anno,_,default,Flags} when is_list(Flags) -> case member(binary, Flags) orelse member(bytes, Flags) orelse member(bits, Flags) orelse member(bitstring, Flags) of true -> - add_error(Line, unsized_binary_in_bin_gen_pattern, St); + add_error(Anno, unsized_binary_in_bin_gen_pattern, St); false -> St end; @@ -3562,7 +3553,7 @@ fun_clauses(Cs, Vt, St) -> Uvt = vt_no_unsafe(vt_no_unused(vtold(Bvt, Vt))), {Uvt,St2#lint{recdef_top = OldRecDef}}. -fun_clause({clause,_Line,H,G,B}, Vt0, St0) -> +fun_clause({clause,_Anno,H,G,B}, Vt0, St0) -> {Hvt,Hnew,St1} = head(H, Vt0, [], St0), % No imported pattern variables Vt1 = vtupdate(Hvt, Vt0), St2 = shadow_vars(Hnew, Vt0, 'fun', St1), @@ -3580,7 +3571,7 @@ fun_clause({clause,_Line,H,G,B}, Vt0, St0) -> {vtold(Vt4, Vt0),St6}. %% In the variable table we store information about variables. The -%% information is a tuple {State,Usage,Lines}, the variables state and +%% information is a tuple {State,Usage,Annos}, the variables state and %% usage. A variable can be in the following states: %% %% bound everything is normal @@ -3592,7 +3583,8 @@ fun_clause({clause,_Line,H,G,B}, Vt0, St0) -> %% used variable has been used %% unused variable has been bound but not used %% -%% Lines is a list of line numbers where the variable was bound. +%% Annos is a list of annotations including the location where the +%% variable was bound. %% %% Report variable errors/warnings as soon as possible and then change %% the state to ok. This simplifies the code and reports errors only @@ -3601,8 +3593,8 @@ fun_clause({clause,_Line,H,G,B}, Vt0, St0) -> %% For keeping track of which variables are bound, ordsets are used. %% In order to be able to give warnings about unused variables, a -%% possible value is {bound, unused, [Line]}. The usual value when a -%% variable is used is {bound, used, [Line]}. An exception occurs for +%% possible value is {bound, unused, [Anno]}. The usual value when a +%% variable is used is {bound, used, [Anno]}. An exception occurs for %% variables in the size position in a bin element in a pattern. %% Currently, such a variable is never matched out, always used, and %% therefore it makes no sense to warn for "variable imported in @@ -3611,66 +3603,66 @@ fun_clause({clause,_Line,H,G,B}, Vt0, St0) -> %% For storing the variable table we use the orddict module. %% We know an empty set is []. -%% pat_var(Variable, LineNo, VarTable, NewVars, State) -> +%% pat_var(Variable, Anno, VarTable, NewVars, State) -> %% {UpdVarTable,UpdNewVars,State} %% A pattern variable has been found. Handle errors and warnings. Return %% all used variables as bound so errors and warnings are only reported %% once. New shadows Vt here, which is necessary in order to separate %% uses of shadowed and shadowing variables. See also pat_binsize_var. -pat_var(V, Line, Vt, New, St) -> +pat_var(V, Anno, Vt, New, St) -> case orddict:find(V, New) of - {ok, {bound,_Usage,Ls}} -> + {ok, {bound,_Usage,As}} -> %% variable already in NewVars, mark as used - {[],[{V,{bound,used,Ls}}],St}; + {[],[{V,{bound,used,As}}],St}; error -> case orddict:find(V, Vt) of - {ok,{bound,_Usage,Ls}} -> - {[{V,{bound,used,Ls}}],[],St}; - {ok,{{unsafe,In},_Usage,Ls}} -> - {[{V,{bound,used,Ls}}],[], - add_error(Line, {unsafe_var,V,In}, St)}; - {ok,{{export,From},_Usage,Ls}} -> - {[{V,{bound,used,Ls}}],[], + {ok,{bound,_Usage,As}} -> + {[{V,{bound,used,As}}],[],St}; + {ok,{{unsafe,In},_Usage,As}} -> + {[{V,{bound,used,As}}],[], + add_error(Anno, {unsafe_var,V,In}, St)}; + {ok,{{export,From},_Usage,As}} -> + {[{V,{bound,used,As}}],[], %% As this is matching, exported vars are risky. - add_warning(Line, {exported_var,V,From}, St)}; + add_warning(Anno, {exported_var,V,From}, St)}; error when St#lint.recdef_top -> - {[],[{V,{bound,unused,[Line]}}], - add_error(Line, {variable_in_record_def,V}, St)}; + {[],[{V,{bound,unused,[Anno]}}], + add_error(Anno, {variable_in_record_def,V}, St)}; error -> %% add variable to NewVars, not yet used - {[],[{V,{bound,unused,[Line]}}],St} + {[],[{V,{bound,unused,[Anno]}}],St} end end. -%% pat_binsize_var(Variable, LineNo, VarTable, NewVars, State) -> +%% pat_binsize_var(Variable, Anno, VarTable, NewVars, State) -> %% {UpdVarTable,UpdNewVars,State'} %% Special case of pat_var/expr_var for variables in binary size expressions %% (never adds variables to NewVars, only marks uses). -pat_binsize_var(V, Line, Vt, New, St) -> +pat_binsize_var(V, Anno, Vt, New, St) -> case orddict:find(V, New) of - {ok,{bound,_Used,Ls}} -> - {[],[{V,{bound,used,Ls}}],St}; + {ok,{bound,_Used,As}} -> + {[],[{V,{bound,used,As}}],St}; error -> case orddict:find(V, Vt) of - {ok,{bound,_Used,Ls}} -> - {[{V,{bound,used,Ls}}],[],St}; - {ok,{{unsafe,In},_Used,Ls}} -> - {[{V,{bound,used,Ls}}],[], - add_error(Line, {unsafe_var,V,In}, St)}; - {ok,{{export,From},_Used,Ls}} -> - {[{V,{bound,used,Ls}}],[], + {ok,{bound,_Used,As}} -> + {[{V,{bound,used,As}}],[],St}; + {ok,{{unsafe,In},_Used,As}} -> + {[{V,{bound,used,As}}],[], + add_error(Anno, {unsafe_var,V,In}, St)}; + {ok,{{export,From},_Used,As}} -> + {[{V,{bound,used,As}}],[], %% As this is not matching, exported vars are %% probably safe. - exported_var(Line, V, From, St)}; + exported_var(Anno, V, From, St)}; error -> - {[{V,{bound,used,[Line]}}],[], - add_error(Line, {unbound_var,V}, St)} + {[{V,{bound,used,[Anno]}}],[], + add_error(Anno, {unbound_var,V}, St)} end end. -%% expr_var(Variable, LineNo, VarTable, State) -> +%% expr_var(Variable, Anno, VarTable, State) -> %% {UpdVarTable,State} %% Check if a variable is defined, or if there is an error or warning %% connected to its usage. Return all variables as bound so errors @@ -3678,47 +3670,47 @@ pat_binsize_var(V, Line, Vt, New, St) -> %% exported vars are probably safe, warn only if warn_export_vars is %% set. -expr_var(V, Line, Vt, #lint{bvt=none}=St) -> - do_expr_var(V, Line, Vt, St); -expr_var(V, Line, Vt0, #lint{bvt=Bvt0}=St0) when is_list(Bvt0) -> +expr_var(V, Anno, Vt, #lint{bvt=none}=St) -> + do_expr_var(V, Anno, Vt, St); +expr_var(V, Anno, Vt0, #lint{bvt=Bvt0}=St0) when is_list(Bvt0) -> %% handles variables in a binary segment size expression - {Vt,Bvt,St} = pat_binsize_var(V, Line, Vt0, Bvt0, St0), + {Vt,Bvt,St} = pat_binsize_var(V, Anno, Vt0, Bvt0, St0), {Vt,St#lint{bvt=vtmerge(Bvt0, Bvt)}}. -do_expr_var(V, Line, Vt, St) -> +do_expr_var(V, Anno, Vt, St) -> case orddict:find(V, Vt) of - {ok,{bound,_Usage,Ls}} -> - {[{V,{bound,used,Ls}}],St}; - {ok,{{unsafe,In},_Usage,Ls}} -> - {[{V,{bound,used,Ls}}], - add_error(Line, {unsafe_var,V,In}, St)}; - {ok,{{export,From},_Usage,Ls}} -> + {ok,{bound,_Usage,As}} -> + {[{V,{bound,used,As}}],St}; + {ok,{{unsafe,In},_Usage,As}} -> + {[{V,{bound,used,As}}], + add_error(Anno, {unsafe_var,V,In}, St)}; + {ok,{{export,From},_Usage,As}} -> case is_warn_enabled(export_vars, St) of true -> - {[{V,{bound,used,Ls}}], - add_warning(Line, {exported_var,V,From}, St)}; + {[{V,{bound,used,As}}], + add_warning(Anno, {exported_var,V,From}, St)}; false -> - {[{V,{{export,From},used,Ls}}],St} + {[{V,{{export,From},used,As}}],St} end; - {ok,{stacktrace,_Usage,Ls}} -> - {[{V,{bound,used,Ls}}], - add_error(Line, {stacktrace_guard,V}, St)}; + {ok,{stacktrace,_Usage,As}} -> + {[{V,{bound,used,As}}], + add_error(Anno, {stacktrace_guard,V}, St)}; error -> - {[{V,{bound,used,[Line]}}], - add_error(Line, {unbound_var,V}, St)} + {[{V,{bound,used,[Anno]}}], + add_error(Anno, {unbound_var,V}, St)} end. -exported_var(Line, V, From, St) -> +exported_var(Anno, V, From, St) -> case is_warn_enabled(export_vars, St) of - true -> add_warning(Line, {exported_var,V,From}, St); + true -> add_warning(Anno, {exported_var,V,From}, St); false -> St end. shadow_vars(Vt, Vt0, In, St0) -> case is_warn_enabled(shadow_vars, St0) of true -> - foldl(fun ({V,{_,_,[L | _]}}, St) -> - add_warning(L, {shadowed_var,V,In}, St); + foldl(fun ({V,{_,_,[A | _]}}, St) -> + add_warning(A, {shadowed_var,V,In}, St); (_, St) -> St end, St0, vtold(Vt, vt_no_unsafe(Vt0))); false -> St0 @@ -3733,7 +3725,7 @@ check_old_unused_vars(Vt, Vt0, St0) -> warn_unused_vars(U, Vt, St0). unused_vars(Vt, Vt0, _St0) -> - U0 = orddict:filter(fun (V, {_State,unused,_Ls}) -> + U0 = orddict:filter(fun (V, {_State,unused,_As}) -> case atom_to_list(V) of "_"++_ -> false; _ -> true @@ -3748,15 +3740,15 @@ warn_unused_vars(U, Vt, St0) -> St1 = case is_warn_enabled(unused_vars, St0) of false -> St0; true -> - foldl(fun ({V,{_,unused,Ls}}, St) -> - foldl(fun (L, St2) -> - add_warning(L, {unused_var,V}, + foldl(fun ({V,{_,unused,As}}, St) -> + foldl(fun (A, St2) -> + add_warning(A, {unused_var,V}, St2) - end, St, Ls) + end, St, As) end, St0, U) end, %% Return all variables as bound so warnings are only reported once. - UVt = map(fun ({V,{State,_,Ls}}) -> {V,{State,used,Ls}} end, U), + UVt = map(fun ({V,{State,_,As}}) -> {V,{State,used,As}} end, U), {vtmerge(Vt, UVt), St1}. @@ -3773,26 +3765,26 @@ is_var_bound(V, Vt) -> %% the variables in UpdVarTable will be returned. vtupdate(Uvt, Vt0) -> - orddict:merge(fun (_V, {S,U1,L1}, {_S,U2,L2}) -> - {S, merge_used(U1, U2), merge_lines(L1, L2)} + orddict:merge(fun (_V, {S,U1,A1}, {_S,U2,A2}) -> + {S, merge_used(U1, U2), merge_annos(A1, A2)} end, Uvt, Vt0). %% vtunsafe(From, UpdVarTable, VarTable) -> UnsafeVarTable. %% Return all new variables in UpdVarTable as unsafe. -vtunsafe({Tag,FileLine}, Uvt, Vt) -> - Line = erl_anno:location(FileLine), - [{V,{{unsafe,{Tag,Line}},U,Ls}} || {V,{_,U,Ls}} <- vtnew(Uvt, Vt)]. +vtunsafe({Tag,Anno}, Uvt, Vt) -> + Location = erl_anno:location(Anno), + [{V,{{unsafe,{Tag,Location}},U,As}} || {V,{_,U,As}} <- vtnew(Uvt, Vt)]. %% vtmerge(VarTable, VarTable) -> VarTable. %% Merge two variables tables generating a new vartable. Give priority to %% errors then warnings. vtmerge(Vt1, Vt2) -> - orddict:merge(fun (_V, {S1,U1,L1}, {S2,U2,L2}) -> + orddict:merge(fun (_V, {S1,U1,A1}, {S2,U2,A2}) -> {merge_state(S1, S2), merge_used(U1, U2), - merge_lines(L1, L2)} + merge_annos(A1, A2)} end, Vt1, Vt2). vtmerge(Vts) -> foldl(fun (Vt, Mvts) -> vtmerge(Vt, Mvts) end, [], Vts). @@ -3800,12 +3792,12 @@ vtmerge(Vts) -> foldl(fun (Vt, Mvts) -> vtmerge(Vt, Mvts) end, [], Vts). %% this version marks variables that exist in both tables as used %% (since that implies the compiler will add an equality check) vtmerge_pat(Vt1, Vt2) -> - orddict:merge(fun (_V, {S1,_Usage1,L1}, {S2,_Usage2,L2}) -> - {merge_state(S1, S2),used, merge_lines(L1, L2)} + orddict:merge(fun (_V, {S1,_Usage1,A1}, {S2,_Usage2,A2}) -> + {merge_state(S1, S2),used, merge_annos(A1, A2)} end, Vt1, Vt2). -merge_lines(Ls1, Ls2) -> - ordsets:union(Ls1,Ls2). +merge_annos(As1, As2) -> + ordsets:union(As1,As2). merge_state({unsafe,_F1}=S1, _S2) -> S1; %Take the error case merge_state(_S1, {unsafe,_F2}=S2) -> S2; @@ -3837,16 +3829,16 @@ vtsubtract(New, Old) -> vtold(New, Old) -> orddict:filter(fun (V, _How) -> orddict:is_key(V, Old) end, New). -vt_no_unsafe(Vt) -> [V || {_,{S,_U,_L}}=V <- Vt, +vt_no_unsafe(Vt) -> [V || {_,{S,_U,_A}}=V <- Vt, case S of {unsafe,_} -> false; _ -> true end]. -vt_no_unused(Vt) -> [V || {_,{_,U,_L}}=V <- Vt, U =/= unused]. +vt_no_unused(Vt) -> [V || {_,{_,U,_A}}=V <- Vt, U =/= unused]. -%% copy_expr(Expr, Line) -> Expr. -%% Make a copy of Expr converting all line numbers to Line. +%% copy_expr(Expr, Anno) -> Expr. +%% Make a copy of Expr converting all annotations numbers to Anno. copy_expr(Expr, Anno) -> erl_parse:map_anno(fun(_A) -> Anno end, Expr). @@ -3854,41 +3846,41 @@ copy_expr(Expr, Anno) -> %% Check a record_info call. We have already checked that it is not %% shadowed by an import. -check_record_info_call(_Line,La,[{atom,Li,Info},{atom,_Ln,Name}],St) -> +check_record_info_call(_Anno,Aa,[{atom,Ai,Info},{atom,_An,Name}],St) -> case member(Info, [fields,size]) of - true -> exist_record(La, Name, St); - false -> add_error(Li, illegal_record_info, St) + true -> exist_record(Aa, Name, St); + false -> add_error(Ai, illegal_record_info, St) end; -check_record_info_call(Line,_La,_As,St) -> - add_error(Line, illegal_record_info, St). +check_record_info_call(Anno,_Aa,_As,St) -> + add_error(Anno, illegal_record_info, St). -has_wildcard_field([{record_field,_Lf,{var,_La,'_'},_Val}|_Fs]) -> true; +has_wildcard_field([{record_field,_Af,{var,Aa,'_'},_Val}|_Fs]) -> Aa; has_wildcard_field([_|Fs]) -> has_wildcard_field(Fs); -has_wildcard_field([]) -> false. +has_wildcard_field([]) -> no. -%% check_remote_function(Line, ModuleName, FuncName, [Arg], State) -> State. +%% check_remote_function(Anno, ModuleName, FuncName, [Arg], State) -> State. %% Perform checks on known remote calls. -check_remote_function(Line, M, F, As, St0) -> - St1 = deprecated_function(Line, M, F, As, St0), - St2 = check_qlc_hrl(Line, M, F, As, St1), - St3 = check_load_nif(Line, M, F, As, St2), - format_function(Line, M, F, As, St3). +check_remote_function(Anno, M, F, As, St0) -> + St1 = deprecated_function(Anno, M, F, As, St0), + St2 = check_qlc_hrl(Anno, M, F, As, St1), + St3 = check_load_nif(Anno, M, F, As, St2), + format_function(Anno, M, F, As, St3). -%% check_load_nif(Line, ModName, FuncName, [Arg], State) -> State +%% check_load_nif(Anno, ModName, FuncName, [Arg], State) -> State %% Add warning if erlang:load_nif/2 is called when any kind of inlining has %% been enabled. -check_load_nif(Line, erlang, load_nif, [_, _], St) -> +check_load_nif(Anno, erlang, load_nif, [_, _], St) -> case is_warn_enabled(nif_inline, St) of - true -> check_nif_inline(Line, St); + true -> check_nif_inline(Anno, St); false -> St end; -check_load_nif(_Line, _ModName, _FuncName, _Args, St) -> +check_load_nif(_Anno, _ModName, _FuncName, _Args, St) -> St. -check_nif_inline(Line, St) -> +check_nif_inline(Anno, St) -> case any(fun is_inline_opt/1, St#lint.compile) of - true -> add_warning(Line, nif_inline, St); + true -> add_warning(Anno, nif_inline, St); false -> St end. @@ -3896,26 +3888,26 @@ is_inline_opt({inline, [_|_]=_FAs}) -> true; is_inline_opt(inline) -> true; is_inline_opt(_) -> false. -%% check_qlc_hrl(Line, ModName, FuncName, [Arg], State) -> State +%% check_qlc_hrl(Anno, ModName, FuncName, [Arg], State) -> State %% Add warning if qlc:q/1,2 has been called but qlc.hrl has not %% been included. -check_qlc_hrl(Line, M, F, As, St) -> +check_qlc_hrl(Anno, M, F, As, St) -> Arity = length(As), case As of - [{lc,_L,_E,_Qs}|_] when M =:= qlc, F =:= q, + [{lc,_A,_E,_Qs}|_] when M =:= qlc, F =:= q, Arity < 3, not St#lint.xqlc -> - add_warning(Line, {missing_qlc_hrl, Arity}, St); + add_warning(Anno, {missing_qlc_hrl, Arity}, St); _ -> St end. -%% deprecated_function(Line, ModName, FuncName, [Arg], State) -> State. +%% deprecated_function(Anno, ModName, FuncName, [Arg], State) -> State. %% Add warning for calls to deprecated functions. -dialyzer({no_match, deprecated_function/5}). -deprecated_function(Line, M, F, As, St) -> +deprecated_function(Anno, M, F, As, St) -> Arity = length(As), MFA = {M, F, Arity}, case otp_internal:obsolete(M, F, Arity) of @@ -3925,7 +3917,7 @@ deprecated_function(Line, M, F, As, St) -> true -> St; false -> - add_warning(Line, {deprecated, MFA, String}, St) + add_warning(Anno, {deprecated, MFA, String}, St) end; {deprecated, Replacement, Rel} -> case not is_warn_enabled(deprecated_function, St) orelse @@ -3933,86 +3925,88 @@ deprecated_function(Line, M, F, As, St) -> true -> St; false -> - add_warning(Line, {deprecated, MFA, Replacement, Rel}, St) + add_warning(Anno, {deprecated, MFA, Replacement, Rel}, St) end; {removed, String} when is_list(String) -> - add_removed_warning(Line, MFA, {removed, MFA, String}, St); + add_removed_warning(Anno, MFA, {removed, MFA, String}, St); {removed, Replacement, Rel} -> - add_removed_warning(Line, MFA, {removed, MFA, Replacement, Rel}, St); + add_removed_warning(Anno, MFA, {removed, MFA, Replacement, Rel}, St); no -> St end. -add_removed_warning(Line, {M, _, _}=MFA, Warning, #lint{not_removed=NotRemoved}=St) -> +add_removed_warning(Anno, {M, _, _}=MFA, Warning, #lint{not_removed=NotRemoved}=St) -> case is_warn_enabled(removed, St) andalso not gb_sets:is_element(M, NotRemoved) andalso not gb_sets:is_element(MFA, NotRemoved) of true -> - add_warning(Line, Warning, St); + add_warning(Anno, Warning, St); false -> St end. -dialyzer({no_match, deprecated_type/5}). -deprecated_type(L, M, N, As, St) -> +deprecated_type(Anno, M, N, As, St) -> NAs = length(As), case otp_internal:obsolete_type(M, N, NAs) of {deprecated, String} when is_list(String) -> case is_warn_enabled(deprecated_type, St) of true -> - add_warning(L, {deprecated_type, {M,N,NAs}, String}, St); + add_warning(Anno, {deprecated_type, {M,N,NAs}, String}, St); false -> St end; {removed, String} -> - add_warning(L, {removed_type, {M,N,NAs}, String}, St); + add_warning(Anno, {removed_type, {M,N,NAs}, String}, St); no -> St end. -obsolete_guard({call,Line,{atom,Lr,F},As}, St0) -> +obsolete_guard({call,Anno,{atom,Ar,F},As}, St0) -> Arity = length(As), case erl_internal:old_type_test(F, Arity) of false -> - deprecated_function(Line, erlang, F, As, St0); + deprecated_function(Anno, erlang, F, As, St0); true -> St = case is_warn_enabled(obsolete_guard, St0) of true -> - add_warning(Lr, {obsolete_guard, {F, Arity}}, St0); + add_warning(Ar, {obsolete_guard, {F, Arity}}, St0); false -> St0 end, - test_overriden_by_local(Lr, F, Arity, St) + test_overriden_by_local(Ar, F, Arity, St) end; obsolete_guard(_G, St) -> St. -test_overriden_by_local(Line, OldTest, Arity, St) -> +test_overriden_by_local(Anno, OldTest, Arity, St) -> ModernTest = list_to_atom("is_"++atom_to_list(OldTest)), case is_local_function(St#lint.locals, {ModernTest, Arity}) of true -> - add_error(Line, {obsolete_guard_overridden,OldTest}, St); + add_error(Anno, {obsolete_guard_overridden,OldTest}, St); false -> St end. -%% keyword_warning(Line, Atom, State) -> State. +%% keyword_warning(Anno, Atom, State) -> State. %% Add warning for atoms that will be reserved keywords in the future. %% (Currently, no such keywords to warn for.) -keyword_warning(_Line, _A, St) -> St. +keyword_warning(_Anno, _A, St) -> St. -%% format_function(Line, ModName, FuncName, [Arg], State) -> State. +%% format_function(Anno, ModName, FuncName, [Arg], State) -> State. %% Add warning for bad calls to io:fwrite/format functions. -format_function(Line, M, F, As, St) -> +format_function(DefAnno, M, F, As, St) -> case is_format_function(M, F) of true -> case St#lint.warn_format of Lev when Lev > 0 -> case check_format_1(As) of {warn,Level,Fmt,Fas} when Level =< Lev -> - add_warning(Line, {format_error,{Fmt,Fas}}, St); + add_warning(DefAnno, {format_error,{Fmt,Fas}}, St); + {warn,Level,Anno,Fmt,Fas} when Level =< Lev -> + add_warning(Anno, {format_error,{Fmt,Fas}}, St); _ -> St end; _Lev -> St @@ -4037,8 +4031,8 @@ check_format_1([_Dev,Fmt,As]) -> check_format_1(_As) -> {warn,1,"format call with wrong number of arguments",[]}. -canonicalize_string({string,Line,Cs}) -> - foldr(fun (C, T) -> {cons,Line,{integer,Line,C},T} end, {nil,Line}, Cs); +canonicalize_string({string,Anno,Cs}) -> + foldr(fun (C, T) -> {cons,Anno,{integer,Anno,C},T} end, {nil,Anno}, Cs); canonicalize_string(Term) -> Term. @@ -4046,43 +4040,52 @@ canonicalize_string(Term) -> check_format_2(Fmt, As) -> case Fmt of - {string,_L,S} -> check_format_2a(S, As); - {atom,_L,A} -> check_format_2a(atom_to_list(A), As); - _ -> {warn,2,"format string not a textual constant",[]} + {string,A,S} -> + check_format_2a(S, A, As); + {atom,A,Atom} -> + check_format_2a(atom_to_list(Atom), A, As); + _ -> + Anno = erl_parse:first_location(Fmt), + {warn,2,Anno,"format string not a textual constant",[]} end. -check_format_2a(Fmt, As) -> +check_format_2a(Fmt, FmtAnno, As) -> case args_list(As) of - true -> check_format_3(Fmt, As); - false -> {warn,1,"format arguments not a list",[]}; - maybe -> {warn,2,"format arguments perhaps not a list",[]} + true -> + check_format_3(Fmt, FmtAnno, As); + false -> + Anno = element(2, As), + {warn,1,Anno,"format arguments not a list",[]}; + maybe -> + Anno = erl_parse:first_location(As), + {warn,2,Anno,"format arguments perhaps not a list",[]} end. %% check_format_3(FormatString, [Arg]) -> ok | {warn,Level,Format,[Arg]}. -check_format_3(Fmt, As) -> +check_format_3(Fmt, FmtAnno, As) -> case check_format_string(Fmt) of {ok,Need} -> case args_length(As) of Len when length(Need) =:= Len -> ok; - _Len -> {warn,1,"wrong number of arguments in format call",[]} + _Len -> {warn,1,element(2, As),"wrong number of arguments in format call",[]} end; {error,S} -> - {warn,1,"format string invalid (~ts)",[S]} + {warn,1,FmtAnno,"format string invalid (~ts)",[S]} end. -args_list({cons,_L,_H,T}) -> args_list(T); +args_list({cons,_A,_H,T}) -> args_list(T); %% Strange case: user has written something like [a | "bcd"]; pretend %% we don't know: -args_list({string,_L,_Cs}) -> maybe; -args_list({nil,_L}) -> true; +args_list({string,_A,_Cs}) -> maybe; +args_list({nil,_A}) -> true; args_list({atom,_,_}) -> false; args_list({integer,_,_}) -> false; args_list({float,_,_}) -> false; args_list(_Other) -> maybe. -args_length({cons,_L,_H,T}) -> 1 + args_length(T); -args_length({nil,_L}) -> 0. +args_length({cons,_A,_H,T}) -> 1 + args_length(T); +args_length({nil,_A}) -> 0. check_format_string(Fmt) -> extract_sequences(Fmt, []). diff --git a/lib/stdlib/src/erl_parse.yrl b/lib/stdlib/src/erl_parse.yrl index 390ce44e20..f6d747901f 100644 --- a/lib/stdlib/src/erl_parse.yrl +++ b/lib/stdlib/src/erl_parse.yrl @@ -240,7 +240,7 @@ expr -> function_call : '$1'. expr -> record_expr : '$1'. expr -> expr_remote : '$1'. -expr_remote -> expr_max ':' expr_max : {remote,?anno('$2'),'$1','$3'}. +expr_remote -> expr_max ':' expr_max : {remote,first_anno('$1'),'$1','$3'}. expr_remote -> expr_max : '$1'. expr_max -> var : '$1'. @@ -292,7 +292,7 @@ list -> '[' expr tail : {cons,?anno('$1'),'$2','$3'}. tail -> ']' : {nil,?anno('$1')}. tail -> '|' expr ']' : '$2'. -tail -> ',' expr tail : {cons,?anno('$2'),'$2','$3'}. +tail -> ',' expr tail : {cons,first_anno('$2'),'$2','$3'}. binary -> '<<' '>>' : {bin,?anno('$1'),[]}. @@ -302,7 +302,7 @@ bin_elements -> bin_element : ['$1']. bin_elements -> bin_element ',' bin_elements : ['$1'|'$3']. bin_element -> bit_expr opt_bit_size_expr opt_bit_type_list : - {bin_element,?anno('$1'),'$1','$2','$3'}. + {bin_element,first_anno('$1'),'$1','$2','$3'}. bit_expr -> prefix_op expr_max : ?mkop1('$1', '$2'). bit_expr -> expr_max : '$1'. @@ -353,10 +353,10 @@ map_field -> map_field_assoc : '$1'. map_field -> map_field_exact : '$1'. map_field_assoc -> map_key '=>' expr : - {map_field_assoc,?anno('$1'),'$1','$3'}. + {map_field_assoc,?anno('$2'),'$1','$3'}. map_field_exact -> map_key ':=' expr : - {map_field_exact,?anno('$1'),'$1','$3'}. + {map_field_exact,?anno('$2'),'$1','$3'}. map_key -> expr : '$1'. @@ -370,13 +370,13 @@ record_expr -> '#' atom '.' atom : record_expr -> '#' atom record_tuple : {record,?anno('$1'),element(3, '$2'),'$3'}. record_expr -> expr_max '#' atom '.' atom : - {record_field,?anno('$2'),'$1',element(3, '$3'),'$5'}. + {record_field,first_anno('$1'),'$1',element(3, '$3'),'$5'}. record_expr -> expr_max '#' atom record_tuple : - {record,?anno('$2'),'$1',element(3, '$3'),'$4'}. + {record,first_anno('$1'),'$1',element(3, '$3'),'$4'}. record_expr -> record_expr '#' atom '.' atom : - {record_field,?anno('$2'),'$1',element(3, '$3'),'$5'}. + {record_field,first_anno('$1'),'$1',element(3, '$3'),'$5'}. record_expr -> record_expr '#' atom record_tuple : - {record,?anno('$2'),'$1',element(3, '$3'),'$4'}. + {record,first_anno('$1'),'$1',element(3, '$3'),'$4'}. record_tuple -> '{' '}' : []. record_tuple -> '{' record_fields '}' : '$2'. @@ -390,7 +390,7 @@ record_field -> atom '=' expr : {record_field,?anno('$1'),'$1','$3'}. %% N.B. This is called from expr. function_call -> expr_remote argument_list : - {call,?anno('$1'),'$1',element(1, '$2')}. + {call,first_anno('$1'),'$1',element(1, '$2')}. if_expr -> 'if' if_clauses 'end' : {'if',?anno('$1'),'$2'}. @@ -399,7 +399,7 @@ if_clauses -> if_clause : ['$1']. if_clauses -> if_clause ';' if_clauses : ['$1' | '$3']. if_clause -> guard clause_body : - {clause,?anno(hd(hd('$1'))),[],'$1','$2'}. + {clause,first_anno(hd(hd('$1'))),[],'$1','$2'}. case_expr -> 'case' expr 'of' cr_clauses 'end' : @@ -413,7 +413,7 @@ cr_clauses -> cr_clause ';' cr_clauses : ['$1' | '$3']. %% should be a better way. cr_clause -> expr clause_guard clause_body : - {clause,?anno('$1'),['$1'],'$2','$3'}. + {clause,first_anno('$1'),['$1'],'$2','$3'}. receive_expr -> 'receive' cr_clauses 'end' : {'receive',?anno('$1'),'$2'}. @@ -444,7 +444,7 @@ fun_clause -> pat_argument_list clause_guard clause_body : {clause,Anno,'fun',Args,'$2','$3'}. fun_clause -> var pat_argument_list clause_guard clause_body : - {clause,element(2, '$1'),element(3, '$1'),element(1, '$2'),'$3','$4'}. + {clause,?anno('$1'),element(3, '$1'),element(1, '$2'),'$3','$4'}. try_expr -> 'try' exprs 'of' cr_clauses try_catch : build_try(?anno('$1'),'$2','$4','$5'). @@ -462,15 +462,16 @@ try_clauses -> try_clause : ['$1']. try_clauses -> try_clause ';' try_clauses : ['$1' | '$3']. try_clause -> pat_expr clause_guard clause_body : - A = ?anno('$1'), - {clause,A,[{tuple,A,[{atom,A,throw},'$1',{var,A,'_'}]}],'$2','$3'}. + A = first_anno('$1'), + Az = last_anno('$1'), % Good enough... + {clause,A,[{tuple,A,[{atom,A,throw},'$1',{var,Az,'_'}]}],'$2','$3'}. try_clause -> atom ':' pat_expr try_opt_stacktrace clause_guard clause_body : A = ?anno('$1'), - T = case '$4' of '_' -> {var,A,'_'}; V -> V end, + T = case '$4' of '_' -> {var,last_anno('$3'),'_'}; V -> V end, {clause,A,[{tuple,A,['$1','$3',T]}],'$5','$6'}. try_clause -> var ':' pat_expr try_opt_stacktrace clause_guard clause_body : A = ?anno('$1'), - T = case '$4' of '_' -> {var,A,'_'}; V -> V end, + T = case '$4' of '_' -> {var,last_anno('$3'),'_'}; V -> V end, {clause,A,[{tuple,A,['$1','$3',T]}],'$5','$6'}. try_opt_stacktrace -> ':' var : '$2'. @@ -560,6 +561,8 @@ Erlang code. -export([map_anno/2, fold_anno/3, mapfold_anno/3, new_anno/1, anno_to_term/1, anno_from_term/1]). +-export([first_location/1]). % Internal export. + -export_type([abstract_clause/0, abstract_expr/0, abstract_form/0, abstract_type/0, form_info/0, error_info/0]). %% The following types are exported because they are used by syntax_tools @@ -986,7 +989,7 @@ Erlang code. -type type_name() :: atom(). --type form_info() :: {'eof', erl_anno:line()} +-type form_info() :: {'eof', erl_anno:location()} | {'error', erl_scan:error_info() | error_info()} | {'warning', erl_scan:error_info() | error_info()}. @@ -994,7 +997,7 @@ Erlang code. %% XXX. To be refined. -type error_description() :: term(). --type error_info() :: {erl_anno:line(), module(), error_description()}. +-type error_info() :: {erl_anno:location(), module(), error_description()}. -type token() :: erl_scan:token(). %% mkop(Op, Arg) -> {op,Anno,Op,Arg}. @@ -1053,7 +1056,7 @@ parse_exprs(Tokens) -> ?ANNO_CHECK(Tokens), A = erl_anno:new(0), case parse([{atom,A,f},{'(',A},{')',A},{'->',A}|Tokens]) of - {ok,{function,_Lf,f,0,[{clause,_Lc,[],[],Exprs}]}} -> + {ok,{function,_Af,f,0,[{clause,_Ac,[],[],Exprs}]}} -> {ok,Exprs}; {error,_} = Err -> Err end. @@ -1070,10 +1073,10 @@ parse_term(Tokens) -> try normalise(Expr) of Term -> {ok,Term} catch - _:_R -> {error,{location(?anno(Expr)),?MODULE,"bad term"}} + _:_R -> {error,{first_location(Expr),?MODULE,"bad term"}} end; - {ok,{function,_Af,f,A,[{clause,_Ac,[],[],[_E1,E2|_Es]}]}} -> - {error,{location(?anno(E2)),?MODULE,"bad term"}}; + {ok,{function,_Af,f,0,[{clause,_Ac,[],[],[_E1,E2|_Es]}]}} -> + {error,{first_location(E2),?MODULE,"bad term"}}; {error,_} = Err -> Err end. @@ -1089,17 +1092,16 @@ build_typed_attribute({atom,Aa,Attr}, lists:foreach(fun({var, A, '_'}) -> ret_err(A, "bad type variable"); (_) -> ok end, Args), - case lists:all(fun({var, _, _}) -> true; - (_) -> false - end, Args) of - true -> {attribute,Aa,Attr,{TypeName,Type,Args}}; - false -> error_bad_decl(Aa, Attr) - end; -build_typed_attribute({atom,Aa,Attr},_) -> + lists:foreach(fun({var, _, _}) -> true; + (Other) -> ret_abstr_err(Other, + "bad type variable") + end, Args), + {attribute,Aa,Attr,{TypeName,Type,Args}}; +build_typed_attribute({atom,Aa,Attr}=Abstr,_) -> case Attr of - record -> error_bad_decl(Aa, record); - type -> error_bad_decl(Aa, type); - opaque -> error_bad_decl(Aa, opaque); + record -> error_bad_decl(Abstr, record); + type -> error_bad_decl(Abstr, type); + opaque -> error_bad_decl(Abstr, opaque); _ -> ret_err(Aa, "bad attribute") end. @@ -1129,7 +1131,7 @@ find_arity_from_specs([Spec|_]) -> build_compat_constraint({atom, _, is_subtype}, [{var, _, _}=LHS, Type]) -> build_constraint(LHS, Type); build_compat_constraint({atom, _, is_subtype}, [LHS, _Type]) -> - ret_err(?anno(LHS), "bad type variable"); + ret_abstr_err(LHS, "bad type variable"); build_compat_constraint({atom, A, Atom}, _Types) -> ret_err(A, io_lib:format("unsupported constraint ~tw", [Atom])). @@ -1140,13 +1142,14 @@ build_constraint({atom, A, Atom}, _Foo) -> build_constraint({var, A, '_'}, _Types) -> ret_err(A, "bad type variable"); build_constraint(LHS, Type) -> - IsSubType = {atom, ?anno(LHS), is_subtype}, - {type, ?anno(LHS), constraint, [IsSubType, [LHS, Type]]}. + Anno = first_anno(LHS), + IsSubType = {atom, Anno, is_subtype}, + {type, Anno, constraint, [IsSubType, [LHS, Type]]}. lift_unions(T1, {type, _Aa, union, List}) -> - {type, ?anno(T1), union, [T1|List]}; + {type, first_anno(T1), union, [T1|List]}; lift_unions(T1, T2) -> - {type, ?anno(T1), union, [T1, T2]}. + {type, first_anno(T1), union, [T1, T2]}. build_gen_type({atom, Aa, tuple}) -> {type, Aa, tuple, any}; @@ -1191,46 +1194,45 @@ build_attribute({atom,Aa,module}, Val) -> {attribute,Aa,module,Module}; [{atom,_Am,Module},ExpList] -> {attribute,Aa,module,{Module,var_list(ExpList)}}; - _Other -> - error_bad_decl(Aa, module) + [Other|_] -> error_bad_decl(Other, module) end; build_attribute({atom,Aa,export}, Val) -> case Val of [ExpList] -> {attribute,Aa,export,farity_list(ExpList)}; - _Other -> error_bad_decl(Aa, export) + [_,Other|_] -> error_bad_decl(Other, export) end; build_attribute({atom,Aa,import}, Val) -> case Val of [{atom,_Am,Mod},ImpList] -> {attribute,Aa,import,{Mod,farity_list(ImpList)}}; - _Other -> error_bad_decl(Aa, import) + [_,Other|_] -> error_bad_decl(Other, import) end; build_attribute({atom,Aa,record}, Val) -> case Val of [{atom,_An,Record},RecTuple] -> {attribute,Aa,record,{Record,record_tuple(RecTuple)}}; - _Other -> error_bad_decl(Aa, record) + [Other|_] -> error_bad_decl(Other, record) end; build_attribute({atom,Aa,file}, Val) -> case Val of [{string,_An,Name},{integer,_Al,Line}] -> {attribute,Aa,file,{Name,Line}}; - _Other -> error_bad_decl(Aa, file) + [Other|_] -> error_bad_decl(Other, file) end; build_attribute({atom,Aa,Attr}, Val) -> case Val of [Expr0] -> Expr = attribute_farity(Expr0), {attribute,Aa,Attr,term(Expr)}; - _Other -> ret_err(Aa, "bad attribute") + [_,Other|_] -> ret_abstr_err(Other, "bad attribute") end. var_list({cons,_Ac,{var,_,V},Tail}) -> [V|var_list(Tail)]; var_list({nil,_An}) -> []; var_list(Other) -> - ret_err(?anno(Other), "bad variable list"). + ret_abstr_err(Other, "bad variable list"). attribute_farity({cons,A,H,T}) -> {cons,A,attribute_farity(H),attribute_farity(T)}; @@ -1251,21 +1253,25 @@ attribute_farity_list(Args) -> attribute_farity_map(Args) -> [{Op,A,K,attribute_farity(V)} || {Op,A,K,V} <- Args]. --spec error_bad_decl(erl_anno:anno(), attributes()) -> no_return(). +-spec error_bad_decl(erl_parse_tree(), attributes()) -> no_return(). -error_bad_decl(Anno, S) -> - ret_err(Anno, io_lib:format("bad ~tw declaration", [S])). +error_bad_decl(Abstr, S) -> + ret_abstr_err(Abstr, io_lib:format("bad ~tw declaration", [S])). farity_list({cons,_Ac,{op,_Ao,'/',{atom,_Aa,A},{integer,_Ai,I}},Tail}) -> [{A,I}|farity_list(Tail)]; +farity_list({cons,_Ac,{op,_Ao,'/',{atom,_Aa,_A},Other},_Tail}) -> + ret_abstr_err(Other, "bad function arity"); +farity_list({cons,_Ac,{op,_Ao,'/',Other,_},_Tail}) -> + ret_abstr_err(Other, "bad function name"); farity_list({nil,_An}) -> []; farity_list(Other) -> - ret_err(?anno(Other), "bad function arity"). + ret_abstr_err(Other, "bad Name/Arity"). record_tuple({tuple,_At,Fields}) -> record_fields(Fields); record_tuple(Other) -> - ret_err(?anno(Other), "bad record declaration"). + ret_abstr_err(Other, "bad record declaration"). record_fields([{atom,Aa,A}|Fields]) -> [{record_field,Aa,{atom,Aa,A}}|record_fields(Fields)]; @@ -1275,12 +1281,12 @@ record_fields([{typed,Expr,TypeInfo}|Fields]) -> [Field] = record_fields([Expr]), [{typed_record_field,Field,TypeInfo}|record_fields(Fields)]; record_fields([Other|_Fields]) -> - ret_err(?anno(Other), "bad record field"); + ret_abstr_err(Other, "bad record field"); record_fields([]) -> []. term(Expr) -> try normalise(Expr) - catch _:_R -> ret_err(?anno(Expr), "bad attribute") + catch _:_R -> ret_abstr_err(Expr, "bad attribute") end. %% build_function([Clause]) -> {function,Anno,Name,Arity,[Clause]} @@ -1318,6 +1324,54 @@ build_try(A,Es,Scs,{Ccs,As}) -> ret_err(Anno, S) -> return_error(location(Anno), S). +-spec ret_abstr_err(_, _) -> no_return(). +ret_abstr_err(Abstract, S) -> + return_error(first_location(Abstract), S). + +first_location(Abstract) -> + Anno = first_anno(Abstract), + erl_anno:location(Anno). + +%% Use the fact that fold_anno() visits nodes from left to right. +%% Could be a bit slow on deeply nested code without column numbers +%% even though only the left-most branch is traversed. +first_anno(Abstract) -> + Anno0 = element(2, Abstract), + F = fun(Anno, Anno1) -> + Loc = erl_anno:location(Anno), + Loc1 = erl_anno:location(Anno1), + case loc_lte(Loc, Loc1) of + true -> + Anno; + false -> + throw(Anno1) + end + end, + catch fold_anno(F, Anno0, Abstract). + +last_anno(Abstract) -> + Anno = lists:last(sort_annos(Abstract)), + case erl_anno:end_location(Anno) of + undefined -> + Anno; + EndLocation -> + erl_anno:set_location(EndLocation, Anno) + end. + +sort_annos(Abstract) -> + AllAnnos = fold_anno(fun(Anno, Acc) -> [Anno|Acc] end, [], Abstract), + CF = fun(Anno1, Anno2) -> + loc_lte(erl_anno:location(Anno1), erl_anno:location(Anno2)) + end, + lists:sort(CF, AllAnnos). + +loc_lte(Line1, Location2) when is_integer(Line1) -> + loc_lte({Line1, 1}, Location2); +loc_lte(Location1, Line2) when is_integer(Line2) -> + loc_lte(Location1, {Line2, 1}); +loc_lte(Location1, Location2) -> + Location1 =< Location2. + location(Anno) -> erl_anno:location(Anno). diff --git a/lib/stdlib/src/erl_pp.erl b/lib/stdlib/src/erl_pp.erl index 2ccd6c53b5..40737eae29 100644 --- a/lib/stdlib/src/erl_pp.erl +++ b/lib/stdlib/src/erl_pp.erl @@ -58,7 +58,7 @@ -ifdef(DEBUG). -define(FORM_TEST(T), _ = case T of - {eof, _Line} -> ok; + {eof, _Location} -> ok; {warning, _W} -> ok; {error, _E} -> ok; _ -> ?TEST(T) @@ -262,16 +262,16 @@ encoding(Options) -> unicode -> unicode end. -lform({attribute,Line,Name,Arg}, Opts) -> - lattribute({attribute,Line,Name,Arg}, Opts); -lform({function,Line,Name,Arity,Clauses}, Opts) -> - lfunction({function,Line,Name,Arity,Clauses}, Opts); +lform({attribute,Anno,Name,Arg}, Opts) -> + lattribute({attribute,Anno,Name,Arg}, Opts); +lform({function,Anno,Name,Arity,Clauses}, Opts) -> + lfunction({function,Anno,Name,Arity,Clauses}, Opts); %% These are specials to make it easier for the compiler. lform({error,_}=E, Opts) -> message(E, Opts); lform({warning,_}=W, Opts) -> message(W, Opts); -lform({eof,_Line}, _Opts) -> +lform({eof,_Location}, _Opts) -> $\n. message(M, #options{encoding = Encoding}) -> @@ -281,15 +281,15 @@ message(M, #options{encoding = Encoding}) -> end, leaf(format(F, [M])). -lattribute({attribute,_Line,type,Type}, Opts) -> +lattribute({attribute,_Anno,type,Type}, Opts) -> [typeattr(type, Type, Opts),leaf(".\n")]; -lattribute({attribute,_Line,opaque,Type}, Opts) -> +lattribute({attribute,_Anno,opaque,Type}, Opts) -> [typeattr(opaque, Type, Opts),leaf(".\n")]; -lattribute({attribute,_Line,spec,Arg}, _Opts) -> +lattribute({attribute,_Anno,spec,Arg}, _Opts) -> [specattr(spec, Arg),leaf(".\n")]; -lattribute({attribute,_Line,callback,Arg}, _Opts) -> +lattribute({attribute,_Anno,callback,Arg}, _Opts) -> [specattr(callback, Arg),leaf(".\n")]; -lattribute({attribute,_Line,Name,Arg}, Opts) -> +lattribute({attribute,_Anno,Name,Arg}, Opts) -> [lattribute(Name, Arg, Opts),leaf(".\n")]. lattribute(module, {M,Vs}, _Opts) -> @@ -311,8 +311,8 @@ lattribute(optional_callbacks, Falist, Opts) -> try attrib(optional_callbacks, falist(Falist)) catch _:_ -> attr(optional_callbacks, [abstract(Falist, Opts)]) end; -lattribute(file, {Name,Line}, _Opts) -> - attr(file, [{string,a0(),Name},{integer,a0(),Line}]); +lattribute(file, {Name,Anno}, _Opts) -> + attr(file, [{string,a0(),Name},{integer,a0(),Anno}]); lattribute(record, {Name,Is}, Opts) -> Nl = [leaf("-record("),{atom,Name},$,], [{first,Nl,record_fields(Is, Opts)},$)]; @@ -329,58 +329,58 @@ typeattr(Tag, {TypeName,Type,Args}, _Opts) -> ltype(T) -> ltype(T, 0). -ltype({ann_type,_Line,[V,T]}, Prec) -> +ltype({ann_type,_Anno,[V,T]}, Prec) -> {L,P,R} = type_inop_prec('::'), Vl = ltype(V, L), Tr = ltype(T, R), El = {list,[{cstep,[Vl,' ::'],Tr}]}, maybe_paren(P, Prec, El); -ltype({paren_type,_Line,[T]}, P) -> +ltype({paren_type,_Anno,[T]}, P) -> %% Generated before Erlang/OTP 18. ltype(T, P); -ltype({type,_Line,union,Ts}, Prec) -> +ltype({type,_Anno,union,Ts}, Prec) -> {_L,P,R} = type_inop_prec('|'), E = {seq,[],[],[' |'],ltypes(Ts, R)}, maybe_paren(P, Prec, E); -ltype({type,_Line,list,[T]}, _) -> +ltype({type,_Anno,list,[T]}, _) -> {seq,$[,$],$,,[ltype(T)]}; -ltype({type,_Line,nonempty_list,[T]}, _) -> +ltype({type,_Anno,nonempty_list,[T]}, _) -> {seq,$[,$],[$,],[ltype(T),leaf("...")]}; -ltype({type,Line,nil,[]}, _) -> - lexpr({nil,Line}, options(none)); -ltype({type,Line,map,any}, _) -> - simple_type({atom,Line,map}, []); -ltype({type,_Line,map,Pairs}, Prec) -> +ltype({type,Anno,nil,[]}, _) -> + lexpr({nil,Anno}, options(none)); +ltype({type,Anno,map,any}, _) -> + simple_type({atom,Anno,map}, []); +ltype({type,_Anno,map,Pairs}, Prec) -> {P,_R} = type_preop_prec('#'), E = map_type(Pairs), maybe_paren(P, Prec, E); -ltype({type,Line,tuple,any}, _) -> - simple_type({atom,Line,tuple}, []); -ltype({type,_Line,tuple,Ts}, _) -> +ltype({type,Anno,tuple,any}, _) -> + simple_type({atom,Anno,tuple}, []); +ltype({type,_Anno,tuple,Ts}, _) -> tuple_type(Ts, fun ltype/2); -ltype({type,_Line,record,[{atom,_,N}|Fs]}, Prec) -> +ltype({type,_Anno,record,[{atom,_,N}|Fs]}, Prec) -> {P,_R} = type_preop_prec('#'), E = record_type(N, Fs), maybe_paren(P, Prec, E); -ltype({type,_Line,range,[_I1,_I2]=Es}, Prec) -> +ltype({type,_Anno,range,[_I1,_I2]=Es}, Prec) -> {_L,P,R} = type_inop_prec('..'), F = fun(E, Opts) -> lexpr(E, R, Opts) end, E = expr_list(Es, '..', F, options(none)), maybe_paren(P, Prec, E); -ltype({type,_Line,binary,[I1,I2]}, _) -> +ltype({type,_Anno,binary,[I1,I2]}, _) -> binary_type(I1, I2); % except binary() -ltype({type,_Line,'fun',[]}, _) -> +ltype({type,_Anno,'fun',[]}, _) -> leaf("fun()"); ltype({type,_,'fun',[{type,_,any},_]}=FunType, _) -> [fun_type(['fun',$(], FunType),$)]; -ltype({type,_Line,'fun',[{type,_,product,_},_]}=FunType, _) -> +ltype({type,_Anno,'fun',[{type,_,product,_},_]}=FunType, _) -> [fun_type(['fun',$(], FunType),$)]; -ltype({type,Line,T,Ts}, _) -> - simple_type({atom,Line,T}, Ts); -ltype({user_type,Line,T,Ts}, _) -> - simple_type({atom,Line,T}, Ts); -ltype({remote_type,Line,[M,F,Ts]}, _) -> - simple_type({remote,Line,M,F}, Ts); +ltype({type,Anno,T,Ts}, _) -> + simple_type({atom,Anno,T}, Ts); +ltype({user_type,Anno,T,Ts}, _) -> + simple_type({atom,Anno,T}, Ts); +ltype({remote_type,Anno,[M,F,Ts]}, _) -> + simple_type({remote,Anno,M,F}, Ts); ltype({atom,_,T}, _) -> {singleton_atom_type,T}; ltype(E, P) -> @@ -405,9 +405,9 @@ map_type(Fs) -> map_pair_types(Fs) -> tuple_type(Fs, fun map_pair_type/2). -map_pair_type({type,_Line,map_field_assoc,[KType,VType]}, Prec) -> +map_pair_type({type,_Anno,map_field_assoc,[KType,VType]}, Prec) -> {list,[{cstep,[ltype(KType, Prec),leaf(" =>")],ltype(VType, Prec)}]}; -map_pair_type({type,_Line,map_field_exact,[KType,VType]}, Prec) -> +map_pair_type({type,_Anno,map_field_exact,[KType,VType]}, Prec) -> {list,[{cstep,[ltype(KType, Prec),leaf(" :=")],ltype(VType, Prec)}]}. record_type(Name, Fields) -> @@ -416,7 +416,7 @@ record_type(Name, Fields) -> field_types(Fs) -> tuple_type(Fs, fun field_type/2). -field_type({type,_Line,field_type,[Name,Type]}, _Prec) -> +field_type({type,_Anno,field_type,[Name,Type]}, _Prec) -> typed(lexpr(Name, options(none)), Type). typed(B, Type) -> @@ -440,7 +440,7 @@ specattr(SpecKind, {FuncSpec,TypeSpecs}) -> spec_clauses(TypeSpecs) -> {prefer_nl,[$;],[sig_type(T) || T <- TypeSpecs]}. -sig_type({type,_Line,bounded_fun,[T,Gs]}) -> +sig_type({type,_Anno,bounded_fun,[T,Gs]}) -> guard_type(fun_type([], T), Gs); sig_type(FunType) -> fun_type([], FunType). @@ -450,16 +450,16 @@ guard_type(Before, Gs) -> Gl = {list,[{step,'when',expr_list(Gs, [$,], fun constraint/2, Opts)}]}, {list,[{step,Before,Gl}]}. -constraint({type,_Line,constraint,[{atom,_,is_subtype},[{var,_,_}=V,Type]]}, +constraint({type,_Anno,constraint,[{atom,_,is_subtype},[{var,_,_}=V,Type]]}, _Opts) -> typed(lexpr(V, options(none)), Type); -constraint({type,_Line,constraint,[Tag,As]}, _Opts) -> +constraint({type,_Anno,constraint,[Tag,As]}, _Opts) -> simple_type(Tag, As). fun_type(Before, {type,_,'fun',[FType,Ret]}) -> {first,Before,{step,[type_args(FType),' ->'],ltype(Ret)}}. -type_args({type,_Line,any}) -> +type_args({type,_Anno,any}) -> leaf("(...)"); type_args({type,_line,product,Ts}) -> targs(Ts). @@ -500,12 +500,12 @@ falist(Falist) -> end || Fa <- Falist], [{seq,$[,$],$,,L}]. -lfunction({function,_Line,Name,_Arity,Cs}, Opts) -> +lfunction({function,_Anno,Name,_Arity,Cs}, Opts) -> Cll = nl_clauses(fun (C, H) -> func_clause(Name, C, H) end, $;, Opts, Cs), [Cll,leaf(".\n")]. -func_clause(Name, {clause,Line,Head,Guard,Body}, Opts) -> - Hl = call({atom,Line,Name}, Head, 0, Opts), +func_clause(Name, {clause,Anno,Head,Guard,Body}, Opts) -> + Hl = call({atom,Anno,Name}, Head, 0, Opts), Gl = guard_when(Hl, Guard, Opts), Bl = body(Body, Opts), {step,Gl,Bl}. @@ -621,8 +621,8 @@ lexpr({'receive',_,Cs,To,ToOpt}, _, Opts) -> {reserved,'end'}]}; lexpr({'fun',_,{function,F,A}}, _Prec, _Opts) -> [leaf("fun "),{atom,F},leaf(format("/~w", [A]))]; -lexpr({'fun',L,{function,_,_}=Func,Extra}, Prec, Opts) -> - {force_nl,fun_info(Extra),lexpr({'fun',L,Func}, Prec, Opts)}; +lexpr({'fun',A,{function,_,_}=Func,Extra}, Prec, Opts) -> + {force_nl,fun_info(Extra),lexpr({'fun',A,Func}, Prec, Opts)}; lexpr({'fun',_,{function,M,F,A}}, _Prec, Opts) -> NameItem = lexpr(M, Opts), CallItem = lexpr(F, Opts), diff --git a/lib/stdlib/src/escript.erl b/lib/stdlib/src/escript.erl index 6a7824c481..8393a8d572 100644 --- a/lib/stdlib/src/escript.erl +++ b/lib/stdlib/src/escript.erl @@ -164,12 +164,12 @@ extract(File, Options) when is_list(File), is_list(Options) -> try EO = parse_extract_options(Options, #extract_options{compile_source = false}), - {HeaderSz, NextLineNo, Fd, Sections} = + {HeaderSz, StartLine, Fd, Sections} = parse_header(File, not EO#extract_options.compile_source), Type = Sections#sections.type, case {Type, EO#extract_options.compile_source} of {source, true} -> - Bin = compile_source(Type, File, Fd, NextLineNo, HeaderSz); + Bin = compile_source(Type, File, Fd, StartLine, HeaderSz); {_, _} -> ok = file:close(Fd), case file:read_file(File) of @@ -197,9 +197,9 @@ parse_extract_options([H | T], EO) -> parse_extract_options([], EO) -> EO. -compile_source(Type, File, Fd, NextLineNo, HeaderSz) -> +compile_source(Type, File, Fd, StartLine, HeaderSz) -> {text, _Module, Forms, _HasRecs, _Mode} = - do_parse_file(Type, File, Fd, NextLineNo, HeaderSz, false), + do_parse_file(Type, File, Fd, StartLine, HeaderSz, false), ok = file:close(Fd), case compile:forms(Forms, [return_errors, debug_info]) of {ok, _, BeamBin} -> @@ -401,12 +401,12 @@ parse_file(File) -> end. parse_file(File, CheckOnly) -> - {HeaderSz, NextLineNo, Fd, Sections} = + {HeaderSz, StartLine, Fd, Sections} = parse_header(File, false), do_parse_file(Sections#sections.type, - File, Fd, NextLineNo, HeaderSz, CheckOnly). + File, Fd, StartLine, HeaderSz, CheckOnly). -do_parse_file(Type, File, Fd, NextLineNo, HeaderSz, CheckOnly) -> +do_parse_file(Type, File, Fd, StartLine, HeaderSz, CheckOnly) -> S = initial_state(File), #state{mode = Mode, source = Source, @@ -424,7 +424,7 @@ do_parse_file(Type, File, Fd, NextLineNo, HeaderSz, CheckOnly) -> parse_beam(S, File, HeaderSz, CheckOnly); source -> %% Source code - parse_source(S, File, Fd, NextLineNo, HeaderSz, CheckOnly) + parse_source(S, File, Fd, StartLine, HeaderSz, CheckOnly) end, {Source, Module, FormsOrBin, HasRecs, Mode}. @@ -600,7 +600,8 @@ parse_source(S, File, Fd, StartLine, HeaderSz, CheckOnly) -> _ = io:get_line(Fd, ''), Encoding = epp:set_encoding(Fd), {ok, _} = file:position(Fd, HeaderSz), - case epp:open(File, Fd, StartLine, IncludePath, PreDefMacros) of + case epp:open([{fd, Fd}, {name, File}, {location, {StartLine, 1}}, + {includes, IncludePath}, {macros, PreDefMacros}]) of {ok, Epp} -> _ = [io:setopts(Fd, [{encoding,Encoding}]) || Encoding =/= none], @@ -698,7 +699,7 @@ epp_parse_file2(Epp, S, Forms, Parsed) -> epp_parse_file(Epp, S2, [Form | Forms]); true -> Args = lists:flatten(io_lib:format("illegal mode attribute: ~p", [NewMode])), - io:format(standard_error, "~ts:~w ~s\n", [S#state.file,Ln,Args]), + io:format(standard_error, "~ts:~s: ~s\n", [S#state.file,pos(Ln),Args]), Error = {error,{Ln,erl_parse,Args}}, Nerrs= S#state.n_errors + 1, epp_parse_file(Epp, S2#state{n_errors = Nerrs}, [Error | Forms]) @@ -714,8 +715,8 @@ epp_parse_file2(Epp, S, Forms, Parsed) -> epp_parse_file(Epp, S, [Form | Forms]) end; {error,{Ln,Mod,Args}} = Form -> - io:format(standard_error, "~ts:~w: ~ts\n", - [S#state.file,Ln,Mod:format_error(Args)]), + io:format(standard_error, "~ts:~s: ~ts\n", + [S#state.file,pos(Ln),Mod:format_error(Args)]), epp_parse_file(Epp, S#state{n_errors = S#state.n_errors + 1}, [Form | Forms]); {eof, LastLine} -> S#state{forms_or_bin = lists:reverse([{eof, LastLine} | Forms])} @@ -793,13 +794,18 @@ report_errors(Errors) -> Errors). list_errors(F, [{Line,Mod,E}|Es]) -> - io:format(standard_error, "~ts:~w: ~ts\n", [F,Line,Mod:format_error(E)]), + io:fwrite(standard_error, "~ts:~s: ~ts\n", [F,pos(Line),Mod:format_error(E)]), list_errors(F, Es); list_errors(F, [{Mod,E}|Es]) -> io:format(standard_error, "~ts: ~ts\n", [F,Mod:format_error(E)]), list_errors(F, Es); list_errors(_F, []) -> ok. +pos({Line,Col}) -> + io_lib:format("~w:~w", [Line,Col]); +pos(Line) -> + io_lib:format("~w", [Line]). + report_warnings(Ws0) -> Ws1 = lists:flatmap(fun({{F,_L},Eds}) -> format_message(F, Eds); ({F,Eds}) -> format_message(F, Eds) end, @@ -808,7 +814,7 @@ report_warnings(Ws0) -> lists:foreach(fun({_,Str}) -> io:put_chars(standard_error, Str) end, Ws). format_message(F, [{Line,Mod,E}|Es]) -> - M = {{F,Line},io_lib:format("~ts:~w: Warning: ~ts\n", [F,Line,Mod:format_error(E)])}, + M = {{F,Line},io_lib:format("~ts:~s: Warning: ~ts\n", [F,pos(Line),Mod:format_error(E)])}, [M|format_message(F, Es)]; format_message(F, [{Mod,E}|Es]) -> M = {none,io_lib:format("~ts: Warning: ~ts\n", [F,Mod:format_error(E)])}, diff --git a/lib/stdlib/src/eval_bits.erl b/lib/stdlib/src/eval_bits.erl index 35eca359dc..966bc65902 100644 --- a/lib/stdlib/src/eval_bits.erl +++ b/lib/stdlib/src/eval_bits.erl @@ -89,9 +89,9 @@ eval_field({bin_element, _, {string, _, S}, {integer,_,8}, [integer,{unit,1},uns eval_field({bin_element, _, {string, _, S}, default, default}, Bs0, _Fun) -> Latin1 = [C band 16#FF || C <- S], {fun() ->list_to_binary(Latin1) end,Bs0}; -eval_field({bin_element, Line, {string, _, S}, Size0, Options0}, Bs0, Fun) -> +eval_field({bin_element, Anno, {string, _, S}, Size0, Options0}, Bs0, Fun) -> {Size1,[Type,{unit,Unit},Sign,Endian]} = - make_bit_type(Line, Size0, Options0), + make_bit_type(Anno, Size0, Options0), {value,Size,Bs1} = Fun(Size1, Bs0), {fun() -> Res = << <<(eval_exp_field1(C, Size, Unit, @@ -106,10 +106,10 @@ eval_field({bin_element, Line, {string, _, S}, Size0, Options0}, Bs0, Fun) -> end, Res end,Bs1}; -eval_field({bin_element,Line,E,Size0,Options0}, Bs0, Fun) -> +eval_field({bin_element,Anno,E,Size0,Options0}, Bs0, Fun) -> {value,V,Bs1} = Fun(E, Bs0), {Size1,[Type,{unit,Unit},Sign,Endian]} = - make_bit_type(Line, Size0, Options0), + make_bit_type(Anno, Size0, Options0), {value,Size,Bs} = Fun(Size1, Bs1), {fun() -> eval_exp_field1(V, Size, Unit, Type, Endian, Sign) end,Bs}. @@ -209,22 +209,22 @@ bin_gen_field({bin_element,_,{string,_,S},default,default}, _ -> done end; -bin_gen_field({bin_element,Line,{string,SLine,S},Size0,Options0}, +bin_gen_field({bin_element,Anno,{string,SAnno,S},Size0,Options0}, Bin0, Bs0, BBs0, Mfun, Efun) -> {Size1, [Type,{unit,Unit},Sign,Endian]} = - make_bit_type(Line, Size0, Options0), + make_bit_type(Anno, Size0, Options0), case catch Efun(Size1, BBs0) of {value, Size, _BBs} -> % F = fun(C, Bin, Bs, BBs) -> bin_gen_field1(Bin, Type, Size, Unit, Sign, Endian, - {integer,SLine,C}, Bs, BBs, Mfun) + {integer,SAnno,C}, Bs, BBs, Mfun) end, bin_gen_field_string(S, Bin0, Bs0, BBs0, F) end; -bin_gen_field({bin_element,Line,VE,Size0,Options0}, +bin_gen_field({bin_element,Anno,VE,Size0,Options0}, Bin, Bs0, BBs0, Mfun, Efun) -> {Size1, [Type,{unit,Unit},Sign,Endian]} = - make_bit_type(Line, Size0, Options0), + make_bit_type(Anno, Size0, Options0), V = erl_eval:partial_eval(VE), NewV = coerce_to_float(V, Type), case catch Efun(Size1, BBs0) of @@ -295,21 +295,21 @@ match_field_1({bin_element,_,{string,_,S},default,default}, Size = byte_size(Bits), <<Bits:Size/binary,Rest/binary-unit:1>> = Bin, {Bs,BBs,Rest}; -match_field_1({bin_element,Line,{string,SLine,S},Size0,Options0}, +match_field_1({bin_element,Anno,{string,SAnno,S},Size0,Options0}, Bin0, Bs0, BBs0, Mfun, Efun) -> {Size1, [Type,{unit,Unit},Sign,Endian]} = - make_bit_type(Line, Size0, Options0), + make_bit_type(Anno, Size0, Options0), Size2 = erl_eval:partial_eval(Size1), {value, Size, _BBs} = Efun(Size2, BBs0), F = fun(C, Bin, Bs, BBs) -> match_field(Bin, Type, Size, Unit, Sign, Endian, - {integer,SLine,C}, Bs, BBs, Mfun) + {integer,SAnno,C}, Bs, BBs, Mfun) end, match_field_string(S, Bin0, Bs0, BBs0, F); -match_field_1({bin_element,Line,VE,Size0,Options0}, +match_field_1({bin_element,Anno,VE,Size0,Options0}, Bin, Bs0, BBs0, Mfun, Efun) -> {Size1, [Type,{unit,Unit},Sign,Endian]} = - make_bit_type(Line, Size0, Options0), + make_bit_type(Anno, Size0, Options0), V = erl_eval:partial_eval(VE), NewV = coerce_to_float(V, Type), Size2 = erl_eval:partial_eval(Size1), @@ -329,9 +329,9 @@ match_field(Bin, Type, Size, Unit, Sign, Endian, NewV, Bs0, BBs0, Mfun) -> {Bs,BBs,Rest}. %% Almost identical to the one in sys_pre_expand. -coerce_to_float({integer,L,I}=E, float) -> +coerce_to_float({integer,Anno,I}=E, float) -> try - {float,L,float(I)} + {float,Anno,float(I)} catch error:badarg -> E; error:badarith -> E @@ -410,14 +410,14 @@ get_float(Bin, Size, big) -> {Val,Rest}. %% Identical to the one in sys_pre_expand. -make_bit_type(Line, default, Type0) -> +make_bit_type(Anno, default, Type0) -> case erl_bits:set_bit_type(default, Type0) of - {ok,all,Bt} -> {{atom,Line,all},erl_bits:as_list(Bt)}; - {ok,undefined,Bt} -> {{atom,Line,undefined},erl_bits:as_list(Bt)}; - {ok,Size,Bt} -> {{integer,Line,Size},erl_bits:as_list(Bt)}; + {ok,all,Bt} -> {{atom,Anno,all},erl_bits:as_list(Bt)}; + {ok,undefined,Bt} -> {{atom,Anno,undefined},erl_bits:as_list(Bt)}; + {ok,Size,Bt} -> {{integer,Anno,Size},erl_bits:as_list(Bt)}; {error,Reason} -> erlang:raise(error, Reason, ?STACKTRACE) end; -make_bit_type(_Line, Size, Type0) -> %Size evaluates to an integer or 'all' +make_bit_type(_Anno, Size, Type0) -> %Size evaluates to an integer or 'all' case erl_bits:set_bit_type(Size, Type0) of {ok,Size,Bt} -> {Size,erl_bits:as_list(Bt)}; {error,Reason} -> erlang:raise(error, Reason, ?STACKTRACE) diff --git a/lib/stdlib/src/ms_transform.erl b/lib/stdlib/src/ms_transform.erl index 8ce6996ba9..dd8417a75d 100644 --- a/lib/stdlib/src/ms_transform.erl +++ b/lib/stdlib/src/ms_transform.erl @@ -19,7 +19,8 @@ %% -module(ms_transform). --export([format_error/1,transform_from_shell/3,parse_transform/2]). +-export([format_error/1,transform_from_shell/3, + parse_transform/2,parse_transform_info/0]). %% Error codes. -define(ERROR_BASE_GUARD,0). @@ -189,6 +190,11 @@ format_error({?ERR_BODYMULTIFIELD,RName,FName}) -> format_error(Else) -> lists:flatten(io_lib:format("Unknown error code ~tw",[Else])). +-spec parse_transform_info() -> #{'error_location' => 'column'}. + +parse_transform_info() -> + #{error_location => column}. + %% %% Called when translating in shell %% @@ -204,14 +210,14 @@ transform_from_shell(Dialect, Clauses, BoundEnvironment) -> {'EXIT',Reason} -> cleanup_filename(SaveFilename), exit(Reason); - {error,Line,R} -> + {error,AnnoOrUnknown,R} -> {error, [{cleanup_filename(SaveFilename), - [{Line, ?MODULE, R}]}], []}; + [{location(AnnoOrUnknown), ?MODULE, R}]}], []}; Else -> case (catch fixup_environment(Else,BoundEnvironment)) of - {error,Line1,R1} -> + {error,AnnoOrUnknown1,R1} -> {error, [{cleanup_filename(SaveFilename), - [{Line1, ?MODULE, R1}]}], []}; + [{location(AnnoOrUnknown1), ?MODULE, R1}]}], []}; Else1 -> Ret = normalise(Else1), cleanup_filename(SaveFilename), @@ -238,9 +244,9 @@ parse_transform(Forms, _Options) -> {'EXIT',Reason} -> cleanup_filename(SaveFilename), exit(Reason); - {error,Line,R} -> + {error,AnnoOrUnknown,R} -> {error, [{cleanup_filename(SaveFilename), - [{Line, ?MODULE, R}]}], []}; + [{location(AnnoOrUnknown), ?MODULE, R}]}], []}; Else -> %io:format("Transformed into: ~p~n",[Else]), case get_warnings() of @@ -254,6 +260,11 @@ parse_transform(Forms, _Options) -> end end. +location(unknown) -> + none; +location(Anno) -> + erl_anno:location(Anno). + get_warnings() -> case get(warnings) of undefined -> @@ -262,8 +273,8 @@ get_warnings() -> Else end. -add_warning(Line,R) -> - put(warnings,[{Line,R}| get_warnings()]). +add_warning(Location,R) -> + put(warnings,[{Location,R}| get_warnings()]). setup_filename() -> {erase(filename),erase(records),erase(warnings)}. @@ -315,8 +326,8 @@ add_record_definition({Name,FieldList}) -> FieldList), put_records([{Name,KeyList}|get_records()]). -record_field({record_field,_,{atom,Line0,FieldName}}, C) -> - {FieldName,C,{atom,Line0,undefined}}; +record_field({record_field,_,{atom,Anno0,FieldName}}, C) -> + {FieldName,C,{atom,Anno0,undefined}}; record_field({record_field,_,{atom,_,FieldName},Def}, C) -> {FieldName,C,Def}; record_field({typed_record_field,Field,_Type}, C) -> @@ -334,9 +345,9 @@ form({attribute,_,file,{Filename,_}}=Form) -> form({attribute,_,record,Definition}=Form) -> add_record_definition(Definition), Form; -form({function,Line,Name0,Arity0,Clauses0}) -> +form({function,Anno,Name0,Arity0,Clauses0}) -> {Name,Arity,Clauses} = function(Name0, Arity0, Clauses0), - {function,Line,Name,Arity,Clauses}; + {function,Anno,Name,Arity,Clauses}; form(AnyOther) -> AnyOther. function(Name, Arity, Clauses0) -> @@ -348,40 +359,40 @@ clauses([C0|Cs]) -> [C1|C2]; clauses([]) -> []. -clause({clause,Line,H0,G0,B0},Bound) -> +clause({clause,Anno,H0,G0,B0},Bound) -> {H1,Bound1} = copy(H0,Bound), {B1,_Bound2} = copy(B0,Bound1), - {clause,Line,H1,G0,B1}. + {clause,Anno,H1,G0,B1}. -copy({call,Line,{remote,_Line2,{atom,_Line3,ets},{atom,_Line4,fun2ms}}, +copy({call,Anno,{remote,_Anno2,{atom,_Anno3,ets},{atom,_Anno4,fun2ms}}, As0},Bound) -> - {transform_call(ets,Line,As0,Bound),Bound}; -copy({call,Line,{remote,_Line2,{atom,_Line3,dbg},{atom,_Line4,fun2ms}}, + {transform_call(ets,Anno,As0,Bound),Bound}; +copy({call,Anno,{remote,_Anno2,{atom,_Anno3,dbg},{atom,_Anno4,fun2ms}}, As0},Bound) -> - {transform_call(dbg,Line,As0,Bound),Bound}; -copy({match,Line,A,B},Bound) -> + {transform_call(dbg,Anno,As0,Bound),Bound}; +copy({match,Anno,A,B},Bound) -> {B1,Bound1} = copy(B,Bound), {A1,Bound2} = copy(A,Bound), - {{match,Line,A1,B1},gb_sets:union(Bound1,Bound2)}; -copy({var,_Line,'_'} = VarDef,Bound) -> + {{match,Anno,A1,B1},gb_sets:union(Bound1,Bound2)}; +copy({var,_Anno,'_'} = VarDef,Bound) -> {VarDef,Bound}; -copy({var,_Line,Name} = VarDef,Bound) -> +copy({var,_Anno,Name} = VarDef,Bound) -> Bound1 = gb_sets:add(Name,Bound), {VarDef,Bound1}; -copy({'fun',Line,{clauses,Clauses}},Bound) -> % Dont export bindings from funs +copy({'fun',Anno,{clauses,Clauses}},Bound) -> % Dont export bindings from funs {NewClauses,_IgnoredBindings} = copy_list(Clauses,Bound), - {{'fun',Line,{clauses,NewClauses}},Bound}; -copy({named_fun,Line,Name,Clauses},Bound) -> % Dont export bindings from funs + {{'fun',Anno,{clauses,NewClauses}},Bound}; +copy({named_fun,Anno,Name,Clauses},Bound) -> % Dont export bindings from funs Bound1 = case Name of '_' -> Bound; Name -> gb_sets:add(Name,Bound) end, {NewClauses,_IgnoredBindings} = copy_list(Clauses,Bound1), - {{named_fun,Line,Name,NewClauses},Bound}; -copy({'case',Line,Of,ClausesList},Bound) -> % Dont export bindings from funs + {{named_fun,Anno,Name,NewClauses},Bound}; +copy({'case',Anno,Of,ClausesList},Bound) -> % Dont export bindings from funs {NewOf,NewBind0} = copy(Of,Bound), {NewClausesList,NewBindings} = copy_case_clauses(ClausesList,NewBind0,[]), - {{'case',Line,NewOf,NewClausesList},NewBindings}; + {{'case',Anno,NewOf,NewClausesList},NewBindings}; copy(T,Bound) when is_tuple(T) -> {L,Bound1} = copy_list(tuple_to_list(T),Bound), {list_to_tuple(L),Bound1}; @@ -393,7 +404,7 @@ copy(AnyOther,Bound) -> copy_case_clauses([],Bound,AddSets) -> ReallyAdded = gb_sets:intersection(AddSets), {[],gb_sets:union(Bound,ReallyAdded)}; -copy_case_clauses([{clause,Line,Match,Guard,Clauses}|T],Bound,AddSets) -> +copy_case_clauses([{clause,Anno,Match,Guard,Clauses}|T],Bound,AddSets) -> {NewMatch,MatchBinds} = copy(Match,Bound), {NewGuard,GuardBinds} = copy(Guard,MatchBinds), %% Really no new binds {NewClauses,AllBinds} = copy(Clauses,GuardBinds), @@ -402,7 +413,7 @@ copy_case_clauses([{clause,Line,Match,Guard,Clauses}|T],Bound,AddSets) -> AddedBinds = gb_sets:subtract(AllBinds,Bound), {NewTail,ExportedBindings} = copy_case_clauses(T,Bound,[AddedBinds | AddSets]), - {[{clause,Line,NewMatch,NewGuard,NewClauses}|NewTail],ExportedBindings}. + {[{clause,Anno,NewMatch,NewGuard,NewClauses}|NewTail],ExportedBindings}. copy_list([H|T],Bound) -> {C1,Bound1} = copy(H,Bound), @@ -411,33 +422,33 @@ copy_list([H|T],Bound) -> copy_list([],Bound) -> {[],Bound}. -transform_call(Type,_Line,[{'fun',Line2,{clauses, ClauseList}}],Bound) -> - ms_clause_list(Line2, ClauseList,Type,Bound); -transform_call(_Type,Line,_NoAbstractFun,_) -> - throw({error,Line,?ERR_NOFUN}). +transform_call(Type,_Anno,[{'fun',Anno2,{clauses, ClauseList}}],Bound) -> + ms_clause_list(Anno2, ClauseList,Type,Bound); +transform_call(_Type,Anno,_NoAbstractFun,_) -> + throw({error,Anno,?ERR_NOFUN}). % Fixup semicolons in guards -ms_clause_expand({clause, Line, Parameters, Guard = [_,_|_], Body}) -> - [ {clause, Line, Parameters, [X], Body} || X <- Guard ]; +ms_clause_expand({clause, Anno, Parameters, Guard = [_,_|_], Body}) -> + [ {clause, Anno, Parameters, [X], Body} || X <- Guard ]; ms_clause_expand(_Other) -> false. -ms_clause_list(Line,[H|T],Type,Bound) -> +ms_clause_list(Anno,[H|T],Type,Bound) -> case ms_clause_expand(H) of NewHead when is_list(NewHead) -> - ms_clause_list(Line,NewHead ++ T, Type, Bound); + ms_clause_list(Anno,NewHead ++ T, Type, Bound); false -> - {cons, Line, ms_clause(H, Type, Bound), - ms_clause_list(Line, T, Type, Bound)} + {cons, Anno, ms_clause(H, Type, Bound), + ms_clause_list(Anno, T, Type, Bound)} end; -ms_clause_list(Line,[],_,_) -> - {nil,Line}. -ms_clause({clause, Line, Parameters, Guards, Body},Type,Bound) -> - check_type(Line,Parameters,Type), +ms_clause_list(Anno,[],_,_) -> + {nil,Anno}. +ms_clause({clause, Anno, Parameters, Guards, Body},Type,Bound) -> + check_type(Anno,Parameters,Type), {MSHead,Bindings} = transform_head(Parameters,Bound), - MSGuards = transform_guards(Line, Guards, Bindings), - MSBody = transform_body(Line,Body,Bindings), - {tuple, Line, [MSHead,MSGuards,MSBody]}. + MSGuards = transform_guards(Anno, Guards, Bindings), + MSBody = transform_body(Anno,Body,Bindings), + {tuple, Anno, [MSHead,MSGuards,MSBody]}. check_type(_,[{var,_,_}],_) -> @@ -450,155 +461,155 @@ check_type(_,[{cons,_,_,_}],dbg) -> ok; check_type(_,[{nil,_}],dbg) -> ok; -check_type(Line0,[{match,_,{var,_,_},X}],Any) -> - check_type(Line0,[X],Any); -check_type(Line0,[{match,_,X,{var,_,_}}],Any) -> - check_type(Line0,[X],Any); -check_type(Line,_Type,ets) -> - throw({error,Line,?ERR_ETS_HEAD}); -check_type(Line,_,dbg) -> - throw({error,Line,?ERR_DBG_HEAD}). +check_type(Anno0,[{match,_,{var,_,_},X}],Any) -> + check_type(Anno0,[X],Any); +check_type(Anno0,[{match,_,X,{var,_,_}}],Any) -> + check_type(Anno0,[X],Any); +check_type(Anno,_Type,ets) -> + throw({error,Anno,?ERR_ETS_HEAD}); +check_type(Anno,_,dbg) -> + throw({error,Anno,?ERR_DBG_HEAD}). -record(tgd,{ b, %Bindings p, %Part of spec eb %Error code base, 0 for guards, 100 for bodies }). -transform_guards(Line,[],_Bindings) -> - {nil,Line}; -transform_guards(Line,[G],Bindings) -> +transform_guards(Anno,[],_Bindings) -> + {nil,Anno}; +transform_guards(Anno,[G],Bindings) -> B = #tgd{b = Bindings, p = guard, eb = ?ERROR_BASE_GUARD}, - tg0(Line,G,B); -transform_guards(Line,_,_) -> - throw({error,Line,?ERR_SEMI_GUARD}). + tg0(Anno,G,B); +transform_guards(Anno,_,_) -> + throw({error,Anno,?ERR_SEMI_GUARD}). -transform_body(Line,Body,Bindings) -> +transform_body(Anno,Body,Bindings) -> B = #tgd{b = Bindings, p = body, eb = ?ERROR_BASE_BODY}, - tg0(Line,Body,B). + tg0(Anno,Body,B). -guard_top_trans({call,Line0,{atom,Line1,OldTest},Params}) -> +guard_top_trans({call,Anno0,{atom,Anno1,OldTest},Params}) -> case old_bool_test(OldTest,length(Params)) of undefined -> - {call,Line0,{atom,Line1,OldTest},Params}; + {call,Anno0,{atom,Anno1,OldTest},Params}; Trans -> - {call,Line0,{atom,Line1,Trans},Params} + {call,Anno0,{atom,Anno1,Trans},Params} end; guard_top_trans(Else) -> Else. -tg0(Line,[],_) -> - {nil,Line}; -tg0(Line,[H0|T],B) when B#tgd.p =:= guard -> +tg0(Anno,[],_) -> + {nil,Anno}; +tg0(Anno,[H0|T],B) when B#tgd.p =:= guard -> H = guard_top_trans(H0), - {cons,Line, tg(H,B), tg0(Line,T,B)}; -tg0(Line,[H|T],B) -> - {cons,Line, tg(H,B), tg0(Line,T,B)}. + {cons,Anno, tg(H,B), tg0(Anno,T,B)}; +tg0(Anno,[H|T],B) -> + {cons,Anno, tg(H,B), tg0(Anno,T,B)}. -tg({match,Line,_,_},B) -> - throw({error,Line,?ERR_GENMATCH+B#tgd.eb}); -tg({op, Line, Operator, O1, O2}=Expr, B) -> +tg({match,Anno,_,_},B) -> + throw({error,Anno,?ERR_GENMATCH+B#tgd.eb}); +tg({op, Anno, Operator, O1, O2}=Expr, B) -> case erl_eval:partial_eval(Expr) of Expr -> - {tuple, Line, [{atom, Line, Operator}, tg(O1, B), tg(O2, B)]}; + {tuple, Anno, [{atom, Anno, Operator}, tg(O1, B), tg(O2, B)]}; Value -> Value end; -tg({op, Line, Operator, O1}=Expr, B) -> +tg({op, Anno, Operator, O1}=Expr, B) -> case erl_eval:partial_eval(Expr) of Expr -> - {tuple, Line, [{atom, Line, Operator}, tg(O1, B)]}; + {tuple, Anno, [{atom, Anno, Operator}, tg(O1, B)]}; Value -> Value end; -tg({call, _Line, {atom, Line2, bindings},[]},_B) -> - {atom, Line2, '$*'}; -tg({call, _Line, {atom, Line2, object},[]},_B) -> - {atom, Line2, '$_'}; -tg({call, Line, {atom, _, is_record}=Call,[Object, {atom,Line3,RName}=R]},B) -> +tg({call, _Anno, {atom, Anno2, bindings},[]},_B) -> + {atom, Anno2, '$*'}; +tg({call, _Anno, {atom, Anno2, object},[]},_B) -> + {atom, Anno2, '$_'}; +tg({call, Anno, {atom, _, is_record}=Call,[Object, {atom,Anno3,RName}=R]},B) -> MSObject = tg(Object,B), RDefs = get_records(), case lists:keysearch(RName,1,RDefs) of {value, {RName, FieldList}} -> RSize = length(FieldList)+1, - {tuple, Line, [Call, MSObject, R, {integer, Line3, RSize}]}; + {tuple, Anno, [Call, MSObject, R, {integer, Anno3, RSize}]}; _ -> - throw({error,Line3,{?ERR_GENBADREC+B#tgd.eb,RName}}) + throw({error,Anno3,{?ERR_GENBADREC+B#tgd.eb,RName}}) end; -tg({call, Line, {atom, Line2, FunName},ParaList},B) -> +tg({call, Anno, {atom, Anno2, FunName},ParaList},B) -> case is_ms_function(FunName,length(ParaList), B#tgd.p) of true -> - {tuple, Line, [{atom, Line2, FunName} | + {tuple, Anno, [{atom, Anno2, FunName} | lists:map(fun(X) -> tg(X,B) end, ParaList)]}; _ -> - throw({error,Line,{?ERR_GENLOCALCALL+B#tgd.eb, + throw({error,Anno,{?ERR_GENLOCALCALL+B#tgd.eb, FunName,length(ParaList)}}) end; -tg({call, Line, {remote,_,{atom,_,erlang},{atom, Line2, FunName}},ParaList}, +tg({call, Anno, {remote,_,{atom,_,erlang},{atom, Anno2, FunName}},ParaList}, B) -> L = length(ParaList), case is_imported_from_erlang(FunName,L,B#tgd.p) of true -> case is_operator(FunName,L,B#tgd.p) of false -> - tg({call, Line, {atom, Line2, FunName},ParaList},B); + tg({call, Anno, {atom, Anno2, FunName},ParaList},B); true -> - tg(list_to_tuple([op,Line2,FunName | ParaList]),B) + tg(list_to_tuple([op,Anno2,FunName | ParaList]),B) end; _ -> - throw({error,Line,{?ERR_GENREMOTECALL+B#tgd.eb,erlang, + throw({error,Anno,{?ERR_GENREMOTECALL+B#tgd.eb,erlang, FunName,length(ParaList)}}) end; -tg({call, Line, {remote,_,{atom,_,ModuleName}, +tg({call, Anno, {remote,_,{atom,_,ModuleName}, {atom, _, FunName}},ParaList},B) -> - throw({error,Line,{?ERR_GENREMOTECALL+B#tgd.eb,ModuleName,FunName,length(ParaList)}}); -tg({cons,Line, H, T},B) -> - {cons, Line, tg(H,B), tg(T,B)}; -tg({nil, Line},_B) -> - {nil, Line}; -tg({tuple,Line,L},B) -> - {tuple,Line,[{tuple,Line,lists:map(fun(X) -> tg(X,B) end, L)}]}; -tg({integer,Line,I},_) -> - {integer,Line,I}; -tg({char,Line,C},_) -> - {char,Line,C}; -tg({float, Line,F},_) -> - {float,Line,F}; -tg({atom,Line,A},_) -> + throw({error,Anno,{?ERR_GENREMOTECALL+B#tgd.eb,ModuleName,FunName,length(ParaList)}}); +tg({cons,Anno, H, T},B) -> + {cons, Anno, tg(H,B), tg(T,B)}; +tg({nil, Anno},_B) -> + {nil, Anno}; +tg({tuple,Anno,L},B) -> + {tuple,Anno,[{tuple,Anno,lists:map(fun(X) -> tg(X,B) end, L)}]}; +tg({integer,Anno,I},_) -> + {integer,Anno,I}; +tg({char,Anno,C},_) -> + {char,Anno,C}; +tg({float, Anno,F},_) -> + {float,Anno,F}; +tg({atom,Anno,A},_) -> case atom_to_list(A) of [$$|_] -> - {tuple, Line,[{atom, Line, 'const'},{atom,Line,A}]}; + {tuple, Anno,[{atom, Anno, 'const'},{atom,Anno,A}]}; _ -> - {atom,Line,A} + {atom,Anno,A} end; -tg({string,Line,S},_) -> - {string,Line,S}; -tg({var,Line,VarName},B) -> +tg({string,Anno,S},_) -> + {string,Anno,S}; +tg({var,Anno,VarName},B) -> case lkup_bind(VarName, B#tgd.b) of undefined -> - {tuple, Line,[{atom, Line, 'const'},{var,Line,VarName}]}; + {tuple, Anno,[{atom, Anno, 'const'},{var,Anno,VarName}]}; AtomName -> - {atom, Line, AtomName} + {atom, Anno, AtomName} end; -tg({record_field,Line,Object,RName,{atom,_Line1,KeyName}},B) -> +tg({record_field,Anno,Object,RName,{atom,_Anno1,KeyName}},B) -> RDefs = get_records(), case lists:keysearch(RName,1,RDefs) of {value, {RName, FieldList}} -> case lists:keysearch(KeyName,1, FieldList) of {value, {KeyName,Position,_}} -> NewObject = tg(Object,B), - {tuple, Line, [{atom, Line, 'element'}, - {integer, Line, Position}, NewObject]}; + {tuple, Anno, [{atom, Anno, 'element'}, + {integer, Anno, Position}, NewObject]}; _ -> - throw({error,Line,{?ERR_GENBADFIELD+B#tgd.eb, RName, + throw({error,Anno,{?ERR_GENBADFIELD+B#tgd.eb, RName, KeyName}}) end; _ -> - throw({error,Line,{?ERR_GENBADREC+B#tgd.eb,RName}}) + throw({error,Anno,{?ERR_GENBADREC+B#tgd.eb,RName}}) end; -tg({record,Line,RName,RFields},B) -> +tg({record,Anno,RName,RFields},B) -> RDefs = get_records(), KeyList0 = lists:foldl(fun({record_field,_,{atom,_,Key},Value}, L) -> @@ -609,7 +620,7 @@ tg({record,Line,RName,RFields},B) -> NV = tg(Value,B), [{{default},NV}|L]; (_,_) -> - throw({error,Line, + throw({error,Anno, {?ERR_GENBADREC+B#tgd.eb, RName}}) end, @@ -624,7 +635,7 @@ tg({record,Line,RName,RFields},B) -> KeyList = lists:keydelete({default},1,KeyList0), case lists:keysearch({default},1,KeyList) of {value,{{default},_}} -> - throw({error,Line,{?ERR_GENMULTIFIELD+B#tgd.eb,RName,'_'}}); + throw({error,Anno,{?ERR_GENMULTIFIELD+B#tgd.eb,RName,'_'}}); _ -> ok end, @@ -647,31 +658,31 @@ tg({record,Line,RName,RFields},B) -> end, [], FieldList0), - check_multi_field(RName,Line,KeyList, + check_multi_field(RName,Anno,KeyList, ?ERR_GENMULTIFIELD+B#tgd.eb), - check_undef_field(RName,Line,KeyList,FieldList0, + check_undef_field(RName,Anno,KeyList,FieldList0, ?ERR_GENBADFIELD+B#tgd.eb), - {tuple,Line,[{tuple,Line,[{atom,Line,RName}|FieldList1]}]}; + {tuple,Anno,[{tuple,Anno,[{atom,Anno,RName}|FieldList1]}]}; _ -> - throw({error,Line,{?ERR_GENBADREC+B#tgd.eb,RName}}) + throw({error,Anno,{?ERR_GENBADREC+B#tgd.eb,RName}}) end; -tg({record_index,Line,RName,{atom,Line2,KeyName}},B) -> +tg({record_index,Anno,RName,{atom,Anno2,KeyName}},B) -> RDefs = get_records(), case lists:keysearch(RName,1,RDefs) of {value, {RName, FieldList}} -> case lists:keysearch(KeyName,1, FieldList) of {value, {KeyName,Position,_}} -> - {integer, Line2, Position}; + {integer, Anno2, Position}; _ -> - throw({error,Line2,{?ERR_GENBADFIELD+B#tgd.eb, RName, + throw({error,Anno2,{?ERR_GENBADFIELD+B#tgd.eb, RName, KeyName}}) end; _ -> - throw({error,Line,{?ERR_GENBADREC+B#tgd.eb,RName}}) + throw({error,Anno,{?ERR_GENBADREC+B#tgd.eb,RName}}) end; -tg({record,Line,{var,Line2,_VName}=AVName, RName,RFields},B) -> +tg({record,Anno,{var,Anno2,_VName}=AVName, RName,RFields},B) -> RDefs = get_records(), MSVName = tg(AVName,B), KeyList = lists:foldl(fun({record_field,_,{atom,_,Key},Value}, @@ -679,7 +690,7 @@ tg({record,Line,{var,Line2,_VName}=AVName, RName,RFields},B) -> NV = tg(Value,B), [{Key,NV}|L]; (_,_) -> - throw({error,Line,?ERR_HEADBADREC}) + throw({error,Anno,?ERR_HEADBADREC}) end, [], RFields), @@ -691,47 +702,47 @@ tg({record,Line,{var,Line2,_VName}=AVName, RName,RFields},B) -> {value, {FN, X0}} -> X0; _ -> - {tuple, Line2, - [{atom, Line2, element}, - {integer, Line2, Pos}, + {tuple, Anno2, + [{atom, Anno2, element}, + {integer, Anno2, Pos}, MSVName]} end, [El | Acc] end, [], FieldList0), - check_multi_field(RName,Line,KeyList, + check_multi_field(RName,Anno,KeyList, ?ERR_GENMULTIFIELD+B#tgd.eb), - check_undef_field(RName,Line,KeyList,FieldList0, + check_undef_field(RName,Anno,KeyList,FieldList0, ?ERR_GENBADFIELD+B#tgd.eb), - {tuple,Line,[{tuple,Line,[{atom,Line,RName}|FieldList1]}]}; + {tuple,Anno,[{tuple,Anno,[{atom,Anno,RName}|FieldList1]}]}; _ -> - throw({error,Line,{?ERR_GENBADREC+B#tgd.eb,RName}}) + throw({error,Anno,{?ERR_GENBADREC+B#tgd.eb,RName}}) end; -tg({bin_element,_Line0,{var, Line, A},_,_} = Whole,B) -> +tg({bin_element,_Anno0,{var, Anno, A},_,_} = Whole,B) -> case lkup_bind(A, B#tgd.b) of undefined -> Whole; % exists in environment hopefully _AtomName -> - throw({error,Line,{?ERR_GENBINCONSTRUCT+B#tgd.eb,A}}) + throw({error,Anno,{?ERR_GENBINCONSTRUCT+B#tgd.eb,A}}) end; tg(default,_B) -> default; -tg({bin_element,Line,X,Y,Z},B) -> - {bin_element, Line, tg(X,B), tg(Y,B), Z}; +tg({bin_element,Anno,X,Y,Z},B) -> + {bin_element, Anno, tg(X,B), tg(Y,B), Z}; -tg({bin,Line,List},B) -> - {bin,Line,[tg(X,B) || X <- List]}; +tg({bin,Anno,List},B) -> + {bin,Anno,[tg(X,B) || X <- List]}; tg(T,B) when is_tuple(T), tuple_size(T) >= 2 -> Element = element(1,T), - Line = element(2,T), - throw({error,Line,{?ERR_GENELEMENT+B#tgd.eb, + Anno = element(2,T), + throw({error,Anno,{?ERR_GENELEMENT+B#tgd.eb, translate_language_element(Element)}}); tg(Other,B) -> Element = io_lib:format("unknown element ~tw", [Other]), - throw({error,unknown,{?ERR_GENELEMENT+B#tgd.eb,Element}}). + throw({error,erl_anno:new(0),{?ERR_GENELEMENT+B#tgd.eb,Element}}). transform_head([V],OuterBound) -> Bind = cre_bind(), @@ -739,16 +750,16 @@ transform_head([V],OuterBound) -> th(NewV,NewBind,OuterBound). -toplevel_head_match({match,_,{var,Line,VName},Expr},B,OB) -> - warn_var_clash(Line,VName,OB), +toplevel_head_match({match,_,{var,Anno,VName},Expr},B,OB) -> + warn_var_clash(Anno,VName,OB), {Expr,new_bind({VName,'$_'},B)}; -toplevel_head_match({match,_,Expr,{var,Line,VName}},B,OB) -> - warn_var_clash(Line,VName,OB), +toplevel_head_match({match,_,Expr,{var,Anno,VName}},B,OB) -> + warn_var_clash(Anno,VName,OB), {Expr,new_bind({VName,'$_'},B)}; toplevel_head_match(Other,B,_OB) -> {Other,B}. -th({record,Line,RName,RFields},B,OB) -> +th({record,Anno,RName,RFields},B,OB) -> % youch... RDefs = get_records(), {KeyList0,NewB} = lists:foldl(fun({record_field,_,{atom,_,Key},Value}, @@ -760,7 +771,7 @@ th({record,Line,RName,RFields},B,OB) -> {NV,B1} = th(Value,B0,OB), {[{{default},NV}|L],B1}; (_,_) -> - throw({error,Line,{?ERR_HEADBADREC, + throw({error,Anno,{?ERR_HEADBADREC, RName}}) end, {[],B}, @@ -769,12 +780,12 @@ th({record,Line,RName,RFields},B,OB) -> {value,{{default},OverriddenDefValue}} -> OverriddenDefValue; _ -> - {atom,Line,'_'} + {atom,Anno,'_'} end, KeyList = lists:keydelete({default},1,KeyList0), case lists:keysearch({default},1,KeyList) of {value,{{default},_}} -> - throw({error,Line,{?ERR_HEADMULTIFIELD,RName,'_'}}); + throw({error,Anno,{?ERR_HEADMULTIFIELD,RName,'_'}}); _ -> ok end, @@ -792,39 +803,39 @@ th({record,Line,RName,RFields},B,OB) -> end, [], FieldList0), - check_multi_field(RName,Line,KeyList, + check_multi_field(RName,Anno,KeyList, ?ERR_HEADMULTIFIELD), - check_undef_field(RName,Line,KeyList,FieldList0, + check_undef_field(RName,Anno,KeyList,FieldList0, ?ERR_HEADBADFIELD), - {{tuple,Line,[{atom,Line,RName}|FieldList1]},NewB}; + {{tuple,Anno,[{atom,Anno,RName}|FieldList1]},NewB}; _ -> - throw({error,Line,{?ERR_HEADBADREC,RName}}) + throw({error,Anno,{?ERR_HEADBADREC,RName}}) end; -th({match,Line,_,_},_,_) -> - throw({error,Line,?ERR_HEADMATCH}); -th({atom,Line,A},B,_OB) -> +th({match,Anno,_,_},_,_) -> + throw({error,Anno,?ERR_HEADMATCH}); +th({atom,Anno,A},B,_OB) -> case atom_to_list(A) of [$$|NL] -> case (catch list_to_integer(NL)) of N when is_integer(N) -> - throw({error,Line,{?ERR_HEADDOLLARATOM,A}}); + throw({error,Anno,{?ERR_HEADDOLLARATOM,A}}); _ -> - {{atom,Line,A},B} + {{atom,Anno,A},B} end; _ -> - {{atom,Line,A},B} + {{atom,Anno,A},B} end; -th({bin_element,_Line0,{var, Line, A},_,_},_,_) -> - throw({error,Line,{?ERR_HEADBINMATCH,A}}); +th({bin_element,_Anno0,{var, Anno, A},_,_},_,_) -> + throw({error,Anno,{?ERR_HEADBINMATCH,A}}); -th({var,Line,Name},B,OB) -> - warn_var_clash(Line,Name,OB), +th({var,Anno,Name},B,OB) -> + warn_var_clash(Anno,Name,OB), case lkup_bind(Name,B) of undefined -> NewB = new_bind(Name,B), - {{atom,Line,lkup_bind(Name,NewB)},NewB}; + {{atom,Anno,lkup_bind(Name,NewB)},NewB}; Trans -> - {{atom,Line,Trans},B} + {{atom,Anno,Trans},B} end; th([H|T],B,OB) -> {NH,NB} = th(H,B,OB), @@ -839,8 +850,8 @@ th(Nonstruct,B,_OB) -> warn_var_clash(Anno,Name,OuterBound) -> case gb_sets:is_member(Name,OuterBound) of true -> - Line = erl_anno:line(Anno), - add_warning(Line,{?WARN_SHADOW_VAR,Name}); + Location = erl_anno:location(Anno), + add_warning(Location,{?WARN_SHADOW_VAR,Name}); _ -> ok end. @@ -848,21 +859,21 @@ warn_var_clash(Anno,Name,OuterBound) -> %% Could be more efficient... check_multi_field(_, _, [], _) -> ok; -check_multi_field(RName, Line, [{Key,_}|T], ErrCode) -> +check_multi_field(RName, Anno, [{Key,_}|T], ErrCode) -> case lists:keymember(Key,1,T) of true -> - throw({error,Line,{ErrCode,RName,Key}}); + throw({error,Anno,{ErrCode,RName,Key}}); false -> - check_multi_field(RName, Line, T, ErrCode) + check_multi_field(RName, Anno, T, ErrCode) end. check_undef_field(_, _, [], _, _) -> ok; -check_undef_field(RName, Line, [{Key,_}|T], FieldList, ErrCode) -> +check_undef_field(RName, Anno, [{Key,_}|T], FieldList, ErrCode) -> case lists:keymember(Key, 1, FieldList) of true -> - check_undef_field(RName, Line, T, FieldList, ErrCode); + check_undef_field(RName, Anno, T, FieldList, ErrCode); false -> - throw({error,Line,{ErrCode,RName,Key}}) + throw({error,Anno,{ErrCode,RName,Key}}) end. cre_bind() -> @@ -1057,12 +1068,12 @@ fixup_environment(L,B) when is_list(L) -> fixup_environment(X,B) end, L); -fixup_environment({var,Line,Name},B) -> +fixup_environment({var,Anno,Name},B) -> case lists:keysearch(Name,1,B) of {value,{Name,Value}} -> - freeze(Line,Value); + freeze(Anno,Value); _ -> - throw({error,Line,{?ERR_UNBOUND_VARIABLE,atom_to_list(Name)}}) + throw({error,Anno,{?ERR_UNBOUND_VARIABLE,atom_to_list(Name)}}) end; fixup_environment(T,B) when is_tuple(T) -> list_to_tuple( @@ -1073,8 +1084,8 @@ fixup_environment(T,B) when is_tuple(T) -> fixup_environment(Other,_B) -> Other. -freeze(Line,Term) -> - {frozen,Line,Term}. +freeze(Anno,Term) -> + {frozen,Anno,Term}. %% Most of this is bluntly stolen from erl_parse. diff --git a/lib/stdlib/src/qlc.erl b/lib/stdlib/src/qlc.erl index 713ed1f896..d0e416805f 100644 --- a/lib/stdlib/src/qlc.erl +++ b/lib/stdlib/src/qlc.erl @@ -27,7 +27,9 @@ %% Avoid warning for local function error/1 clashing with autoimported BIF. -compile({no_auto_import,[error/1]}). --export([parse_transform/2, transform_from_evaluator/2]). +-export([parse_transform/2, + parse_transform_info/0, + transform_from_evaluator/2]). -export([q/1, q/2]). @@ -388,9 +390,10 @@ format_error(nomatch_pattern) -> io_lib:format("pattern cannot possibly match", []); format_error(nomatch_filter) -> io_lib:format("filter evaluates to 'false'", []); -format_error({Line, Mod, Reason}) when is_integer(Line) -> - io_lib:format("~p: ~ts~n", - [Line, lists:flatten(Mod:format_error(Reason))]); +format_error({Location, Mod, Reason}) when is_integer(Location); + tuple_size(Location) =:= 2 -> + io_lib:format("~s: ~ts~n", + [pos(Location), lists:flatten(Mod:format_error(Reason))]); %% file_sorter errors format_error({bad_object, FileName}) -> io_lib:format("the temporary file \"~ts\" holding answers is corrupt", @@ -409,6 +412,11 @@ format_error({error, Module, Reason}) -> format_error(E) -> io_lib:format("~tp~n", [E]). +pos({Line,Col}) -> + io_lib:format("~w:~w", [Line,Col]); +pos(Line) -> + io_lib:format("~w", [Line]). + -spec(info(QH) -> Info when QH :: query_handle_or_list(), Info :: abstract_expr() | string()). @@ -450,7 +458,7 @@ info(QH, Options) -> abstract_code -> abstract_code(AbstractCode); string -> - Hook = fun({special, _Line, String}, _I, _P, _F) -> + Hook = fun({special, _Anno, String}, _I, _P, _F) -> String end, lists:flatten(erl_pp:expr(AbstractCode, 0, Hook)); @@ -535,6 +543,11 @@ next_answers(T1, T2) -> parse_transform(Forms, Options) -> qlc_pt:parse_transform(Forms, Options). +-spec parse_transform_info() -> #{'error_location' => 'column'}. + +parse_transform_info() -> + #{error_location => column}. + %% The funcspecs qlc:q/1 and qlc:q/2 are known by erl_eval.erl and %% erl_lint.erl. -spec(q(QLC) -> QH when @@ -666,7 +679,7 @@ string_to_handle(Str, Options, Bindings) when is_list(Str) -> {error, ErrorInfo} -> error(ErrorInfo) end; - {error, ErrorInfo, _EndLine} -> + {error, ErrorInfo, _EndLocation} -> error(ErrorInfo) end end; @@ -765,7 +778,7 @@ name_suffix(A, Suff) -> list_to_atom(lists:concat([A, Suff])). vars(E) -> - var_ufold(fun({var,_L,V}) -> V end, E). + var_ufold(fun({var,_A,V}) -> V end, E). var_ufold(F, E) -> ordsets:from_list(var_fold(F, [], E)). @@ -1023,7 +1036,7 @@ listify(T) -> -record(simple_qlc, {p, % atom(), pattern variable le, - line :: erl_anno:anno(), + anno :: erl_anno:anno(), init_value, optz % #optz }). @@ -1139,8 +1152,8 @@ wait_for_request(Parent, MonRef, Post) -> %%% End of cursor process functions. -abstract_code({special, Line, String}) -> - {string, Line, String}; +abstract_code({special, Anno, String}) -> + {string, Anno, String}; abstract_code(Tuple) when is_tuple(Tuple) -> list_to_tuple(abstract_code(tuple_to_list(Tuple))); abstract_code([H | T]) -> @@ -1150,8 +1163,8 @@ abstract_code(Term) -> %% Also in qlc_pt.erl. -define(Q, q). --define(QLC_Q(L1, L2, L3, L4, LC, Os), - {call,L1,{remote,L2,{atom,L3,?MODULE},{atom,L4,?Q}},[LC | Os]}). +-define(QLC_Q(A1, A2, A3, A4, LC, Os), + {call,A1,{remote,A2,{atom,A3,?MODULE},{atom,A4,?Q}},[LC | Os]}). abstract(Info, false=_Flat, NElements, Depth) -> abstract(Info, NElements, Depth); @@ -1286,66 +1299,66 @@ abstract_term(Term) -> abstract_term(Term, Line) -> abstr_term(Term, anno(Line)). -abstr_term(Tuple, Line) when is_tuple(Tuple) -> - {tuple,Line,[abstr_term(E, Line) || E <- tuple_to_list(Tuple)]}; -abstr_term([_ | _]=L, Line) -> +abstr_term(Tuple, Anno) when is_tuple(Tuple) -> + {tuple,Anno,[abstr_term(E, Anno) || E <- tuple_to_list(Tuple)]}; +abstr_term([_ | _]=L, Anno) -> case io_lib:char_list(L) of true -> - erl_parse:abstract(L, erl_anno:line(Line)); + erl_parse:abstract(L, erl_anno:line(Anno)); false -> - abstr_list(L, Line) + abstr_list(L, Anno) end; -abstr_term(Fun, Line) when is_function(Fun) -> +abstr_term(Fun, Anno) when is_function(Fun) -> case erl_eval:fun_data(Fun) of {fun_data, _Bs, Cs} -> - {'fun', Line, {clauses, Cs}}; + {'fun', Anno, {clauses, Cs}}; {named_fun_data, _Bs, Name, Cs} -> - {named_fun, Line, Name, Cs}; + {named_fun, Anno, Name, Cs}; false -> {name, Name} = erlang:fun_info(Fun, name), {arity, Arity} = erlang:fun_info(Fun, arity), case erlang:fun_info(Fun, type) of {type, external} -> {module, Module} = erlang:fun_info(Fun, module), - {'fun', Line, {function, - {atom,Line,Module}, - {atom,Line,Name}, - {integer,Line,Arity}}}; + {'fun', Anno, {function, + {atom,Anno,Module}, + {atom,Anno,Name}, + {integer,Anno,Arity}}}; {type, local} -> - {'fun', Line, {function,Name,Arity}} + {'fun', Anno, {function,Name,Arity}} end end; -abstr_term(PPR, Line) when is_pid(PPR); is_port(PPR); is_reference(PPR) -> - {special, Line, lists:flatten(io_lib:write(PPR))}; -abstr_term(Map, Line) when is_map(Map) -> - {map,Line, - [{map_field_assoc,Line,abstr_term(K, Line),abstr_term(V, Line)} || +abstr_term(PPR, Anno) when is_pid(PPR); is_port(PPR); is_reference(PPR) -> + {special, Anno, lists:flatten(io_lib:write(PPR))}; +abstr_term(Map, Anno) when is_map(Map) -> + {map,Anno, + [{map_field_assoc,Anno,abstr_term(K, Anno),abstr_term(V, Anno)} || {K,V} <- maps:to_list(Map)]}; -abstr_term(Simple, Line) -> - erl_parse:abstract(Simple, erl_anno:line(Line)). +abstr_term(Simple, Anno) -> + erl_parse:abstract(Simple, erl_anno:line(Anno)). -abstr_list([H | T], Line) -> - {cons, Line, abstr_term(H, Line), abstr_list(T, Line)}; -abstr_list(T, Line) -> - abstr_term(T, Line). +abstr_list([H | T], Anno) -> + {cons, Anno, abstr_term(H, Anno), abstr_list(T, Anno)}; +abstr_list(T, Anno) -> + abstr_term(T, Anno). %% Since generator pattern variables cannot be used in list %% expressions, it is OK to flatten out QLCs using temporary %% variables. -flatten_abstr(?QLC_Q(L1, L2, L3, L4, LC0, Os), VN0, Vars, Body0) -> - {lc,L,E,Qs0} = LC0, - F = fun({generate,Ln,P,LE0}, {VN1,Body1}) -> +flatten_abstr(?QLC_Q(A1, A2, A3, A4, LC0, Os), VN0, Vars, Body0) -> + {lc,Anno,E,Qs0} = LC0, + F = fun({generate,AnnoG,P,LE0}, {VN1,Body1}) -> {VN2,Body2,LE} = flatten_abstr(LE0, VN1, Vars, Body1), - {{generate,Ln,P,LE}, {VN2,Body2}}; + {{generate,AnnoG,P,LE}, {VN2,Body2}}; (Fil, VN_Body) -> {Fil, VN_Body} end, {Qs, {VN3,Body}} = lists:mapfoldl(F, {VN0,Body0}, Qs0), - LC = {lc,L,E,Qs}, + LC = {lc,Anno,E,Qs}, {V, VN} = aux_name1('V', VN3, Vars), - Var = {var, L1, V}, - QLC = ?QLC_Q(L1, L2, L3, L4, LC, Os), - {VN + 1, [{match, L1, Var, QLC} | Body], Var}; + Var = {var, A1, V}, + QLC = ?QLC_Q(A1, A2, A3, A4, LC, Os), + {VN + 1, [{match, A1, Var, QLC} | Body], Var}; flatten_abstr(T0, VN0, Vars, Body0) when is_tuple(T0) -> {VN, Body, L} = flatten_abstr(tuple_to_list(T0), VN0, Vars, Body0), {VN, Body, list_to_tuple(L)}; @@ -1466,9 +1479,9 @@ monitor_request(Pid, Req) -> %% | {unique, boolean()} | unique %% FilterDesc = PatternDesc = TemplateDesc = binary() -le_info(#prepared{qh = #simple_qlc{le = LE, p = P, line = L, optz = Optz}}, +le_info(#prepared{qh = #simple_qlc{le = LE, p = P, anno = Anno, optz = Optz}}, InfOpt) -> - QVar = term_to_binary({var, L, P}), + QVar = term_to_binary({var, Anno, P}), {qlc, QVar, [{generate, QVar, le_info(LE, InfOpt)}], opt_info(Optz)}; le_info(#prepared{qh = #qlc{codef = CodeF, qdata = Qdata, optz = Optz}}, InfOpt) -> @@ -1557,8 +1570,8 @@ join_info(Join, QInfo, Qdata, Code) -> %% Only compared constants (==). [Cs1_0, Cs2_0] end, - L = anno0(), - G1_0 = {var,L,'G1'}, G2_0 = {var,L,'G2'}, + Anno = anno0(), + G1_0 = {var,Anno,'G1'}, G2_0 = {var,Anno,'G2'}, JP = element(JQNum + 1, Code), %% Create code for wh1 and wh2 in #join{}: {{I1,G1}, {I2,G2}, QInfoL} = @@ -1578,10 +1591,12 @@ join_info(Join, QInfo, Qdata, Code) -> end, {JOptVal, JOp} = kind2op(Kind), JOpt = [{join, JOptVal}] ++ opt_info(join_unique_cache(Opt)), - JFil = term_to_binary({op,L,JOp, - {call,L,{atom,L,element},[{integer,L,C1},G1]}, - {call,L,{atom,L,element},[{integer,L,C2},G2]}}), - P = term_to_binary({cons, L, G1, G2}), + JFil = term_to_binary({op,Anno,JOp, + {call,Anno,{atom,Anno,element}, + [{integer,Anno,C1},G1]}, + {call,Anno,{atom,Anno,element}, + [{integer,Anno,C2},G2]}}), + P = term_to_binary({cons, Anno, G1, G2}), JInfo = {generate, JP, {qlc, P, QInfoL ++ [JFil], JOpt}}, {Before, [I1 | After]} = lists:split(QNum1 - 1, QInfo), Before ++ [JInfo] ++ lists:delete(I2, After). @@ -1609,9 +1624,9 @@ join_merge_info(QNum, QInfo, Code, G, ExtraConstants) -> {P, P}; _ -> {PV, _} = aux_name1('P', 0, abstract_vars(P)), - L = erl_anno:new(0), - V = {var, L, PV}, - {V, {match, L, V, P}} + Anno = anno0(), + V = {var, Anno, PV}, + {V, {match, Anno, V, P}} end, DQP = term_to_binary(EPV), LEI = {generate, term_to_binary(M), LEInfo}, @@ -1865,7 +1880,7 @@ may_create_simple(#qlc_opt{unique = Unique, cache = Cache} = Opt, Prep end. -prep_simple_qlc(PVar, Line, LE, Opt) -> +prep_simple_qlc(PVar, Anno, LE, Opt) -> check_join_option(Opt), #prepared{is_cached = IsCached, sort_info = SortInfo, sorted = Sorted, @@ -1878,7 +1893,7 @@ prep_simple_qlc(PVar, Line, LE, Opt) -> end, Optz = #optz{unique = Unique and not IsUnique, cache = Cachez, opt = Opt}, - QLC = #simple_qlc{p = PVar, le = LE, line = Line, + QLC = #simple_qlc{p = PVar, le = LE, anno = Anno, init_value = not_a_list, optz = Optz}, %% LE#prepared.join is not copied #prepared{qh = QLC, is_unique_objects = IsUnique or Unique, diff --git a/lib/stdlib/src/qlc_pt.erl b/lib/stdlib/src/qlc_pt.erl index 7cf631d85d..91bc9e4693 100644 --- a/lib/stdlib/src/qlc_pt.erl +++ b/lib/stdlib/src/qlc_pt.erl @@ -21,7 +21,7 @@ %%% Purpose: Implements the qlc Parse Transform. --export([parse_transform/2, transform_from_evaluator/2, +-export([parse_transform/2, transform_from_evaluator/2, transform_expression/2]). -include_lib("stdlib/include/ms_transform.hrl"). @@ -29,10 +29,9 @@ -define(APIMOD, qlc). -define(Q, q). -%% Also in qlc.erl. --define(QLC_Q(L1, L2, L3, L4, LC, Os), - {call,L1,{remote,L2,{atom,L3,?APIMOD},{atom,L4,?Q}},[LC | Os]}). --define(IMP_Q(L1, L2, LC, Os), {call,L,{atom,L2,?Q},[LC | Os]}). +-define(QLC_Q(A1, A2, A3, A4, LC, Os), + {call,A1,{remote,A2,{atom,A3,?APIMOD},{atom,A4,?Q}},[LC | Os]}). +-define(IMP_Q(A1, A2, LC, Os), {call,Anno,{atom,A2,?Q},[LC | Os]}). %% Also in qlc.erl. -record(qlc_lc, % qlc:q/1,2, a query handle @@ -83,11 +82,11 @@ parse_transform(Forms0, Options) -> true -> %% The returned value should conform to the types, but %% need not evaluate to anything meaningful. - L = anno0(), - {tuple,_,Fs0} = abstr(#qlc_lc{}, L), + Anno = anno0(), + {tuple,_,Fs0} = abstr(#qlc_lc{}, Anno), F = fun(_Id, LC, A) -> - Init = simple(L, 'V', LC, L), - {{tuple,L,set_field(#qlc_lc.lc, Fs0, Init)}, A} + Init = simple(Anno, 'V', LC, Anno), + {{tuple,Anno,set_field(#qlc_lc.lc, Fs0, Init)}, A} end, {Forms1,ok} = qlc_mapfold(F, ok, Forms, State), Forms1; @@ -145,12 +144,13 @@ called_from_type_checker(Options) -> lists:member(type_checker, Options). transform_expression(LC, Bs0, WithLintErrors) -> - L = anno1(), - As = [{var,L,V} || {V,_Val} <- Bs0], + Anno = anno1(), + As = [{var,Anno,V} || {V,_Val} <- Bs0], Ar = length(As), - F = {function,L,bar,Ar,[{clause,L,As,[],[?QLC_Q(L, L, L, L, LC, [])]}]}, - Forms0 = [{attribute,L,file,{"foo",L}}, - {attribute,L,module,foo}, F], + F = {function,Anno,bar,Ar, + [{clause,Anno,As,[],[?QLC_Q(Anno, Anno, Anno, Anno, LC, [])]}]}, + Forms0 = [{attribute,Anno,file,{"foo",Anno}}, + {attribute,Anno,module,foo}, F], {Forms, FormsNoShadows, State} = initiate(Forms0, false), NodeInfo = State#state.node_info, Options = [], @@ -160,7 +160,7 @@ transform_expression(LC, Bs0, WithLintErrors) -> [] -> {NewForms,_State1} = transform(FormsNoShadows, State), NewForms1 = restore_anno(NewForms, NodeInfo), - {function,L,bar,Ar,[{clause,L,As,[],[NF]}]} = + {function,Anno,bar,Ar,[{clause,Anno,As,[],[NF]}]} = lists:last(NewForms1), {ok,NF}; Errors when WithLintErrors -> @@ -219,11 +219,11 @@ integers(I, L) when is_integer(I), I > ?ILIM -> integers(_, L) -> L. --define(I(I), {integer, L, I}). --define(A(A), {atom, L, A}). --define(V(V), {var, L, V}). --define(ABST_NO_MORE, {nil, L}). --define(ABST_MORE(Obj, Cont), {cons, L, Obj, Cont}). +-define(I(I), {integer, Anno, I}). +-define(A(A), {atom, Anno, A}). +-define(V(V), {var, Anno, V}). +-define(ABST_NO_MORE, {nil, Anno}). +-define(ABST_MORE(Obj, Cont), {cons, Anno, Obj, Cont}). %% Qualifier identifier. %% The first one encountered in a QLC has no=1. @@ -262,9 +262,9 @@ mforms(L) -> lists:sort([{File,[M]} || {File,Ms} <- L, M <- Ms]). mforms2(Tag, L) -> - Line = anno0(), + Anno = anno0(), ML = lists:flatmap(fun({File,Ms}) -> - [[{attribute,Line,file,{File,0}}, {Tag,M}] || + [[{attribute,Anno,file,{File,0}}, {Tag,M}] || M <- Ms] end, lists:sort(L)), lists:flatten(lists:sort(ML)). @@ -292,8 +292,8 @@ record_attributes(Forms) -> %% compile_messages(Forms, FormsNoShadows, Options, State) -> %% The qlc module cannot handle binary generators. - BGenF = fun(_QId,{b_generate,Line,_P,_LE}=BGen, GA, A) -> - M = {loc(Line),?APIMOD,binary_generator}, + BGenF = fun(_QId,{b_generate,Anno,_P,_LE}=BGen, GA, A) -> + M = {loc(Anno),?APIMOD,binary_generator}, {BGen,[{get(?QLC_FILE),[M]}|GA],A}; (_QId, Q, GA, A) -> {Q,GA,A} @@ -314,7 +314,7 @@ compile_messages(Forms, FormsNoShadows, Options, State) -> {Errors,Warnings}. badarg(Forms, State) -> - F = fun(_Id, {lc,_L,_E,_Qs}=LC, Es) -> + F = fun(_Id, {lc,_A,_E,_Qs}=LC, Es) -> {LC,Es}; (Id, A, Es) -> E = {get_lcid_line(Id),?APIMOD,not_a_query_list_comprehension}, @@ -372,7 +372,7 @@ genvar_pos(Location, S) -> %% intro_variables(FormsNoShadows, State) -> NodeInfo = State#state.node_info, - Fun = fun(QId, {T,_L,P0,_E0}=Q, {GVs,QIds}, Foo) when T =:= b_generate; + Fun = fun(QId, {T,_A,P0,_E0}=Q, {GVs,QIds}, Foo) when T =:= b_generate; T =:= generate -> PVs = qlc:var_ufold(fun({var,_,V}) -> {QId,V} end, P0), {Q,{ordsets:to_list(PVs) ++ GVs,[{QId,[]} | QIds]},Foo}; @@ -381,12 +381,12 @@ intro_variables(FormsNoShadows, State) -> %% where E is an LC expression consisting of a %% template mentioning all variables occurring in F. Vs = ordsets:to_list(qlc:vars(Filter0)), - AnyLine = anno0(), - Vars = [{var,AnyLine,V} || V <- Vs], - LC = embed_vars(Vars, AnyLine), + AnyAnno = anno0(), + Vars = [{var,AnyAnno,V} || V <- Vs], + LC = embed_vars(Vars, AnyAnno), LC1 = intro_anno(LC, before, QId, NodeInfo), LC2 = intro_anno(LC, 'after', QId, NodeInfo), - Filter = {block,AnyLine,[LC1,Filter0,LC2]}, + Filter = {block,AnyAnno,[LC1,Filter0,LC2]}, {Filter,{GVs,[{QId,[]} | QIds]},Foo} end, Acc0 = {[],[]}, @@ -417,7 +417,7 @@ intro_variables(FormsNoShadows, State) -> intro_anno(LC, Where, QId, NodeInfo) -> Data = {QId,Where}, Fun = fun(Anno) -> - Location = erl_anno:location(Anno), + Location = loc(Anno), true = ets:insert(NodeInfo, {Location,Data}), Anno end, @@ -481,14 +481,14 @@ bitstr_options() -> %% used_genvar_check(FormsNoShadows, State) -> NodeInfo = State#state.node_info, - F = fun(QId, {T, Ln, _P, LE}=Q, {QsIVs0, Exprs0}, IVsSoFar0) + F = fun(QId, {T, AnnoQ, _P, LE}=Q, {QsIVs0, Exprs0}, IVsSoFar0) when T =:= b_generate; T =:= generate -> F = fun(Var) -> {var, Anno0, OrigVar} = undo_no_shadows(Var, State), {var, Anno, _} = NewVar = save_anno(Var, NodeInfo), - Location0 = erl_anno:location(Anno0), - Location = erl_anno:location(Anno), + Location0 = loc(Anno0), + Location = loc(Anno), [{Location, Data}] = ets:lookup(NodeInfo, Location), Pos = {Location0,get(?QLC_FILE),OrigVar}, @@ -500,7 +500,7 @@ used_genvar_check(FormsNoShadows, State) -> lists:member(V, IVsSoFar0)], Exprs = case Vs of [] -> Exprs0; - _ -> [embed_vars(Vs, Ln) | Exprs0] + _ -> [embed_vars(Vs, AnnoQ) | Exprs0] end, {QsIVs,IVsSoFar} = q_intro_vars(QId, QsIVs0, IVsSoFar0), {Q, {QsIVs, Exprs}, IVsSoFar}; @@ -606,7 +606,7 @@ q_intro_vars(QId, [{QId, IVs} | QsIVs], IVsSoFar) -> {QsIVs, IVs ++ IVsSoFar}. %% There is one special case when calling the fun stored in the 'lc' %% field returns something else: %% - If the QLC has the form [Var || Var <- LE] and there are no -%% options to qlc:q/2, a tuple {simple_v1, P, LEf, Line} is returned. +%% options to qlc:q/2, a tuple {simple_v1, P, LEf, Anno} is returned. %% The objects returned are the objects returned by the generator %% (calling LEf returns the objects generated by LE). @@ -634,13 +634,13 @@ transform(FormsNoShadows, State) -> (QId, F, Dict, Foo) -> {F,maps:put(QId, F, Dict),Foo} end, maps:new(), [], FormsNoShadows, State), - {_,Source} = qlc_mapfold(fun(Id, {lc,_L,E,_Qs}=LC, Dict) -> + {_,Source} = qlc_mapfold(fun(Id, {lc,_A,E,_Qs}=LC, Dict) -> {LC,maps:put(Id, E, Dict)} end, Source0, FormsNoShadows, State), %% Unused variables introduced in filters are not optimized away. - F2 = fun(Id, {lc,_L,E,Qs}, {IntroVs0,XWarn0}) -> + F2 = fun(Id, {lc,_A,E,Qs}, {IntroVs0,XWarn0}) -> LcNo = get_lcid_no(Id), LcL = get_lcid_line(Id), [RL,Fun,Go,NGV,S0,RL0,Go0,AT,Err] = @@ -661,7 +661,7 @@ transform(FormsNoShadows, State) -> {QCs, AllIVs} = lists:mapfoldl(F, [], IntroVs_Qs), Dependencies = qualifier_dependencies(Qs, IntroVs), - L = no_compiler_warning(LcL), + Anno = no_compiler_warning(LcL), {EqColumnConstants, EqualColumnConstants, ExtraConsts, SizeInfo} = constants_and_sizes(Qs, E, Dependencies, AllIVs, State), @@ -672,41 +672,41 @@ transform(FormsNoShadows, State) -> %% But there are a few cases where qlc finds more... (r12b). FWarn = warn_failing_qualifiers(Qs, AllIVs, Dependencies, State), - JQs = join_quals(JoinInfo, QCs, L, LcNo, ExtraConsts, AllVars), + JQs = join_quals(JoinInfo, QCs, Anno, LcNo, ExtraConsts, AllVars), XQCs = QCs ++ JQs, Cs0 = clauses(XQCs, RL, Fun, Go, NGV, Err, AllIVs, State), - Template = template(E, RL, Fun, Go, AT, L, AllIVs, State), - Fin = final(RL, AllIVs, L, State), - FunC = {'fun',L,{clauses,Fin ++ Template ++ Cs0}}, + Template = template(E, RL, Fun, Go, AT, Anno, AllIVs, State), + Fin = final(RL, AllIVs, Anno, State), + FunC = {'fun',Anno,{clauses,Fin ++ Template ++ Cs0}}, As0 = pack_args(abst_vars([S0, RL0, Fun, Go0 | replace(AllIVs, AllIVs, nil)], - L), L, State), - AsW = abst_vars([S0, RL0, Go0], L), - FunW = {'fun',L,{clauses,[{clause,L,AsW,[], - [{match,L,{var,L,Fun},FunC}, - {call,L,{var,L,Fun},As0}]}]}}, + Anno), Anno, State), + AsW = abst_vars([S0, RL0, Go0], Anno), + FunW = {'fun',Anno,{clauses,[{clause,Anno,AsW,[], + [{match,Anno,{var,Anno,Fun},FunC}, + {call,Anno,{var,Anno,Fun},As0}]}]}}, OrigE0 = map_get(Id, Source), OrigE = undo_no_shadows(OrigE0, State), - QCode = qcode(OrigE, XQCs, Source, L, State), - Qdata = qdata(XQCs, L), + QCode = qcode(OrigE, XQCs, Source, Anno, State), + Qdata = qdata(XQCs, Anno), TemplateInfo = template_columns(Qs, E, AllIVs, Dependencies, State), %% ExtraConsts should be used by match_spec_quals. MSQs = match_spec_quals(E, Dependencies, Qs, State), - Opt = opt_info(TemplateInfo, SizeInfo, JoinInfo, MSQs, L, + Opt = opt_info(TemplateInfo, SizeInfo, JoinInfo, MSQs, Anno, EqColumnConstants, EqualColumnConstants), LCTuple = case qlc_kind(OrigE, Qs, State) of qlc -> - {tuple,L,[?A(qlc_v1),FunW,QCode,Qdata,Opt]}; - {simple, PL, LE, V} -> - Init = closure(LE, L), - simple(L, V, Init, PL) + {tuple,Anno,[?A(qlc_v1),FunW,QCode,Qdata,Opt]}; + {simple, PAnno, LE, V} -> + Init = closure(LE, Anno), + simple(Anno, V, Init, PAnno) end, - LCFun = {'fun',L,{clauses,[{clause,L,[],[],[LCTuple]}]}}, - {tuple,_,Fs0} = abstr(#qlc_lc{}, L), + LCFun = {'fun',Anno,{clauses,[{clause,Anno,[],[],[LCTuple]}]}}, + {tuple,_,Fs0} = abstr(#qlc_lc{}, Anno), Fs = set_field(#qlc_lc.lc, Fs0, LCFun), - {{tuple,L,Fs},{RestIntroVs,FWarn++XWarn++XWarn0}} + {{tuple,Anno,Fs},{RestIntroVs,FWarn++XWarn++XWarn0}} end, {NForms,{[],XW}} = qlc_mapfold(F2, {IntroVars,[]}, ModifiedForms1, State), display_forms(NForms), @@ -788,30 +788,30 @@ warn_failing_qualifiers(Qualifiers, AllIVs, Dependencies, State) -> -define(TNO, 0). -define(TID, #qid{lcid = template, no = ?TNO}). -opt_info(TemplateInfo, Sizes, JoinInfo, MSQs, L, +opt_info(TemplateInfo, Sizes, JoinInfo, MSQs, Anno, EqColumnConstants0, EqualColumnConstants0) -> - SzCls = [{clause,L,[?I(C)],[],[?I(Sz)]} || {C,Sz} <- lists:sort(Sizes)] - ++ [{clause,L,[?V('_')],[],[?A(undefined)]}], - S = [{size, {'fun', L, {clauses, SzCls}}}], - J = case JoinInfo of [] -> []; _ -> [{join, abstr(JoinInfo, L)}] end, + SzCls = [{clause,Anno,[?I(C)],[],[?I(Sz)]} || {C,Sz} <- lists:sort(Sizes)] + ++ [{clause,Anno,[?V('_')],[],[?A(undefined)]}], + S = [{size, {'fun', Anno, {clauses, SzCls}}}], + J = case JoinInfo of [] -> []; _ -> [{join, abstr(JoinInfo, Anno)}] end, %% Superfluous clauses may be emitted: TCls0 = lists:append( - [[{clause,L,[abstr(Col, L),EqType],[], - [abstr(TemplCols, L)]} || + [[{clause,Anno,[abstr(Col, Anno),EqType],[], + [abstr(TemplCols, Anno)]} || {Col,TemplCols} <- TemplateColumns] || {EqType, TemplateColumns} <- TemplateInfo]), - TCls = lists:sort(TCls0) ++ [{clause,L,[?V('_'),?V('_')],[],[{nil,L}]}], - T = [{template, {'fun', L, {clauses, TCls}}}], + TCls = lists:sort(TCls0) ++ [{clause,Anno,[?V('_'),?V('_')],[],[{nil,Anno}]}], + T = [{template, {'fun', Anno, {clauses, TCls}}}], %% The template may also have a constant function (IdNo = 0). %% Only constant template columns are interesting. EqColumnConstants = opt_column_constants(EqColumnConstants0), - CCs = opt_constants(L, EqColumnConstants), - EqC = {constants,{'fun',L,{clauses,CCs}}}, + CCs = opt_constants(Anno, EqColumnConstants), + EqC = {constants,{'fun',Anno,{clauses,CCs}}}, EqualColumnConstants = opt_column_constants(EqualColumnConstants0), - ECCs = opt_constants(L, EqualColumnConstants), - EqualC = {equal_constants,{'fun',L,{clauses,ECCs}}}, + ECCs = opt_constants(Anno, EqualColumnConstants), + EqualC = {equal_constants,{'fun',Anno,{clauses,ECCs}}}, C = [EqC | [EqualC || true <- [CCs =/= ECCs]]], %% Comparisons yield more constant columns than matchings. @@ -820,41 +820,41 @@ opt_info(TemplateInfo, Sizes, JoinInfo, MSQs, L, ConstColsFamily = family_list(ConstCols), NSortedCols0 = [{IdNo,hd(lists:seq(1, length(Cols)+1)--Cols)} || {IdNo,Cols} <- ConstColsFamily], - NCls = [{clause,L,[?I(IdNo)],[],[?I(N-1)]} || + NCls = [{clause,Anno,[?I(IdNo)],[],[?I(N-1)]} || {IdNo,N} <- NSortedCols0, N > 0] - ++ [{clause,L,[?V('_')],[],[?I(0)]}], - N = [{n_leading_constant_columns,{'fun',L,{clauses,NCls}}}], + ++ [{clause,Anno,[?V('_')],[],[?I(0)]}], + N = [{n_leading_constant_columns,{'fun',Anno,{clauses,NCls}}}], - ConstCls = [{clause,L,[?I(IdNo)],[],[abstr(Cols,L)]} || + ConstCls = [{clause,Anno,[?I(IdNo)],[],[abstr(Cols,Anno)]} || {IdNo,Cols} <- ConstColsFamily] - ++ [{clause,L,[?V('_')],[],[{nil,L}]}], - CC = [{constant_columns,{'fun',L,{clauses,ConstCls}}}], + ++ [{clause,Anno,[?V('_')],[],[{nil,Anno}]}], + CC = [{constant_columns,{'fun',Anno,{clauses,ConstCls}}}], - MSCls = [{clause,L,[?I(G)],[],[{tuple,L,[MS,abstr(Fs,L)]}]} || + MSCls = [{clause,Anno,[?I(G)],[],[{tuple,Anno,[MS,abstr(Fs,Anno)]}]} || {G,MS,Fs} <- MSQs] - ++ [{clause,L,[?V('_')],[],[?A(undefined)]}], - MS = [{match_specs, {'fun',L,{clauses,MSCls}}}], + ++ [{clause,Anno,[?V('_')],[],[?A(undefined)]}], + MS = [{match_specs, {'fun',Anno,{clauses,MSCls}}}], - Cls = [{clause,L,[?A(Tag)],[],[V]} || + Cls = [{clause,Anno,[?A(Tag)],[],[V]} || {Tag,V} <- lists:append([J, S, T, C, N, CC, MS])] - ++ [{clause,L,[?V('_')],[],[?A(undefined)]}], - {'fun', L, {clauses, Cls}}. + ++ [{clause,Anno,[?V('_')],[],[?A(undefined)]}], + {'fun', Anno, {clauses, Cls}}. opt_column_constants(ColumnConstants0) -> [CC || {{IdNo,_Col},Const,_FilNs}=CC <- ColumnConstants0, (IdNo =/= ?TNO) or (length(Const) =:= 1)]. -opt_constants(L, ColumnConstants) -> +opt_constants(Anno, ColumnConstants) -> Ns = lists:usort([IdNo || {{IdNo,_Col},_Const,_FilNs} <- ColumnConstants]), - [{clause,L,[?I(IdNo)],[],[column_fun(ColumnConstants, IdNo, L)]} + [{clause,Anno,[?I(IdNo)],[],[column_fun(ColumnConstants, IdNo, Anno)]} || IdNo <- Ns] - ++ [{clause,L,[?V('_')],[],[?A(no_column_fun)]}]. + ++ [{clause,Anno,[?V('_')],[],[?A(no_column_fun)]}]. abstr(Term, Anno) -> erl_parse:abstract(Term, loc(Anno)). %% Extra generators are introduced for join. -join_quals(JoinInfo, QCs, L, LcNo, ExtraConstants, AllVars) -> +join_quals(JoinInfo, QCs, Anno, LcNo, ExtraConstants, AllVars) -> {LastGoI, LastSI} = lists:foldl(fun({_QId,{_QIVs,{{fil,_},GoI,SI}}}, {GoI0, _SI0}) when GoI >= GoI0 -> @@ -891,18 +891,18 @@ join_quals(JoinInfo, QCs, L, LcNo, ExtraConstants, AllVars) -> QId#qid.no =:= Q2], {QId1,Op,P1,GV1,QIVs1++QIVs2,QId2,P2} end || {Q1, Q2, Op} <- lists:usort(QNums)], - Aux = abst_vars(aux_vars(['F','H','O','C'], LcNo, AllVars), L), + Aux = abst_vars(aux_vars(['F','H','O','C'], LcNo, AllVars), Anno), F = fun({QId1,Op,P1,GV1,QIVs,QId2,P2}, {QId,GoI,SI}) -> AP1 = anon_pattern(P1), AP2 = anon_pattern(P2), Cs1 = join_handle_constants(QId1, ExtraConstants), Cs2 = join_handle_constants(QId2, ExtraConstants), - H1 = join_handle(AP1, L, Aux, Cs1), - H2 = join_handle(AP2, L, Aux, Cs2), + H1 = join_handle(AP1, Anno, Aux, Cs1), + H2 = join_handle(AP2, Anno, Aux, Cs2), %% Op is not used. Join = {join,Op,QId1#qid.no,QId2#qid.no,H1,H2,Cs1,Cs2}, G = {NQId=QId#qid{no = QId#qid.no + 1}, - {QIVs,{{gen,{cons,L,P1,P2},Join,GV1},GoI,SI}}}, + {QIVs,{{gen,{cons,Anno,P1,P2},Join,GV1},GoI,SI}}}, A = {NQId, GoI + 3, SI + 2}, {G, A} end, @@ -915,12 +915,12 @@ join_qnums(Cols) -> %% Variables occurring only once are replaced by '_'. anon_pattern(P) -> MoreThanOnce = lists:usort(occ_vars(P) -- qlc:vars(P)), - {AP, foo} = var_mapfold(fun({var, L, V}, A) -> + {AP, foo} = var_mapfold(fun({var, Anno, V}, A) -> case lists:member(V, MoreThanOnce) of true -> - {{var, L, V}, A}; + {{var, Anno, V}, A}; false -> - {{var, L, '_'}, A} + {{var, Anno, '_'}, A} end end, foo, P), AP. @@ -931,10 +931,10 @@ anon_pattern(P) -> %% in order to determine if key-sorting the operands can be avoided. %% %% No objects will be filtered out if the pattern is just a variable. -join_handle(AP, L, [F, H, O, C], Constants) -> +join_handle(AP, Anno, [F, H, O, C], Constants) -> case {AP, Constants} of {{var, _, _}, []} -> - {'fun',L,{clauses,[{clause,L,[H],[],[H]}]}}; + {'fun',Anno,{clauses,[{clause,Anno,[H],[],[H]}]}}; _ -> A = anno0(), G0 = [begin @@ -942,18 +942,19 @@ join_handle(AP, L, [F, H, O, C], Constants) -> list2op([{op,A,Op,Con,Call} || {Con,Op} <- Cs], 'or') end || {Col,Cs} <- Constants], G = if G0 =:= [] -> G0; true -> [G0] end, - CC1 = {clause,L,[AP],G,[{cons,L,O,closure({call,L,F,[F,C]},L)}]}, - CC2 = {clause,L,[?V('_')],[],[{call,L,F,[F,C]}]}, - Case = {'case',L,O,[CC1,CC2]}, - Cls = [{clause,L,[?V('_'),{nil,L}],[],[{nil,L}]}, - {clause,L,[F,{cons,L,O,C}],[],[Case]}, - {clause,L,[F,C],[[{call,L,?A(is_function),[C]}]], - [{call,L,F,[F,{call,L,C,[]}]}]}, - {clause,L,[?V('_'),C],[],[C]}], - Fun = {'fun', L, {clauses, Cls}}, - {'fun',L,{clauses,[{clause,L,[H],[],[{match,L,F,Fun}, - closure({call,L,F,[F,H]}, - L)]}]}} + CC1 = {clause,Anno,[AP],G, + [{cons,Anno,O,closure({call,Anno,F,[F,C]},Anno)}]}, + CC2 = {clause,Anno,[?V('_')],[],[{call,Anno,F,[F,C]}]}, + Case = {'case',Anno,O,[CC1,CC2]}, + Cls = [{clause,Anno,[?V('_'),{nil,Anno}],[],[{nil,Anno}]}, + {clause,Anno,[F,{cons,Anno,O,C}],[],[Case]}, + {clause,Anno,[F,C],[[{call,Anno,?A(is_function),[C]}]], + [{call,Anno,F,[F,{call,Anno,C,[]}]}]}, + {clause,Anno,[?V('_'),C],[],[C]}], + Fun = {'fun', Anno, {clauses, Cls}}, + {'fun',Anno,{clauses,[{clause,Anno,[H],[], + [{match,Anno,F,Fun}, + closure({call,Anno,F,[F,H]}, Anno)]}]}} end. join_handle_constants(QId, ExtraConstants) -> @@ -1021,7 +1022,7 @@ template_columns(Qs0, E0, AllIVs, Dependencies, State) -> MatchColumns = eq_columns2(Qs, AllIVs, Dependencies, State), Equal = template_cols(EqualColumns), Match = template_cols(MatchColumns), - L = anno0(), + Anno = anno0(), if Match =:= Equal -> [{?V('_'), Match}]; @@ -1050,16 +1051,16 @@ template_as_pattern(E) -> P = simple_template(E), {?TID,foo,foo,{gen,P,{nil,anno0()}}}. -simple_template({call,L,{remote,_,{atom,_,erlang},{atom,_,element}}=Call, +simple_template({call,Anno,{remote,_,{atom,_,erlang},{atom,_,element}}=Call, [{integer,_,I}=A1,A2]}) when I > 0 -> %% This kludge is known by pattern/5 below. - {call, L, Call, [A1, simple_template(A2)]}; + {call, Anno, Call, [A1, simple_template(A2)]}; simple_template({var, _, _}=E) -> E; -simple_template({tuple, L, Es}) -> - {tuple, L, [simple_template(E) || E <- Es]}; -simple_template({cons, L, H, T}) -> - {cons, L, simple_template(H), simple_template(T)}; +simple_template({tuple, Anno, Es}) -> + {tuple, Anno, [simple_template(E) || E <- Es]}; +simple_template({cons, Anno, H, T}) -> + {cons, Anno, simple_template(H), simple_template(T)}; simple_template(E) -> case catch erl_parse:normalise(E) of {'EXIT', _} -> unique_var(); @@ -1152,17 +1153,17 @@ pattern_as_template({var,_,'_'}, TemplVar) -> {TemplVar, TemplVar}; pattern_as_template({var,_,_}=V, _TemplVar) -> {V, V}; -pattern_as_template({match,L,E,{var,_,'_'}}, TemplVar) -> - {TemplVar, {match,L,E,TemplVar}}; -pattern_as_template({match,L,{var,_,'_'},E}, TemplVar) -> - {TemplVar, {match,L,E,TemplVar}}; +pattern_as_template({match,Anno,E,{var,_,'_'}}, TemplVar) -> + {TemplVar, {match,Anno,E,TemplVar}}; +pattern_as_template({match,Anno,{var,_,'_'},E}, TemplVar) -> + {TemplVar, {match,Anno,E,TemplVar}}; pattern_as_template({match,_,_E,{var,_,_}=V}=P, _TemplVar) -> {V, P}; pattern_as_template({match,_,{var,_,_}=V,_E}=P, _TemplVar) -> {V, P}; pattern_as_template(E, TemplVar) -> - L = anno0(), - {TemplVar, {match, L, E, TemplVar}}. + Anno = anno0(), + {TemplVar, {match, Anno, E, TemplVar}}. %% Tries to find columns which are compared or matched against %% constant values or other columns. To that end unification is used. @@ -1645,8 +1646,8 @@ match_in_pattern(E, F, _BF) -> -define(ANON_VAR(N), N). anon_var(E, AnonI) -> - var_mapfold(fun({var, L, '_'}, N) -> - {{var, L, ?ANON_VAR(N)}, N+1}; + var_mapfold(fun({var, Anno, '_'}, N) -> + {{var, Anno, ?ANON_VAR(N)}, N+1}; (Var, N) -> {Var, N} end, AnonI, E). @@ -1709,15 +1710,17 @@ filter1({op, _, Op, L, R}, Fs, FS) when Op =:= 'or'; filter1(L, Fs, FS) ++ filter1(R, Fs, FS); filter1({atom,_,Atom}, _Fs, _FS) when Atom =/= true -> []; -filter1({call,L,{remote,_,{atom,_,erlang},{atom,_,is_record}},[T,R]}, +filter1({call,Anno,{remote,_,{atom,_,erlang},{atom,_,is_record}},[T,R]}, Fs, FS) -> - filter1({op,L,'=:=',{call,L,{remote,L,{atom,L,erlang},{atom,L,element}}, - [{integer,L,1},T]},R}, + filter1({op,Anno,'=:=', + {call,Anno,{remote,Anno,{atom,Anno,erlang},{atom,Anno,element}}, + [{integer,Anno,1},T]},R}, Fs, FS); %% erlang:is_record/3 (the size information is ignored): -filter1({call,L,{remote,L1,{atom,_,erlang}=M,{atom,L2,is_record}},[T,R,_Sz]}, - Fs, FS) -> - filter1({call,L,{remote,L1,M,{atom,L2,is_record}},[T,R]}, Fs, FS); +filter1({call,Anno,{remote,Anno1,{atom,_,erlang}=M,{atom,Anno2,is_record}}, + [T,R,_Sz]}, Fs, FS) -> + filter1({call,Anno,{remote,Anno1,M,{atom,Anno2,is_record}},[T,R]}, + Fs, FS); filter1(_E, Fs, _FS) -> Fs. @@ -1753,12 +1756,12 @@ safe_filter1(_E, _Fs, _FS) -> %% Substitutions: %% M:F() for {M,F}(); erlang:F() for F(); is_record() for record(). -pre_expand({call,L1,{atom,L2,record},As}) -> - pre_expand({call,L1,{atom,L2,is_record},As}); -pre_expand({call,L,{atom,_,_}=F,As}) -> - pre_expand({call,L,{remote,L,{atom,L,erlang},F},As}); -pre_expand({call,L,{tuple,_,[M,F]},As}) -> - pre_expand({call,L,{remote,L,M,F},As}); +pre_expand({call,Anno1,{atom,Anno2,record},As}) -> + pre_expand({call,Anno1,{atom,Anno2,is_record},As}); +pre_expand({call,Anno,{atom,_,_}=F,As}) -> + pre_expand({call,Anno,{remote,Anno,{atom,Anno,erlang},F},As}); +pre_expand({call,Anno,{tuple,_,[M,F]},As}) -> + pre_expand({call,Anno,{remote,Anno,M,F},As}); pre_expand(T) when is_tuple(T) -> list_to_tuple(pre_expand(tuple_to_list(T))); pre_expand([E | Es]) -> @@ -1905,7 +1908,7 @@ element_calls(E, F, _BF, _Imported) -> unique_var() -> {var, anno0(), make_ref()}. -is_unique_var({var, _L, V}) -> +is_unique_var({var, _A, V}) -> is_reference(V). expand_pattern_records(P, State) -> @@ -1923,10 +1926,10 @@ expand_expr_records(E, State) -> NE. %% Partial evaluation. -pe({op,Line,Op,A}) -> - erl_eval:partial_eval({op,Line,Op,pe(A)}); -pe({op,Line,Op,L,R}) -> - erl_eval:partial_eval({op,Line,Op,pe(L),pe(R)}); +pe({op,Anno,Op,A}) -> + erl_eval:partial_eval({op,Anno,Op,pe(A)}); +pe({op,Anno,Op,L,R}) -> + erl_eval:partial_eval({op,Anno,Op,pe(L),pe(R)}); pe(T) when is_tuple(T) -> list_to_tuple(pe(tuple_to_list(T))); pe([E | Es]) -> @@ -2038,7 +2041,7 @@ deref_op('=:=', '=:=') -> deref_op(_, _) -> '=='. -%%% Note: usort works; {integer,L,3} does not match {float,L,3.0}. +%%% Note: usort works; {integer,A,3} does not match {float,A,3.0}. var_values(Var, Frame) -> [{Value, Op} || @@ -2278,14 +2281,14 @@ bindings_subset(F1, F2, Imp) -> %% not to have guard semantics, affected filters will have to be %% recognized and excluded here as well. try_ms(E, P, Fltr, State) -> - L = anno1(), - Fun = {'fun',L,{clauses,[{clause,L,[P],[[Fltr]],[E]}]}}, - Expr = {call,L,{remote,L,{atom,L,ets},{atom,L,fun2ms}},[Fun]}, - Form = {function,L,foo,0,[{clause,L,[],[],[Expr]}]}, + Anno = anno1(), + Fun = {'fun',Anno,{clauses,[{clause,Anno,[P],[[Fltr]],[E]}]}}, + Expr = {call,Anno,{remote,Anno,{atom,Anno,ets},{atom,Anno,fun2ms}},[Fun]}, + Form = {function,Anno,foo,0,[{clause,Anno,[],[],[Expr]}]}, X = ms_transform:parse_transform(State#state.records ++ [Form], []), case catch begin - {function,L,foo,0,[{clause,L,[],[],[MS0]}]} = lists:last(X), + {function,Anno,foo,0,[{clause,Anno,[],[],[MS0]}]} = lists:last(X), MS = erl_parse:normalise(var2const(MS0)), XMS = ets:match_spec_compile(MS), true = ets:is_compiled_ms(XMS), @@ -2314,27 +2317,27 @@ qual_data(Qualifiers) -> set_field(Pos, Fs, Data) -> lists:sublist(Fs, Pos-1) ++ [Data] ++ lists:nthtail(Pos, Fs). -qdata([{#qid{no = QIdNo},{_QIVs,{{gen,_P,LE,_GV},GoI,SI}}} | QCs], L) -> +qdata([{#qid{no = QIdNo},{_QIVs,{{gen,_P,LE,_GV},GoI,SI}}} | QCs], Anno) -> Init = case LE of {join, Op, Q1, Q2, H1, H2, Cs1_0, Cs2_0} -> Cs1 = qcon(Cs1_0), Cs2 = qcon(Cs2_0), - %% -- R12B-3: {nil,L} - %% R12B-4 --: {atom,L,v1} - Compat = {atom,L,v1}, % meant for redundant match spec - CF = closure({tuple,L,[Cs1,Cs2,Compat]}, L), - {tuple,L,[?A(join),?A(Op),?I(Q1),?I(Q2),H1,H2,CF]}; + %% -- R12B-3: {nil,Anno} + %% R12B-4 --: {atom,Anno,v1} + Compat = {atom,Anno,v1}, % meant for redundant match spec + CF = closure({tuple,Anno,[Cs1,Cs2,Compat]}, Anno), + {tuple,Anno,[?A(join),?A(Op),?I(Q1),?I(Q2),H1,H2,CF]}; _ -> - closure(LE, L) + closure(LE, Anno) end, %% Create qual_data (see qlc.erl): - {cons,L,{tuple,L,[?I(QIdNo),?I(GoI),?I(SI),{tuple,L,[?A(gen),Init]}]}, - qdata(QCs, L)}; -qdata([{#qid{no = QIdNo},{_QIVs,{{fil,_F},GoI,SI}}} | QCs], L) -> + {cons,Anno,{tuple,Anno,[?I(QIdNo),?I(GoI),?I(SI),{tuple,Anno,[?A(gen),Init]}]}, + qdata(QCs, Anno)}; +qdata([{#qid{no = QIdNo},{_QIVs,{{fil,_F},GoI,SI}}} | QCs], Anno) -> %% Create qual_data (see qlc.erl): - {cons,L,{tuple,L,[?I(QIdNo),?I(GoI),?I(SI),?A(fil)]},qdata(QCs, L)}; -qdata([], L) -> - {nil,L}. + {cons,Anno,{tuple,Anno,[?I(QIdNo),?I(GoI),?I(SI),?A(fil)]},qdata(QCs, Anno)}; +qdata([], Anno) -> + {nil,Anno}. qcon(Cs) -> A = anno0(), @@ -2348,15 +2351,15 @@ qcon1(ConstOps) -> %% The original code (in Source) is used for filters and the template %% since the translated code can have QLCs and we don't want them to %% be visible. -qcode(E, QCs, Source, L, State) -> +qcode(E, QCs, Source, Anno, State) -> CL = [begin Bin = term_to_binary(C, [compressed]), - {bin, L, [{bin_element, L, - {string, L, binary_to_list(Bin)}, + {bin, Anno, [{bin_element, Anno, + {string, Anno, binary_to_list(Bin)}, default, default}]} end || {_,C} <- lists:keysort(1, [{qlc:template_state(),E} | qcode(QCs, Source, State)])], - {'fun', L, {clauses, [{clause, L, [], [], [{tuple, L, CL}]}]}}. + {'fun', Anno, {clauses, [{clause, Anno, [], [], [{tuple, Anno, CL}]}]}}. qcode([{_QId, {_QIvs, {{gen,P,_LE,_GV}, GoI, _SI}}} | QCs], Source, State) -> [{GoI,undo_no_shadows(P, State)} | qcode(QCs, Source, State)]; @@ -2366,149 +2369,150 @@ qcode([{QId, {_QIVs, {{fil,_F}, GoI, _SI}}} | QCs], Source, State) -> qcode([], _Source, _State) -> []. -closure(Code, L) -> - {'fun',L,{clauses,[{clause,L,[],[],[Code]}]}}. +closure(Code, Anno) -> + {'fun',Anno,{clauses,[{clause,Anno,[],[],[Code]}]}}. -simple(L, Var, Init, Anno) -> - {tuple,L,[?A(simple_v1),?A(Var),Init,abstr(loc(Anno), Anno)]}. +simple(Anno1, Var, Init, Anno) -> + {tuple,Anno1,[?A(simple_v1),?A(Var),Init,abstr(loc(Anno), Anno)]}. clauses([{QId,{QIVs,{QualData,GoI,S}}} | QCs], RL, Fun, Go, NGV, E, IVs,St) -> ?DEBUG("QIVs = ~p~n", [QIVs]), ?DEBUG("IVs = ~p~n", [IVs]), ?DEBUG("GoI = ~p, S = ~p~n", [GoI, S]), - L = no_compiler_warning(get_lcid_line(QId#qid.lcid)), + Anno = no_compiler_warning(get_lcid_line(QId#qid.lcid)), Cs = case QualData of {gen,P,_LE,GV} -> - generator(S, QIVs, P, GV, NGV, E, IVs, RL, Fun, Go,GoI,L,St); + generator(S, QIVs, P, GV, NGV, E, IVs, RL, Fun, + Go, GoI, Anno, St); {fil,F} -> - filter(F, L, QIVs, S, RL, Fun, Go, GoI, IVs, St) + filter(F, Anno, QIVs, S, RL, Fun, Go, GoI, IVs, St) end, Cs ++ clauses(QCs, RL, Fun, Go, NGV, E, IVs, St); clauses([], _RL, _Fun, _Go, _NGV, _IVs, _E, _St) -> []. -final(RL, IVs, L, State) -> +final(RL, IVs, Anno, State) -> IAs = replace(IVs, IVs, '_'), - AsL = pack_args([?I(0) | abst_vars([RL, '_', '_'] ++ IAs, L)], L, State), - Grd = [is_list_c(RL, L)], - Rev = {call,L,{remote,L,?A(lists),?A(reverse)},[?V(RL)]}, - CL = {clause,L,AsL,[Grd],[Rev]}, - AsF = pack_args([?I(0) | abst_vars(['_', '_', '_'] ++ IAs, L)], L, State), - CF = {clause,L,AsF,[],[?ABST_NO_MORE]}, + AsL = pack_args([?I(0) | abst_vars([RL, '_', '_'] ++ IAs, Anno)], Anno, State), + Grd = [is_list_c(RL, Anno)], + Rev = {call,Anno,{remote,Anno,?A(lists),?A(reverse)},[?V(RL)]}, + CL = {clause,Anno,AsL,[Grd],[Rev]}, + AsF = pack_args([?I(0) | abst_vars(['_', '_', '_'] ++ IAs, Anno)], Anno, State), + CF = {clause,Anno,AsF,[],[?ABST_NO_MORE]}, [CL, CF]. -template(E, RL, Fun, Go, AT, L, IVs, State) -> +template(E, RL, Fun, Go, AT, Anno, IVs, State) -> I = qlc:template_state(), GoI = qlc:template_state(), - ARL = {cons,L,E,abst_vars(RL, L)}, - Next = next(Go, GoI, L), - As0 = abst_vars([RL, Fun, Go] ++ IVs, L), - As = pack_args([?I(I) | As0], L, State), - NAs = pack_args([Next, ARL] ++ abst_vars([Fun, Go] ++ IVs, L), L, State), - Grd = [is_list_c(RL, L)], - CL = {clause,L,As,[Grd],[{call,L,?V(Fun),NAs}]}, + ARL = {cons,Anno,E,abst_vars(RL, Anno)}, + Next = next(Go, GoI, Anno), + As0 = abst_vars([RL, Fun, Go] ++ IVs, Anno), + As = pack_args([?I(I) | As0], Anno, State), + NAs = pack_args([Next, ARL] ++ abst_vars([Fun, Go] ++ IVs, Anno), Anno, State), + Grd = [is_list_c(RL, Anno)], + CL = {clause,Anno,As,[Grd],[{call,Anno,?V(Fun),NAs}]}, %% Extra careful here or arguments will be lifted into a wide fun. - F = case split_args([Next | As0], L, State) of + F = case split_args([Next | As0], Anno, State) of {ArgsL, ArgsT} -> - Call = {call,L,?V(Fun),ArgsL++[{var,L,AT}]}, - {block,L, - [{match,L,{var,L,AT},ArgsT}, - {'fun',L,{clauses,[{clause,L,[],[],[Call]}]}}]}; + Call = {call,Anno,?V(Fun),ArgsL++[{var,Anno,AT}]}, + {block,Anno, + [{match,Anno,{var,Anno,AT},ArgsT}, + {'fun',Anno,{clauses,[{clause,Anno,[],[],[Call]}]}}]}; FNAs -> - {'fun',L,{clauses,[{clause,L,[],[],[{call,L,?V(Fun),FNAs}]}]}} + {'fun',Anno,{clauses,[{clause,Anno,[],[],[{call,Anno,?V(Fun),FNAs}]}]}} end, - CF = {clause,L,As,[],[?ABST_MORE(E, F)]}, + CF = {clause,Anno,As,[],[?ABST_MORE(E, F)]}, [CL,CF]. -generator(S, QIVs, P, GV, NGV, E, IVs, RL, Fun, Go, GoI, L, State) -> - ComAs = abst_vars([RL, Fun, Go], L), - InitC = generator_init(S, L, GV, RL, Fun, Go, GoI, IVs, State), - As = [?I(S + 1)| ComAs ++ abst_vars(replace(QIVs -- [GV], IVs, '_'), L)], +generator(S, QIVs, P, GV, NGV, E, IVs, RL, Fun, Go, GoI, Anno, State) -> + ComAs = abst_vars([RL, Fun, Go], Anno), + InitC = generator_init(S, Anno, GV, RL, Fun, Go, GoI, IVs, State), + As = [?I(S + 1)| ComAs ++ abst_vars(replace(QIVs -- [GV], IVs, '_'), Anno)], - MatchS = next(Go, GoI + 1, L), - AsM0 = [MatchS | ComAs ++ abst_vars(replace([GV], IVs, NGV), L)], - AsM = pack_args(AsM0, L, State), + MatchS = next(Go, GoI + 1, Anno), + AsM0 = [MatchS | ComAs ++ abst_vars(replace([GV], IVs, NGV), Anno)], + AsM = pack_args(AsM0, Anno, State), ContS = ?I(S + 1), QIVs__GV = QIVs -- [GV], Tmp = replace([GV], replace(QIVs__GV, IVs, nil), NGV), - AsC = pack_args([ContS | ComAs ++ abst_vars(Tmp, L)], L, State), + AsC = pack_args([ContS | ComAs ++ abst_vars(Tmp, Anno)], Anno, State), - DoneS = next(Go, GoI, L), - AsD0 = [DoneS | ComAs ++ abst_vars(replace(QIVs, IVs, nil), L)], - AsD = pack_args(AsD0, L, State), + DoneS = next(Go, GoI, Anno), + AsD0 = [DoneS | ComAs ++ abst_vars(replace(QIVs, IVs, nil), Anno)], + AsD = pack_args(AsD0, Anno, State), - CsL = generator_list(P, GV, NGV, As, AsM, AsC, AsD, Fun, L, State), - CsF = generator_cont(P, GV, NGV, E, As, AsM, AsC, AsD, Fun, L, State), + CsL = generator_list(P, GV, NGV, As, AsM, AsC, AsD, Fun, Anno, State), + CsF = generator_cont(P, GV, NGV, E, As, AsM, AsC, AsD, Fun, Anno, State), [InitC | CsL ++ CsF]. -generator_init(S, L, GV, RL, Fun, Go, GoI, IVs, State) -> - As0 = abst_vars([RL, Fun, Go] ++ replace([GV], IVs, '_'), L), - As = pack_args([?I(S) | As0], L, State), - Next = next(Go, GoI + 2, L), - NAs = pack_args([?I(S + 1) | replace([?V('_')], As0, Next)], L, State), - {clause,L,As,[],[{call,L,?V(Fun),NAs}]}. - -generator_list(P, GV, NGV, As, AsM, AsC, AsD, Fun, L, State) -> - As1 = pack_args(replace([?V(GV)], As, {cons,L,P,?V(NGV)}), L, State), - As2 = pack_args(replace([?V(GV)], As, {cons,L,?V('_'),?V(NGV)}), L,State), - As3 = pack_args(replace([?V(GV)], As, {nil,L}), L, State), - CM = {clause,L,As1,[],[{call,L,?V(Fun),AsM}]}, - CC = {clause,L,As2,[],[{call,L,?V(Fun),AsC}]}, - CD = {clause,L,As3,[],[{call,L,?V(Fun),AsD}]}, +generator_init(S, Anno, GV, RL, Fun, Go, GoI, IVs, State) -> + As0 = abst_vars([RL, Fun, Go] ++ replace([GV], IVs, '_'), Anno), + As = pack_args([?I(S) | As0], Anno, State), + Next = next(Go, GoI + 2, Anno), + NAs = pack_args([?I(S + 1) | replace([?V('_')], As0, Next)], Anno, State), + {clause,Anno,As,[],[{call,Anno,?V(Fun),NAs}]}. + +generator_list(P, GV, NGV, As, AsM, AsC, AsD, Fun, Anno, State) -> + As1 = pack_args(replace([?V(GV)], As, {cons,Anno,P,?V(NGV)}), Anno, State), + As2 = pack_args(replace([?V(GV)], As, {cons,Anno,?V('_'),?V(NGV)}), Anno,State), + As3 = pack_args(replace([?V(GV)], As, {nil,Anno}), Anno, State), + CM = {clause,Anno,As1,[],[{call,Anno,?V(Fun),AsM}]}, + CC = {clause,Anno,As2,[],[{call,Anno,?V(Fun),AsC}]}, + CD = {clause,Anno,As3,[],[{call,Anno,?V(Fun),AsD}]}, [CM, CC, CD]. %% The clause 'CE' was added in R11B. The version of the generated was %% however not incremented. -generator_cont(P, GV, NGV, E, As0, AsM, AsC, AsD, Fun, L, State) -> - As = pack_args(As0, L, State), +generator_cont(P, GV, NGV, E, As0, AsM, AsC, AsD, Fun, Anno, State) -> + As = pack_args(As0, Anno, State), CF1 = ?ABST_MORE(P, ?V(NGV)), CF2 = ?ABST_MORE(?V('_'), ?V(NGV)), CF3 = ?ABST_NO_MORE, CF4 = ?V(E), - CM = {clause,L,[CF1],[],[{call,L,?V(Fun),AsM}]}, - CC = {clause,L,[CF2],[],[{call,L,?V(Fun),AsC}]}, - CD = {clause,L,[CF3],[],[{call,L,?V(Fun),AsD}]}, - CE = {clause,L,[CF4],[],[CF4]}, + CM = {clause,Anno,[CF1],[],[{call,Anno,?V(Fun),AsM}]}, + CC = {clause,Anno,[CF2],[],[{call,Anno,?V(Fun),AsC}]}, + CD = {clause,Anno,[CF3],[],[{call,Anno,?V(Fun),AsD}]}, + CE = {clause,Anno,[CF4],[],[CF4]}, Cls = [CM, CC, CD, CE], - B = {'case',L,{call,L,?V(GV),[]},Cls}, - [{clause,L,As,[],[B]}]. + B = {'case',Anno,{call,Anno,?V(GV),[]},Cls}, + [{clause,Anno,As,[],[B]}]. -filter(E, L, QIVs, S, RL, Fun, Go, GoI, IVs, State) -> +filter(E, Anno, QIVs, S, RL, Fun, Go, GoI, IVs, State) -> IAs = replace(QIVs, IVs, '_'), - As = pack_args([?I(S) | abst_vars([RL, Fun, Go] ++ IAs, L)], L, State), - NAs = abst_vars([RL, Fun, Go] ++ IVs, L), - TNext = next(Go, GoI + 1, L), - FNext = next(Go, GoI, L), - NAsT = pack_args([TNext | NAs], L, State), - NAsF = pack_args([FNext | NAs], L, State), + As = pack_args([?I(S) | abst_vars([RL, Fun, Go] ++ IAs, Anno)], Anno, State), + NAs = abst_vars([RL, Fun, Go] ++ IVs, Anno), + TNext = next(Go, GoI + 1, Anno), + FNext = next(Go, GoI, Anno), + NAsT = pack_args([TNext | NAs], Anno, State), + NAsF = pack_args([FNext | NAs], Anno, State), %% This is the "guard semantics" used in ordinary list %% comprehension: if a filter looks like a guard test, it returns %% 'false' rather than fails. Body = case is_guard_test(E, State) of true -> - CT = {clause,L,[],[[E]],[{call,L,?V(Fun),NAsT}]}, - CF = {clause,L,[],[[?A(true)]],[{call,L,?V(Fun),NAsF}]}, - [{'if',L,[CT,CF]}]; + CT = {clause,Anno,[],[[E]],[{call,Anno,?V(Fun),NAsT}]}, + CF = {clause,Anno,[],[[?A(true)]],[{call,Anno,?V(Fun),NAsF}]}, + [{'if',Anno,[CT,CF]}]; false -> - CT = {clause,L,[?A(true)],[],[{call,L,?V(Fun),NAsT}]}, - CF = {clause,L,[?A(false)],[],[{call,L,?V(Fun),NAsF}]}, - [{'case',L,E,[CT,CF]}] + CT = {clause,Anno,[?A(true)],[],[{call,Anno,?V(Fun),NAsT}]}, + CF = {clause,Anno,[?A(false)],[],[{call,Anno,?V(Fun),NAsF}]}, + [{'case',Anno,E,[CT,CF]}] end, - [{clause,L,As,[],Body}]. + [{clause,Anno,As,[],Body}]. -pack_args(Args, L, State) -> - case split_args(Args, L, State) of +pack_args(Args, Anno, State) -> + case split_args(Args, Anno, State) of {ArgsL, ArgsT} -> ArgsL ++ [ArgsT]; _ -> Args end. -split_args(Args, L, State) when length(Args) > State#state.maxargs -> +split_args(Args, Anno, State) when length(Args) > State#state.maxargs -> {lists:sublist(Args, State#state.maxargs-1), - {tuple,L,lists:nthtail(State#state.maxargs-1, Args)}}; -split_args(Args, _L, _State) -> + {tuple,Anno,lists:nthtail(State#state.maxargs-1, Args)}}; +split_args(Args, _Anno, _State) -> Args. %% Replace every element in IEs that is a member of Es by R, keep all @@ -2519,11 +2523,11 @@ replace(Es, IEs, R) -> false -> E end || E <- IEs]. -is_list_c(V, L) -> - {call,L,?A(is_list),[?V(V)]}. +is_list_c(V, Anno) -> + {call,Anno,?A(is_list),[?V(V)]}. -next(Go, GoI, L) -> - {call,L,?A(element),[?I(GoI),?V(Go)]}. +next(Go, GoI, Anno) -> + {call,Anno,?A(element),[?I(GoI),?V(Go)]}. aux_vars(Vars, LcN, AllVars) -> [aux_var(Name, LcN, 0, 1, AllVars) || Name <- Vars]. @@ -2552,9 +2556,9 @@ anno1() -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% qual_fold(Fun, GlobAcc0, Acc0, Forms, State) -> - F = fun(Id, {lc,L,E,Qs0}, GA0) -> + F = fun(Id, {lc,Anno,E,Qs0}, GA0) -> {Qs,GA,_NA} = qual_fold(Qs0, Fun, GA0, Acc0, Id, 1, []), - {{lc,L,E,Qs},GA}; + {{lc,Anno,E,Qs},GA}; (_Id, Expr, GA) -> {Expr,GA} end, @@ -2576,19 +2580,21 @@ qlcmf([E0 | Es0], F, Imp, A0, No0) -> {E, A1, No1} = qlcmf(E0, F, Imp, A0, No0), {Es, A, No} = qlcmf(Es0, F, Imp, A1, No1), {[E | Es], A, No}; -qlcmf(?QLC_Q(L1, L2, L3, L4, LC0, Os0), F, Imp, A0, No0) when length(Os0) < 2 -> +qlcmf(?QLC_Q(Anno1, Anno2, Anno3, Anno4, LC0, Os0), F, Imp, A0, No0) + when length(Os0) < 2 -> {Os, A1, No1} = qlcmf(Os0, F, Imp, A0, No0), {LC, A2, No} = qlcmf(LC0, F, Imp, A1, No1), % nested... - NL = make_lcid(L1, No), + NL = make_lcid(Anno1, No), {T, A} = F(NL, LC, A2), - {?QLC_Q(L1, L2, L3, L4, T, Os), A, No + 1}; -qlcmf(?IMP_Q(L1, L2, LC0, Os0), F, Imp=true, A0, No0) when length(Os0) < 2 -> + {?QLC_Q(Anno1, Anno2, Anno3, Anno4, T, Os), A, No + 1}; +qlcmf(?IMP_Q(Anno1, Anno2, LC0, Os0), F, Imp=true, A0, No0) + when length(Os0) < 2 -> {Os, A1, No1} = qlcmf(Os0, F, Imp, A0, No0), {LC, A2, No} = qlcmf(LC0, F, Imp, A1, No1), % nested... - NL = make_lcid(L, No), + NL = make_lcid(Anno, No), {T, A} = F(NL, LC, A2), - {?IMP_Q(L1, L2, T, Os), A, No + 1}; -qlcmf({attribute,_L,file,{File,_Line}}=Attr, _F, _Imp, A, No) -> + {?IMP_Q(Anno1, Anno2, T, Os), A, No + 1}; +qlcmf({attribute,_Anno,file,{File,_Line}}=Attr, _F, _Imp, A, No) -> put(?QLC_FILE, File), {Attr, A, No}; qlcmf(T, F, Imp, A0, No0) when is_tuple(T) -> @@ -2598,7 +2604,7 @@ qlcmf(T, _F, _Imp, A, No) -> {T, A, No}. occ_vars(E) -> - qlc:var_fold(fun({var,_L,V}) -> V end, [], E). + qlc:var_fold(fun({var,_A,V}) -> V end, [], E). %% Every Anno is replaced by a unique number. The number is used in a %% table that holds data about the abstract node where Anno resides. @@ -2607,7 +2613,7 @@ occ_vars(E) -> save_anno(Abstr, NodeInfo) -> F = fun(Anno) -> N = next_slot(NodeInfo), - Location = erl_anno:location(Anno), + Location = loc(Anno), Data = {N, #{location => Location}}, true = ets:insert(NodeInfo, Data), erl_anno:new(N) @@ -2625,7 +2631,7 @@ next_slot(T) -> restore_anno(Abstr, NodeInfo) -> F = fun(Anno) -> - Location = erl_anno:location(Anno), + Location = loc(Anno), case ets:lookup(NodeInfo, Location) of [{Location, Data}] -> OrigLocation = maps:get(location, Data), @@ -2690,45 +2696,45 @@ nos([E0 | Es0], S0) -> {E, S1} = nos(E0, S0), {Es, S} = nos(Es0, S1), {[E | Es], S}; -nos({'fun',L,{clauses,Cs}}, S) -> +nos({'fun',Anno,{clauses,Cs}}, S) -> NCs = [begin {H, S1} = nos_pattern(H0, S), {[G, B], _} = nos([G0, B0], S1), - {clause,Ln,H,G,B} - end || {clause,Ln,H0,G0,B0} <- Cs], - {{'fun',L,{clauses,NCs}}, S}; -nos({named_fun,Loc,Name,Cs}, S) -> - {{var,NLoc,NName}, S1} = case Name of + {clause,CAnno,H,G,B} + end || {clause,CAnno,H0,G0,B0} <- Cs], + {{'fun',Anno,{clauses,NCs}}, S}; +nos({named_fun,Anno,Name,Cs}, S) -> + {{var,NAnno,NName}, S1} = case Name of '_' -> S; Name -> - nos_pattern({var,Loc,Name}, S) + nos_pattern({var,Anno,Name}, S) end, NCs = [begin {H, S2} = nos_pattern(H0, S1), {[G, B], _} = nos([G0, B0], S2), - {clause,CLoc,H,G,B} - end || {clause,CLoc,H0,G0,B0} <- Cs], - {{named_fun,NLoc,NName,NCs}, S}; -nos({lc,L,E0,Qs0}, S) -> + {clause,CAnno,H,G,B} + end || {clause,CAnno,H0,G0,B0} <- Cs], + {{named_fun,NAnno,NName,NCs}, S}; +nos({lc,Anno,E0,Qs0}, S) -> %% QLCs as well as LCs. It is OK to modify LCs as long as they %% occur within QLCs--the warning messages have already been found %% by compile_errors. - F = fun({T,Ln,P0,LE0}, QS0) when T =:= b_generate; T =:= generate -> + F = fun({T,GAnno,P0,LE0}, QS0) when T =:= b_generate; T =:= generate -> {LE, _} = nos(LE0, QS0), {P, QS} = nos_pattern(P0, QS0), - {{T,Ln,P,LE}, QS}; + {{T,GAnno,P,LE}, QS}; (Filter, QS) -> nos(Filter, QS) end, {Qs, S1} = lists:mapfoldl(F, S, Qs0), {E, _} = nos(E0, S1), - {{lc,L,E,Qs}, S}; -nos({var,L,V}=Var, {_LI,Vs,UV,_A,_Sg,State}=S) when V =/= '_' -> + {{lc,Anno,E,Qs}, S}; +nos({var,Anno,V}=Var, {_LI,Vs,UV,_A,_Sg,State}=S) when V =/= '_' -> case used_var(V, Vs, UV) of {true, VN} -> - nos_var(L, V, State), - {{var,L,VN}, S}; + nos_var(Anno, V, State), + {{var,Anno,VN}, S}; false -> {Var, S} end; @@ -2746,7 +2752,7 @@ nos_pattern([P0 | Ps0], S0, PVs0) -> {P, S1, PVs1} = nos_pattern(P0, S0, PVs0), {Ps, S, PVs} = nos_pattern(Ps0, S1, PVs1), {[P | Ps], S, PVs}; -nos_pattern({var,L,V}, {LI,Vs0,UV,A,Sg,State}, PVs0) when V =/= '_' -> +nos_pattern({var,Anno,V}, {LI,Vs0,UV,A,Sg,State}, PVs0) when V =/= '_' -> {Name, Vs, PVs} = case lists:keyfind(V, 1, PVs0) of {V, VN} -> @@ -2760,8 +2766,8 @@ nos_pattern({var,L,V}, {LI,Vs0,UV,A,Sg,State}, PVs0) when V =/= '_' -> end, {N, Vs1, [{V,VN} | PVs0]} end, - nos_var(L, V, State), - {{var,L,Name}, {LI,Vs,UV,A,Sg,State}, PVs}; + nos_var(Anno, V, State), + {{var,Anno,Name}, {LI,Vs,UV,A,Sg,State}, PVs}; nos_pattern(T, S0, PVs0) when is_tuple(T) -> {TL, S, PVs} = nos_pattern(tuple_to_list(T), S0, PVs0), {list_to_tuple(TL), S, PVs}; @@ -2770,7 +2776,7 @@ nos_pattern(T, S, PVs) -> nos_var(Anno, Name, State) -> NodeInfo = State#state.node_info, - Location = erl_anno:location(Anno), + Location = loc(Anno), case ets:lookup(NodeInfo, Location) of [{Location, #{name := _}}] -> true; @@ -2807,7 +2813,7 @@ undo_no_shadows(E, State) -> var_map(fun(Anno) -> undo_no_shadows1(Anno, State) end, E). undo_no_shadows1({var, Anno, _}=Var, State) -> - Location = erl_anno:location(Anno), + Location = loc(Anno), NodeInfo = State#state.node_info, case ets:lookup(NodeInfo, Location) of [{Location, #{name := Name}}] -> @@ -2831,31 +2837,31 @@ get_lcid_line({_No, Line}) -> qid(LCId, No) -> #qid{no = No, lcid = LCId}. -abst_vars([V | Vs], L) -> - [abst_vars(V, L) | abst_vars(Vs, L)]; -abst_vars([], _L) -> +abst_vars([V | Vs], Anno) -> + [abst_vars(V, Anno) | abst_vars(Vs, Anno)]; +abst_vars([], _Anno) -> []; -abst_vars(nil, L) -> - {nil,L}; -abst_vars(V, L) -> - {var,L,V}. +abst_vars(nil, Anno) -> + {nil,Anno}; +abst_vars(V, Anno) -> + {var,Anno,V}. -embed_vars(Vars, L) -> - embed_expr({tuple,L,Vars}, L). +embed_vars(Vars, Anno) -> + embed_expr({tuple,Anno,Vars}, Anno). %% -> [Expr || _ <- []] on abstract format. -embed_expr(Expr, L) -> - {lc,L,Expr,[{generate,L,{var,L,'_'},{nil,L}}]}. +embed_expr(Expr, Anno) -> + {lc,Anno,Expr,[{generate,Anno,{var,Anno,'_'},{nil,Anno}}]}. %% Doesn't handle binaries very well, but don't bother for now. var2const(E) -> - var_map(fun({var, L, V}) -> {atom, L, V} end, E). + var_map(fun({var, A, V}) -> {atom, A, V} end, E). var_map(F, {var, _, _}=V) -> F(V); -var_map(F, {named_fun,NLoc,NName,Cs}) -> - {var,Loc,Name} = F({var,NLoc,NName}), - {named_fun,Loc,Name,var_map(F, Cs)}; +var_map(F, {named_fun,NAnno,NName,Cs}) -> + {var,Anno,Name} = F({var,NAnno,NName}), + {named_fun,Anno,Name,var_map(F, Cs)}; var_map(F, T) when is_tuple(T) -> list_to_tuple(var_map(F, tuple_to_list(T))); var_map(F, [E | Es]) -> diff --git a/lib/stdlib/src/shell.erl b/lib/stdlib/src/shell.erl index 041a89f909..ed257712ab 100644 --- a/lib/stdlib/src/shell.erl +++ b/lib/stdlib/src/shell.erl @@ -252,9 +252,9 @@ server_loop(N0, Eval_0, Bs00, RT, Ds00, History0, Results0) -> fwrite_severity(benign, <<"~ts">>, [E]), server_loop(N0, Eval0, Bs0, RT, Ds0, History0, Results0) end; - {error,{Line,Mod,What}} -> - fwrite_severity(benign, <<"~w: ~ts">>, - [Line, Mod:format_error(What)]), + {error,{Location,Mod,What}} -> + fwrite_severity(benign, <<"~s: ~ts">>, + [pos(Location), Mod:format_error(What)]), server_loop(N0, Eval0, Bs0, RT, Ds0, History0, Results0); {error,terminated} -> %Io process terminated exit(Eval0, kill), @@ -277,7 +277,7 @@ get_command(Prompt, Eval, Bs, RT, Ds) -> fun() -> exit( case - io:scan_erl_exprs(group_leader(), Prompt, 1, [text]) + io:scan_erl_exprs(group_leader(), Prompt, {1,1}, [text]) of {ok,Toks,_EndPos} -> erl_eval:extended_parse_exprs(Toks); @@ -366,107 +366,107 @@ expand_exprs([E|Es], C) -> expand_exprs([], _C) -> []. -expand_expr({cons,L,H,T}, C) -> - {cons,L,expand_expr(H, C),expand_expr(T, C)}; -expand_expr({lc,L,E,Qs}, C) -> - {lc,L,expand_expr(E, C),expand_quals(Qs, C)}; -expand_expr({bc,L,E,Qs}, C) -> - {bc,L,expand_expr(E, C),expand_quals(Qs, C)}; -expand_expr({tuple,L,Elts}, C) -> - {tuple,L,expand_exprs(Elts, C)}; -expand_expr({map,L,Es}, C) -> - {map,L,expand_exprs(Es, C)}; -expand_expr({map,L,Arg,Es}, C) -> - {map,L,expand_expr(Arg, C),expand_exprs(Es, C)}; -expand_expr({map_field_assoc,L,K,V}, C) -> - {map_field_assoc,L,expand_expr(K, C),expand_expr(V, C)}; -expand_expr({map_field_exact,L,K,V}, C) -> - {map_field_exact,L,expand_expr(K, C),expand_expr(V, C)}; -expand_expr({record_index,L,Name,F}, C) -> - {record_index,L,Name,expand_expr(F, C)}; -expand_expr({record,L,Name,Is}, C) -> - {record,L,Name,expand_fields(Is, C)}; -expand_expr({record_field,L,R,Name,F}, C) -> - {record_field,L,expand_expr(R, C),Name,expand_expr(F, C)}; -expand_expr({record,L,R,Name,Ups}, C) -> - {record,L,expand_expr(R, C),Name,expand_fields(Ups, C)}; -expand_expr({record_field,L,R,F}, C) -> %This is really illegal! - {record_field,L,expand_expr(R, C),expand_expr(F, C)}; -expand_expr({block,L,Es}, C) -> - {block,L,expand_exprs(Es, C)}; -expand_expr({'if',L,Cs}, C) -> - {'if',L,expand_cs(Cs, C)}; -expand_expr({'case',L,E,Cs}, C) -> - {'case',L,expand_expr(E, C),expand_cs(Cs, C)}; -expand_expr({'try',L,Es,Scs,Ccs,As}, C) -> - {'try',L,expand_exprs(Es, C),expand_cs(Scs, C), +expand_expr({cons,A,H,T}, C) -> + {cons,A,expand_expr(H, C),expand_expr(T, C)}; +expand_expr({lc,A,E,Qs}, C) -> + {lc,A,expand_expr(E, C),expand_quals(Qs, C)}; +expand_expr({bc,A,E,Qs}, C) -> + {bc,A,expand_expr(E, C),expand_quals(Qs, C)}; +expand_expr({tuple,A,Elts}, C) -> + {tuple,A,expand_exprs(Elts, C)}; +expand_expr({map,A,Es}, C) -> + {map,A,expand_exprs(Es, C)}; +expand_expr({map,A,Arg,Es}, C) -> + {map,A,expand_expr(Arg, C),expand_exprs(Es, C)}; +expand_expr({map_field_assoc,A,K,V}, C) -> + {map_field_assoc,A,expand_expr(K, C),expand_expr(V, C)}; +expand_expr({map_field_exact,A,K,V}, C) -> + {map_field_exact,A,expand_expr(K, C),expand_expr(V, C)}; +expand_expr({record_index,A,Name,F}, C) -> + {record_index,A,Name,expand_expr(F, C)}; +expand_expr({record,A,Name,Is}, C) -> + {record,A,Name,expand_fields(Is, C)}; +expand_expr({record_field,A,R,Name,F}, C) -> + {record_field,A,expand_expr(R, C),Name,expand_expr(F, C)}; +expand_expr({record,A,R,Name,Ups}, C) -> + {record,A,expand_expr(R, C),Name,expand_fields(Ups, C)}; +expand_expr({record_field,A,R,F}, C) -> %This is really illegal! + {record_field,A,expand_expr(R, C),expand_expr(F, C)}; +expand_expr({block,A,Es}, C) -> + {block,A,expand_exprs(Es, C)}; +expand_expr({'if',A,Cs}, C) -> + {'if',A,expand_cs(Cs, C)}; +expand_expr({'case',A,E,Cs}, C) -> + {'case',A,expand_expr(E, C),expand_cs(Cs, C)}; +expand_expr({'try',A,Es,Scs,Ccs,As}, C) -> + {'try',A,expand_exprs(Es, C),expand_cs(Scs, C), expand_cs(Ccs, C),expand_exprs(As, C)}; -expand_expr({'receive',L,Cs}, C) -> - {'receive',L,expand_cs(Cs, C)}; -expand_expr({'receive',L,Cs,To,ToEs}, C) -> - {'receive',L,expand_cs(Cs, C), expand_expr(To, C), expand_exprs(ToEs, C)}; -expand_expr({call,L,{atom,_,e},[N]}, C) -> +expand_expr({'receive',A,Cs}, C) -> + {'receive',A,expand_cs(Cs, C)}; +expand_expr({'receive',A,Cs,To,ToEs}, C) -> + {'receive',A,expand_cs(Cs, C), expand_expr(To, C), expand_exprs(ToEs, C)}; +expand_expr({call,A,{atom,_,e},[N]}, C) -> case get_cmd(N, C) of {undefined,_,_} -> no_command(N); {[Ce],_V,_CommandN} -> Ce; {Ces,_V,_CommandN} when is_list(Ces) -> - {block,L,Ces} + {block,A,Ces} end; -expand_expr({call,_L,{atom,_,v},[N]}, C) -> +expand_expr({call,_A,{atom,_,v},[N]}, C) -> case get_cmd(N, C) of {_,undefined,_} -> no_command(N); {Ces,V,CommandN} when is_list(Ces) -> {value,erl_anno:new(CommandN),V} end; -expand_expr({call,L,F,Args}, C) -> - {call,L,expand_expr(F, C),expand_exprs(Args, C)}; -expand_expr({'catch',L,E}, C) -> - {'catch',L,expand_expr(E, C)}; -expand_expr({match,L,Lhs,Rhs}, C) -> - {match,L,Lhs,expand_expr(Rhs, C)}; -expand_expr({op,L,Op,Arg}, C) -> - {op,L,Op,expand_expr(Arg, C)}; -expand_expr({op,L,Op,Larg,Rarg}, C) -> - {op,L,Op,expand_expr(Larg, C),expand_expr(Rarg, C)}; -expand_expr({remote,L,M,F}, C) -> - {remote,L,expand_expr(M, C),expand_expr(F, C)}; -expand_expr({'fun',L,{clauses,Cs}}, C) -> - {'fun',L,{clauses,expand_exprs(Cs, C)}}; -expand_expr({named_fun,L,Name,Cs}, C) -> - {named_fun,L,Name,expand_exprs(Cs, C)}; -expand_expr({clause,L,H,G,B}, C) -> +expand_expr({call,A,F,Args}, C) -> + {call,A,expand_expr(F, C),expand_exprs(Args, C)}; +expand_expr({'catch',A,E}, C) -> + {'catch',A,expand_expr(E, C)}; +expand_expr({match,A,Lhs,Rhs}, C) -> + {match,A,Lhs,expand_expr(Rhs, C)}; +expand_expr({op,A,Op,Arg}, C) -> + {op,A,Op,expand_expr(Arg, C)}; +expand_expr({op,A,Op,Larg,Rarg}, C) -> + {op,A,Op,expand_expr(Larg, C),expand_expr(Rarg, C)}; +expand_expr({remote,A,M,F}, C) -> + {remote,A,expand_expr(M, C),expand_expr(F, C)}; +expand_expr({'fun',A,{clauses,Cs}}, C) -> + {'fun',A,{clauses,expand_exprs(Cs, C)}}; +expand_expr({named_fun,A,Name,Cs}, C) -> + {named_fun,A,Name,expand_exprs(Cs, C)}; +expand_expr({clause,A,H,G,B}, C) -> %% Could expand H and G, but then erl_eval has to be changed as well. - {clause,L,H, G, expand_exprs(B, C)}; -expand_expr({bin,L,Fs}, C) -> - {bin,L,expand_bin_elements(Fs, C)}; + {clause,A,H, G, expand_exprs(B, C)}; +expand_expr({bin,A,Fs}, C) -> + {bin,A,expand_bin_elements(Fs, C)}; expand_expr(E, _C) -> % Constants. E. -expand_cs([{clause,L,P,G,B}|Cs], C) -> - [{clause,L,P,G,expand_exprs(B, C)}|expand_cs(Cs, C)]; +expand_cs([{clause,A,P,G,B}|Cs], C) -> + [{clause,A,P,G,expand_exprs(B, C)}|expand_cs(Cs, C)]; expand_cs([], _C) -> []. -expand_fields([{record_field,L,F,V}|Fs], C) -> - [{record_field,L,expand_expr(F, C),expand_expr(V, C)}| +expand_fields([{record_field,A,F,V}|Fs], C) -> + [{record_field,A,expand_expr(F, C),expand_expr(V, C)}| expand_fields(Fs, C)]; expand_fields([], _C) -> []. -expand_quals([{generate,L,P,E}|Qs], C) -> - [{generate,L,P,expand_expr(E, C)}|expand_quals(Qs, C)]; -expand_quals([{b_generate,L,P,E}|Qs], C) -> - [{b_generate,L,P,expand_expr(E, C)}|expand_quals(Qs, C)]; +expand_quals([{generate,A,P,E}|Qs], C) -> + [{generate,A,P,expand_expr(E, C)}|expand_quals(Qs, C)]; +expand_quals([{b_generate,A,P,E}|Qs], C) -> + [{b_generate,A,P,expand_expr(E, C)}|expand_quals(Qs, C)]; expand_quals([E|Qs], C) -> [expand_expr(E, C)|expand_quals(Qs, C)]; expand_quals([], _C) -> []. expand_bin_elements([], _C) -> []; -expand_bin_elements([{bin_element,L,E,Sz,Ts}|Fs], C) -> - [{bin_element,L,expand_expr(E, C),Sz,Ts}|expand_bin_elements(Fs, C)]. +expand_bin_elements([{bin_element,A,E,Sz,Ts}|Fs], C) -> + [{bin_element,A,expand_expr(E, C),Sz,Ts}|expand_bin_elements(Fs, C)]. no_command(N) -> throw({error, @@ -535,9 +535,9 @@ shell_rep(Ev, Bs0, RT, Ds0) -> receive {shell_rep,Ev,{value,V,Bs,Ds}} -> {V,Ev,Bs,Ds}; - {shell_rep,Ev,{command_error,{Line,M,Error}}} -> - fwrite_severity(benign, <<"~w: ~ts">>, - [Line, M:format_error(Error)]), + {shell_rep,Ev,{command_error,{Location,M,Error}}} -> + fwrite_severity(benign, <<"~s: ~ts">>, + [pos(Location), M:format_error(Error)]), {{'EXIT',Error},Ev,Bs0,Ds0}; {shell_req,Ev,get_cmd} -> Ev ! {shell_rep,self(),get()}, @@ -774,8 +774,8 @@ used_records({call,_,{remote,_,{atom,_,erlang},{atom,_,is_record}}, {name, Name, A}; used_records({call,_,{atom,_,record_info},[A,{atom,_,Name}]}) -> {name, Name, A}; -used_records({call,Line,{tuple,_,[M,F]},As}) -> - used_records({call,Line,{remote,Line,M,F},As}); +used_records({call,A,{tuple,_,[M,F]},As}) -> + used_records({call,A,{remote,A,M,F},As}); used_records({type,_,record,[{atom,_,Name}|Fs]}) -> {name, Name, Fs}; used_records(T) when is_tuple(T) -> @@ -908,9 +908,9 @@ apply_fun({M,F}, As, _Shell) -> apply_fun(MForFun, As, _Shell) -> apply(MForFun, As). -prep_check({call,Line,{atom,_,f},[{var,_,_Name}]}) -> +prep_check({call,Anno,{atom,_,f},[{var,_,_Name}]}) -> %% Do not emit a warning for f(V) when V is unbound. - {atom,Line,ok}; + {atom,Anno,ok}; prep_check({value,_CommandN,_Val}) -> %% erl_lint cannot handle the history expansion {value,_,_}. {atom,a0(),ok}; @@ -925,11 +925,11 @@ expand_records([], E0) -> E0; expand_records(UsedRecords, E0) -> RecordDefs = [Def || {_Name,Def} <- UsedRecords], - L = erl_anno:new(1), + A = erl_anno:new(1), E = prep_rec(E0), - Forms0 = RecordDefs ++ [{function,L,foo,0,[{clause,L,[],[],[E]}]}], + Forms0 = RecordDefs ++ [{function,A,foo,0,[{clause,A,[],[],[E]}]}], Forms = erl_expand_records:module(Forms0, [strict_record_tests]), - {function,L,foo,0,[{clause,L,[],[],[NE]}]} = lists:last(Forms), + {function,A,foo,0,[{clause,A,[],[],[NE]}]} = lists:last(Forms), prep_rec(NE). prep_rec({value,_CommandN,_V}=Value) -> @@ -985,7 +985,7 @@ local_func(rd, [{atom,_,RecName0},RecDef0], Bs, _Shell, RT, _Lf, _Ef) -> {ok,AttrForm} -> [RN] = add_records([AttrForm], Bs, RT), {value,RN,Bs}; - {error,{_Line,M,ErrDesc}} -> + {error,{_Location,M,ErrDesc}} -> ErrStr = io_lib:fwrite(<<"~ts">>, [M:format_error(ErrDesc)]), exit(lists:flatten(ErrStr)) end; @@ -1144,7 +1144,7 @@ add_records(RAs, Bs0, RT) -> Recs = [{Name,D} || {attribute,_,_,{Name,_}}=D <- RAs], Bs1 = record_bindings(Recs, Bs0), case check_command([], Bs1) of - {error,{_Line,M,ErrDesc}} -> + {error,{_Location,M,ErrDesc}} -> %% A source file that has not been compiled. ErrStr = io_lib:fwrite(<<"~ts">>, [M:format_error(ErrDesc)]), exit(lists:flatten(ErrStr)); @@ -1394,6 +1394,11 @@ substitute_v1(_F, E) -> a0() -> erl_anno:new(0). +pos({Line,Col}) -> + io_lib:format("~w:~w", [Line,Col]); +pos(Line) -> + io_lib:format("~w", [Line]). + check_and_get_history_and_results() -> check_env(shell_history_length), check_env(shell_saved_results), diff --git a/lib/stdlib/test/epp_SUITE.erl b/lib/stdlib/test/epp_SUITE.erl index a607598136..81457863ab 100644 --- a/lib/stdlib/test/epp_SUITE.erl +++ b/lib/stdlib/test/epp_SUITE.erl @@ -29,7 +29,7 @@ otp_8562/1, otp_8665/1, otp_8911/1, otp_10302/1, otp_10820/1, otp_11728/1, encoding/1, extends/1, function_macro/1, test_error/1, test_warning/1, otp_14285/1, - test_if/1,source_name/1,otp_16978/1]). + test_if/1,source_name/1,otp_16978/1,otp_16824/1]). -export([epp_parse_erl_form/2]). @@ -70,7 +70,7 @@ all() -> overload_mac, otp_8388, otp_8470, otp_8562, otp_8665, otp_8911, otp_10302, otp_10820, otp_11728, encoding, extends, function_macro, test_error, test_warning, - otp_14285, test_if, source_name, otp_16978]. + otp_14285, test_if, source_name, otp_16978,otp_16824]. groups() -> [{upcase_mac, [], [upcase_mac_1, upcase_mac_2]}, @@ -463,7 +463,7 @@ skip_header(Config) when is_list(Config) -> io:get_line(Fd, ''), io:get_line(Fd, ''), io:get_line(Fd, ''), - {ok, Epp} = epp:open(list_to_atom(File), Fd, 4, [], []), + {ok, Epp} = epp:open([{fd, Fd}, {name, list_to_atom(File)}, {location, 4}]), Forms = epp:parse_file(Epp), [] = [Reason || {error, Reason} <- Forms], @@ -479,7 +479,7 @@ otp_6277(Config) when is_list(Config) -> -define(ASSERT, ?MODULE). ?ASSERT().">>, - [{error,{{4,16},epp,{undefined,'MODULE', none}}}]}], + [{error,{4,epp,{undefined,'MODULE', none}}}]}], [] = check(Config, Ts), ok. @@ -510,34 +510,34 @@ otp_7702(Config) when is_list(Config) -> {file_7702,[{abstract_code,{_,Forms}}]} = AC, Forms2 = unopaque_forms(Forms), - [{attribute,1,file,_}, + [{attribute,{1,1},file,_}, _, _, {function,_,t,0, [{clause,_,[],[], - [{'receive',14, + [{'receive',{14,25}, [_, - {clause,14, - [{var,14,'M'}], + {clause,{14,38}, + [{var,{14,38},'M'}], [], [{_,_,_, - [{tuple,14, - [{atom,14,unexpected_message}, - {var,14,'M'}, - {atom,14,on_line}, - {integer,14,14}, - {atom,14,was_expecting}, - {string,14,"foo"}]}]}]}], - {integer,14,10000}, - [{call,14, - {atom,14,exit}, - [{tuple,14, - [{atom,14,timeout}, - {atom,14,on_line}, - {integer,14,14}, - {atom,14,was_expecting}, - {string,14,"foo"}]}]}]}]}]}, - {eof,14}] = Forms2, + [{tuple,{14,38}, + [{atom,{14,38},unexpected_message}, + {var,{14,38},'M'}, + {atom,{14,38},on_line}, + {integer,{14,38},14}, + {atom,{14,38},was_expecting}, + {string,{14,38},"foo"}]}]}]}], + {integer,{14,38},10000}, + [{call,{14,38}, + {atom,{14,38},exit}, + [{tuple,{14,38}, + [{atom,{14,38},timeout}, + {atom,{14,38},on_line}, + {integer,{14,38},14}, + {atom,{14,38},was_expecting}, + {string,{14,38},"foo"}]}]}]}]}]}, + {eof,{14,43}}] = Forms2, file:delete(File), file:delete(BeamFile), @@ -687,7 +687,7 @@ otp_8130(Config) when is_list(Config) -> {otp_8130_c8, <<"\n-include_lib(\"$apa/foo.hrl\").\n">>, - {errors,[{{2,2},epp,{include,lib,"$apa/foo.hrl"}}],[]}}, + {errors,[{{2,14},epp,{include,lib,"$apa/foo.hrl"}}],[]}}, {otp_8130_c9a, @@ -702,23 +702,23 @@ otp_8130(Config) when is_list(Config) -> {otp_8130_c10, <<"\n-file.">>, - {errors,[{{2,2},epp,{bad,file}}],[]}}, + {errors,[{{2,6},epp,{bad,file}}],[]}}, {otp_8130_c11, <<"\n-include_lib 92.">>, - {errors,[{{2,2},epp,{bad,include_lib}}],[]}}, + {errors,[{{2,14},epp,{bad,include_lib}}],[]}}, {otp_8130_c12, <<"\n-include_lib(\"kernel/include/fopp.hrl\").\n">>, - {errors,[{{2,2},epp,{include,lib,"kernel/include/fopp.hrl"}}],[]}}, + {errors,[{{2,14},epp,{include,lib,"kernel/include/fopp.hrl"}}],[]}}, {otp_8130_c13, <<"\n-include(foo).\n">>, - {errors,[{{2,2},epp,{bad,include}}],[]}}, + {errors,[{{2,10},epp,{bad,include}}],[]}}, {otp_8130_c14, <<"\n-undef({foo}).\n">>, - {errors,[{{2,2},epp,{bad,undef}}],[]}}, + {errors,[{{2,8},epp,{bad,undef}}],[]}}, {otp_8130_c15, <<"\n-define(a, 1).\n" @@ -752,11 +752,11 @@ otp_8130(Config) when is_list(Config) -> {otp_8130_c21, <<"\n-define(A(B, B), B).\n">>, - {errors,[{{2,2},epp,{bad,define}}],[]}}, + {errors,[{{2,14},epp,{duplicated_argument,'B'}}],[]}}, {otp_8130_c22, <<"\n-define(a(B, B), B).\n">>, - {errors,[{{2,2},epp,{bad,define}}],[]}}, + {errors,[{{2,14},epp,{duplicated_argument,'B'}}],[]}}, {otp_8130_c23, <<"\n-file(?b, 3).\n">>, @@ -764,11 +764,11 @@ otp_8130(Config) when is_list(Config) -> {otp_8130_c24, <<"\n-include(\"no such file.erl\").\n">>, - {errors,[{{2,2},epp,{include,file,"no such file.erl"}}],[]}}, + {errors,[{{2,10},epp,{include,file,"no such file.erl"}}],[]}}, {otp_8130_c25, <<"\n-define(A.\n">>, - {errors,[{{2,2},epp,{bad,define}}],[]}}, + {errors,[{{2,10},epp,{bad,define}}],[]}}, {otp_8130_7, <<"-record(b, {b}).\n" @@ -782,11 +782,11 @@ otp_8130(Config) when is_list(Config) -> Cks = [{otp_check_1, <<"\n-include_lib(\"epp_test.erl\").\n">>, - [{error,{{2,2},epp,{depth,"include_lib"}}}]}, + [{error,{2,epp,{depth,"include_lib"}}}]}, {otp_check_2, <<"\n-include(\"epp_test.erl\").\n">>, - [{error,{{2,2},epp,{depth,"include"}}}]} + [{error,{2,epp,{depth,"include"}}}]} ], [] = check(Config, Cks), @@ -885,7 +885,7 @@ ifdef(Config) -> {ifdef_c4, <<"\n-ifdef a.\n" "-endif.\n">>, - {errors,[{{2,2},epp,{bad,ifdef}}],[]}}, + {errors,[{{2,8},epp,{bad,ifdef}}],[]}}, {ifdef_c5, <<"-ifdef(a).\n" @@ -908,7 +908,7 @@ ifdef(Config) -> "-else.\n" "t() -> a.\n" "-endif.\n">>, - {errors,[{{2,2},epp,{bad,else}}],[]}}, + {errors,[{{3,1},epp,{bad,else}}],[]}}, {ifdef_c8, <<"-ifdef(a).\n" @@ -950,11 +950,11 @@ ifdef(Config) -> {ifndef_c4, <<"\n-ifndef a.\n" "-endif.\n">>, - {errors,[{{2,2},epp,{bad,ifndef}}],[]}}, + {errors,[{{2,9},epp,{bad,ifndef}}],[]}}, {define_c5, <<"-\ndefine a.\n">>, - {errors,[{{2,1},epp,{bad,define}}],[]}} + {errors,[{{2,8},epp,{bad,define}}],[]}} ], [] = compile(Config, Cs), @@ -1046,7 +1046,7 @@ test_error(Config) -> "-ifdef(NOT_DEFINED).\n" " -error(\"this one will be skipped\").\n" "-endif.\n">>, - {errors,[{1,epp,{error,"string and macro: epp_test"}}],[]}}, + {errors,[{{1,21},epp,{error,"string and macro: epp_test"}}],[]}}, {error_c2, <<"-ifdef(CONFIG_A).\n" @@ -1058,11 +1058,11 @@ test_error(Config) -> "-error(\"Neither CONFIG_A nor CONFIG_B are available\").\n" "-endif.\n" "-endif.\n">>, - {errors,[{7,epp,{error,"Neither CONFIG_A nor CONFIG_B are available"}}],[]}}, + {errors,[{{7,2},epp,{error,"Neither CONFIG_A nor CONFIG_B are available"}}],[]}}, {error_c3, <<"-error(a b c).\n">>, - {errors,[{1,epp,{bad,error}}],[]}} + {errors,[{{1,21},epp,{bad,error}}],[]}} ], @@ -1076,7 +1076,7 @@ test_warning(Config) -> "-ifdef(NOT_DEFINED).\n" "-warning(\"this one will be skipped\").\n" "-endif.\n">>, - {warnings,[{1,epp,{warning,{a,term,epp_test}}}]}}, + {warnings,[{{1,21},epp,{warning,{a,term,epp_test}}}]}}, {warn_c2, <<"-ifdef(CONFIG_A).\n" @@ -1089,11 +1089,11 @@ test_warning(Config) -> "-warning(\"Using fallback\").\n" "-endif.\n" "-endif.\n">>, - {warnings,[{8,epp,{warning,"Using fallback"}}]}}, + {warnings,[{{8,2},epp,{warning,"Using fallback"}}]}}, {warn_c3, <<"-warning(a b c).\n">>, - {errors,[{1,epp,{bad,warning}}],[]}} + {errors,[{{1,21},epp,{bad,warning}}],[]}} ], [] = compile(Config, Cs), @@ -1113,10 +1113,10 @@ test_if(Config) -> "-if(a+3).\n" "syntax error not triggered here.\n" "-endif.\n">>, - {errors,[{1,epp,{bad,'if'}}, - {3,epp,{bad,'if'}}, - {5,erl_parse,["syntax error before: ","error"]}, - {11,epp,{illegal,"unterminated",'if'}}], + {errors,[{{1,23},epp,{bad,'if'}}, + {{3,5},epp,{bad,'if'}}, + {{5,12},erl_parse,["syntax error before: ","error"]}, + {{11,1},epp,{illegal,"unterminated",'if'}}], []}}, {if_2c, %Bad guard expressions. @@ -1124,42 +1124,42 @@ test_if(Config) -> "-endif.\n" "-if(begin true end).\n" "-endif.\n">>, - {errors,[{1,epp,{bad,'if'}}, - {3,epp,{bad,'if'}}], + {errors,[{{1,21},epp,{bad,'if'}}, + {{3,2},epp,{bad,'if'}}], []}}, {if_3c, %Invalid use of defined/1. <<"-if defined(42).\n" "-endif.\n">>, - {errors,[{1,epp,{bad,'if'}}],[]}}, + {errors,[{{1,24},epp,{bad,'if'}}],[]}}, {if_4c, <<"-elif OTP_RELEASE > 18.\n">>, - {errors,[{1,epp,{illegal,"unbalanced",'elif'}}],[]}}, + {errors,[{{1,21},epp,{illegal,"unbalanced",'elif'}}],[]}}, {if_5c, <<"-ifdef(not_defined_today).\n" "-else.\n" "-elif OTP_RELEASE > 18.\n" "-endif.\n">>, - {errors,[{3,epp,{illegal,"unbalanced",'elif'}}],[]}}, + {errors,[{{3,2},epp,{illegal,"unbalanced",'elif'}}],[]}}, {if_6c, <<"-if(defined(OTP_RELEASE)).\n" "-else.\n" "-elif(true).\n" "-endif.\n">>, - {errors,[{3,epp,elif_after_else}],[]}}, + {errors,[{{3,2},epp,elif_after_else}],[]}}, {if_7c, <<"-if(begin true end).\n" %Not a guard expression. "-endif.\n">>, - {errors,[{1,epp,{bad,'if'}}],[]}}, + {errors,[{{1,21},epp,{bad,'if'}}],[]}}, {if_8c, <<"-if(?foo).\n" %Undefined symbol. "-endif.\n">>, - {errors,[{1,epp,{undefined,foo,none}}],[]}} + {errors,[{{1,25},epp,{undefined,foo,none}}],[]}} ], [] = compile(Config, Cs), @@ -1260,8 +1260,8 @@ overload_mac(Config) when is_list(Config) -> %% cannot overload predefined macros {overload_mac_c2, - <<"-define(MODULE(X), X).">>, - {errors,[{{1,50},epp,{redefine_predef,'MODULE'}}],[]}}, + <<"\n-define(MODULE(X), X).">>, + {errors,[{{2,9},epp,{redefine_predef,'MODULE'}}],[]}}, %% cannot overload macros with same arity {overload_mac_c3, @@ -1331,15 +1331,15 @@ otp_8388(Config) when is_list(Config) -> "t() -> ?m(a,).\n">>, {errors,[{{2,9},epp,{arg_error,m}}],[]}}, {macro_3, - <<"-define(LINE, a).\n">>, - {errors,[{{1,50},epp,{redefine_predef,'LINE'}}],[]}}, + <<"\n-define(LINE, a).\n">>, + {errors,[{{2,9},epp,{redefine_predef,'LINE'}}],[]}}, {macro_4, <<"-define(A(B, C, D), {B,C,D}).\n" "t() -> ?A(a,,3).\n">>, {errors,[{{2,9},epp,{mismatch,'A'}}],[]}}, {macro_5, <<"-define(Q, {?F0(), ?F1(,,4)}).\n">>, - {errors,[{{1,62},epp,{arg_error,'F1'}}],[]}}, + {errors,[{{1,40},epp,{arg_error,'F1'}}],[]}}, {macro_6, <<"-define(FOO(X), ?BAR(X)).\n" "-define(BAR(X), ?FOO(X)).\n" @@ -1365,10 +1365,10 @@ otp_8470(Config) when is_list(Config) -> %% OTP-8562. Record with no fields is considered typed. otp_8562(Config) when is_list(Config) -> Cs = [{otp_8562, - <<"-define(P(), {a,b}.\n" + <<"\n-define(P(), {a,b}.\n" "-define(P3, .\n">>, - {errors,[{{1,60},epp,missing_parenthesis}, - {{2,13},epp,missing_parenthesis}], []}} + {errors,[{{2,19},epp,missing_parenthesis}, + {{3,13},epp,missing_parenthesis}], []}} ], [] = compile(Config, Cs), ok. @@ -1413,9 +1413,9 @@ do_otp_8911(Config) -> %% OTP-8665. Bugfix premature end. otp_8665(Config) when is_list(Config) -> - Cs = [{otp_8562, - <<"-define(A, a)\n">>, - {errors,[{{1,54},epp,premature_end}],[]}} + Cs = [{otp_8665, + <<"\n-define(A, a)\n">>, + {errors,[{{2,13},epp,premature_end}],[]}} ], [] = compile(Config, Cs), ok. @@ -1423,10 +1423,10 @@ otp_8665(Config) when is_list(Config) -> %% OTP-10302. Unicode characters scanner/parser. otp_10302(Config) when is_list(Config) -> %% Two messages (one too many). Keeps otp_4871 happy. - Cs = [{otp_8562, + Cs = [{otp_10302, <<"%% coding: utf-8\n \n \x{E4}">>, - {errors,[{3,epp,cannot_parse}, - {3,file_io_server,invalid_unicode}],[]}} + {errors,[{{3,1},epp,cannot_parse}, + {{3,1},file_io_server,invalid_unicode}],[]}} ], [] = compile(Config, Cs), Dir = proplists:get_value(priv_dir, Config), @@ -1516,7 +1516,7 @@ do_otp_10820(File, C, PC) -> %% OTP_14285: Unicode atoms. otp_14285(Config) when is_list(Config) -> %% This is just a sample of errors. - Cs = [{otp_8562, + Cs = [{otp_14285, <<"-export([f/0]). -define('a\x{400}b', 'a\x{400}d'). f() -> @@ -1526,8 +1526,8 @@ otp_14285(Config) when is_list(Config) -> h() -> ?'a\x{400}no'(). "/utf8>>, - {errors,[{6,epp,{call,[63,[91,["97",44,"1024",44,"98"],93]]}}, - {8,epp,{undefined,'a\x{400}no',0}}], + {errors,[{{6,20},epp,{call,[63,[91,["97",44,"1024",44,"98"],93]]}}, + {{8,20},epp,{undefined,'a\x{400}no',0}}], []}} ], [] = compile(Config, Cs), @@ -1565,11 +1565,11 @@ encoding(Config) when is_list(Config) -> %% ",246," ">>, ok = file:write_file(ErlFile, C1), - {ok,[{attribute,1,file,_}, - {attribute,1,module,encoding}, + {ok,[{attribute,{1,1},file,_}, + {attribute,{1,2},module,encoding}, {error,_}, - {error,{2,epp,cannot_parse}}, - {eof,2}]} = epp_parse_file(ErlFile, []), + {error,{{2,12},epp,cannot_parse}}, + {eof,{2,12}}]} = epp_parse_file(ErlFile, [{location, {1,1}}]), {ok,[{attribute,1,file,_}, {attribute,1,module,encoding}, {eof,3}]} = @@ -1614,7 +1614,7 @@ encoding(Config) when is_list(Config) -> extends(Config) -> Cs = [{extends_c1, <<"-extends(some.other.module).\n">>, - {errors,[{1,erl_parse,["syntax error before: ","'.'"]}],[]}}], + {errors,[{{1,33},erl_parse,["syntax error before: ","'.'"]}],[]}}], [] = compile(Config, Cs), Ts = [{extends_1, @@ -1637,29 +1637,29 @@ function_macro(Config) -> "-file(?FUNCTION_ARITY, 1).\n" "f1() ?FUNCTION_NAME/?FUNCTION_ARITY.\n" "f2(?FUNCTION_NAME.\n">>, - {errors,[{1,epp,{redefine_predef,'FUNCTION_NAME'}}, - {2,epp,{redefine_predef,'FUNCTION_ARITY'}}, - {6,epp,{illegal_function,'FUNCTION_NAME'}}, - {7,epp,{illegal_function,'FUNCTION_NAME'}}, - {8,epp,{illegal_function,'FUNCTION_ARITY'}}, - {9,erl_parse,["syntax error before: ","f1"]}, - {10,erl_parse,["syntax error before: ","'.'"]}], + {errors,[{{1,28},epp,{redefine_predef,'FUNCTION_NAME'}}, + {{2,9},epp,{redefine_predef,'FUNCTION_ARITY'}}, + {{6,11},epp,{illegal_function,'FUNCTION_NAME'}}, + {{7,9},epp,{illegal_function,'FUNCTION_NAME'}}, + {{8,8},epp,{illegal_function,'FUNCTION_ARITY'}}, + {{9,7},erl_parse,["syntax error before: ","f1"]}, + {{10,18},erl_parse,["syntax error before: ","'.'"]}], []}}, {f_c2, <<"a({a) -> ?FUNCTION_NAME.\n" "b(}{) -> ?FUNCTION_ARITY.\n" "c(?FUNCTION_NAME, ?not_defined) -> ok.\n">>, - {errors,[{1,erl_parse,["syntax error before: ","')'"]}, - {2,erl_parse,["syntax error before: ","'}'"]}, - {3,epp,{undefined,not_defined,none}}], + {errors,[{{1,24},erl_parse,["syntax error before: ","')'"]}, + {{2,3},erl_parse,["syntax error before: ","'}'"]}, + {{3,20},epp,{undefined,not_defined,none}}], []}}, {f_c3, <<"?FUNCTION_NAME() -> ok.\n" "?FUNCTION_ARITY() -> ok.\n">>, - {errors,[{1,epp,{illegal_function_usage,'FUNCTION_NAME'}}, - {2,epp,{illegal_function_usage,'FUNCTION_ARITY'}}], + {errors,[{{1,21},epp,{illegal_function_usage,'FUNCTION_NAME'}}, + {{2,2},epp,{illegal_function_usage,'FUNCTION_ARITY'}}], []}} ], @@ -1734,9 +1734,232 @@ otp_16978(Config) when is_list(Config) -> ok. +otp_16824(Config) when is_list(Config) -> + Cs = [{otp_16824_1, + <<"\n-file(.">>, + {errors,[{{2,7},epp,{bad,file}}],[]}}, + + {otp_16824_2, + <<"\n-file(foo, a).">>, + {errors,[{{2,7},epp,{bad,file}}],[]}}, + + {otp_16824_3, + <<"\n-file(\"foo\" + a).">>, + {errors,[{{2,13},epp,{bad,file}}],[]}}, + + {otp_16824_4, + <<"\n-file(\"foo\", a).">>, + {errors,[{{2,14},epp,{bad,file}}],[]}}, + + %% The location before "foo", not after, unfortunately. + {otp_16824_5, + <<"\n-file(\"foo\"">>, + {errors,[{{2,7},epp,{bad,file}}],[]}}, + + {otp_16824_6, + <<"\n-endif()">>, + {errors,[{{2,7},epp,{bad,endif}}],[]}}, + + {otp_16824_7, + <<"\n-if[.\n" + "-endif.">>, + {errors,[{{2,4},epp,{bad,'if'}}], + []}}, + + {otp_16824_8, + <<"\n-else\n" + "-endif.">>, + {errors,[{{3,1},epp,{bad,else}}],[]}}, + + {otp_16824_9, + <<"\n-ifndef.\n" + "-endif.">>, + {errors,[{{2,8},epp,{bad,ifndef}}],[]}}, + + {otp_16824_10, + <<"\n-ifndef(.\n" + "-endif.">>, + {errors,[{{2,9},epp,{bad,ifndef}}],[]}}, + + {otp_16824_11, + <<"\n-ifndef(a.\n" + "-endif.">>, + {errors,[{{2,10},epp,{bad,ifndef}}],[]}}, + + {otp_16824_12, + <<"\n-ifndef(A.\n" + "-endif.">>, + {errors,[{{2,10},epp,{bad,ifndef}}],[]}}, + + {otp_16824_13, + <<"\n-ifndef(a,A).\n" + "-endif.">>, + {errors,[{{2,10},epp,{bad,ifndef}}],[]}}, + + {otp_16824_14, + <<"\n-ifndef(A,a).\n" + "-endif.">>, + {errors,[{{2,10},epp,{bad,ifndef}}],[]}}, + + {otp_16824_15, + <<"\n-ifdef.\n" + "-endif.">>, + {errors,[{{2,7},epp,{bad,ifdef}}],[]}}, + + {otp_16824_16, + <<"\n-ifdef(.\n" + "-endif.">>, + {errors,[{{2,8},epp,{bad,ifdef}}],[]}}, + + {otp_16824_17, + <<"\n-ifdef(a.\n" + "-endif.">>, + {errors,[{{2,9},epp,{bad,ifdef}}],[]}}, + + {otp_16824_18, + <<"\n-ifdef(A.\n" + "-endif.">>, + {errors,[{{2,9},epp,{bad,ifdef}}],[]}}, + + {otp_16824_19, + <<"\n-ifdef(a,A).\n" + "-endif.">>, + {errors,[{{2,9},epp,{bad,ifdef}}],[]}}, + + {otp_16824_20, + <<"\n-ifdef(A,a).\n" + "-endif.">>, + {errors,[{{2,9},epp,{bad,ifdef}}],[]}}, + + {otp_16824_21, + <<"\n-include_lib.\n">>, + {errors,[{{2,13},epp,{bad,include_lib}}],[]}}, + + {otp_16824_22, + <<"\n-include_lib(.\n">>, + {errors,[{{2,14},epp,{bad,include_lib}}],[]}}, + + {otp_16824_23, + <<"\n-include_lib(a.\n">>, + {errors,[{{2,14},epp,{bad,include_lib}}],[]}}, + + {otp_16824_24, + <<"\n-include_lib(\"a\"].\n">>, + {errors,[{{2,17},epp,{bad,include_lib}}],[]}}, + + {otp_16824_25, + <<"\n-include_lib(\"a\", 1).\n">>, + {errors,[{{2,17},epp,{bad,include_lib}}],[]}}, + + {otp_16824_26, + <<"\n-include.\n">>, + {errors,[{{2,9},epp,{bad,include}}],[]}}, + + {otp_16824_27, + <<"\n-include(.\n">>, + {errors,[{{2,10},epp,{bad,include}}],[]}}, + + {otp_16824_28, + <<"\n-include(a.\n">>, + {errors,[{{2,10},epp,{bad,include}}],[]}}, + + {otp_16824_29, + <<"\n-include(\"a\"].\n">>, + {errors,[{{2,13},epp,{bad,include}}],[]}}, + + {otp_16824_30, + <<"\n-include(\"a\", 1).\n">>, + {errors,[{{2,13},epp,{bad,include}}],[]}}, + + {otp_16824_31, + <<"\n-undef.\n">>, + {errors,[{{2,7},epp,{bad,undef}}],[]}}, + + {otp_16824_32, + <<"\n-undef(.\n">>, + {errors,[{{2,8},epp,{bad,undef}}],[]}}, + + {otp_16824_33, + <<"\n-undef(a.\n">>, + {errors,[{{2,9},epp,{bad,undef}}],[]}}, + + {otp_16824_34, + <<"\n-undef(A.\n">>, + {errors,[{{2,9},epp,{bad,undef}}],[]}}, + + {otp_16824_35, + <<"\n-undef(a,A).\n">>, + {errors,[{{2,9},epp,{bad,undef}}],[]}}, + + {otp_16824_36, + <<"\n-undef(A,a).\n">>, + {errors,[{{2,9},epp,{bad,undef}}],[]}}, + + {otp_16824_37, + <<"\n-define.\n">>, + {errors,[{{2,8},epp,{bad,define}}],[]}}, + + {otp_16824_38, + <<"\n-define(.\n">>, + {errors,[{{2,9},epp,{bad,define}}],[]}}, + + {otp_16824_39, + <<"\n-define(1.\n">>, + {errors,[{{2,9},epp,{bad,define}}],[]}}, + + {otp_16824_40, + <<"\n-define(a b.\n">>, + {errors,[{{2,11},epp,{bad,define}}],[]}}, + + {otp_16824_41, + <<"\n-define(A b.\n">>, + {errors,[{{2,11},epp,{bad,define}}],[]}}, + + {otp_16824_42, + <<"\n-define(a(A, A), 1).\n">>, + {errors,[{{2,14},epp,{duplicated_argument,'A'}}],[]}}, + + {otp_16824_43, + <<"\n-define(a(A, A, B), 1).\n">>, + {errors,[{{2,14},epp,{duplicated_argument,'A'}}],[]}}, + + {otp_16824_44, + <<"\n-define(a(.">>, + {errors,[{{2,11},epp,{bad,define}}],[]}}, + + {otp_16824_45, + <<"\n-define(a(1.">>, + {errors,[{{2,11},epp,{bad,define}}],[]}}, + + {otp_16824_46, + <<"\n-define(a().">>, + {errors,[{{2,12},epp,missing_comma}],[]}}, + + {otp_16824_47, + <<"\n-define(a())">>, + {errors,[{{2,12},epp,missing_comma}],[]}}, + + {otp_16824_48, + <<"\n-define(A(A,), foo).\n">>, + {errors,[{{2,12},epp,{bad,define}}],[]}}, + + {otp_16824_49, + <<"\n-warning.">>, + {errors,[{{2,9},epp,{bad,warning}}],[]}}, + + {otp_16824_50, + <<"\n-warning">>, + {errors,[{{2,2},epp,{bad,warning}}],[]}} + + ], + [] = compile(Config, Cs), + ok. + +%% Start location is 1. check(Config, Tests) -> eval_tests(Config, fun check_test/3, Tests). +%% Start location is {1,1}. compile(Config, Tests) -> eval_tests(Config, fun compile_test/3, Tests). @@ -1860,34 +2083,7 @@ fail() -> ct:fail(failed). message_compare(T, T) -> - true; -message_compare(T1, T2) -> - ln(T1) =:= T2. - -%% Replaces locations like {Line,Column} with Line. -ln({warnings,L}) -> - {warnings,ln0(L)}; -ln({errors,EL,WL}) -> - {errors,ln0(EL),ln0(WL)}; -ln(L) -> - ln0(L). - -ln0(L) -> - lists:keysort(1, ln1(L)). - -ln1([]) -> - []; -ln1([{File,Ms}|MsL]) when is_list(File) -> - [{File,ln0(Ms)}|ln1(MsL)]; -ln1([M|Ms]) -> - [ln2(M)|ln1(Ms)]. - -ln2({{L,_C},Mod,Mess}) -> - {L,Mod,Mess}; -ln2({error,M}) -> - {error,ln2(M)}; -ln2(M) -> - M. + T =:= T. %% +fnu means a peer node has to be started; slave will not do start_node(Name, Xargs) -> diff --git a/lib/stdlib/test/erl_expand_records_SUITE.erl b/lib/stdlib/test/erl_expand_records_SUITE.erl index 257546d6a4..9ed2bbb578 100644 --- a/lib/stdlib/test/erl_expand_records_SUITE.erl +++ b/lib/stdlib/test/erl_expand_records_SUITE.erl @@ -195,7 +195,8 @@ guard(Config) when is_list(Config) -> ok = file:write_file(File, Test), {ok, guard, Ws} = compile:file(File, [return,{outdir,?privdir}]), Warnings = [L || {_File,WL} <- Ws, {L,_M,nomatch_guard} <- WL], - [7,9,11,13,15,17,19,21,23,25,27] = Warnings, + [{7,15}, {9,15}, {11,15}, {13,15}, {15,15}, {17,15}, + {19,15}, {21,15}, {23,15}, {25,15}, {27,15}] = Warnings, ok = file:delete(File), ok = file:delete(Beam), diff --git a/lib/stdlib/test/erl_lint_SUITE.erl b/lib/stdlib/test/erl_lint_SUITE.erl index d5d099bbbd..17911bba05 100644 --- a/lib/stdlib/test/erl_lint_SUITE.erl +++ b/lib/stdlib/test/erl_lint_SUITE.erl @@ -71,7 +71,7 @@ external_funs/1,otp_15456/1,otp_15563/1, unused_type/1,removed/1, otp_16516/1, inline_nifs/1, - warn_missing_spec/1]). + warn_missing_spec/1,otp_16824/1]). suite() -> [{ct_hooks,[ts_install_cth]}, @@ -94,7 +94,7 @@ all() -> record_errors, otp_11879_cont, non_latin1_module, otp_14323, stacktrace_syntax, otp_14285, otp_14378, external_funs, otp_15456, otp_15563, unused_type, removed, otp_16516, - inline_nifs, warn_missing_spec]. + inline_nifs, warn_missing_spec, otp_16824]. groups() -> [{unused_vars_warn, [], @@ -140,12 +140,12 @@ c(A) -> end. ">>, [warn_unused_vars], -{warnings,[{1,erl_lint,{unused_var,'F'}}, - {15,erl_lint,{unused_var,'Y'}}, - {22,erl_lint,{unused_var,'N'}}, - {23,erl_lint,{shadowed_var,'N','fun'}}, - {28,erl_lint,{unused_var,'B'}}, - {29,erl_lint,{unused_var,'B'}}]}}, +{warnings,[{{1,23},erl_lint,{unused_var,'F'}}, + {{15,5},erl_lint,{unused_var,'Y'}}, + {{22,3},erl_lint,{unused_var,'N'}}, + {{23,19},erl_lint,{shadowed_var,'N','fun'}}, + {{28,7},erl_lint,{unused_var,'B'}}, + {{29,7},erl_lint,{unused_var,'B'}}]}}, {basic2, <<"-record(r, {x,y}). f({X,Y}) -> {Z=X,Z=Y}; @@ -171,8 +171,8 @@ unused_vars_warn_lc(Config) when is_list(Config) -> [C || <<V:X>> <- Z, <<B:V>> <- Z, <<C:B>> <- Z]. ">>, [warn_unused_vars], - {warnings, [{4,erl_lint,{shadowed_var,'X',generate}}, - {7,erl_lint,{unused_var,'Y'}}]}}, + {warnings, [{{4,27},erl_lint,{shadowed_var,'X',generate}}, + {{7,22},erl_lint,{unused_var,'Y'}}]}}, {lc2, <<"bin([X]) -> @@ -185,8 +185,8 @@ unused_vars_warn_lc(Config) when is_list(Config) -> [C || <<V:X>> <- Z, <<B:V>> <- Z, <<C:B>> <- Z]. ">>, [warn_unused_vars], - {warnings,[{4,erl_lint,{shadowed_var,'X',generate}}, - {7,erl_lint,{unused_var,'Y'}}]}}, + {warnings,[{{4,27},erl_lint,{shadowed_var,'X',generate}}, + {{7,22},erl_lint,{unused_var,'Y'}}]}}, {lc3, <<"a([A]) -> @@ -208,7 +208,7 @@ unused_vars_warn_lc(Config) when is_list(Config) -> [C || {C,_} <- A]. ">>, [warn_unused_vars], - {warnings,[{2,erl_lint,{unused_var,'B'}}]}}, + {warnings,[{{2,19},erl_lint,{unused_var,'B'}}]}}, {lc5, <<"c(A) -> @@ -225,7 +225,7 @@ unused_vars_warn_lc(Config) when is_list(Config) -> [{A,B} || {Id,_} <- A]. % Id unused. ">>, [warn_unused_vars], - {warnings,[{3,erl_lint,{unused_var,'Id'}}]}}, + {warnings,[{{3,30},erl_lint,{unused_var,'Id'}}]}}, {lc7, <<"e(A) -> @@ -233,8 +233,8 @@ unused_vars_warn_lc(Config) when is_list(Config) -> [B || B <- A]. % B shadowed. ">>, [warn_unused_vars], - {warnings,[{2,erl_lint,{unused_var,'B'}}, - {3,erl_lint,{shadowed_var,'B',generate}}]}}, + {warnings,[{{2,19},erl_lint,{unused_var,'B'}}, + {{3,25},erl_lint,{shadowed_var,'B',generate}}]}}, {lc8, <<"f(A) -> @@ -243,7 +243,7 @@ unused_vars_warn_lc(Config) when is_list(Config) -> B. ">>, [warn_unused_vars], - {warnings,[{3,erl_lint,{shadowed_var,'B',generate}}]}}, + {warnings,[{{3,25},erl_lint,{shadowed_var,'B',generate}}]}}, {lc9, <<"g(A) -> @@ -251,9 +251,9 @@ unused_vars_warn_lc(Config) when is_list(Config) -> [A || B <- A]. % B shadowed, B unused. ">>, [warn_unused_vars], - {warnings,[{2,erl_lint,{unused_var,'B'}}, - {3,erl_lint,{unused_var,'B'}}, - {3,erl_lint,{shadowed_var,'B',generate}}]}}, + {warnings,[{{2,19},erl_lint,{unused_var,'B'}}, + {{3,25},erl_lint,{unused_var,'B'}}, + {{3,25},erl_lint,{shadowed_var,'B',generate}}]}}, {lc10, <<"h(A) -> @@ -262,8 +262,8 @@ unused_vars_warn_lc(Config) when is_list(Config) -> B. ">>, [warn_unused_vars], - {warnings,[{3,erl_lint,{unused_var,'B'}}, - {3,erl_lint,{shadowed_var,'B',generate}}]}}, + {warnings,[{{3,25},erl_lint,{unused_var,'B'}}, + {{3,25},erl_lint,{shadowed_var,'B',generate}}]}}, {lc11, <<"i(X) -> @@ -271,10 +271,10 @@ unused_vars_warn_lc(Config) when is_list(Config) -> Z = X <- [foo]]. % X and Z shadowed. X unused! ">>, [warn_unused_vars], - {warnings,[{2,erl_lint,{unused_var,'Z'}}, - {3,erl_lint,{unused_var,'X'}}, - {3,erl_lint,{shadowed_var,'X',generate}}, - {3,erl_lint,{shadowed_var,'Z',generate}}]}}, + {warnings,[{{2,25},erl_lint,{unused_var,'Z'}}, + {{3,25},erl_lint,{shadowed_var,'Z',generate}}, + {{3,29},erl_lint,{unused_var,'X'}}, + {{3,29},erl_lint,{shadowed_var,'X',generate}}]}}, {lc12, <<"j({X}) -> @@ -291,19 +291,19 @@ unused_vars_warn_lc(Config) when is_list(Config) -> X <- X]. % X shadowed. X unused. ">>, [warn_unused_vars], - {warnings,[{2,erl_lint,{unused_var,'Z'}}, - {3,erl_lint,{unused_var,'Z'}}, - {3,erl_lint,{shadowed_var,'Z',generate}}, - {4,erl_lint,{unused_var,'Z'}}, - {4,erl_lint,{shadowed_var,'Z',generate}}, - {5,erl_lint,{shadowed_var,'Z',generate}}, - {7,erl_lint,{shadowed_var,'X',generate}}, - {8,erl_lint,{unused_var,'X'}}, - {8,erl_lint,{shadowed_var,'X',generate}}, - {10,erl_lint,{unused_var,'Y'}}, - {11,erl_lint,{shadowed_var,'X',generate}}, - {12,erl_lint,{unused_var,'X'}}, - {12,erl_lint,{shadowed_var,'X',generate}}]}}, + {warnings,[{{2,25},erl_lint,{unused_var,'Z'}}, + {{3,25},erl_lint,{unused_var,'Z'}}, + {{3,25},erl_lint,{shadowed_var,'Z',generate}}, + {{4,25},erl_lint,{unused_var,'Z'}}, + {{4,25},erl_lint,{shadowed_var,'Z',generate}}, + {{5,25},erl_lint,{shadowed_var,'Z',generate}}, + {{7,27},erl_lint,{shadowed_var,'X',generate}}, + {{8,25},erl_lint,{unused_var,'X'}}, + {{8,25},erl_lint,{shadowed_var,'X',generate}}, + {{10,34},erl_lint,{unused_var,'Y'}}, + {{11,25},erl_lint,{shadowed_var,'X',generate}}, + {{12,25},erl_lint,{unused_var,'X'}}, + {{12,25},erl_lint,{shadowed_var,'X',generate}}]}}, {lc13, <<"k(X) -> @@ -323,14 +323,14 @@ unused_vars_warn_lc(Config) when is_list(Config) -> [Z || Y = X > 3, Z = X]. % Y unused. ">>, [warn_unused_vars], - {error,[{8,erl_lint,{unbound_var,'Y'}}, - {11,erl_lint,{unbound_var,'Y'}}], - [{2,erl_lint,{unused_var,'Y'}}, - {4,erl_lint,{unused_var,'Y'}}, - {8,erl_lint,{unused_var,'Y'}}, - {10,erl_lint,{unused_var,'Y'}}, - {13,erl_lint,{unused_var,'Z'}}, - {15,erl_lint,{unused_var,'Y'}}]}}, + {error,[{{8,21},erl_lint,{unbound_var,'Y'}}, + {{11,24},erl_lint,{unbound_var,'Y'}}], + [{{2,30},erl_lint,{unused_var,'Y'}}, + {{4,34},erl_lint,{unused_var,'Y'}}, + {{8,34},erl_lint,{unused_var,'Y'}}, + {{10,31},erl_lint,{unused_var,'Y'}}, + {{13,36},erl_lint,{unused_var,'Z'}}, + {{15,25},erl_lint,{unused_var,'Y'}}]}}, {lc14, <<"lc2() -> @@ -339,7 +339,7 @@ unused_vars_warn_lc(Config) when is_list(Config) -> X <- Z]. ">>, [warn_unused_vars], - {warnings,[{3,erl_lint,{shadowed_var,'Z',generate}}]}}, + {warnings,[{{3,25},erl_lint,{shadowed_var,'Z',generate}}]}}, {lc15, <<"lc3() -> @@ -348,8 +348,8 @@ unused_vars_warn_lc(Config) when is_list(Config) -> Z <- Z]. % Z shadowed. Z unused. ">>, [warn_unused_vars], - {warnings,[{4,erl_lint,{unused_var,'Z'}}, - {4,erl_lint,{shadowed_var,'Z',generate}}]}}, + {warnings,[{{4,25},erl_lint,{unused_var,'Z'}}, + {{4,25},erl_lint,{shadowed_var,'Z',generate}}]}}, {lc16, <<"bin(Z) -> @@ -382,11 +382,11 @@ unused_vars_warn_lc(Config) when is_list(Config) -> end. ">>, [warn_unused_vars], - {error,[{22,erl_lint,{unsafe_var,'U',{'case',2}}}, - {27,erl_lint,{unsafe_var,'U',{'case',2}}}], - [{16,erl_lint,{unused_var,'Y'}}, - {24,erl_lint,{unused_var,'U'}}, - {26,erl_lint,{unused_var,'U'}}]}}, + {error,[{{22,27},erl_lint,{unsafe_var,'U',{'case',{2,19}}}}, + {{27,27},erl_lint,{unsafe_var,'U',{'case',{2,19}}}}], + [{{16,27},erl_lint,{unused_var,'Y'}}, + {{24,35},erl_lint,{unused_var,'U'}}, + {{26,35},erl_lint,{unused_var,'U'}}]}}, {lc17, <<"bin(Z) -> @@ -413,9 +413,9 @@ unused_vars_warn_lc(Config) when is_list(Config) -> U. % U unsafe. ">>, [warn_unused_vars], - {error,[{22,erl_lint,{unsafe_var,'U',{'case',3}}}], - [{17,erl_lint,{unused_var,'Y'}}, - {21,erl_lint,{unused_var,'U'}}]}}, + {error,[{{22,19},erl_lint,{unsafe_var,'U',{'case',{3,19}}}}], + [{{17,27},erl_lint,{unused_var,'Y'}}, + {{21,27},erl_lint,{unused_var,'U'}}]}}, {lc18, <<"bin(Z) -> @@ -442,9 +442,9 @@ unused_vars_warn_lc(Config) when is_list(Config) -> % U shadowed. (X exported.) ">>, [warn_unused_vars], - {error,[{21,erl_lint,{unsafe_var,'U',{'case',2}}}, - {21,erl_lint,{unsafe_var,'Y',{'case',14}}}], - [{20,erl_lint,{unused_var,'U'}} + {error,[{{21,27},erl_lint,{unsafe_var,'U',{'case',{2,19}}}}, + {{21,41},erl_lint,{unsafe_var,'Y',{'case',{14,19}}}}], + [{{20,27},erl_lint,{unused_var,'U'}} ]}}, {lc19, @@ -454,7 +454,7 @@ unused_vars_warn_lc(Config) when is_list(Config) -> <<A:B>> = <<17:32>>. % A unused. ">>, [warn_unused_vars], - {warnings,[{4,erl_lint,{unused_var,'A'}}]}}, + {warnings,[{{4,21},erl_lint,{unused_var,'A'}}]}}, {lc20, <<"c({I1,I2}) -> @@ -471,9 +471,9 @@ unused_vars_warn_lc(Config) when is_list(Config) -> ">>, [warn_unused_vars], - {warnings,[{6,erl_lint,{unused_var,'C1'}}, - {7,sys_core_fold,no_clause_match}, - {9,erl_lint,{unused_var,'C3'}}]}}, + {warnings,[{{6,18},erl_lint,{unused_var,'C1'}}, + {{7,19},sys_core_fold,no_clause_match}, + {{9,25},erl_lint,{unused_var,'C3'}}]}}, {lc21, <<"t() -> @@ -494,8 +494,8 @@ unused_vars_warn_lc(Config) when is_list(Config) -> end. ">>, [warn_unused_vars], - {error,[{6,erl_lint,{unbound_var,'X'}}], - [{14,erl_lint,{unused_var,'Q'}}]}} + {error,[{{6,27},erl_lint,{unbound_var,'X'}}], + [{{14,25},erl_lint,{unused_var,'Q'}}]}} ], [] = run(Config, Ts), @@ -531,7 +531,7 @@ unused_vars_warn_rec(Config) when is_list(Config) -> end. ">>, [warn_unused_vars], - {warnings,[{22,erl_lint,{unused_var,'Same'}}]}}, + {warnings,[{{22,41},erl_lint,{unused_var,'Same'}}]}}, {rec2, <<"-record(r, {a,b}). f(X, Y) -> #r{a=[K || K <- Y], b=[K || K <- Y]}. @@ -542,18 +542,18 @@ unused_vars_warn_rec(Config) when is_list(Config) -> i(X, Y) -> #r{a=if is_list(Y) -> Y end, b=if is_list(Y) -> Y end}. ">>, [warn_unused_vars], - {warnings,[{2,erl_lint,{unused_var,'X'}}, - {3,erl_lint,{unused_var,'X'}}, - {5,erl_lint,{unused_var,'X'}}, - {7,erl_lint,{unused_var,'X'}}]}}, + {warnings,[{{2,17},erl_lint,{unused_var,'X'}}, + {{3,17},erl_lint,{unused_var,'X'}}, + {{5,17},erl_lint,{unused_var,'X'}}, + {{7,17},erl_lint,{unused_var,'X'}}]}}, {rec3, <<"-record(r, {a}). t() -> X = 1, #r{a=foo, a=bar, a=qux}. ">>, [warn_unused_vars], - {error,[{2,erl_lint,{redefine_field,r,a}}, - {2,erl_lint,{redefine_field,r,a}}], - [{2,erl_lint,{unused_var,'X'}}]}}], + {error,[{{2,39},erl_lint,{redefine_field,r,a}}, + {{2,46},erl_lint,{redefine_field,r,a}}], + [{{2,22},erl_lint,{unused_var,'X'}}]}}], [] = run(Config, Ts), ok. @@ -577,16 +577,16 @@ unused_vars_warn_fun(Config) when is_list(Config) -> end. ">>, [warn_unused_vars], - {warnings,[{1,erl_lint,{unused_var,'A'}}, - {2,erl_lint,{unused_var,'A'}}, - {2,erl_lint,{shadowed_var,'A','fun'}}, - {4,erl_lint,{unused_var,'A'}}, - {4,erl_lint,{shadowed_var,'A','fun'}}, - {5,erl_lint,{unused_var,'Q'}}, - {8,erl_lint,{unused_var,'E'}}, - {8,erl_lint,{shadowed_var,'E','fun'}}, - {8,sys_core_fold,useless_building}, - {12,erl_lint,{unused_var,'E'}}]}}, + {warnings,[{{1,24},erl_lint,{unused_var,'A'}}, + {{2,23},erl_lint,{unused_var,'A'}}, + {{2,23},erl_lint,{shadowed_var,'A','fun'}}, + {{4,25},erl_lint,{unused_var,'A'}}, + {{4,25},erl_lint,{shadowed_var,'A','fun'}}, + {{5,26},erl_lint,{unused_var,'Q'}}, + {{8,19},sys_core_fold,useless_building}, + {{8,23},erl_lint,{unused_var,'E'}}, + {{8,23},erl_lint,{shadowed_var,'E','fun'}}, + {{12,26},erl_lint,{unused_var,'E'}}]}}, {fun2, <<"u() -> @@ -617,14 +617,14 @@ unused_vars_warn_fun(Config) when is_list(Config) -> fun(U) -> foo end. % U shadowed. U unused. ">>, [warn_unused_vars], - {error,[{9,erl_lint,{unsafe_var,'U',{'case',2}}}], - [{8,erl_lint,{unused_var,'U'}}, - {17,erl_lint,{unused_var,'U'}}, - {17,erl_lint,{shadowed_var,'U','fun'}}, - {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'}}]}}, + {error,[{{9,19},erl_lint,{unsafe_var,'U',{'case',{2,19}}}}], + [{{8,23},erl_lint,{unused_var,'U'}}, + {{17,23},erl_lint,{unused_var,'U'}}, + {{17,23},erl_lint,{shadowed_var,'U','fun'}}, + {{22,27},erl_lint,{unused_var,'U'}}, + {{24,27},erl_lint,{unused_var,'U'}}, + {{26,23},erl_lint,{unused_var,'U'}}, + {{26,23},erl_lint,{shadowed_var,'U','fun'}}]}}, {named_fun, <<"u() -> fun U() -> foo end, % U unused. @@ -663,21 +663,21 @@ unused_vars_warn_fun(Config) when is_list(Config) -> 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'}}]}} + {error,[{{3,19},erl_lint,{unbound_var,'U'}}, + {{12,19},erl_lint,{unsafe_var,'U',{'case',{5,19}}}}], + [{{2,19},erl_lint,{unused_var,'U'}}, + {{11,19},erl_lint,{unused_var,'U'}}, + {{20,19},erl_lint,{unused_var,'U'}}, + {{20,19},erl_lint,{shadowed_var,'U','named fun'}}, + {{25,27},erl_lint,{unused_var,'U'}}, + {{27,27},erl_lint,{unused_var,'U'}}, + {{29,19},erl_lint,{unused_var,'U'}}, + {{29,19},erl_lint,{shadowed_var,'U','named fun'}}, + {{31,19},erl_lint,{unused_var,'U'}}, + {{31,25},erl_lint,{unused_var,'U'}}, + {{31,25},erl_lint,{shadowed_var,'U','fun'}}, + {{33,36},erl_lint,{unused_var,'U'}}, + {{33,36},erl_lint,{shadowed_var,'U','fun'}}]}} ], [] = run(Config, Ts), ok. @@ -695,11 +695,11 @@ unused_vars_OTP_4858(Config) when is_list(Config) -> <<Size, B:Size/binary,Rest/binary>> = <<2,\"AB\",3,\"CDE\">>. ">>, [warn_unused_vars], - {error,[{4,erl_lint,{unbound_var,'BadSize'}}], - [{4,erl_lint,{unused_var,'B'}}, - {4,erl_lint,{unused_var,'Size'}}, - {8,erl_lint,{unused_var,'B'}}, - {8,erl_lint,{unused_var,'Rest'}}]}} + {error,[{{4,38},erl_lint,{unbound_var,'BadSize'}}], + [{{4,21},erl_lint,{unused_var,'Size'}}, + {{4,36},erl_lint,{unused_var,'B'}}, + {{8,26},erl_lint,{unused_var,'B'}}, + {{8,40},erl_lint,{unused_var,'Rest'}}]}} ], [] = run(Config, Ts), ok. @@ -717,8 +717,8 @@ unused_unsafe_vars_warn(Config) when is_list(Config) -> ok. ">>, [warn_unused_vars], - {warnings,[{2,erl_lint,{unused_var,'UnusedVar1'}}, - {4,erl_lint,{unused_var,'UnusedVar2'}}]}}, + {warnings,[{{2,19},erl_lint,{unused_var,'UnusedVar1'}}, + {{4,23},erl_lint,{unused_var,'UnusedVar2'}}]}}, {unused_unsafe2, <<"t2() -> try @@ -728,7 +728,7 @@ unused_unsafe_vars_warn(Config) when is_list(Config) -> end. ">>, [warn_unused_vars], - {warnings,[{3,erl_lint,{unused_var,'X'}}]}}, + {warnings,[{{3,23},erl_lint,{unused_var,'X'}}]}}, {unused_unsafe2, <<"t3(X, Y) -> X andalso Y. @@ -778,15 +778,15 @@ export_vars_warn(Config) when is_list(Config) -> end. ">>, [warn_unused_vars], - {error,[{14,erl_lint,{unsafe_var,'A',{'case',2}}}], - [{6,erl_lint,{unused_var,'W'}}, - {7,erl_lint,{unused_var,'Z'}}, - {10,erl_lint,{unused_var,'Z'}}, - {15,erl_lint,{unused_var,'X'}}, - {19,erl_lint,{exported_var,'B',{'case',2}}}, - {20,erl_lint,{unused_var,'U'}}, - {25,erl_lint,{unused_var,'X'}}, - {26,erl_lint,{unused_var,'U'}}]}}, + {error,[{{14,27},erl_lint,{unsafe_var,'A',{'case',{2,19}}}}], + [{{6,27},erl_lint,{unused_var,'W'}}, + {{7,27},erl_lint,{unused_var,'Z'}}, + {{10,27},erl_lint,{unused_var,'Z'}}, + {{15,27},erl_lint,{unused_var,'X'}}, + {{19,27},erl_lint,{exported_var,'B',{'case',{2,19}}}}, + {{20,27},erl_lint,{unused_var,'U'}}, + {{25,27},erl_lint,{unused_var,'X'}}, + {{26,27},erl_lint,{unused_var,'U'}}]}}, {exp2, <<"bin(A) -> @@ -801,11 +801,11 @@ export_vars_warn(Config) when is_list(Config) -> [B || B <- Z]. % Z exported. B shadowed. ">>, [warn_export_vars], - {error,[{9,erl_lint,{unbound_var,'B'}}], - [{8,erl_lint,{exported_var,'X',{'receive',2}}}, - {9,erl_lint,{exported_var,'Y',{'receive',2}}}, - {10,erl_lint,{exported_var,'Z',{'receive',2}}}, - {10,erl_lint,{shadowed_var,'B',generate}}]}}, + {error,[{{9,23},erl_lint,{unbound_var,'B'}}], + [{{8,29},erl_lint,{exported_var,'X',{'receive',{2,19}}}}, + {{9,19},erl_lint,{exported_var,'Y',{'receive',{2,19}}}}, + {{10,25},erl_lint,{shadowed_var,'B',generate}}, + {{10,30},erl_lint,{exported_var,'Z',{'receive',{2,19}}}}]}}, {exp3, <<"bin(A) -> @@ -820,9 +820,9 @@ export_vars_warn(Config) when is_list(Config) -> [B || B <- Z]. % (Z exported.) B shadowed. ">>, [], - {error,[{9,erl_lint,{unbound_var,'B'}}], - [{9,erl_lint,{exported_var,'Y',{'receive',2}}}, - {10,erl_lint,{shadowed_var,'B',generate}}]}}, + {error,[{{9,23},erl_lint,{unbound_var,'B'}}], + [{{9,19},erl_lint,{exported_var,'Y',{'receive',{2,19}}}}, + {{10,25},erl_lint,{shadowed_var,'B',generate}}]}}, {exp4, <<"t(X) -> @@ -834,7 +834,7 @@ export_vars_warn(Config) when is_list(Config) -> Z = X. ">>, [], - {warnings,[{7,erl_lint,{exported_var,'Z',{'if',2}}}]}} + {warnings,[{{7,19},erl_lint,{exported_var,'Z',{'if',{2,19}}}}]}} ], [] = run(Config, Ts), ok. @@ -855,8 +855,8 @@ shadow_vars(Config) when is_list(Config) -> [B || B <- Z]. % B shadowed. ">>, [nowarn_shadow_vars], - {error,[{9,erl_lint,{unbound_var,'B'}}], - [{9,erl_lint,{exported_var,'Y',{'receive',2}}}]}}, + {error,[{{9,23},erl_lint,{unbound_var,'B'}}], + [{{9,19},erl_lint,{exported_var,'Y',{'receive',{2,19}}}}]}}, {shadow2, <<"t() -> _ = (catch MS = MS = 1), % MS used unsafe @@ -876,7 +876,7 @@ unused_import(Config) when is_list(Config) -> map(fun(X) -> 2*X end, L). ">>, [warn_unused_import], - {warnings,[{1,erl_lint,{unused_import,{{foldl,3},lists}}}]}}], + {warnings,[{{1,22},erl_lint,{unused_import,{{foldl,3},lists}}}]}}], [] = run(Config, Ts), ok. @@ -894,8 +894,8 @@ unused_function(Config) when is_list(Config) -> fact_1(N, P) -> fact_1(N-1, P*N). ">>, {[]}, %Tuple indicates no 'export_all'. - {warnings,[{5,erl_lint,{unused_function,{fact,1}}}, - {8,erl_lint,{unused_function,{fact_1,2}}}]}}, + {warnings,[{{5,15},erl_lint,{unused_function,{fact,1}}}, + {{8,15},erl_lint,{unused_function,{fact_1,2}}}]}}, %% Turn off warnings for unused functions. {func2, @@ -931,7 +931,7 @@ unused_type(Config) when is_list(Config) -> Ts = [{func1, <<"-type foo() :: term().">>, {[]}, %Tuple indicates no export_all - {warnings,[{1,erl_lint,{unused_type,{foo,0}}}]}}, + {warnings,[{{1,22},erl_lint,{unused_type,{foo,0}}}]}}, %% Turn off warnings for unused types. {func2, @@ -957,23 +957,23 @@ unsafe_vars(Config) when is_list(Config) -> Y. ">>, [warn_unused_vars], - {error,[{3,erl_lint,{unsafe_var,'Y',{'orelse',2}}}], - [{2,erl_lint,{unused_var,'X'}}]}}, + {error,[{{3,19},erl_lint,{unsafe_var,'Y',{'orelse',{2,29}}}}], + [{{2,19},erl_lint,{unused_var,'X'}}]}}, {unsafe2, <<"t2() -> (X = true) orelse (Y = false), X. ">>, [warn_unused_vars], - {warnings,[{2,erl_lint,{unused_var,'Y'}}]}}, + {warnings,[{{2,38},erl_lint,{unused_var,'Y'}}]}}, {unsafe3, <<"t3() -> (X = true) andalso (Y = false), Y. ">>, [warn_unused_vars], - {error,[{3,erl_lint,{unsafe_var,'Y',{'andalso',2}}}], - [{2,erl_lint,{unused_var,'X'}}]}}, + {error,[{{3,19},erl_lint,{unsafe_var,'Y',{'andalso',{2,30}}}}], + [{{2,20},erl_lint,{unused_var,'X'}}]}}, {unsafe4, <<"t4() -> (X = true) andalso (true = X), @@ -1004,8 +1004,8 @@ unsafe_vars(Config) when is_list(Config) -> X. ">>, [warn_unused_vars], - {errors,[{3,erl_lint,{unsafe_var,'X',{'if',2}}}, - {4,erl_lint,{unsafe_var,'X',{'if',2}}}], + {errors,[{{3,32},erl_lint,{unsafe_var,'X',{'if',{2,20}}}}, + {{4,19},erl_lint,{unsafe_var,'X',{'if',{2,20}}}}], []}}, {unsafe8, <<"t8(X) -> @@ -1013,7 +1013,7 @@ unsafe_vars(Config) when is_list(Config) -> _Y." >>, [], - {errors,[{3,erl_lint,{unsafe_var,'_Y',{'catch',2}}}], + {errors,[{{3,19},erl_lint,{unsafe_var,'_Y',{'catch',{2,34}}}}], []}}, {unsafe9, <<"t9(X) -> @@ -1042,9 +1042,9 @@ unsafe_vars(Config) when is_list(Config) -> {A,B,C,D}." >>, [], - {errors,[{24,erl_lint,{unsafe_var,'A',{'catch',4}}}, - {24,erl_lint,{unsafe_var,'B',{'case',2}}}, - {24,erl_lint,{unsafe_var,'D',{'case',2}}}], + {errors,[{{24,20},erl_lint,{unsafe_var,'A',{'catch',{4,27}}}}, + {{24,22},erl_lint,{unsafe_var,'B',{'case',{2,19}}}}, + {{24,26},erl_lint,{unsafe_var,'D',{'case',{2,19}}}}], []}}, {unsafe_comprehension, <<"foo() -> @@ -1065,7 +1065,7 @@ unsafe_vars(Config) when is_list(Config) -> end. ">>, [], - {errors,[{14,erl_lint,{unsafe_var,'P',{'case',2}}}],[]}} + {errors,[{{14,22},erl_lint,{unsafe_var,'P',{'case',{2,18}}}}],[]}} ], [] = run(Config, Ts), ok. @@ -1084,7 +1084,7 @@ unsafe_vars2(Config) when is_list(Config) -> State1. % unsafe ">>, [warn_unused_vars], - {errors,[{9,erl_lint,{unsafe_var,'State1',{'if',4}}}],[]}}, + {errors,[{{9,19},erl_lint,{unsafe_var,'State1',{'if',{4,27}}}}],[]}}, {unsafe2_2, <<"foo(State) -> case State of @@ -1097,7 +1097,7 @@ unsafe_vars2(Config) when is_list(Config) -> State1. % unsafe ">>, [], - {errors,[{9,erl_lint,{unsafe_var,'State1',{'if',4}}}],[]}} + {errors,[{{9,19},erl_lint,{unsafe_var,'State1',{'if',{4,27}}}}],[]}} ], [] = run(Config, Ts), ok. @@ -1127,9 +1127,9 @@ unsafe_vars_try(Config) when is_list(Config) -> Result. ">>, [], - {errors,[{6,erl_lint,{unsafe_var,'Result',{'try',2}}}, - {13,erl_lint,{unsafe_var,'Result',{'try',8}}}, - {20,erl_lint,{unsafe_var,'Result',{'try',15}}}], + {errors,[{{6,17},erl_lint,{unsafe_var,'Result',{'try',{2,17}}}}, + {{13,17},erl_lint,{unsafe_var,'Result',{'try',{8,17}}}}, + {{20,17},erl_lint,{unsafe_var,'Result',{'try',{15,17}}}}], []}}, {unsafe_try2, <<"foo1a() -> @@ -1173,19 +1173,19 @@ unsafe_vars_try(Config) when is_list(Config) -> {Try,R,Ro,Rc,Ra}. ">>, [], - {errors,[{9,erl_lint,{unsafe_var,'Ra',{'try',3}}}, - {9,erl_lint,{unsafe_var,'Rc',{'try',3}}}, - {17,erl_lint,{unsafe_var,'R',{'try',12}}}, - {19,erl_lint,{unsafe_var,'Ra',{'try',12}}}, - {19,erl_lint,{unsafe_var,'Rc',{'try',12}}}, - {27,erl_lint,{unsafe_var,'R',{'try',22}}}, - {29,erl_lint,{unsafe_var,'Ra',{'try',22}}}, - {29,erl_lint,{unsafe_var,'Ro',{'try',22}}}, - {37,erl_lint,{unsafe_var,'R',{'try',32}}}, - {39,erl_lint,{unsafe_var,'R',{'try',32}}}, - {39,erl_lint,{unsafe_var,'Ra',{'try',32}}}, - {39,erl_lint,{unsafe_var,'Rc',{'try',32}}}, - {39,erl_lint,{unsafe_var,'Ro',{'try',32}}}], + {errors,[{{9,22},erl_lint,{unsafe_var,'Rc',{'try',{3,19}}}}, + {{9,25},erl_lint,{unsafe_var,'Ra',{'try',{3,19}}}}, + {{17,24},erl_lint,{unsafe_var,'R',{'try',{12,19}}}}, + {{19,22},erl_lint,{unsafe_var,'Rc',{'try',{12,19}}}}, + {{19,25},erl_lint,{unsafe_var,'Ra',{'try',{12,19}}}}, + {{27,24},erl_lint,{unsafe_var,'R',{'try',{22,19}}}}, + {{29,22},erl_lint,{unsafe_var,'Ro',{'try',{22,19}}}}, + {{29,25},erl_lint,{unsafe_var,'Ra',{'try',{22,19}}}}, + {{37,24},erl_lint,{unsafe_var,'R',{'try',{32,19}}}}, + {{39,22},erl_lint,{unsafe_var,'R',{'try',{32,19}}}}, + {{39,24},erl_lint,{unsafe_var,'Ro',{'try',{32,19}}}}, + {{39,27},erl_lint,{unsafe_var,'Rc',{'try',{32,19}}}}, + {{39,30},erl_lint,{unsafe_var,'Ra',{'try',{32,19}}}}], []}}, {unsafe_try3, <<"foo1(X) -> @@ -1215,27 +1215,27 @@ unsafe_vars_try(Config) when is_list(Config) -> {X,Try,R,RR,Ra,Class,Data}. ">>, [], - {errors,[{5,erl_lint,{unsafe_var,'R',{'try',3}}}, - {7,erl_lint,{unsafe_var,'Rc',{'try',3}}}, - {13,erl_lint,{unbound_var,'RR'}}, - {13,erl_lint,{unbound_var,'Ro'}}, - {13,erl_lint,{unsafe_var,'R',{'try',10}}}, - {15,erl_lint,{unsafe_var,'Class',{'try',10}}}, - {15,erl_lint,{unsafe_var,'Data',{'try',10}}}, - {15,erl_lint,{unsafe_var,'R',{'try',10}}}, - {15,erl_lint,{unsafe_var,'RR',{'try',10}}}, - {15,erl_lint,{unsafe_var,'Ro',{'try',10}}}, - {21,erl_lint,{unbound_var,'RR'}}, - {21,erl_lint,{unsafe_var,'R',{'try',18}}}, - {23,erl_lint,{unsafe_var,'Class',{'try',18}}}, - {23,erl_lint,{unsafe_var,'Data',{'try',18}}}, - {23,erl_lint,{unsafe_var,'R',{'try',18}}}, - {23,erl_lint,{unsafe_var,'RR',{'try',18}}}, - {25,erl_lint,{unsafe_var,'Class',{'try',18}}}, - {25,erl_lint,{unsafe_var,'Data',{'try',18}}}, - {25,erl_lint,{unsafe_var,'R',{'try',18}}}, - {25,erl_lint,{unsafe_var,'RR',{'try',18}}}, - {25,erl_lint,{unsafe_var,'Ra',{'try',18}}}], + {errors,[{{5,41},erl_lint,{unsafe_var,'R',{'try',{3,19}}}}, + {{7,24},erl_lint,{unsafe_var,'Rc',{'try',{3,19}}}}, + {{13,38},erl_lint,{unsafe_var,'R',{'try',{10,19}}}}, + {{13,40},erl_lint,{unbound_var,'RR'}}, + {{13,43},erl_lint,{unbound_var,'Ro'}}, + {{15,24},erl_lint,{unsafe_var,'R',{'try',{10,19}}}}, + {{15,26},erl_lint,{unsafe_var,'RR',{'try',{10,19}}}}, + {{15,29},erl_lint,{unsafe_var,'Ro',{'try',{10,19}}}}, + {{15,32},erl_lint,{unsafe_var,'Class',{'try',{10,19}}}}, + {{15,38},erl_lint,{unsafe_var,'Data',{'try',{10,19}}}}, + {{21,38},erl_lint,{unsafe_var,'R',{'try',{18,19}}}}, + {{21,40},erl_lint,{unbound_var,'RR'}}, + {{23,27},erl_lint,{unsafe_var,'R',{'try',{18,19}}}}, + {{23,29},erl_lint,{unsafe_var,'RR',{'try',{18,19}}}}, + {{23,32},erl_lint,{unsafe_var,'Class',{'try',{18,19}}}}, + {{23,38},erl_lint,{unsafe_var,'Data',{'try',{18,19}}}}, + {{25,24},erl_lint,{unsafe_var,'R',{'try',{18,19}}}}, + {{25,26},erl_lint,{unsafe_var,'RR',{'try',{18,19}}}}, + {{25,29},erl_lint,{unsafe_var,'Ra',{'try',{18,19}}}}, + {{25,32},erl_lint,{unsafe_var,'Class',{'try',{18,19}}}}, + {{25,38},erl_lint,{unsafe_var,'Data',{'try',{18,19}}}}], []}}, {unsafe_try4, <<"foo1(X) -> @@ -1250,22 +1250,22 @@ unsafe_vars_try(Config) when is_list(Config) -> {X,Try,R,RR,Ro,Rc,Ra,Class,Data}. ">>, [], - {errors,[{6,erl_lint,{unbound_var,'RR'}}, - {6,erl_lint,{unbound_var,'Ro'}}, - {6,erl_lint,{unsafe_var,'R',{'try',3}}}, - {8,erl_lint,{unsafe_var,'Class',{'try',3}}}, - {8,erl_lint,{unsafe_var,'Data',{'try',3}}}, - {8,erl_lint,{unsafe_var,'R',{'try',3}}}, - {8,erl_lint,{unsafe_var,'RR',{'try',3}}}, - {8,erl_lint,{unsafe_var,'Rc',{'try',3}}}, - {8,erl_lint,{unsafe_var,'Ro',{'try',3}}}, - {10,erl_lint,{unsafe_var,'Class',{'try',3}}}, - {10,erl_lint,{unsafe_var,'Data',{'try',3}}}, - {10,erl_lint,{unsafe_var,'R',{'try',3}}}, - {10,erl_lint,{unsafe_var,'RR',{'try',3}}}, - {10,erl_lint,{unsafe_var,'Ra',{'try',3}}}, - {10,erl_lint,{unsafe_var,'Rc',{'try',3}}}, - {10,erl_lint,{unsafe_var,'Ro',{'try',3}}}], + {errors,[{{6,41},erl_lint,{unsafe_var,'R',{'try',{3,19}}}}, + {{6,43},erl_lint,{unbound_var,'RR'}}, + {{6,46},erl_lint,{unbound_var,'Ro'}}, + {{8,27},erl_lint,{unsafe_var,'R',{'try',{3,19}}}}, + {{8,29},erl_lint,{unsafe_var,'RR',{'try',{3,19}}}}, + {{8,32},erl_lint,{unsafe_var,'Ro',{'try',{3,19}}}}, + {{8,35},erl_lint,{unsafe_var,'Rc',{'try',{3,19}}}}, + {{8,38},erl_lint,{unsafe_var,'Class',{'try',{3,19}}}}, + {{8,44},erl_lint,{unsafe_var,'Data',{'try',{3,19}}}}, + {{10,24},erl_lint,{unsafe_var,'R',{'try',{3,19}}}}, + {{10,26},erl_lint,{unsafe_var,'RR',{'try',{3,19}}}}, + {{10,29},erl_lint,{unsafe_var,'Ro',{'try',{3,19}}}}, + {{10,32},erl_lint,{unsafe_var,'Rc',{'try',{3,19}}}}, + {{10,35},erl_lint,{unsafe_var,'Ra',{'try',{3,19}}}}, + {{10,38},erl_lint,{unsafe_var,'Class',{'try',{3,19}}}}, + {{10,44},erl_lint,{unsafe_var,'Data',{'try',{3,19}}}}], []}}, {unsafe_try5, <<"bang() -> @@ -1283,7 +1283,7 @@ unsafe_vars_try(Config) when is_list(Config) -> Acc. ">>, [], - {errors,[{13,erl_lint,{unsafe_var,'Acc',{'try',6}}}],[]}}], + {errors,[{{13,17},erl_lint,{unsafe_var,'Acc',{'try',{6,21}}}}],[]}}], [] = run(Config, Ts), ok. @@ -1316,18 +1316,18 @@ unsized_binary_in_bin_gen_pattern(Config) when is_list(Config) -> [ X || <<X,b/bitstring>> <= Bin ].">>, [], {errors, - [{2,erl_lint,unsized_binary_in_bin_gen_pattern}, - {4,erl_lint,unsized_binary_in_bin_gen_pattern}, - {6,erl_lint,unsized_binary_in_bin_gen_pattern}, - {8,erl_lint,unsized_binary_in_bin_gen_pattern}, - {10,erl_lint,unsized_binary_in_bin_gen_pattern}, - {12,erl_lint,unsized_binary_in_bin_gen_pattern}, - {14,erl_lint,unsized_binary_in_bin_gen_pattern}, - {16,erl_lint,unsized_binary_in_bin_gen_pattern}, - {18,erl_lint,unsized_binary_in_bin_gen_pattern}, - {20,erl_lint,unsized_binary_in_bin_gen_pattern}, - {22,erl_lint,unsized_binary_in_bin_gen_pattern}, - {24,erl_lint,unsized_binary_in_bin_gen_pattern}], + [{{2,33},erl_lint,unsized_binary_in_bin_gen_pattern}, + {{4,33},erl_lint,unsized_binary_in_bin_gen_pattern}, + {{6,31},erl_lint,unsized_binary_in_bin_gen_pattern}, + {{8,31},erl_lint,unsized_binary_in_bin_gen_pattern}, + {{10,21},erl_lint,unsized_binary_in_bin_gen_pattern}, + {{12,21},erl_lint,unsized_binary_in_bin_gen_pattern}, + {{14,23},erl_lint,unsized_binary_in_bin_gen_pattern}, + {{16,23},erl_lint,unsized_binary_in_bin_gen_pattern}, + {{18,23},erl_lint,unsized_binary_in_bin_gen_pattern}, + {{20,23},erl_lint,unsized_binary_in_bin_gen_pattern}, + {{22,16},erl_lint,unsized_binary_in_bin_gen_pattern}, + {{24,16},erl_lint,unsized_binary_in_bin_gen_pattern}], []}}], [] = run(Config, Ts), ok. @@ -1394,7 +1394,8 @@ guard(Config) when is_list(Config) -> ">>, [nowarn_obsolete_guard], {errors, - [{6,erl_lint,illegal_guard_expr},{18,erl_lint,illegal_guard_expr}], + [{{6,25},erl_lint,illegal_guard_expr}, + {{18,25},erl_lint,illegal_guard_expr}], []}}, {guard2, <<"-record(apa,{}). @@ -1454,10 +1455,10 @@ guard(Config) when is_list(Config) -> tuple. ">>, [nowarn_obsolete_guard], - {errors,[{6,erl_lint,illegal_guard_expr}, - {6,erl_lint,illegal_guard_expr}, - {18,erl_lint,illegal_guard_expr}, - {18,erl_lint,illegal_guard_expr}], + {errors,[{{6,26},erl_lint,illegal_guard_expr}, + {{6,39},erl_lint,illegal_guard_expr}, + {{18,26},erl_lint,illegal_guard_expr}, + {{18,42},erl_lint,illegal_guard_expr}], []}}, {guard3, <<"-record(apa,{}). @@ -1572,13 +1573,13 @@ guard(Config) when is_list(Config) -> foo. ">>, [warn_unused_vars, nowarn_obsolete_guard], - {errors,[{2,erl_lint,illegal_guard_expr}, - {4,erl_lint,illegal_guard_expr}, - {6,erl_lint,illegal_guard_expr}, - {8,erl_lint,illegal_guard_expr}, - {10,erl_lint,illegal_guard_expr}, - {12,erl_lint,illegal_guard_expr}, - {14,erl_lint,illegal_guard_expr}], + {errors,[{{2,27},erl_lint,illegal_guard_expr}, + {{4,27},erl_lint,illegal_guard_expr}, + {{6,27},erl_lint,illegal_guard_expr}, + {{8,27},erl_lint,illegal_guard_expr}, + {{10,27},erl_lint,illegal_guard_expr}, + {{12,27},erl_lint,illegal_guard_expr}, + {{14,27},erl_lint,illegal_guard_expr}], []}}, {guard6, <<"-record(apa,{a=a,b=foo:bar()}). @@ -1590,7 +1591,7 @@ guard(Config) when is_list(Config) -> [X || X <- [], #ful{a = a} == {r,X,foo}]. ">>, [], - {errors,[{7,erl_lint,{undefined_record,ful}}], + {errors,[{{7,33},erl_lint,{undefined_record,ful}}], []}}, {guard7, <<"-record(apa,{}). @@ -1606,16 +1607,16 @@ guard(Config) when is_list(Config) -> t(A) when A ++ [x] -> ok." >>, [], - {errors,[{1,erl_lint,illegal_guard_expr}, - {2,erl_lint,illegal_guard_expr}, - {3,erl_lint,illegal_guard_expr}],[]}}, + {errors,[{{1,31},erl_lint,illegal_guard_expr}, + {{2,20},erl_lint,illegal_guard_expr}, + {{3,20},erl_lint,illegal_guard_expr}],[]}}, {guard9, <<"t(X, Y) when erlang:'andalso'(X, Y) -> ok; t(X, Y) when erlang:'orelse'(X, Y) -> ok. ">>, [], - {errors,[{1,erl_lint,illegal_guard_expr}, - {2,erl_lint,illegal_guard_expr}], + {errors,[{{1,34},erl_lint,illegal_guard_expr}, + {{2,29},erl_lint,illegal_guard_expr}], []}}, {guard10, <<"is_port(_) -> false. @@ -1623,8 +1624,8 @@ guard(Config) when is_list(Config) -> ">>, [], {error, - [{2,erl_lint,{obsolete_guard_overridden,port}}], - [{2,erl_lint,{obsolete_guard,{port,1}}}]}} + [{{2,26},erl_lint,{obsolete_guard_overridden,port}}], + [{{2,26},erl_lint,{obsolete_guard,{port,1}}}]}} ], [] = run(Config, Ts1), ok. @@ -1644,9 +1645,9 @@ otp_4886(Config) when is_list(Config) -> {erlang,is_record}(X, foo, 1). ">>, [], - {errors,[{3,erl_lint,{undefined_record,foo}}, - {4,erl_lint,{undefined_record,foo}}, - {5,erl_lint,{undefined_record,foo}}], + {errors,[{{3,32},erl_lint,{undefined_record,foo}}, + {{4,39},erl_lint,{undefined_record,foo}}, + {{5,41},erl_lint,{undefined_record,foo}}], []}}], [] = run(Config, Ts), ok. @@ -1667,11 +1668,11 @@ otp_4988(Config) when is_list(Config) -> {A}. ">>, [], - {errors,[{1,erl_lint,{bad_inline,{1,foo}}}, - {1,erl_lint,{bad_inline,{f,3}}}, - {1,erl_lint,{bad_inline,{f,4}}}, - {1,erl_lint,{bad_inline,{f,a}}}, - {3,erl_lint,{bad_inline,{g,12}}}], + {errors,[{{1,22},erl_lint,{bad_inline,{1,foo}}}, + {{1,22},erl_lint,{bad_inline,{f,3}}}, + {{1,22},erl_lint,{bad_inline,{f,4}}}, + {{1,22},erl_lint,{bad_inline,{f,a}}}, + {{3,16},erl_lint,{bad_inline,{g,12}}}], []}}], [] = run(Config, Ts), ok. @@ -1720,13 +1721,13 @@ otp_5091(Config) when is_list(Config) -> F(<<16:8, 7:16>>). ">>, [], - {warnings,[{3,erl_lint,{shadowed_var,'L','fun'}}]}}, + {warnings,[{{3,28},erl_lint,{shadowed_var,'L','fun'}}]}}, {otp_5091_6, <<"t(A) -> (fun(<<L:16,M:L,N:M>>) -> ok end)(A). ">>, [], - {warnings,[{2,erl_lint,{unused_var,'N'}}]}}, + {warnings,[{{2,34},erl_lint,{unused_var,'N'}}]}}, {otp_5091_7, <<"t() -> U = 8, @@ -1734,7 +1735,7 @@ otp_5091(Config) when is_list(Config) -> U>>) -> U end)(<<32:8>>). ">>, [], - {warnings,[{3,erl_lint,{shadowed_var,'U','fun'}}]}}, + {warnings,[{{3,26},erl_lint,{shadowed_var,'U','fun'}}]}}, {otp_5091_8, <<"t() -> [X || <<A:8, @@ -1758,7 +1759,7 @@ otp_5091(Config) when is_list(Config) -> F(<<16:8, 8:16, 32:8>>). ">>, [], - {warnings,[{3,erl_lint,{shadowed_var,'L','fun'}}]}}, + {warnings,[{{3,29},erl_lint,{shadowed_var,'L','fun'}}]}}, {otp_5091_10, <<"t() -> L = 8, <<A:L,B:A>> = <<16:8, 7:16>>, B. @@ -1778,9 +1779,9 @@ otp_5091(Config) when is_list(Config) -> end. ">>, [], - {warnings,[{2,erl_lint,{unused_var,'A'}}, - {2,erl_lint,{shadowed_var,'A','fun'}}, - {3,erl_lint,{unused_var,'Q'}}]}}, + {warnings,[{{2,24},erl_lint,{unused_var,'A'}}, + {{2,24},erl_lint,{shadowed_var,'A','fun'}}, + {{3,24},erl_lint,{unused_var,'Q'}}]}}, {otp_5091_13, <<"t([A,B]) -> % A unused, B unused fun({A,B}, % A shadowed, B unused, B shadowed @@ -1788,12 +1789,12 @@ otp_5091(Config) when is_list(Config) -> end. ">>, [], - {warnings,[{1,erl_lint,{unused_var,'A'}}, - {1,erl_lint,{unused_var,'B'}}, - {2,erl_lint,{unused_var,'B'}}, - {2,erl_lint,{shadowed_var,'A','fun'}}, - {2,erl_lint,{shadowed_var,'B','fun'}}, - {3,erl_lint,{unused_var,'Q'}}]}}, + {warnings,[{{1,24},erl_lint,{unused_var,'A'}}, + {{1,26},erl_lint,{unused_var,'B'}}, + {{2,23},erl_lint,{shadowed_var,'A','fun'}}, + {{2,25},erl_lint,{unused_var,'B'}}, + {{2,25},erl_lint,{shadowed_var,'B','fun'}}, + {{3,23},erl_lint,{unused_var,'Q'}}]}}, {otp_5091_14, <<"t() -> A = 4, @@ -1801,8 +1802,8 @@ otp_5091(Config) when is_list(Config) -> A>>) -> 2 end. ">>, [], - {warnings,[{3,erl_lint,{unused_var,'A'}}, - {3,erl_lint,{shadowed_var,'A','fun'}}]}}, + {warnings,[{{3,24},erl_lint,{unused_var,'A'}}, + {{3,24},erl_lint,{shadowed_var,'A','fun'}}]}}, {otp_5091_15, <<"t() -> A = 4, % unused @@ -1810,8 +1811,8 @@ otp_5091(Config) when is_list(Config) -> 16:A>>) -> 2 end. ">>, [], - {warnings,[{2,erl_lint,{unused_var,'A'}}, - {3,erl_lint,{shadowed_var,'A','fun'}}]}}, + {warnings,[{{2,18},erl_lint,{unused_var,'A'}}, + {{3,24},erl_lint,{shadowed_var,'A','fun'}}]}}, {otp_5091_16, <<"t() -> A = 4, @@ -1819,8 +1820,8 @@ otp_5091(Config) when is_list(Config) -> A:8>>) -> 7 end. % shadowed, unused ">>, [], - {warnings,[{4,erl_lint,{unused_var,'A'}}, - {4,erl_lint,{shadowed_var,'A','fun'}}]}}, + {warnings,[{{4,24},erl_lint,{unused_var,'A'}}, + {{4,24},erl_lint,{shadowed_var,'A','fun'}}]}}, {otp_5091_17, <<"t() -> L = 16, @@ -1832,7 +1833,7 @@ otp_5091(Config) when is_list(Config) -> end. ">>, [], - {warnings,[{3,erl_lint,{shadowed_var,'L','fun'}}]}}, + {warnings,[{{3,24},erl_lint,{shadowed_var,'L','fun'}}]}}, {otp_5091_18, <<"t() -> L = 4, % L unused @@ -1844,8 +1845,8 @@ otp_5091(Config) when is_list(Config) -> end. ">>, [], - {warnings,[{2,erl_lint,{unused_var,'L'}}, - {3,erl_lint,{shadowed_var,'L','fun'}}]}}, + {warnings,[{{2,18},erl_lint,{unused_var,'L'}}, + {{3,23},erl_lint,{shadowed_var,'L','fun'}}]}}, {otp_5091_19, <<"t() -> L = 4, @@ -1855,32 +1856,32 @@ otp_5091(Config) when is_list(Config) -> L>> <- []]. ">>, [], - {warnings,[{3,erl_lint,{shadowed_var,'L',generate}}]}}, + {warnings,[{{3,26},erl_lint,{shadowed_var,'L',generate}}]}}, {otp_5091_20, <<"t() -> L = 4, % L unused. [1 || L <- []]. % L unused, L shadowed. ">>, [], - {warnings,[{2,erl_lint,{unused_var,'L'}}, - {3,erl_lint,{unused_var,'L'}}, - {3,erl_lint,{shadowed_var,'L',generate}}]}}, + {warnings,[{{2,18},erl_lint,{unused_var,'L'}}, + {{3,24},erl_lint,{unused_var,'L'}}, + {{3,24},erl_lint,{shadowed_var,'L',generate}}]}}, {otp_5091_21, <<"t() -> L = 4, [1 || L <- [L]]. % L shadowed. L unused. ">>, [], - {warnings,[{3,erl_lint,{unused_var,'L'}}, - {3,erl_lint,{shadowed_var,'L',generate}}]}}, + {warnings,[{{3,24},erl_lint,{unused_var,'L'}}, + {{3,24},erl_lint,{shadowed_var,'L',generate}}]}}, {otp_5091_22, <<"t() -> L = 4, % unused fun(L) -> L end. % shadowed ">>, [], - {warnings,[{2,erl_lint,{unused_var,'L'}}, - {3,erl_lint,{shadowed_var,'L','fun'}}]}}, + {warnings,[{{2,18},erl_lint,{unused_var,'L'}}, + {{3,22},erl_lint,{shadowed_var,'L','fun'}}]}}, {otp_5091_23, <<"t([A,A]) -> a.">>, [], []}, {otp_5091_24, @@ -1911,14 +1912,14 @@ otp_5276(Config) when is_list(Config) -> t() -> ok. ">>, {[]}, - {error,[{1,erl_lint,{bad_deprecated,{frutt,0}}}, - {2,erl_lint,{bad_deprecated,{does_not_exist,1}}}, - {3,erl_lint,{invalid_deprecated,'foo bar'}}, - {5,erl_lint,{bad_deprecated,{f,'_'}}}, - {8,erl_lint,{invalid_deprecated,{'_','_',never}}}, - {9,erl_lint,{invalid_deprecated,{{badly,formed},1}}}, - {11,erl_lint,{bad_deprecated,{atom_to_list,1}}}], - [{13,erl_lint,{unused_function,{frutt,0}}}]}}], + {error,[{{1,22},erl_lint,{bad_deprecated,{frutt,0}}}, + {{2,15},erl_lint,{bad_deprecated,{does_not_exist,1}}}, + {{3,15},erl_lint,{invalid_deprecated,'foo bar'}}, + {{5,15},erl_lint,{bad_deprecated,{f,'_'}}}, + {{8,15},erl_lint,{invalid_deprecated,{'_','_',never}}}, + {{9,15},erl_lint,{invalid_deprecated,{{badly,formed},1}}}, + {{11,15},erl_lint,{bad_deprecated,{atom_to_list,1}}}], + [{{13,14},erl_lint,{unused_function,{frutt,0}}}]}}], [] = run(Config, Ts), ok. @@ -1952,9 +1953,9 @@ otp_6585(Config) when is_list(Config) -> f([]). ">>, [warn_obsolete_guard], - {warnings,[{5,erl_lint,{obsolete_guard,{list,1}}}, - {6,erl_lint,{obsolete_guard,{record,2}}}, - {7,erl_lint,{obsolete_guard,{pid,1}}}]}}], + {warnings,[{{5,24},erl_lint,{obsolete_guard,{list,1}}}, + {{6,24},erl_lint,{obsolete_guard,{record,2}}}, + {{7,24},erl_lint,{obsolete_guard,{pid,1}}}]}}], [] = run(Config, Ts), ok. @@ -1968,8 +1969,8 @@ otp_5338(Config) when is_list(Config) -> #c{}. ">>, [], - {error,[{1,erl_lint,{unbound_var,'X'}}], - [{3,erl_lint,{unused_var,'X'}}]}}], + {error,[{{1,39},erl_lint,{unbound_var,'X'}}], + [{{3,19},erl_lint,{unused_var,'X'}}]}}], [] = run(Config, Ts), ok. @@ -1986,8 +1987,8 @@ otp_5362(Config) when is_list(Config) -> begin A = 3, true end]). ">>, {[warn_unused_vars]}, - {warnings,[{1002,erl_lint,{unused_function,{t,0}}}, - {1004,erl_lint,{unused_var,'A'}}]}}, + {warnings,[{{1002,14},erl_lint,{unused_function,{t,0}}}, + {{1004,36},erl_lint,{unused_var,'A'}}]}}, {otp_5362_2, <<"-export([inline/0]). @@ -2020,14 +2021,14 @@ otp_5362(Config) when is_list(Config) -> ok. ">>, {[warn_unused_vars, warn_unused_import]}, - {error,[{5,erl_lint,{bad_inline,{inl,7}}}, - {6,erl_lint,{bad_inline,{inl,17}}}, - {11,erl_lint,{undefined_function,{fipp,0}}}, - {22,erl_lint,{bad_nowarn_unused_function,{and_not_used,2}}}], - [{3,erl_lint,{unused_import,{{b,1},lists}}}, - {9,erl_lint,{unused_function,{foop,0}}}, - {19,erl_lint,{unused_function,{not_used,0}}}, - {23,erl_lint,{unused_function,{and_not_used,1}}}]}}, + {error,[{{5,15},erl_lint,{bad_inline,{inl,7}}}, + {{6,15},erl_lint,{bad_inline,{inl,17}}}, + {{11,18},erl_lint,{undefined_function,{fipp,0}}}, + {{22,15},erl_lint,{bad_nowarn_unused_function,{and_not_used,2}}}], + [{{3,15},erl_lint,{unused_import,{{b,1},lists}}}, + {{9,14},erl_lint,{unused_function,{foop,0}}}, + {{19,14},erl_lint,{unused_function,{not_used,0}}}, + {{23,14},erl_lint,{unused_function,{and_not_used,1}}}]}}, {otp_5362_3, <<"-record(a, {x, @@ -2050,12 +2051,12 @@ otp_5362(Config) when is_list(Config) -> }. ">>, {[nowarn_unused_function]}, - {errors2, [{4,erl_parse,"bad record field"}, - {5,erl_parse,"bad record declaration"}], - [{2,erl_lint,{redefine_field,a,x}}, - {14,erl_lint,{undefined_record,nix}}, - {15,erl_lint,{undefined_field,ok,nix}}, - {16,erl_lint,{field_name_is_variable,ok,'Var'}}]}}, + {errors2, [{{4,27},erl_parse,"bad record field"}, + {{5,26},erl_parse,"bad record declaration"}], + [{{2,27},erl_lint,{redefine_field,a,x}}, + {{14,20},erl_lint,{undefined_record,nix}}, + {{15,24},erl_lint,{undefined_field,ok,nix}}, + {{16,24},erl_lint,{field_name_is_variable,ok,'Var'}}]}}, %% Nowarn_bif_clash has changed behaviour as local functions %% nowdays supersede auto-imported BIFs, why nowarn_bif_clash in itself generates an error @@ -2071,8 +2072,8 @@ otp_5362(Config) when is_list(Config) -> warn_deprecated_function, warn_bif_clash]}, {error, - [{5,erl_lint,{call_to_redefined_old_bif,{spawn,1}}}], - [{4,erl_lint,{deprecated,{erlang,now,0}, + [{{5,19},erl_lint,{call_to_redefined_old_bif,{spawn,1}}}], + [{{4,19},erl_lint,{deprecated,{erlang,now,0}, "see the \"Time and Time Correction in Erlang\" " "chapter of the ERTS User's Guide for more " "information"}}]}}, @@ -2085,7 +2086,7 @@ otp_5362(Config) when is_list(Config) -> ">>, {[nowarn_unused_function]}, {errors, - [{2,erl_lint,disallowed_nowarn_bif_clash}],[]}}, + [{{2,16},erl_lint,disallowed_nowarn_bif_clash}],[]}}, %% The special nowarn_X are not affected by general warn_X. {otp_5362_6, @@ -2099,7 +2100,7 @@ otp_5362(Config) when is_list(Config) -> warn_deprecated_function, warn_bif_clash]}, {errors, - [{2,erl_lint,disallowed_nowarn_bif_clash}],[]}}, + [{{2,16},erl_lint,disallowed_nowarn_bif_clash}],[]}}, {otp_5362_7, <<"-export([spawn/1]). @@ -2114,9 +2115,9 @@ otp_5362(Config) when is_list(Config) -> spawn(A). ">>, {[nowarn_unused_function]}, - {errors,[{3,erl_lint,disallowed_nowarn_bif_clash}, - {4,erl_lint,disallowed_nowarn_bif_clash}, - {4,erl_lint,{bad_nowarn_bif_clash,{spawn,2}}}], + {errors,[{{3,16},erl_lint,disallowed_nowarn_bif_clash}, + {{4,16},erl_lint,disallowed_nowarn_bif_clash}, + {{4,16},erl_lint,{bad_nowarn_bif_clash,{spawn,2}}}], []} }, @@ -2131,7 +2132,7 @@ otp_5362(Config) when is_list(Config) -> {[nowarn_unused_function, {nowarn_bif_clash,{spawn,1}}]}, % has no effect {warnings, - [{5,erl_lint,{deprecated,{erlang,now,0}, + [{{5,19},erl_lint,{deprecated,{erlang,now,0}, "see the \"Time and Time Correction in Erlang\" " "chapter of the ERTS User's Guide for more " "information"}}]}}, @@ -2157,13 +2158,13 @@ otp_5362(Config) when is_list(Config) -> warn_deprecated_function, warn_bif_clash]}, {errors, - [{2,erl_lint,disallowed_nowarn_bif_clash}],[]}}, + [{{2,16},erl_lint,disallowed_nowarn_bif_clash}],[]}}, {call_deprecated_function, <<"t(X) -> calendar:local_time_to_universal_time(X).">>, [], {warnings, - [{1,erl_lint,{deprecated,{calendar,local_time_to_universal_time,1}, + [{{1,29},erl_lint,{deprecated,{calendar,local_time_to_universal_time,1}, "use calendar:local_time_to_universal_time_dst/1 " "instead"}}]}}, @@ -2171,7 +2172,7 @@ otp_5362(Config) when is_list(Config) -> <<"t(X) -> erlang:hash(X, 10000).">>, [], {warnings, - [{1,erl_lint,{removed,{erlang,hash,2}, + [{{1,29},erl_lint,{removed,{erlang,hash,2}, "use erlang:phash2/2 instead"}}]}}, {nowarn_call_removed_function_1, @@ -2187,7 +2188,7 @@ otp_5362(Config) when is_list(Config) -> {call_removed_module, <<"t(X) -> os_mon_mib:any_function_really(X).">>, [], - {warnings,[{1,erl_lint, + {warnings,[{{1,29},erl_lint, {removed,{os_mon_mib,any_function_really,1}, "this module was removed in OTP 22.0"}}]}}, @@ -2226,7 +2227,7 @@ otp_15456(Config) when is_list(Config) -> {nowarn_deprecated_function,{random,uniform_s,1}}, {nowarn_deprecated_function,{erlang,abs,1}}, warn_deprecated_function]}, - {warnings,[{5,erl_lint, + {warnings,[{{5,50},erl_lint, {deprecated,{random,seed,3}, "use the 'rand' module instead"}}]}}, @@ -2249,7 +2250,7 @@ otp_15456(Config) when is_list(Config) -> %% defined in the module. {nowarn_unused_function,{not_defined_in_module,1}}, warn_unused_function]}, - {warnings,[{6,erl_lint,{unused_function,{other,0}}}]} + {warnings,[{{6,15},erl_lint,{unused_function,{other,0}}}]} }], [] = run(Config, Ts), @@ -2262,7 +2263,7 @@ otp_5371(Config) when is_list(Config) -> {A,B}. ">>, [], - {errors,[{1,erl_lint,illegal_bin_pattern}],[]}}, + {errors,[{{1,23},erl_lint,illegal_bin_pattern}],[]}}, {otp_5371_2, <<"x([<<A:8>>] = [<<B:8>>]) -> {A,B}. @@ -2270,8 +2271,8 @@ otp_5371(Config) when is_list(Config) -> {A,B}. ">>, [], - {errors,[{1,erl_lint,illegal_bin_pattern}, - {3,erl_lint,illegal_bin_pattern}],[]}}, + {errors,[{{1,24},erl_lint,illegal_bin_pattern}, + {{3,20},erl_lint,illegal_bin_pattern}],[]}}, {otp_5371_3, <<"-record(foo, {a,b,c}). -record(bar, {x,y,z}). @@ -2288,11 +2289,11 @@ otp_5371(Config) when is_list(Config) -> {X,Y}. ">>, [], - {errors,[{4,erl_lint,illegal_bin_pattern}, - {6,erl_lint,illegal_bin_pattern}, - {8,erl_lint,illegal_bin_pattern}, - {10,erl_lint,illegal_bin_pattern}, - {12,erl_lint,illegal_bin_pattern}],[]}}, + {errors,[{{4,26},erl_lint,illegal_bin_pattern}, + {{6,26},erl_lint,illegal_bin_pattern}, + {{8,26},erl_lint,illegal_bin_pattern}, + {{10,30},erl_lint,illegal_bin_pattern}, + {{12,30},erl_lint,illegal_bin_pattern}],[]}}, {otp_5371_4, <<"-record(foo, {a,b,c}). -record(bar, {x,y,z}). @@ -2305,9 +2306,9 @@ otp_5371(Config) when is_list(Config) -> {X,Y}. ">>, [], - {warnings,[{4,v3_core,nomatch}, - {6,v3_core,nomatch}, - {8,v3_core,nomatch}]}} + {warnings,[{{4,15},v3_core,nomatch}, + {{6,15},v3_core,nomatch}, + {{8,15},v3_core,nomatch}]}} ], [] = run(Config, Ts), ok. @@ -2319,35 +2320,35 @@ otp_7227(Config) when is_list(Config) -> {A,B,C,D}. ">>, [], - {errors,[{1,erl_lint,illegal_bin_pattern}],[]}}, + {errors,[{{1,42},erl_lint,illegal_bin_pattern}],[]}}, {otp_7227_2, <<"t([(<<A:8>> = {C,D}) = <<B:8>>]) -> {A,B,C,D}. ">>, [], - {errors,[{1,erl_lint,illegal_bin_pattern}],[]}}, + {errors,[{{1,25},erl_lint,illegal_bin_pattern}],[]}}, {otp_7227_3, <<"t([(<<A:8>> = {C,D}) = (<<B:8>> = <<C:8>>)]) -> {A,B,C,D}. ">>, [], - {errors,[{1,erl_lint,illegal_bin_pattern}, - {1,erl_lint,illegal_bin_pattern}, - {1,erl_lint,illegal_bin_pattern}],[]}}, + {errors,[{{1,45},erl_lint,illegal_bin_pattern}, + {{1,45},erl_lint,illegal_bin_pattern}, + {{1,55},erl_lint,illegal_bin_pattern}],[]}}, {otp_7227_4, <<"t(Val) -> <<A:8>> = <<B:8>> = Val, {A,B}. ">>, [], - {errors,[{2,erl_lint,illegal_bin_pattern}],[]}}, + {errors,[{{2,19},erl_lint,illegal_bin_pattern}],[]}}, {otp_7227_5, <<"t(Val) -> <<A:8>> = X = <<B:8>> = Val, {A,B,X}. ">>, [], - {errors,[{2,erl_lint,illegal_bin_pattern}],[]}}, + {errors,[{{2,19},erl_lint,illegal_bin_pattern}],[]}}, {otp_7227_6, <<"t(X, Y) -> <<A:8>> = <<X:4,Y:4>>, @@ -2361,23 +2362,23 @@ otp_7227(Config) when is_list(Config) -> {A,B,X}. ">>, [], - {errors,[{2,erl_lint,illegal_bin_pattern}, - {2,erl_lint,illegal_bin_pattern}, - {2,erl_lint,illegal_bin_pattern}],[]}}, + {errors,[{{2,36},erl_lint,illegal_bin_pattern}, + {{2,36},erl_lint,illegal_bin_pattern}, + {{2,46},erl_lint,illegal_bin_pattern}],[]}}, {otp_7227_8, <<"t(Val) -> (<<A:8>> = X) = (Y = <<B:8>>) = Val, {A,B,X,Y}. ">>, [], - {errors,[{2,erl_lint,illegal_bin_pattern}],[]}}, + {errors,[{{2,40},erl_lint,illegal_bin_pattern}],[]}}, {otp_7227_9, <<"t(Val) -> (Z = <<A:8>> = X) = (Y = <<B:8>> = W) = Val, {A,B,X,Y,Z,W}. ">>, [], - {errors,[{2,erl_lint,illegal_bin_pattern}],[]}} + {errors,[{{2,44},erl_lint,illegal_bin_pattern}],[]}} ], [] = run(Config, Ts), ok. @@ -2390,7 +2391,7 @@ otp_5494(Config) when is_list(Config) -> t() -> a. ">>, [], - {warnings,[{2,erl_lint,{duplicated_export,{t,0}}}]}}], + {warnings,[{{2,16},erl_lint,{duplicated_export,{t,0}}}]}}], [] = run(Config, Ts), ok. @@ -2421,8 +2422,8 @@ otp_5878(Config) when is_list(Config) -> t() ->#rec1{}. ">>, [warn_unused_record], - {error,[{1,erl_lint,{undefined_record,rec2}}], - [{2,erl_lint,{unused_record,rec2}}]}}, + {error,[{{1,40},erl_lint,{undefined_record,rec2}}], + [{{2,15},erl_lint,{unused_record,rec2}}]}}, {otp_5878_20, <<"-record(r1, {a = begin A = 4, {A,B} end}). % B unbound @@ -2430,10 +2431,10 @@ otp_5878(Config) when is_list(Config) -> t() -> #r2{}. ">>, [warn_unused_record], - {error,[{1,erl_lint,{unbound_var,'B'}}, - {1,erl_lint,{variable_in_record_def,'A'}}, - {2,erl_lint,{variable_in_record_def,'A'}}], - [{1,erl_lint,{unused_record,r1}}]}}, + {error,[{{1,44},erl_lint,{variable_in_record_def,'A'}}, + {{1,54},erl_lint,{unbound_var,'B'}}, + {{2,38},erl_lint,{variable_in_record_def,'A'}}], + [{{1,22},erl_lint,{unused_record,r1}}]}}, {otp_5878_30, <<"-record(r1, {t = case foo of _ -> 3 end}). @@ -2443,8 +2444,8 @@ otp_5878(Config) when is_list(Config) -> t() -> {#r1{},#r2{},#r3{},#r4{}}. ">>, [warn_unused_record], - {errors,[{2,erl_lint,{variable_in_record_def,'A'}}, - {3,erl_lint,{variable_in_record_def,'A'}}], + {errors,[{{2,44},erl_lint,{variable_in_record_def,'A'}}, + {{3,44},erl_lint,{variable_in_record_def,'A'}}], []}}, {otp_5878_40, @@ -2454,7 +2455,7 @@ otp_5878(Config) when is_list(Config) -> t() -> {#r1{},#r2{},#r3{}}. ">>, [warn_unused_record], - {errors,[{1,erl_lint,{unbound_var,'A'}}],[]}}, + {errors,[{{1,40},erl_lint,{unbound_var,'A'}}],[]}}, {otp_5878_50, <<"-record(r1, {a = {A, % A unbound @@ -2481,11 +2482,11 @@ otp_5878(Config) when is_list(Config) -> t() -> {#r1{},#r2{},#r3{},#r4{}}. ">>, [warn_unused_record], - {error,[{1,erl_lint,{unbound_var,'A'}}, - {2,erl_lint,{unbound_var,'A'}}, - {4,erl_lint,{variable_in_record_def,'A'}}, - {17,erl_lint,{variable_in_record_def,'A'}}], - [{8,erl_lint,{unused_var,'X'}}]}}, + {error,[{{1,39},erl_lint,{unbound_var,'A'}}, + {{2,33},erl_lint,{unbound_var,'A'}}, + {{4,42},erl_lint,{variable_in_record_def,'A'}}, + {{17,44},erl_lint,{variable_in_record_def,'A'}}], + [{{8,36},erl_lint,{unused_var,'X'}}]}}, {otp_5878_60, <<"-record(r1, {a = fun(NotShadowing) -> NotShadowing end}). @@ -2506,8 +2507,8 @@ otp_5878(Config) when is_list(Config) -> t() -> #r1{}. ">>, [warn_unused_record], - {errors,[{3,erl_lint,{unbound_var,'Y'}}, - {4,erl_lint,{variable_in_record_def,'Y'}}], + {errors,[{{3,40},erl_lint,{unbound_var,'Y'}}, + {{4,38},erl_lint,{variable_in_record_def,'Y'}}], []}}, {otp_5878_80, @@ -2517,7 +2518,7 @@ otp_5878(Config) when is_list(Config) -> t() ->#r{}. ">>, [warn_unused_record], - {warnings,[{1,erl_lint,{unused_var,'V'}}]}}, + {warnings,[{{1,59},erl_lint,{unused_var,'V'}}]}}, {otp_5878_90, <<"-record(r, {a = foo()}). % unused @@ -2525,15 +2526,15 @@ otp_5878(Config) when is_list(Config) -> t() -> ok. ">>, [warn_unused_record], - {error,[{1,erl_lint,{undefined_function,{foo,0}}}], - [{1,erl_lint,{unused_record,r}}]}} + {error,[{{1,37},erl_lint,{undefined_function,{foo,0}}}], + [{{1,22},erl_lint,{unused_record,r}}]}} ], [] = run(Config, Ts), Abstr = <<"-module(lint_test, [A, B]). ">>, - {errors,[{1,erl_lint,pmod_unsupported}],[]} = + {errors,[{{1,2},erl_lint,pmod_unsupported}],[]} = run_test2(Config, Abstr, [warn_unused_record]), QLC1 = <<"-module(lint_test). @@ -2546,10 +2547,10 @@ otp_5878(Config) when is_list(Config) -> X <- Z ++ [A,Y]])}). t() -> {#r1{},#r2{},#r3{}}. ">>, - {error,[{8,qlc,{used_generator_variable,'A'}}, - {8,qlc,{used_generator_variable,'Y'}}, - {8,qlc,{used_generator_variable,'Z'}}], - [{6,erl_lint,{unused_var,'V'}}]} = + {error,[{{8,49},qlc,{used_generator_variable,'Z'}}, + {{8,55},qlc,{used_generator_variable,'A'}}, + {{8,57},qlc,{used_generator_variable,'Y'}}], + [{{6,60},erl_lint,{unused_var,'V'}}]} = run_test2(Config, QLC1, [warn_unused_record]), Ill1 = <<"-module(lint_test). @@ -2587,12 +2588,12 @@ otp_5878(Config) when is_list(Config) -> bar. ">>, - {errors,[{6,erl_lint,{unbound_var,'A'}}, - {13,erl_lint,illegal_guard_expr}, - {15,erl_lint,{undefined_field,r3,q}}, - {17,erl_lint,{undefined_field,r,q}}, - {21,erl_lint,illegal_guard_expr}, - {23,erl_lint,{illegal_guard_local_call,{l,0}}}], + {errors,[{{6,32},erl_lint,{unbound_var,'A'}}, + {{13,31},erl_lint,illegal_guard_expr}, + {{15,35},erl_lint,{undefined_field,r3,q}}, + {{17,34},erl_lint,{undefined_field,r,q}}, + {{21,37},erl_lint,illegal_guard_expr}, + {{23,30},erl_lint,{illegal_guard_local_call,{l,0}}}], []} = run_test2(Config, Ill1, [warn_unused_record]), @@ -2606,14 +2607,14 @@ otp_5878(Config) when is_list(Config) -> foo end. ">>, - {errors,[{4,erl_lint,{undefined_function,{x,0}}}, - {5,erl_lint,illegal_guard_expr}, - {7,erl_lint,illegal_guard_expr}], - []} = + {errors,[{{4,24},erl_lint,{undefined_function,{x,0}}}, + {{5,30},erl_lint,illegal_guard_expr}, + {{7,30},erl_lint,illegal_guard_expr}], + []} = run_test2(Config, Ill2, [warn_unused_record]), - + Ill3 = <<"t() -> ok.">>, - {errors,[{1,erl_lint,undefined_module}],[]} = + {errors,[{{1,1},erl_lint,undefined_module}],[]} = run_test2(Config, Ill3, [warn_unused_record]), Usage1 = <<"-module(lint_test). @@ -2626,8 +2627,8 @@ otp_5878(Config) when is_list(Config) -> t() -> {#u2{}}. ">>, - {warnings,[{5,erl_lint,{unused_record,u3}}, - {6,erl_lint,{unused_record,u4}}]} = + {warnings,[{{5,18},erl_lint,{unused_record,u3}}, + {{6,18},erl_lint,{unused_record,u4}}]} = run_test2(Config, Usage1, [warn_unused_record]), Usage2 = <<"-module(lint_test). @@ -2655,9 +2656,9 @@ otp_5878(Config) when is_list(Config) -> H3 = q([X || X <- [1,2]], []), {H1,H2,H3}. ">>, - {warnings,[{6,erl_lint,{missing_qlc_hrl,1}}, - {7,erl_lint,{missing_qlc_hrl,2}}, - {8,erl_lint,{missing_qlc_hrl,2}}]} = + {warnings,[{{6,24},erl_lint,{missing_qlc_hrl,1}}, + {{7,24},erl_lint,{missing_qlc_hrl,2}}, + {{8,24},erl_lint,{missing_qlc_hrl,2}}]} = run_test2(Config, QLC2, [warn_unused_record]), %% Records that are used by types are not unused. @@ -2720,13 +2721,13 @@ otp_6885(Config) when is_list(Config) -> ok. ">>, - {errors,[{3,erl_lint,unsized_binary_not_at_end}, - {4,erl_lint,unsized_binary_not_at_end}, - {5,erl_lint,unsized_binary_not_at_end}, - {10,erl_lint,typed_literal_string}, - {12,erl_lint,typed_literal_string}, - {14,erl_lint,typed_literal_string}, - {16,erl_lint,typed_literal_string}], + {errors,[{{3,17},erl_lint,unsized_binary_not_at_end}, + {{4,17},erl_lint,unsized_binary_not_at_end}, + {{5,10},erl_lint,unsized_binary_not_at_end}, + {{10,19},erl_lint,typed_literal_string}, + {{12,19},erl_lint,typed_literal_string}, + {{14,19},erl_lint,typed_literal_string}, + {{16,19},erl_lint,typed_literal_string}], []} = run_test2(Config, Ts, []), ok. @@ -2737,16 +2738,16 @@ otp_10436(Config) when is_list(Config) -> -opaque t1() :: {i, integer()}. -opaque t2() :: {a, atom()}. ">>, - {warnings,[{4,erl_lint,{not_exported_opaque,{t2,0}}}, - {4,erl_lint,{unused_type,{t2,0}}}]} = + {warnings,[{{4,14},erl_lint,{not_exported_opaque,{t2,0}}}, + {{4,14},erl_lint,{unused_type,{t2,0}}}]} = run_test2(Config, Ts, []), Ts2 = <<"-module(otp_10436_2). -export_type([t1/0, t2/0]). -opaque t1() :: term(). -opaque t2() :: any(). ">>, - {warnings,[{3,erl_lint,{underspecified_opaque,{t1,0}}}, - {4,erl_lint,{underspecified_opaque,{t2,0}}}]} = + {warnings,[{{3,15},erl_lint,{underspecified_opaque,{t1,0}}}, + {{4,15},erl_lint,{underspecified_opaque,{t2,0}}}]} = run_test2(Config, Ts2, []), ok. @@ -2757,8 +2758,8 @@ otp_11254(Config) when is_list(Config) -> manifest(Module, Name) -> fun Module:Nine/1. ">>, - {error,[{4,erl_lint,{unbound_var,'Nine'}}], - [{3,erl_lint,{unused_var,'Name'}}]} = + {error,[{{4,26},erl_lint,{unbound_var,'Nine'}}], + [{{3,30},erl_lint,{unused_var,'Name'}}]} = run_test2(Config, Ts, []), ok. @@ -2782,8 +2783,8 @@ otp_11772(Config) when is_list(Config) -> t() -> 1. ">>, - {errors,[{7,erl_lint,{builtin_type,{node,0}}}, - {8,erl_lint,{builtin_type,{mfa,0}}}], + {errors,[{{7,14},erl_lint,{builtin_type,{node,0}}}, + {{8,14},erl_lint,{builtin_type,{mfa,0}}}], []} = run_test2(Config, Ts, []), ok. @@ -2807,10 +2808,10 @@ otp_11771(Config) when is_list(Config) -> t() -> 1. ">>, - {errors,[{7,erl_lint,{builtin_type,{arity,0}}}, - {8,erl_lint,{builtin_type,{bitstring,0}}}, - {9,erl_lint,{builtin_type,{iodata,0}}}, - {10,erl_lint,{builtin_type,{boolean,0}}}], + {errors,[{{7,14},erl_lint,{builtin_type,{arity,0}}}, + {{8,14},erl_lint,{builtin_type,{bitstring,0}}}, + {{9,14},erl_lint,{builtin_type,{iodata,0}}}, + {{10,14},erl_lint,{builtin_type,{boolean,0}}}], []} = run_test2(Config, Ts, []), ok. @@ -2830,8 +2831,8 @@ otp_11872(Config) when is_list(Config) -> t() -> 1. ">>, - {errors,[{6,erl_lint,{undefined_type,{product,0}}}, - {8,erl_lint,{builtin_type,{map,0}}}], []} = + {errors,[{{6,14},erl_lint,{undefined_type,{product,0}}}, + {{8,14},erl_lint,{builtin_type,{map,0}}}], []} = run_test2(Config, Ts, []), ok. @@ -2843,7 +2844,7 @@ export_all(Config) when is_list(Config) -> id(I) -> I. ">>, [] = run_test2(Config, Ts, [nowarn_export_all]), - {warnings,[{2,erl_lint,export_all}]} = + {warnings,[{{2,14},erl_lint,export_all}]} = run_test2(Config, Ts, []), ok. @@ -2865,7 +2866,7 @@ bif_clash(Config) when is_list(Config) -> N. ">>, [], - {errors,[{2,erl_lint,{call_to_redefined_old_bif,{size,1}}}],[]}}, + {errors,[{{2,19},erl_lint,{call_to_redefined_old_bif,{size,1}}}],[]}}, %% Verify that warnings cannot be turned off in the old way. {clash2, @@ -2903,7 +2904,7 @@ bif_clash(Config) when is_list(Config) -> size(X). ">>, [], - {errors,[{5,erl_lint,{call_to_redefined_old_bif,{size,1}}}],[]}}, + {errors,[{{5,17},erl_lint,{call_to_redefined_old_bif,{size,1}}}],[]}}, %% For a post R14 bif, its only a warning {clash5, <<"-export([binary_part/2]). @@ -2913,7 +2914,7 @@ bif_clash(Config) when is_list(Config) -> binary:part(B,X,Y). ">>, [], - {warnings,[{3,erl_lint,{call_to_redefined_bif,{binary_part,2}}}]}}, + {warnings,[{{3,17},erl_lint,{call_to_redefined_bif,{binary_part,2}}}]}}, %% If you really mean to call yourself here, you can "unimport" size/1 {clash6, <<"-export([size/1]). @@ -2950,7 +2951,7 @@ bif_clash(Config) when is_list(Config) -> binary:part(B,X,Y). ">>, [], - {errors,[{3,erl_lint,{illegal_guard_local_call,{binary_part,2}}}],[]}}, + {errors,[{{3,25},erl_lint,{illegal_guard_local_call,{binary_part,2}}}],[]}}, %% no_auto_import is not like nowarn_bif_clash, it actually removes the autoimport {clash9, <<"-export([x/1]). @@ -2959,7 +2960,7 @@ bif_clash(Config) when is_list(Config) -> binary_part(X,{1,2}) =:= <<1,2>>. ">>, [], - {errors,[{4,erl_lint,{undefined_function,{binary_part,2}}}],[]}}, + {errors,[{{4,18},erl_lint,{undefined_function,{binary_part,2}}}],[]}}, %% but we could import it again... {clash10, <<"-export([x/1]). @@ -2990,7 +2991,7 @@ bif_clash(Config) when is_list(Config) -> binary_part(X,{1,2}) =:= fun binary_part/2. ">>, [], - {errors,[{5,erl_lint,{undefined_function,{binary_part,2}}}],[]}}, + {errors,[{{5,43},erl_lint,{undefined_function,{binary_part,2}}}],[]}}, %% Not from erlang and not from anywhere else {clash13, <<"-export([x/1]). @@ -3000,7 +3001,7 @@ bif_clash(Config) when is_list(Config) -> binary_part(X,{1,2}) =:= fun binary_part/2. ">>, [], - {errors,[{5,erl_lint,{undefined_function,{binary_part,2}}}],[]}}, + {errors,[{{5,43},erl_lint,{undefined_function,{binary_part,2}}}],[]}}, %% ...while real auto-import is OK. {clash14, <<"-export([x/1]). @@ -3017,7 +3018,7 @@ bif_clash(Config) when is_list(Config) -> binary_part(X,{1,2}). ">>, [], - {errors,[{2,erl_lint,{redefine_old_bif_import,{abs,1}}}],[]}}, + {errors,[{{2,16},erl_lint,{redefine_old_bif_import,{abs,1}}}],[]}}, %% For a new BIF, it's only a warning {clash16, <<"-export([x/1]). @@ -3026,7 +3027,7 @@ bif_clash(Config) when is_list(Config) -> abs(X). ">>, [], - {warnings,[{2,erl_lint,{redefine_bif_import,{binary_part,3}}}]}}, + {warnings,[{{2,16},erl_lint,{redefine_bif_import,{binary_part,3}}}]}}, %% And, you cannot redefine already imported things that aren't auto-imported {clash17, <<"-export([x/1]). @@ -3036,7 +3037,7 @@ bif_clash(Config) when is_list(Config) -> abs(X). ">>, [], - {errors,[{3,erl_lint,{redefine_import,{{binary_port,3},x}}}],[]}}, + {errors,[{{3,16},erl_lint,{redefine_import,{{binary_port,3},x}}}],[]}}, %% Not with local functions either {clash18, <<"-export([x/1]). @@ -3047,7 +3048,7 @@ bif_clash(Config) when is_list(Config) -> abs(X). ">>, [], - {errors,[{3,erl_lint,{define_import,{binary_port,3}}}],[]}}, + {errors,[{{3,15},erl_lint,{define_import,{binary_port,3}}}],[]}}, %% Like clash8: Dont accept a guard if it's explicitly module-name called either {clash19, <<"-export([binary_port/3]). @@ -3057,7 +3058,7 @@ bif_clash(Config) when is_list(Config) -> binary_part(A,B,C+1). ">>, [], - {errors,[{4,erl_lint,illegal_guard_expr}],[]}}, + {errors,[{{4,39},erl_lint,illegal_guard_expr}],[]}}, %% Not with local functions either {clash20, <<"-export([binary_port/3]). @@ -3066,7 +3067,7 @@ bif_clash(Config) when is_list(Config) -> binary_part(A,B,C). ">>, [warn_unused_import], - {warnings,[{2,erl_lint,{redefine_bif_import,{binary_part,3}}}]}}, + {warnings,[{{2,16},erl_lint,{redefine_bif_import,{binary_part,3}}}]}}, %% Don't accept call to a guard BIF if there is a local definition %% or an import with the same name. Note: is_record/2 is an %% exception, since it is more of syntatic sugar than a real BIF. @@ -3089,12 +3090,12 @@ bif_clash(Config) when is_list(Config) -> ok. ">>, [{no_auto_import,[{is_tuple,1}]}], - {errors,[{4,erl_lint,{illegal_guard_local_call,{is_tuple,1}}}, - {5,erl_lint,{illegal_guard_local_call,{is_list,1}}}, - {6,erl_lint,{illegal_guard_local_call,{is_tuple,1}}}, - {7,erl_lint,{illegal_guard_local_call,{is_list,1}}}, - {8,erl_lint,{illegal_guard_local_call,{is_record,3}}}, - {9,erl_lint,{illegal_guard_local_call,{is_record,3}}}],[]}}, + {errors,[{{4,25},erl_lint,{illegal_guard_local_call,{is_tuple,1}}}, + {{5,25},erl_lint,{illegal_guard_local_call,{is_list,1}}}, + {{6,25},erl_lint,{illegal_guard_local_call,{is_tuple,1}}}, + {{7,25},erl_lint,{illegal_guard_local_call,{is_list,1}}}, + {{8,25},erl_lint,{illegal_guard_local_call,{is_record,3}}}, + {{9,25},erl_lint,{illegal_guard_local_call,{is_record,3}}}],[]}}, %% We can also suppress all auto imports at once {clash22, <<"-export([size/1, binary_part/2]). @@ -3123,8 +3124,8 @@ behaviour_basic(Config) when is_list(Config) -> <<"-behaviour(application). ">>, [], - {warnings,[{1,erl_lint,{undefined_behaviour_func,{start,2},application}}, - {1,erl_lint,{undefined_behaviour_func,{stop,1},application}}]}}, + {warnings,[{{1,22},erl_lint,{undefined_behaviour_func,{start,2},application}}, + {{1,22},erl_lint,{undefined_behaviour_func,{stop,1},application}}]}}, {behaviour2, <<"-behaviour(application). @@ -3132,7 +3133,7 @@ behaviour_basic(Config) when is_list(Config) -> stop(_) -> ok. ">>, [], - {warnings,[{1,erl_lint,{undefined_behaviour_func,{start,2},application}}]}}, + {warnings,[{{1,22},erl_lint,{undefined_behaviour_func,{start,2},application}}]}}, {behaviour3, <<"-behavior(application). %% Test American spelling. @@ -3149,7 +3150,7 @@ behaviour_basic(Config) when is_list(Config) -> stop(_) -> ok. ">>, [], - {warnings,[{1,erl_lint,{undefined_behaviour_func,{start,2},application}}]}} + {warnings,[{{1,22},erl_lint,{undefined_behaviour_func,{start,2},application}}]}} ], [] = run(Config, Ts), ok. @@ -3161,9 +3162,9 @@ behaviour_multiple(Config) when is_list(Config) -> -behaviour(supervisor). ">>, [], - {warnings,[{1,erl_lint,{undefined_behaviour_func,{start,2},application}}, - {1,erl_lint,{undefined_behaviour_func,{stop,1},application}}, - {2,erl_lint,{undefined_behaviour_func,{init,1},supervisor}}]}}, + {warnings,[{{1,22},erl_lint,{undefined_behaviour_func,{start,2},application}}, + {{1,22},erl_lint,{undefined_behaviour_func,{stop,1},application}}, + {{2,16},erl_lint,{undefined_behaviour_func,{init,1},supervisor}}]}}, {behaviour2, <<"-behaviour(application). @@ -3196,11 +3197,11 @@ behaviour_multiple(Config) when is_list(Config) -> handle_info(_, _) -> ok. ">>, [], - {warnings,[{1,erl_lint,{undefined_behaviour_func,{init,1},gen_server}}, - {2,erl_lint,{undefined_behaviour_func,{init,1},supervisor}}, - {2, + {warnings,[{{1,22},erl_lint,{undefined_behaviour_func,{init,1},gen_server}}, + {{2,16},erl_lint,{undefined_behaviour_func,{init,1},supervisor}}, + {{2,16}, erl_lint, - {conflicting_behaviours,{init,1},supervisor,1,gen_server}}]}}, + {conflicting_behaviours,{init,1},supervisor,{1,22},gen_server}}]}}, {american_behavior3, <<"-behavior(gen_server). -behavior(supervisor). @@ -3210,11 +3211,11 @@ behaviour_multiple(Config) when is_list(Config) -> handle_info(_, _) -> ok. ">>, [], - {warnings,[{1,erl_lint,{undefined_behaviour_func,{init,1},gen_server}}, - {2,erl_lint,{undefined_behaviour_func,{init,1},supervisor}}, - {2, + {warnings,[{{1,22},erl_lint,{undefined_behaviour_func,{init,1},gen_server}}, + {{2,16},erl_lint,{undefined_behaviour_func,{init,1},supervisor}}, + {{2,16}, erl_lint, - {conflicting_behaviours,{init,1},supervisor,1,gen_server}}]}}, + {conflicting_behaviours,{init,1},supervisor,{1,22},gen_server}}]}}, {behaviour4, <<"-behaviour(gen_server). @@ -3239,12 +3240,12 @@ behaviour_multiple(Config) when is_list(Config) -> terminate(_, _, _, _) -> ok. ">>, [], - {warnings,[{2, + {warnings,[{{2,16}, erl_lint, - {conflicting_behaviours,{init,1},gen_fsm,1,gen_server}}, - {3, + {conflicting_behaviours,{init,1},gen_fsm,{1,22},gen_server}}, + {{3,16}, erl_lint, - {conflicting_behaviours,{init,1},supervisor,1,gen_server}}]}} + {conflicting_behaviours,{init,1},supervisor,{1,22},gen_server}}]}} ], [] = run(Config, Ts), ok. @@ -3272,8 +3273,8 @@ otp_11861(Conf) when is_list(Conf) -> ">>, [], %% b2/1 is optional in both modules - {warnings,[{4,erl_lint, - {conflicting_behaviours,{b1,1},callback2,3,callback1}}]}}, + {warnings,[{{4,16},erl_lint, + {conflicting_behaviours,{b1,1},callback2,{3,16},callback1}}]}}, {otp_11861_2, <<" -export([b2/1]). @@ -3286,9 +3287,9 @@ otp_11861(Conf) when is_list(Conf) -> ">>, [], %% b2/1 is optional in callback2, but not in callback1 - {warnings,[{3,erl_lint,{undefined_behaviour_func,{b1,1},callback1}}, - {4,erl_lint, - {conflicting_behaviours,{b2,1},callback2,3,callback1}}]}}, + {warnings,[{{3,16},erl_lint,{undefined_behaviour_func,{b1,1},callback1}}, + {{4,16},erl_lint, + {conflicting_behaviours,{b2,1},callback2,{3,16},callback1}}]}}, {otp_11861_3, <<" -callback b(_) -> atom(). @@ -3303,14 +3304,14 @@ otp_11861(Conf) when is_list(Conf) -> ">>, [], %% No behaviour-info(), but callback. - {errors,[{3,erl_lint,{undefined_callback,{lint_test,b1,1}}}],[]}}, + {errors,[{{3,16},erl_lint,{undefined_callback,{lint_test,b1,1}}}],[]}}, {otp_11861_5, <<" -optional_callbacks([{b1,1}]). % non-existing ">>, [], %% No behaviour-info() and no callback: warning anyway - {errors,[{2,erl_lint,{undefined_callback,{lint_test,b1,1}}}],[]}}, + {errors,[{{2,16},erl_lint,{undefined_callback,{lint_test,b1,1}}}],[]}}, {otp_11861_6, <<" -optional_callbacks([b1/1]). % non-existing @@ -3318,7 +3319,7 @@ otp_11861(Conf) when is_list(Conf) -> ">>, [], %% behaviour-info() and no callback: warning anyway - {errors,[{2,erl_lint,{undefined_callback,{lint_test,b1,1}}}],[]}}, + {errors,[{{2,16},erl_lint,{undefined_callback,{lint_test,b1,1}}}],[]}}, {otp_11861_7, <<" -optional_callbacks([b1/1]). % non-existing @@ -3327,8 +3328,8 @@ otp_11861(Conf) when is_list(Conf) -> ">>, [], %% behaviour-info() callback: warning - {errors,[{2,erl_lint,{undefined_callback,{lint_test,b1,1}}}, - {3,erl_lint,{behaviour_info,{lint_test,b,1}}}], + {errors,[{{2,16},erl_lint,{undefined_callback,{lint_test,b1,1}}}, + {{3,16},erl_lint,{behaviour_info,{lint_test,b,1}}}], []}}, {otp_11861_8, <<" @@ -3336,7 +3337,7 @@ otp_11861(Conf) when is_list(Conf) -> -optional_callbacks([b/1, {b, 1}]). ">>, [], - {errors,[{3,erl_lint,{redefine_optional_callback,{b,1}}}],[]}}, + {errors,[{{3,16},erl_lint,{redefine_optional_callback,{b,1}}}],[]}}, {otp_11861_9, <<" -behaviour(gen_server). @@ -3379,21 +3380,21 @@ otp_11861(Conf) when is_list(Conf) -> -behaviour(bad_behaviour1). ">>, [], - {warnings,[{2,erl_lint, + {warnings,[{{2,16},erl_lint, {ill_defined_behaviour_callbacks,bad_behaviour1}}]}}, {otp_11861_12, <<" -behaviour(non_existing_behaviour). ">>, [], - {warnings,[{2,erl_lint, + {warnings,[{{2,16},erl_lint, {undefined_behaviour,non_existing_behaviour}}]}}, {otp_11861_13, <<" -behaviour(bad_behaviour_none). ">>, [], - {warnings,[{2,erl_lint,{undefined_behaviour,bad_behaviour_none}}]}}, + {warnings,[{{2,16},erl_lint,{undefined_behaviour,bad_behaviour_none}}]}}, {otp_11861_14, <<" -callback b(_) -> atom(). @@ -3413,13 +3414,13 @@ otp_11861(Conf) when is_list(Conf) -> -callback b(_) -> atom(). ">>, [], - {errors,[{3,erl_lint,{redefine_callback,{b,1}}}],[]}}, + {errors,[{{3,16},erl_lint,{redefine_callback,{b,1}}}],[]}}, {otp_11861_17, <<" -behaviour(bad_behaviour2). ">>, [], - {warnings,[{2,erl_lint,{undefined_behaviour_callbacks, + {warnings,[{{2,16},erl_lint,{undefined_behaviour_callbacks, bad_behaviour2}}]}}, {otp_11861_18, <<" @@ -3460,15 +3461,15 @@ otp_7550(Config) when is_list(Config) -> <<A/utf32-unit:1>>. ">>, [], - {errors,[{2,erl_lint,utf_bittype_size_or_unit}, - {4,erl_lint,utf_bittype_size_or_unit}, - {6,erl_lint,utf_bittype_size_or_unit}, - {9,erl_lint,utf_bittype_size_or_unit}, - {11,erl_lint,utf_bittype_size_or_unit}, - {13,erl_lint,utf_bittype_size_or_unit}, - {16,erl_lint,utf_bittype_size_or_unit}, - {18,erl_lint,utf_bittype_size_or_unit}, - {20,erl_lint,utf_bittype_size_or_unit} + {errors,[{{2,21},erl_lint,utf_bittype_size_or_unit}, + {{4,21},erl_lint,utf_bittype_size_or_unit}, + {{6,21},erl_lint,utf_bittype_size_or_unit}, + {{9,21},erl_lint,utf_bittype_size_or_unit}, + {{11,21},erl_lint,utf_bittype_size_or_unit}, + {{13,21},erl_lint,utf_bittype_size_or_unit}, + {{16,21},erl_lint,utf_bittype_size_or_unit}, + {{18,21},erl_lint,utf_bittype_size_or_unit}, + {{20,21},erl_lint,utf_bittype_size_or_unit} ], []}}], [] = run(Config, Ts), @@ -3482,14 +3483,14 @@ otp_8051(Config) when is_list(Config) -> -export_type([foo/0]). ">>, [], - {errors,[{1,erl_lint,{undefined_type,{bar,0}}}],[]}}], + {errors,[{{1,38},erl_lint,{undefined_type,{bar,0}}}],[]}}], [] = run(Config, Ts), ok. %% Check that format warnings are generated. format_warn(Config) when is_list(Config) -> L1 = 14, - L2 = 4, + L2 = 5, format_level(1, L1, Config), format_level(2, L1+L2, Config), format_level(3, L1+L2, Config), %there is no level 3 @@ -3553,7 +3554,7 @@ on_load_failing(Config) when is_list(Config) -> ">>, {[]}, %Tuple indicates no 'export_all'. {errors, - [{1,erl_lint,{bad_on_load,atom}}],[]}}, + [{{1,22},erl_lint,{bad_on_load,atom}}],[]}}, {on_load_2, %% Badly formed. @@ -3561,7 +3562,7 @@ on_load_failing(Config) when is_list(Config) -> ">>, {[]}, %Tuple indicates no 'export_all'. {errors, - [{1,erl_lint,{bad_on_load,{42,0}}}],[]}}, + [{{1,22},erl_lint,{bad_on_load,{42,0}}}],[]}}, {on_load_3, %% Multiple on_load attributes. @@ -3572,7 +3573,7 @@ on_load_failing(Config) when is_list(Config) -> ">>, {[]}, %Tuple indicates no 'export_all'. {errors, - [{2,erl_lint,multiple_on_loads}],[]}}, + [{{2,16},erl_lint,multiple_on_loads}],[]}}, {on_load_4, %% Wrong arity. @@ -3581,7 +3582,7 @@ on_load_failing(Config) when is_list(Config) -> ">>, {[]}, %Tuple indicates no 'export_all'. {errors, - [{1,erl_lint,{bad_on_load_arity,{foo,1}}}],[]}}, + [{{1,22},erl_lint,{bad_on_load_arity,{foo,1}}}],[]}}, {on_load_5, %% Non-existing function. @@ -3589,7 +3590,7 @@ on_load_failing(Config) when is_list(Config) -> ">>, {[]}, %Tuple indicates no 'export_all'. {errors, - [{1,erl_lint,{undefined_on_load,{non_existing,0}}}],[]}} + [{{1,22},erl_lint,{undefined_on_load,{non_existing,0}}}],[]}} ], [] = run(Config, Ts), ok. @@ -3600,7 +3601,7 @@ too_many_arguments(Config) when is_list(Config) -> <<"f(_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_) -> ok.">>, [], {errors, - [{1,erl_lint,{too_many_arguments,256}}],[]}} + [{{1,21},erl_lint,{too_many_arguments,256}}],[]}} ], [] = run(Config, Ts), @@ -3612,45 +3613,45 @@ basic_errors(Config) -> Ts = [{redefine_module, <<"-module(redefine_module).">>, [], - {errors,[{1,erl_lint,redefine_module}],[]}}, + {errors,[{{1,22},erl_lint,redefine_module}],[]}}, {attr_after_function, <<"f() -> ok. -attr(x).">>, [], - {errors,[{2,erl_lint,{attribute,attr}}],[]}}, + {errors,[{{2,17},erl_lint,{attribute,attr}}],[]}}, {redefine_function, <<"f() -> ok. f() -> ok.">>, [], - {errors,[{2,erl_lint,{redefine_function,{f,0}}}],[]}}, + {errors,[{{2,15},erl_lint,{redefine_function,{f,0}}}],[]}}, {redefine_record, <<"-record(r, {a}). -record(r, {a}). f(#r{}) -> ok.">>, [], - {errors,[{2,erl_lint,{redefine_record,r}}],[]}}, + {errors,[{{2,16},erl_lint,{redefine_record,r}}],[]}}, {illegal_record_info, <<"f1() -> record_info(42, record). f2() -> record_info(shoe_size, record). f3() -> fun record_info/2.">>, [], - {errors,[{1,erl_lint,illegal_record_info}, - {2,erl_lint,illegal_record_info}, - {3,erl_lint,illegal_record_info}],[]}}, + {errors,[{{1,29},erl_lint,illegal_record_info}, + {{2,28},erl_lint,illegal_record_info}, + {{3,23},erl_lint,illegal_record_info}],[]}}, {illegal_expr, <<"f() -> a:b.">>, [], - {errors,[{1,erl_lint,illegal_expr}],[]}}, + {errors,[{{1,28},erl_lint,illegal_expr}],[]}}, {illegal_pattern, <<"f(A+B) -> ok.">>, [], - {errors,[{1,erl_lint,illegal_pattern}],[]}} + {errors,[{{1,24},erl_lint,illegal_pattern}],[]}} ], [] = run(Config, Ts), ok. @@ -3676,23 +3677,23 @@ bin_syntax_errors(Config) -> foo. ">>, [], - {error,[{2,erl_lint,illegal_bitsize}, - {3,erl_lint,{illegal_bitsize_local_call,{l,0}}}, - {5,erl_lint,{undefined_bittype,bad_type}}, - {6,erl_lint,bittype_unit}, - {8,erl_lint,illegal_pattern}, - {9,erl_lint,illegal_pattern}, - {11,erl_lint,{bittype_mismatch,integer,binary,"type"}}, - {11,erl_lint,{bittype_mismatch,unsigned,signed,"sign"}}, - {12,erl_lint,{bittype_mismatch,8,4,"unit"}}, - {12,erl_lint,{bittype_mismatch,big,little,"endianness"}}, - {13,erl_lint,{unbound_var,'A'}}, - {13,erl_lint,{unbound_var,'B'}} + {error,[{{2,17},erl_lint,illegal_bitsize}, + {{3,15},erl_lint,{illegal_bitsize_local_call,{l,0}}}, + {{5,19},erl_lint,{undefined_bittype,bad_type}}, + {{6,12},erl_lint,bittype_unit}, + {{8,13},erl_lint,illegal_pattern}, + {{9,15},erl_lint,illegal_pattern}, + {{11,20},erl_lint,{bittype_mismatch,integer,binary,"type"}}, + {{11,41},erl_lint,{bittype_mismatch,unsigned,signed,"sign"}}, + {{12,20},erl_lint,{bittype_mismatch,big,little,"endianness"}}, + {{12,37},erl_lint,{bittype_mismatch,8,4,"unit"}}, + {{13,22},erl_lint,{unbound_var,'A'}}, + {{13,24},erl_lint,{unbound_var,'B'}} ], - [{1,erl_lint,non_integer_bitsize}, - {4,erl_lint,non_integer_bitsize}, - {7,erl_lint,{bad_bitsize,"float"}}, - {13,erl_lint,non_integer_bitsize}]}} + [{{1,27},erl_lint,non_integer_bitsize}, + {{4,21},erl_lint,non_integer_bitsize}, + {{7,12},erl_lint,{bad_bitsize,"float"}}, + {{13,21},erl_lint,non_integer_bitsize}]}} ], [] = run(Config, Ts), ok. @@ -3704,14 +3705,14 @@ predef(Config) when is_list(Config) -> %% dict(), digraph() and so on were removed in Erlang/OTP 18.0. E2 = get_compilation_result(Config, "predef2", []), Tag = undefined_type, - {[{7,erl_lint,{Tag,{array,0}}}, - {12,erl_lint,{Tag,{dict,0}}}, - {17,erl_lint,{Tag,{digraph,0}}}, - {27,erl_lint,{Tag,{gb_set,0}}}, - {32,erl_lint,{Tag,{gb_tree,0}}}, - {37,erl_lint,{Tag,{queue,0}}}, - {42,erl_lint,{Tag,{set,0}}}, - {47,erl_lint,{Tag,{tid,0}}}],[]} = E2, + {[{{7,13},erl_lint,{Tag,{array,0}}}, + {{12,12},erl_lint,{Tag,{dict,0}}}, + {{17,15},erl_lint,{Tag,{digraph,0}}}, + {{27,14},erl_lint,{Tag,{gb_set,0}}}, + {{32,15},erl_lint,{Tag,{gb_tree,0}}}, + {{37,13},erl_lint,{Tag,{queue,0}}}, + {{42,11},erl_lint,{Tag,{set,0}}}, + {{47,16},erl_lint,{Tag,{tid,0}}}],[]} = E2, ok. maps(Config) -> @@ -3731,9 +3732,9 @@ maps(Config) -> ok. ">>, [], - {errors,[{2,erl_lint,illegal_map_construction}, - {4,erl_lint,illegal_map_construction}, - {8,erl_lint,illegal_map_construction}], + {errors,[{{2,24},erl_lint,illegal_map_construction}, + {{4,24},erl_lint,illegal_map_construction}, + {{8,36},erl_lint,illegal_map_construction}], []}}, {illegal_pattern, <<"t(#{ a := A, @@ -3747,14 +3748,14 @@ maps(Config) -> {A,F}. ">>, [], - {errors,[{2,erl_lint,illegal_pattern}, - {7,erl_lint,illegal_pattern}], + {errors,[{{2,22},erl_lint,illegal_pattern}, + {{7,28},erl_lint,illegal_pattern}], []}}, {error_in_illegal_map_construction, <<"t() -> #{ a := X }.">>, [], - {errors,[{1,erl_lint,illegal_map_construction}, - {1,erl_lint,{unbound_var,'X'}}], + {errors,[{{1,33},erl_lint,illegal_map_construction}, + {{1,36},erl_lint,{unbound_var,'X'}}], []}}, {legal_map_pattern, <<" @@ -3802,14 +3803,14 @@ maps(Config) -> A. ">>, [], - {errors,[{4,erl_lint,illegal_map_construction}, - {6,erl_lint,{unbound_var,'V'}}],[]}}, + {errors,[{{4,18},erl_lint,illegal_map_construction}, + {{6,9},erl_lint,{unbound_var,'V'}}],[]}}, {unused_vars_with_empty_maps, <<"t(Foo, Bar, Baz) -> {#{},#{}}.">>, [warn_unused_variables], - {warnings,[{1,erl_lint,{unused_var,'Bar'}}, - {1,erl_lint,{unused_var,'Baz'}}, - {1,erl_lint,{unused_var,'Foo'}}]}}], + {warnings,[{{1,23},erl_lint,{unused_var,'Foo'}}, + {{1,28},erl_lint,{unused_var,'Bar'}}, + {{1,33},erl_lint,{unused_var,'Baz'}}]}}], [] = run(Config, Ts), ok. @@ -3838,7 +3839,7 @@ maps_type(Config) when is_list(Config) -> t(M) -> M. ">>, [], - {errors,[{3,erl_lint,{builtin_type,{map,0}}}],[]}}], + {errors,[{{3,7},erl_lint,{builtin_type,{map,0}}}],[]}}], [] = run(Config, Ts), ok. @@ -3850,7 +3851,7 @@ maps_parallel_match(Config) when is_list(Config) -> V. ">>, [], - {errors,[{3,erl_lint,{unbound_var,'K'}}],[]}}, + {errors,[{{3,18},erl_lint,{unbound_var,'K'}}],[]}}, {parallel_map_patterns_unbound2, <<" t(#{} = M) -> @@ -3860,10 +3861,10 @@ maps_parallel_match(Config) when is_list(Config) -> [V1,V2]. ">>, [], - {errors,[{3,erl_lint,{unbound_var,'K1'}}, - {3,erl_lint,{unbound_var,'K1'}}, - {4,erl_lint,{unbound_var,'K2'}}, - {4,erl_lint,{unbound_var,'K2'}}],[]}}, + {errors,[{{3,18},erl_lint,{unbound_var,'K1'}}, + {{3,18},erl_lint,{unbound_var,'K1'}}, + {{4,18},erl_lint,{unbound_var,'K2'}}, + {{4,18},erl_lint,{unbound_var,'K2'}}],[]}}, {parallel_map_patterns_bound, <<" t(#{} = M,K1,K2) -> @@ -3943,7 +3944,7 @@ otp_11851(Config) when is_list(Config) -> t()-> a. ">>, [], - {errors,[{5,erl_lint,{bad_callback,{lint_test,a,1}}}],[]}}, + {errors,[{{5,14},erl_lint,{bad_callback,{lint_test,a,1}}}],[]}}, {otp_11851_3, <<"-export([a/1]). @@ -3954,7 +3955,7 @@ otp_11851(Config) when is_list(Config) -> a(_) -> true. ">>, [], - {errors,[{4,erl_parse,"bad type variable"}],[]}}, + {errors,[{{4,19},erl_parse,"bad type variable"}],[]}}, {otp_11851_4, <<" -spec a(_) -> ok. @@ -3964,10 +3965,10 @@ otp_11851(Config) when is_list(Config) -> -spec ?MODULE:a(_) -> ok. ">>, [], - {errors,[{3,erl_lint,{redefine_spec,{a,1}}}, - {5,erl_lint,{redefine_spec,{lint_test,a,1}}}, - {6,erl_lint,{redefine_spec,{lint_test,a,1}}}, - {6,erl_lint,{spec_fun_undefined,{a,1}}}], + {errors,[{{3,14},erl_lint,{redefine_spec,{a,1}}}, + {{5,14},erl_lint,{redefine_spec,{lint_test,a,1}}}, + {{6,14},erl_lint,{redefine_spec,{lint_test,a,1}}}, + {{6,14},erl_lint,{spec_fun_undefined,{a,1}}}], []}} ], [] = run(Config, Ts), @@ -4002,8 +4003,8 @@ compile_forms(Terms, Opts) -> %% OTP-13230: -deprecated without -module. otp_13230(Config) when is_list(Config) -> Abstr = <<"-deprecated([{frutt,0,next_version}]).">>, - {errors,[{1,erl_lint,undefined_module}, - {1,erl_lint,{bad_deprecated,{frutt,0}}}], + {errors,[{{1,2},erl_lint,undefined_module}, + {{1,2},erl_lint,{bad_deprecated,{frutt,0}}}], []} = run_test2(Config, Abstr, []), ok. @@ -4014,8 +4015,8 @@ record_errors(Config) when is_list(Config) -> u(R) -> R#r{a=1,b=2,a=2}. ">>, [], - {errors,[{2,erl_lint,{redefine_field,r,a}}, - {3,erl_lint,{redefine_field,r,a}}],[]}}], + {errors,[{{2,36},erl_lint,{redefine_field,r,a}}, + {{3,35},erl_lint,{redefine_field,r,a}}],[]}}], run(Config, Ts). otp_11879_cont(Config) -> @@ -4026,7 +4027,7 @@ otp_11879_cont(Config) -> ">>, [], {errors, - [{2,erl_parse,"unsupported constraint " ++ ["is_subtype"]}], + [{{2,36},erl_parse,"unsupported constraint " ++ ["is_subtype"]}], []}}, {constraint2, <<"-export([t/1]). @@ -4035,7 +4036,7 @@ otp_11879_cont(Config) -> ">>, [], {errors, - [{2,erl_parse,"unsupported constraint " ++ ["bad_atom"]}], + [{{2,36},erl_parse,"unsupported constraint " ++ ["bad_atom"]}], []}}, {constraint3, <<"-export([t/1]). @@ -4043,14 +4044,14 @@ otp_11879_cont(Config) -> t(a) -> foo:bar(). ">>, [], - {errors,[{2,erl_parse,"bad type variable"}],[]}}, + {errors,[{{2,47},erl_parse,"bad type variable"}],[]}}, {constraint4, <<"-export([t/1]). -spec t(X) -> X when is_subtype(atom(), integer()). t(a) -> foo:bar(). ">>, [], - {errors,[{2,erl_parse,"bad type variable"}],[]}}, + {errors,[{{2,47},erl_parse,"bad type variable"}],[]}}, {constraint5, <<"-export([t/1]). -spec t(X) -> X when is_subtype(X, integer()). @@ -4114,20 +4115,20 @@ non_latin1_module(Config) -> 'кирилли́ческий атом':F()."/utf8>>, [], {error, - [{4,erl_lint,non_latin1_module_unsupported}, - {5,erl_lint,non_latin1_module_unsupported}, - {6,erl_lint,non_latin1_module_unsupported}, - {8,erl_lint,non_latin1_module_unsupported}, - {8,erl_lint,BadCallback}, - {11,erl_lint,illegal_guard_expr}, - {15,erl_lint,non_latin1_module_unsupported}, - {17,erl_lint,non_latin1_module_unsupported}, - {17,erl_lint,BadModule}, - {20,erl_lint,non_latin1_module_unsupported}, - {23,erl_lint,non_latin1_module_unsupported}, - {25,erl_lint,non_latin1_module_unsupported}], - [{5,erl_lint,UndefBehav}, - {6,erl_lint,UndefBehav}]}}], + [{{4,14},erl_lint,non_latin1_module_unsupported}, + {{5,14},erl_lint,non_latin1_module_unsupported}, + {{6,14},erl_lint,non_latin1_module_unsupported}, + {{8,14},erl_lint,non_latin1_module_unsupported}, + {{8,14},erl_lint,BadCallback}, + {{11,23},erl_lint,illegal_guard_expr}, + {{15,17},erl_lint,non_latin1_module_unsupported}, + {{17,14},erl_lint,non_latin1_module_unsupported}, + {{17,14},erl_lint,BadModule}, + {{20,15},erl_lint,non_latin1_module_unsupported}, + {{23,17},erl_lint,non_latin1_module_unsupported}, + {{25,17},erl_lint,non_latin1_module_unsupported}], + [{{5,14},erl_lint,UndefBehav}, + {{6,14},erl_lint,UndefBehav}]}}], run(Config, Ts), ok. @@ -4150,7 +4151,7 @@ otp_14378(Config) -> t() -> erlang:now().">>, [], - {warnings,[{4,erl_lint, + {warnings,[{{4,18},erl_lint, {deprecated,{erlang,now,0}, "see the \"Time and Time Correction in Erlang\" " "chapter of the ERTS User's Guide for more " @@ -4188,21 +4189,21 @@ otp_14323(Config) -> g() -> b. h() -> c.">>, [], - {errors,[{5,erl_lint,{undefined_function,{module_info,0}}}, - {6,erl_lint,{undefined_function,{record_info,2}}}, - {7,erl_lint,{undefined_function,{m,1}}}, - {9,erl_lint,{bad_dialyzer_option,nowarn_function}}, - {10,erl_lint,{bad_dialyzer_attribute,1}}, - {11,erl_lint,{bad_dialyzer_option,malformed}}, - {12,erl_lint,{bad_dialyzer_option,malformed}}, - {13,erl_lint,{undefined_function,{a,1}}}, - {14,erl_lint,{bad_dialyzer_attribute, + {errors,[{{5,16},erl_lint,{undefined_function,{module_info,0}}}, + {{6,16},erl_lint,{undefined_function,{record_info,2}}}, + {{7,16},erl_lint,{undefined_function,{m,1}}}, + {{9,16},erl_lint,{bad_dialyzer_option,nowarn_function}}, + {{10,16},erl_lint,{bad_dialyzer_attribute,1}}, + {{11,16},erl_lint,{bad_dialyzer_option,malformed}}, + {{12,16},erl_lint,{bad_dialyzer_option,malformed}}, + {{13,16},erl_lint,{undefined_function,{a,1}}}, + {{14,16},erl_lint,{bad_dialyzer_attribute, {nowarn_function,{a,-1}}}}], []}}, {otp_14323_2, <<"-type t(_) :: atom().">>, [], - {errors,[{1,erl_parse,"bad type variable"}],[]}}], + {errors,[{{1,29},erl_parse,"bad type variable"}],[]}}], [] = run(Config, Ts), ok. @@ -4214,7 +4215,7 @@ stacktrace_syntax(Config) -> end. ">>, [], - {errors,[{3,erl_lint,{stacktrace_guard,'Stk'}}],[]}}, + {errors,[{{3,48},erl_lint,{stacktrace_guard,'Stk'}}],[]}}, {bound, <<"t1() -> Stk = [], @@ -4223,7 +4224,7 @@ stacktrace_syntax(Config) -> end. ">>, [], - {errors,[{4,erl_lint,{stacktrace_bound,'Stk'}}],[]}}, + {errors,[{{4,29},erl_lint,{stacktrace_bound,'Stk'}}],[]}}, {bound_in_pattern, <<"t1() -> try error(foo) @@ -4231,7 +4232,7 @@ stacktrace_syntax(Config) -> end. ">>, [], - {errors,[{3,erl_lint,{stacktrace_bound,'T'}}],[]}}, + {errors,[{{3,33},erl_lint,{stacktrace_bound,'T'}}],[]}}, {guard_and_bound, <<"t1() -> Stk = [], @@ -4240,8 +4241,8 @@ stacktrace_syntax(Config) -> end. ">>, [], - {errors,[{4,erl_lint,{stacktrace_bound,'Stk'}}, - {4,erl_lint,{stacktrace_guard,'Stk'}}],[]}} + {errors,[{{4,29},erl_lint,{stacktrace_bound,'Stk'}}, + {{4,49},erl_lint,{stacktrace_guard,'Stk'}}],[]}} ], run(Config, Ts), @@ -4266,7 +4267,7 @@ otp_14285(Config) -> "/utf8>>, [], {errors, - [{2,erl_lint,E1}], + [{{2,15},erl_lint,E1}], []}}, {otp_14285_2, <<"'кирилли́ческий атом'() -> a. @@ -4274,21 +4275,21 @@ otp_14285(Config) -> "/utf8>>, [], {errors, - [{2,erl_lint,E2}], + [{{2,16},erl_lint,E2}], []}}, {otp_14285_3, <<"'кирилли́ческий атом'() -> #'кирилли́ческий атом'{}. "/utf8>>, [], {errors, - [{1,erl_lint,E3}], + [{{1,48},erl_lint,E3}], []}}, {otp_14285_4, <<"t() -> <<34/'кирилли́ческий атом'>>. "/utf8>>, [], {errors, - [{1,erl_lint,E4}], + [{{1,30},erl_lint,E4}], []}}], run(Config, Ts), ok. @@ -4303,8 +4304,8 @@ external_funs(Config) when is_list(Config) -> BugVar = process_info(self()), if true -> fun M:F/1 end.">>, [], - {warnings,[{2,erl_lint,{unused_var,'BugVar'}}, - {5,erl_lint,{unused_var,'BugVar'}}]}}], + {warnings,[{{2,17},erl_lint,{unused_var,'BugVar'}}, + {{5,17},erl_lint,{unused_var,'BugVar'}}]}}], run(Config, Ts), ok. @@ -4317,8 +4318,8 @@ otp_15563(Config) when is_list(Config) -> foo() -> a. ">>, [warn_unused_vars], - {errors,[{2,erl_lint,{bad_module,{lists,flatten,1}}}, - {3,erl_lint,{bad_callback,{lists,concat,1}}}], + {errors,[{{2,16},erl_lint,{bad_module,{lists,flatten,1}}}, + {{3,16},erl_lint,{bad_callback,{lists,concat,1}}}], []}}], [] = run(Config, Ts), ok. @@ -4337,12 +4338,12 @@ removed(Config) when is_list(Config) -> t() -> ok. ">>, {[]}, - {error,[{3,erl_lint,{bad_removed,{t,0}}}, - {4,erl_lint,{bad_removed,{t,'_'}}}, - {5,erl_lint,{bad_removed,{'_','_'}}}, - {6,erl_lint,{invalid_removed,{{badly,formed},1}}}, - {7,erl_lint,{invalid_removed,'badly formed'}}], - [{9,erl_lint,{unused_function,{frutt,0}}}]}} + {error,[{{3,15},erl_lint,{bad_removed,{t,0}}}, + {{4,15},erl_lint,{bad_removed,{t,'_'}}}, + {{5,15},erl_lint,{bad_removed,{'_','_'}}}, + {{6,15},erl_lint,{invalid_removed,{{badly,formed},1}}}, + {{7,15},erl_lint,{invalid_removed,'badly formed'}}], + [{{9,14},erl_lint,{unused_function,{frutt,0}}}]}} ], [] = run(Config, Ts), ok. @@ -4365,8 +4366,8 @@ one_multi_init(Config) -> g. ">>, [], - {errors,[{2,erl_lint,bad_multi_field_init}, - {4,erl_lint,bad_multi_field_init}],[]}}, + {errors,[{{2,28},erl_lint,bad_multi_field_init}, + {{4,20},erl_lint,bad_multi_field_init}],[]}}, {otp_16516_2, %% No error since "_ = '_'" is actually used as a catch-all %% initialization. V is unused (as compilation with the 'E' @@ -4405,12 +4406,12 @@ several_multi_inits(Config) -> V1. ">>, [], - {errors,[{3,erl_lint,bad_multi_field_init}, - {4,erl_lint,{unbound_var,'V1'}}, - {4,erl_lint,{unbound_var,'V2'}}, - {6,erl_lint,bad_multi_field_init}, - {7,erl_lint,{unbound_var,'V1'}}, - {7,erl_lint,{unbound_var,'V2'}}],[]}}, + {errors,[{{3,28},erl_lint,bad_multi_field_init}, + {{4,20},erl_lint,{unbound_var,'V1'}}, + {{4,24},erl_lint,{unbound_var,'V2'}}, + {{6,20},erl_lint,bad_multi_field_init}, + {{7,20},erl_lint,{unbound_var,'V1'}}, + {{7,24},erl_lint,{unbound_var,'V2'}}],[]}}, {otp_16516_5, <<"-record(r, {f, g}). t(V1, V2) -> @@ -4421,9 +4422,10 @@ several_multi_inits(Config) -> _ = V2, f = 3}. ">>, [], - {error,[{4,erl_lint,bad_multi_field_init}, - {7,erl_lint,bad_multi_field_init}], - [{2,erl_lint,{unused_var,'V2'}},{5,erl_lint,{unused_var,'V2'}}]}}, + {error,[{{4,22},erl_lint,bad_multi_field_init}, + {{7,22},erl_lint,bad_multi_field_init}], + [{{2,21},erl_lint,{unused_var,'V2'}}, + {{5,21},erl_lint,{unused_var,'V2'}}]}}, {otp_16516_6, <<"-record(r, {f, g}). t(V1, V2) when #r{_ = V1, f = 3, @@ -4434,10 +4436,10 @@ several_multi_inits(Config) -> a. ">>, [], - {error,[{3,erl_lint,bad_multi_field_init}, - {6,erl_lint,bad_multi_field_init}], - [{2,erl_lint,{unused_var,'V2'}}, - {5,erl_lint,{unused_var,'V2'}}]}}], + {error,[{{3,33},erl_lint,bad_multi_field_init}, + {{6,33},erl_lint,bad_multi_field_init}], + [{{2,21},erl_lint,{unused_var,'V2'}}, + {{5,21},erl_lint,{unused_var,'V2'}}]}}], [] = run(Config, Ts). inline_nifs(Config) -> @@ -4447,14 +4449,14 @@ inline_nifs(Config) -> gurka() -> ok. ">>, [], - {warnings,[{2,erl_lint,nif_inline}]}}, + {warnings,[{{2,22},erl_lint,nif_inline}]}}, {explicit_inline, <<"-compile({inline, [gurka/0]}). t() -> erlang:load_nif([], []). gurka() -> ok. ">>, [], - {warnings,[{2,erl_lint,nif_inline}]}}], + {warnings,[{{2,22},erl_lint,nif_inline}]}}], [] = run(Config, Ts). warn_missing_spec(Config) -> @@ -4471,17 +4473,53 @@ warn_missing_spec(Config) -> internal_no_spec() -> ok.">>, run(Config, [ {warn_missing_spec, Test, [warn_missing_spec], - {warnings, [{6, erl_lint, {missing_spec, {external_no_spec, 0}}}]}}, + {warnings, [{{6,15}, erl_lint, {missing_spec, {external_no_spec, 0}}}]}}, {warn_missing_spec_all, Test, [warn_missing_spec_all], - {warnings, [{6, erl_lint, {missing_spec, {external_no_spec, 0}}}, - {11, erl_lint, {missing_spec, {internal_no_spec, 0}}}]}} + {warnings, [{{6,15}, erl_lint, {missing_spec, {external_no_spec, 0}}}, + {{11,15}, erl_lint, {missing_spec, {internal_no_spec, 0}}}]}} ]). +otp_16824(Config) -> + Ts = [{otp_16824_1, + <<"-record(a, {x,y}). + t() -> + R = #a{}, + R#a{_ = 4}, + R. + ">>, + {[]}, + {error,[{{4,23},erl_lint,{wildcard_in_update,a}}], + [{{2,15},erl_lint,{unused_function,{t,0}}}]}}, + + {otp_16824_2, + <<"\n-type t(_A, 3 + 4) :: integer(). + ">>, + {[]}, + {errors,[{{2,13},erl_parse,"bad type variable"}],[]}}, + + {otp_16824_3, + <<"-export_type([s/0, t/0, u/0]). + -record(r, {a :: integer() ,b :: atom()}). + -type s() :: #s{a :: atom(), b :: integer()}. + -type t() :: #r{c :: integer()}. + -type u() :: #r{a :: integer(), a :: atom()}. + ">>, + {[]}, + {errors,[{{3,27},erl_lint,{undefined_record,s}}, + {{4,30},erl_lint,{undefined_field,r,c}}, + {{5,46},erl_lint,{redefine_field,r,a}}], + []}} + ], + [] = run(Config, Ts), + + ok. + format_error(E) -> lists:flatten(erl_lint:format_error(E)). run(Config, Tests) -> F = fun({N,P,Ws,E}, BadL) -> + io:format("### ~s\n", [N]), case catch run_test(Config, P, Ws) of E -> BadL; @@ -4537,20 +4575,26 @@ run_test2(Conf, Test, Warnings0) -> case compile:file(File, [binary|Opts]) of {ok, _M, Code, Ws} when is_binary(Code) -> - warnings(File, Ws); + warnings(File, Ws, Test); {error, [{File,Es}], []} -> + print_diagnostics(Es, Test), {errors, call_format_error(Es), []}; {error, [{File,Es}], [{File,Ws}]} -> + print_diagnostics(Es, Test), + print_diagnostics(Ws, Test), {error, call_format_error(Es), call_format_error(Ws)}; {error, [{File,Es1},{File,Es2}], []} -> + print_diagnostics(Es1, Test), + print_diagnostics(Es2, Test), {errors2, Es1, Es2} end. -warnings(File, Ws) -> +warnings(File, Ws, Source) -> case lists:append([W || {F, W} <- Ws, F =:= File]) of [] -> []; L -> + print_diagnostics(L, Source), {warnings, call_format_error(L)} end. @@ -4560,5 +4604,28 @@ call_format_error(L) -> _ = [Mod:format_error(Term) || {_,Mod,Term} <- L], L. +print_diagnostics(Warnings, Source) -> + case binary:match(Source, <<"-file(">>) of + nomatch -> + Lines = binary:split(Source, <<"\n">>, [global]), + Cs = [print_diagnostic(W, Lines) || W <- Warnings], + io:put_chars(Cs); + _ -> + %% There are probably fake line numbers greater than + %% the number of actual lines. + ok + end. + +print_diagnostic({{LineNum,Column},Mod,Data}, Lines) -> + Line0 = lists:nth(LineNum, Lines), + <<Line1:(Column-1)/binary,_/binary>> = Line0, + Spaces = re:replace(Line1, <<"[^\t]">>, <<" ">>, [global]), + CaretLine = [Spaces,"^"], + [io_lib:format("~p:~p: ~ts\n", [LineNum,Column,Mod:format_error(Data)]), + Line0, "\n", + CaretLine, "\n\n"]; +print_diagnostic(_, _) -> + []. + fail() -> ct:fail(failed). diff --git a/lib/stdlib/test/erl_lint_SUITE_data/format.erl b/lib/stdlib/test/erl_lint_SUITE_data/format.erl index 540befd146..4748f315c6 100644 --- a/lib/stdlib/test/erl_lint_SUITE_data/format.erl +++ b/lib/stdlib/test/erl_lint_SUITE_data/format.erl @@ -30,6 +30,7 @@ f(F) -> io:format(a, "abc"), %1 io:format(a, [a | "abc"]), %2 io:format(4,5,6,7), %1 + io:format("~p", "abc" ++ "xyz"), %2 io:format("la cucaracha~n"), io:format(""), diff --git a/lib/stdlib/test/erl_pp_SUITE.erl b/lib/stdlib/test/erl_pp_SUITE.erl index 4edecdb8c3..0f3e6f0e3c 100644 --- a/lib/stdlib/test/erl_pp_SUITE.erl +++ b/lib/stdlib/test/erl_pp_SUITE.erl @@ -972,7 +972,7 @@ otp_8567(Config) when is_list(Config) -> "-record s, {a :: integer()}.\n" "-type t() :: {#r{},#s{}}.\n">>, ok = file:write_file(FileName, C), - {error,[{_,[{3,erl_parse,["syntax error before: ","')'"]}]}],_} = + {error,[{_,[{{3,8},erl_parse,["syntax error before: ","')'"]}]}],_} = compile:file(FileName, [return]), F = <<"-module(otp_8567).\n" @@ -1022,7 +1022,7 @@ otp_8664(Config) when is_list(Config) -> "-spec t() -> 9 and 4.\n" "t() -> 0.\n">>, ok = file:write_file(FileName, C2), - {error,[{_,[{3,erl_lint,{type_syntax,integer}}]}],_} = + {error,[{_,[{{3,16},erl_lint,{type_syntax,integer}}]}],_} = compile:file(FileName, [return]), ok. @@ -1164,7 +1164,7 @@ pr_1014(Config) -> "-compile export_all.\n" "-type m() :: #{..., a := integer()}.\n">>, ok = file:write_file(FileName, C), - {error,[{_,[{3,erl_parse,["syntax error before: ","'...'"]}]}],_} = + {error,[{_,[{{3,16},erl_parse,["syntax error before: ","'...'"]}]}],_} = compile:file(FileName, [return]), ok. diff --git a/lib/stdlib/test/escript_SUITE.erl b/lib/stdlib/test/escript_SUITE.erl index 136ebca027..71ad323ebe 100644 --- a/lib/stdlib/test/escript_SUITE.erl +++ b/lib/stdlib/test/escript_SUITE.erl @@ -89,16 +89,16 @@ basic(Config) when is_list(Config) -> run(Config, Dir, "factorial_compile_main 7", <<"factorial 7 = 5040\nExitCode:0">>), run(Config, Dir, "factorial_warning 20", - [data_dir,<<"factorial_warning:12: Warning: function bar/0 is unused\n" + [data_dir,<<"factorial_warning:12:1: Warning: function bar/0 is unused\n" "factorial 20 = 2432902008176640000\nExitCode:0">>]), run_with_opts(Config, Dir, "-s", "factorial_warning", - [data_dir,<<"factorial_warning:12: Warning: function bar/0 is unused\nExitCode:0">>]), + [data_dir,<<"factorial_warning:12:1: Warning: function bar/0 is unused\nExitCode:0">>]), run_with_opts(Config, Dir, "-s -i", "factorial_warning", - [data_dir,<<"factorial_warning:12: Warning: function bar/0 is unused\nExitCode:0">>]), + [data_dir,<<"factorial_warning:12:1: Warning: function bar/0 is unused\nExitCode:0">>]), run_with_opts(Config, Dir, "-c -s", "factorial_warning", - [data_dir,<<"factorial_warning:12: Warning: function bar/0 is unused\nExitCode:0">>]), + [data_dir,<<"factorial_warning:12:1: Warning: function bar/0 is unused\nExitCode:0">>]), run(Config, Dir, "filesize "++filename:join(proplists:get_value(data_dir, Config),"filesize"), - [data_dir,<<"filesize:11: Warning: function id/1 is unused\n324\nExitCode:0">>]), + [data_dir,<<"filesize:11:1: Warning: function id/1 is unused\n324\nExitCode:0">>]), run(Config, Dir, "test_script_name", [data_dir,<<"test_script_name\nExitCode:0">>]), run(Config, Dir, "tail_rec 1000", @@ -116,16 +116,16 @@ errors(Config) when is_list(Config) -> Data = proplists:get_value(data_dir, Config), Dir = filename:absname(Data), %Get rid of trailing slash. run(Config, Dir, "compile_error", - [data_dir,<<"compile_error:5: syntax error before: '*'\n">>, - data_dir,<<"compile_error:8: syntax error before: blarf\n">>, + [data_dir,<<"compile_error:5:12: syntax error before: '*'\n">>, + data_dir,<<"compile_error:8:9: syntax error before: blarf\n">>, <<"escript: There were compilation errors.\nExitCode:127">>]), run(Config, Dir, "lint_error", - [data_dir,<<"lint_error:6: function main/1 already defined\n">>, - data_dir,"lint_error:8: variable 'ExitCode' is unbound\n", + [data_dir,<<"lint_error:6:1: function main/1 already defined\n">>, + data_dir,"lint_error:8:10: variable 'ExitCode' is unbound\n", <<"escript: There were compilation errors.\nExitCode:127">>]), run_with_opts(Config, Dir, "-s", "lint_error", - [data_dir,<<"lint_error:6: function main/1 already defined\n">>, - data_dir,"lint_error:8: variable 'ExitCode' is unbound\n", + [data_dir,<<"lint_error:6:1: function main/1 already defined\n">>, + data_dir,"lint_error:8:10: variable 'ExitCode' is unbound\n", <<"escript: There were compilation errors.\nExitCode:127">>]), ok. diff --git a/lib/stdlib/test/ms_transform_SUITE.erl b/lib/stdlib/test/ms_transform_SUITE.erl index 866454ef6a..6ac38b73fa 100644 --- a/lib/stdlib/test/ms_transform_SUITE.erl +++ b/lib/stdlib/test/ms_transform_SUITE.erl @@ -44,6 +44,7 @@ -export([no_warnings/1]). -export([eep37/1]). -export([otp_14454/1]). +-export([otp_16824/1]). init_per_testcase(_Func, Config) -> Config. @@ -60,7 +61,7 @@ all() -> record_index, multipass, bitsyntax, record_defaults, andalso_orelse, float_1_function, action_function, warnings, no_warnings, top_match, old_guards, autoimported, - semicolon, eep37, otp_14454]. + semicolon, eep37, otp_14454, otp_16824]. groups() -> []. @@ -89,14 +90,16 @@ warnings(Config) when is_list(Config) -> " when is_integer(A) and (A+5 > B) -> " " A andalso B " " end)">>, - [{_,[{_,ms_transform,{?WARN_NUMBER_SHADOW,'A'}}]}] = + [{_,[{{1,22},ms_transform,{?WARN_NUMBER_SHADOW,'A'}}]}] = compile_ww(Prog), + [{_,[{1,ms_transform,{50,'A'}}]}] = + compile_ww(<<>>,Prog,[{error_location,line}]), Prog2 = <<"C = 5, ets:fun2ms(fun ({A,B} = C) when is_integer(A) and (A+5 > B) -> {A andalso B,C} end)">>, - [{_,[{3,ms_transform,{?WARN_NUMBER_SHADOW,'C'}}]}] = + [{_,[{{3,8},ms_transform,{?WARN_NUMBER_SHADOW,'C'}}]}] = compile_ww(Prog2), Rec3 = <<"-record(a,{a,b,c,d=foppa}).">>, Prog3 = <<"A = 3, @@ -106,8 +109,8 @@ warnings(Config) when is_list(Config) -> when is_integer(A) and (A+5 > B) -> {A andalso B,C} end)">>, - [{_,[{3,ms_transform,{?WARN_NUMBER_SHADOW,'C'}}, - {4,ms_transform,{?WARN_NUMBER_SHADOW,'A'}}]}] = + [{_,[{{3,20},ms_transform,{?WARN_NUMBER_SHADOW,'C'}}, + {{4,15},ms_transform,{?WARN_NUMBER_SHADOW,'A'}}]}] = compile_ww(Rec3,Prog3), Rec4 = <<"-record(a,{a,b,c,d=foppa}).">>, Prog4 = <<"A=3,C=5, " @@ -787,6 +790,20 @@ otp_14454(Config) when is_list(Config) -> ok. +otp_16824(Config) when is_list(Config) -> + setup(Config), + Prog = << + "-module(tmp).\n", + "-include_lib(\"stdlib/include/ms_transform.hrl\").\n", + "-export([tmp/1]).\n\n", + "tmp(_) -> ets:fun2ms(fun(<<>>) -> 1 end).\n">>, + FN = temp_name(), + ok = file:write_file(FN, Prog), + {ok, Forms} = parse_file(FN), + {error,[{_, [{{5,25},ms_transform,_}]}], []} = + compile:forms(Forms, [return]), + ok. + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Helpers %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -823,14 +840,18 @@ compile_and_run(Records,Expr) -> Expr/binary,".\n">>, FN=temp_name(), file:write_file(FN,Prog), - {ok,Forms} = epp:parse_file(FN,"",""), + {ok,Forms} = parse_file(FN), {ok,tmp,Bin} = compile:forms(Forms), code:load_binary(tmp,FN,Bin), tmp:tmp(). compile_ww(Expr) -> compile_ww(<<>>,Expr). + compile_ww(Records,Expr) -> + compile_ww(Records,Expr,[]). + +compile_ww(Records,Expr, Opts) -> Prog = << "-module(tmp).\n", "-include_lib(\"stdlib/include/ms_transform.hrl\").\n", @@ -841,10 +862,10 @@ compile_ww(Records,Expr) -> Expr/binary,".\n">>, FN=temp_name(), file:write_file(FN,Prog), - {ok,Forms} = epp:parse_file(FN,"",""), + {ok,Forms} = parse_file(FN), {ok,tmp,_Bin,Wlist} = compile:forms(Forms,[return_warnings, nowarn_unused_vars, - nowarn_unused_record]), + nowarn_unused_record | Opts]), Wlist. compile_no_ww(Expr) -> @@ -855,12 +876,15 @@ compile_no_ww(Expr) -> Expr/binary,".\n">>, FN=temp_name(), file:write_file(FN,Prog), - {ok,Forms} = epp:parse_file(FN,"",""), + {ok,Forms} = parse_file(FN), {ok,tmp,_Bin,Wlist} = compile:forms(Forms,[return_warnings, nowarn_unused_vars, nowarn_unused_record]), Wlist. +parse_file(FN) -> + epp:parse_file(FN, [{location, {1,1}}]). + do_eval(String) -> {done,{ok,T,_},[]} = erl_scan:tokens( [], diff --git a/lib/stdlib/test/qlc_SUITE.erl b/lib/stdlib/test/qlc_SUITE.erl index 8a43f15d2c..8cb4067b1d 100644 --- a/lib/stdlib/test/qlc_SUITE.erl +++ b/lib/stdlib/test/qlc_SUITE.erl @@ -170,10 +170,10 @@ badarg() -> q(bar, cache_all, extra). ">>, [], -{errors,[{5,?QLC,not_a_query_list_comprehension}, - {6,?QLC,not_a_query_list_comprehension}, - {8,?QLC,not_a_query_list_comprehension}, - {9,?QLC,not_a_query_list_comprehension}], +{errors,[{{5,5},?QLC,not_a_query_list_comprehension}, + {{6,5},?QLC,not_a_query_list_comprehension}, + {{8,5},?QLC,not_a_query_list_comprehension}, + {{9,5},?QLC,not_a_query_list_comprehension}], []}}], [] = compile(Config, Ts), ok. @@ -366,7 +366,7 @@ nomatch(Config) when is_list(Config) -> end]). ">>, [], - {warnings,[{5,v3_kernel,{nomatch_shadow,4}}]}}, + {warnings,[{{5,24},v3_kernel,{nomatch_shadow,4}}]}}, {nomatch1, <<"generator1() -> @@ -374,7 +374,7 @@ nomatch(Config) when is_list(Config) -> ">>, [], %% {warnings,[{{2,27},qlc,nomatch_pattern}]}}, - {warnings,[{2,v3_core,nomatch}]}}, + {warnings,[{{2,21},v3_core,nomatch}]}}, {nomatch2, <<"nomatch() -> @@ -386,7 +386,7 @@ nomatch(Config) when is_list(Config) -> ">>, [], %% {warnings,[{{3,33},qlc,nomatch_pattern}]}}, - {warnings,[{3,v3_core,nomatch}]}}, + {warnings,[{{3,27},v3_core,nomatch}]}}, {nomatch3, <<"nomatch() -> @@ -399,7 +399,7 @@ nomatch(Config) when is_list(Config) -> ">>, [], %% {warnings,[{{3,52},qlc,nomatch_pattern}]}}, - {warnings,[{3,v3_core,nomatch}]}}, + {warnings,[{{3,37},v3_core,nomatch}]}}, {nomatch4, <<"nomatch() -> @@ -423,7 +423,7 @@ nomatch(Config) when is_list(Config) -> end, [{\"ab\"}]). ">>, [], - {warnings,[{3,v3_core,nomatch}]}} + {warnings,[{{3,38},v3_core,nomatch}]}} ], [] = compile(Config, Ts), @@ -5640,7 +5640,7 @@ join_complex(Config) when is_list(Config) -> ]), qlc:e(Q).">>, [], - {warnings,[{3,qlc,too_complex_join}]}}, + {warnings,[{{3,23},qlc,too_complex_join}]}}, {two, <<"two() -> @@ -5653,6 +5653,19 @@ join_complex(Config) when is_list(Config) -> Z =:= W],{join,merge}), qlc:e(Q).">>, [], + {warnings,[{{2,23},qlc,too_many_joins}]}}, + + {two_again, + <<"two() -> + Q = qlc:q([{X,Y,Z,W} || + {X} <- [], + {Y} <- [], + {Z} <- [], + {W} <- [], + X =:= Y, + Z =:= W],{join,merge}), + qlc:e(Q).">>, + [{error_location, line}], {warnings,[{2,qlc,too_many_joins}]}} ], @@ -5885,7 +5898,7 @@ otp_6562(Config) when is_list(Config) -> qlc:info(Q). ">>, [], - {errors,[{2,qlc,binary_generator}], + {errors,[{{2,40},qlc,binary_generator}], []}} ], [] = compile(Config, Bits), @@ -6158,8 +6171,7 @@ otp_7238(Config) when is_list(Config) -> {qlc:q([X || X={X} <- []]), [t || \"a\"=\"b\" <- []]}.">>, [], %% {warnings,[{{2,30},qlc,nomatch_pattern}, - %% {{2,44},v3_core,nomatch}]}}, - {warnings,[{2,v3_core,nomatch}]}}, + {warnings,[{{2,44},v3_core,nomatch}]}}, %% Not found by qlc... {nomatch_2, @@ -6173,7 +6185,7 @@ otp_7238(Config) when is_list(Config) -> qlc:q([t || [$a, $b] = \"ba\" <- []]).">>, [], %% {warnings,[{{2,37},qlc,nomatch_pattern}]}}, - {warnings,[{2,v3_core,nomatch}]}}, + {warnings,[{{2,22},v3_core,nomatch}]}}, %% Not found by qlc... {nomatch_4, @@ -6231,7 +6243,7 @@ otp_7238(Config) when is_list(Config) -> qlc:q([X || X <- [], x =:= []]).">>, [], %% {warnings,[{{2,39},qlc,nomatch_filter}]}}, - {warnings,[{2,sys_core_fold,nomatch_guard}]}}, + {warnings,[{{2,22},sys_core_fold,nomatch_guard}]}}, {nomatch_12, <<"nomatch_12() -> @@ -6274,7 +6286,7 @@ otp_7238(Config) when is_list(Config) -> <<"nomatch_template1() -> qlc:q([{X} = {} || X <- []]).">>, [], - {warnings,[{2,sys_core_fold,no_clause_match}]}} + {warnings,[{{2,27},sys_core_fold,no_clause_match}]}} ], [] = compile(Config, T1), @@ -7061,7 +7073,9 @@ otp_12946(Config) when is_list(Config) -> init() -> ok. y">>, - {errors,[{4,erl_parse,_}],[]} = compile_file(Config, Text, []), + {errors,[{{4,12},erl_parse,_}],[]} = compile_file(Config, Text, []), + {errors,[{4,erl_parse,_}],[]} = + compile_file(Config, Text, [{error_location, line}]), ok. %% Examples from qlc(3). @@ -7735,8 +7749,8 @@ table(List, Indices, KeyPos, ParentFun) -> end, FormatFun = fun(all) -> - L = erl_anno:new(17), - {call,L,{remote,L,{atom,L,?MODULE},{atom,L,the_list}}, + A = erl_anno:new(17), + {call,A,{remote,A,{atom,A,?MODULE},{atom,A,the_list}}, [erl_parse:abstract(List, 17)]}; ({lookup, Column, Values}) -> {?MODULE, list_keys, [Values, Column, List]} @@ -7991,9 +8005,7 @@ comp_compare(T, T) -> true; comp_compare(T1, T2_0) -> T2 = wskip(T2_0), - T1 =:= T2 - %% This clause should eventually be removed. - orelse ln(T1) =:= T2 orelse T1 =:= ln(T2). + T1 =:= T2. wskip([]) -> []; @@ -8008,35 +8020,6 @@ wskip([M|L]) -> wskip(T) -> T. -%% Replaces locations like {Line,Column} with Line. -ln({warnings,L}) -> - {warnings,ln0(L)}; -ln({errors,EL,WL}) -> - {errors,ln0(EL),ln0(WL)}; -ln(L) -> - ln0(L). - -ln0(L) -> - lists:sort(ln1(L)). - -ln1([]) -> - []; -ln1([{File,Ms}|MsL]) when is_list(File) -> - [{File,ln0(Ms)}|ln1(MsL)]; -ln1([{{L,_C},Mod,Mess0}|Ms]) -> - Mess = case Mess0 of - {exported_var,V,{Where,{L1,_C1}}} -> - {exported_var,V,{Where,L1}}; - {unsafe_var,V,{Where,{L1,_C1}}} -> - {unsafe_var,V,{Where,L1}}; - %% There are more... - M -> - M - end, - [{L,Mod,Mess}|ln1(Ms)]; -ln1([M|Ms]) -> - [M|ln1(Ms)]. - %% -> {FileName, Module}; {string(), atom()} compile_file_mod(Config) -> NameL = lists:concat([?TESTMODULE, "_", ?testcase]), diff --git a/lib/stdlib/test/shell_SUITE.erl b/lib/stdlib/test/shell_SUITE.erl index d6110270b4..8631173770 100644 --- a/lib/stdlib/test/shell_SUITE.erl +++ b/lib/stdlib/test/shell_SUITE.erl @@ -307,13 +307,13 @@ restricted_local(Config) when is_list(Config) -> forget(Config) when is_list(Config) -> %% f/0 [ok] = scan(<<"begin f() end.">>), - "1: variable 'A' is unbound" = + "1:13: variable 'A' is unbound" = comm_err(<<"A = 3, f(), A.">>), [ok] = scan(<<"A = 3, A = f(), A.">>), %% f/1 [ok] = scan(<<"begin f(A) end.">>), - "1: variable 'A' is unbound" = + "1:14: variable 'A' is unbound" = comm_err(<<"A = 3, f(A), A.">>), [ok] = scan(<<"A = 3, A = f(A), A.">>), "exception error: no function clause matching call to f/1" = @@ -335,7 +335,7 @@ records(Config) when is_list(Config) -> comm_err(<<"rd({foo},{bar}).">>), "bad record declaration" = exit_string(<<"A = bar, rd(foo,A).">>), [foo] = scan(<<"begin rd(foo,{bar}) end.">>), - "1: record foo undefined" = + "1:22: record foo undefined" = comm_err(<<"begin rd(foo,{bar}), #foo{} end.">>), ['f o o'] = scan(<<"rd('f o o', {bar}).">>), [foo] = scan(<<"rd(foo,{bar}), rd(foo,{foo = #foo{}}).">>), @@ -343,7 +343,7 @@ records(Config) when is_list(Config) -> %% rf/0,1 [_, {attribute,_,record,{foo,_}},ok] = scan(<<"rf('_'). rd(foo,{bar}),rl().">>), - "1: record foo undefined" = + "1:33: record foo undefined" = comm_err(<<"rd(foo,{bar}), #foo{}, rf(foo), #foo{}.">>), [ok,{foo,undefined}] = scan(<<"rd(foo,{bar}), A = #foo{}, rf(foo). A.">>), @@ -669,7 +669,7 @@ otp_5195(Config) when is_list(Config) -> %% "list expression\".\n" = %% t(<<"qlc:q([X || X <- [{a}], Y <- [X]]).">>), %% Same as last one (if the shell does not translate error tuples): - [{error,qlc,{1,qlc,{used_generator_variable,'X'}}}] = + [{error,qlc,{{1,31},qlc,{used_generator_variable,'X'}}}] = scan(<<"qlc:q([X || X <- [{a}], Y <- [X]]).">>), {error,qlc,{1,qlc,{used_generator_variable,'X'}}} = evaluate(<<"qlc:q([X || X <- [{a}], Y <- [X]]).">>, []), @@ -2490,7 +2490,7 @@ otp_6554(Config) when is_list(Config) -> application:unset_env(stdlib, shell_history_length), [true] = scan(<<"begin <<10:(1024*1024*10)>>," "<<10:(1024*1024*10)>>, garbage_collect() end.">>), - "1: syntax error before: '.'" = comm_err("1-."), + "1:3: syntax error before: '.'" = comm_err("1-."), %% comm_err(<<"exit().">>), % would hang "exception error: no function clause matching call to history/1" = comm_err(<<"history(foo).">>), @@ -2923,7 +2923,7 @@ otp_14296(Config) when is_list(Config) -> F = fun() -> a end, LocalFun = term_to_string(F), S = LocalFun ++ ".", - "1: syntax error before: Fun" = comm_err(S) + "1:2: syntax error before: Fun" = comm_err(S) end(), fun() -> @@ -2937,7 +2937,7 @@ otp_14296(Config) when is_list(Config) -> fun() -> UnknownPid = "<100000.0.0>", S = UnknownPid ++ ".", - "1: syntax error before: '<'" = comm_err(S) + "1:1: syntax error before: '<'" = comm_err(S) end(), fun() -> @@ -2958,13 +2958,13 @@ otp_14296(Config) when is_list(Config) -> fun() -> UnknownPort = "#Port<100000.0>", S = UnknownPort ++ ".", - "1: syntax error before: Port" = comm_err(S) + "1:2: syntax error before: Port" = comm_err(S) end(), fun() -> UnknownRef = "#Ref<100000.0.0.0>", S = UnknownRef ++ ".", - "1: syntax error before: Ref" = comm_err(S) + "1:2: syntax error before: Ref" = comm_err(S) end(), fun() -> diff --git a/lib/syntax_tools/src/epp_dodger.erl b/lib/syntax_tools/src/epp_dodger.erl index da22a91de0..455fddbdb9 100644 --- a/lib/syntax_tools/src/epp_dodger.erl +++ b/lib/syntax_tools/src/epp_dodger.erl @@ -61,7 +61,7 @@ %% * We do our best to make macros without arguments pass the parsing %% stage transparently. Atoms are accepted in most contexts, but %% variables are not, so we use only atoms to encode these macros. -%% Sadly, the parsing sometimes discards even the line number info from +%% Sadly, the parsing sometimes discards even the location info from %% atom tokens, so we can only use the actual characters for this. %% %% * We recognize `?m(...' at the start of a form and prevent this from @@ -86,14 +86,12 @@ -define(pp_form, '?preprocessor declaration?'). -%% @type errorinfo() = {ErrorLine::integer(), -%% Module::atom(), -%% Descriptor::term()}. +%% @type errorinfo() = //stdlib/erl_scan:error_info(). %% %% This is a so-called Erlang I/O ErrorInfo structure; see the {@link %% //stdlib/io} module for details. --type errorinfo() :: {integer(), atom(), term()}. +-type errorinfo() :: erl_scan:error_info(). -type option() :: atom() | {atom(), term()}. @@ -219,7 +217,7 @@ do_parse_file(DefEncoding, File, Parser, Options) -> find_invalid_unicode([H|T]) -> case H of - {error, {_Line, file_io_server, invalid_unicode}} -> + {error, {_Location, file_io_server, invalid_unicode}} -> invalid_unicode; _Other -> find_invalid_unicode(T) @@ -235,37 +233,37 @@ find_invalid_unicode([]) -> none. parse(Dev) -> parse(Dev, 1). -%% @spec parse(IODevice, StartLine) -> {ok, Forms} | {error, errorinfo()} +%% @spec parse(IODevice, StartLocation) -> {ok, Forms} | {error, errorinfo()} %% IODevice = pid() -%% StartLine = integer() +%% StartLocation = //stdlib/erl_anno:location() %% Forms = [erl_syntax:syntaxTree()] %% -%% @equiv parse(IODevice, StartLine, []) +%% @equiv parse(IODevice, StartLocation, []) %% @see parse/1 --spec parse(file:io_device(), integer()) -> {'ok', erl_syntax:forms()}. +-spec parse(file:io_device(), erl_anno:location()) -> {'ok', erl_syntax:forms()}. parse(Dev, L) -> parse(Dev, L, []). -%% @spec parse(IODevice, StartLine, Options) -> +%% @spec parse(IODevice, StartLocation, Options) -> %% {ok, Forms} | {error, errorinfo()} %% IODevice = pid() -%% StartLine = integer() +%% StartLocation = //stdlib/erl_anno:location() %% Options = [term()] %% Forms = [erl_syntax:syntaxTree()] %% %% @doc Reads and parses program text from an I/O stream. Characters are %% read from `IODevice' until end-of-file; apart from this, the -%% behaviour is the same as for {@link parse_file/2}. `StartLine' is the -%% initial line number, which should be a positive integer. +%% behaviour is the same as for {@link parse_file/2}. `StartLocation' is the +%% initial location. %% %% @see parse/2 %% @see parse_file/2 %% @see parse_form/2 %% @see quick_parse/3 --spec parse(file:io_device(), integer(), [option()]) -> +-spec parse(file:io_device(), erl_anno:location(), [option()]) -> {'ok', erl_syntax:forms()}. parse(Dev, L0, Options) -> @@ -280,25 +278,25 @@ parse(Dev, L0, Options) -> quick_parse(Dev) -> quick_parse(Dev, 1). -%% @spec quick_parse(IODevice, StartLine) -> +%% @spec quick_parse(IODevice, StartLocation) -> %% {ok, Forms} | {error, errorinfo()} %% IODevice = pid() -%% StartLine = integer() +%% StartLocation = //stdlib/erl_anno:location() %% Forms = [erl_syntax:syntaxTree()] %% -%% @equiv quick_parse(IODevice, StartLine, []) +%% @equiv quick_parse(IODevice, StartLocation, []) %% @see quick_parse/1 --spec quick_parse(file:io_device(), integer()) -> +-spec quick_parse(file:io_device(), erl_anno:location()) -> {'ok', erl_syntax:forms()}. quick_parse(Dev, L) -> quick_parse(Dev, L, []). -%% @spec (IODevice, StartLine, Options) -> +%% @spec (IODevice, StartLocation, Options) -> %% {ok, Forms} | {error, errorinfo()} %% IODevice = pid() -%% StartLine = integer() +%% StartLocation = //stdlib/erl_anno:location() %% Options = [term()] %% Forms = [erl_syntax:syntaxTree()] %% @@ -310,7 +308,7 @@ quick_parse(Dev, L) -> %% @see quick_parse_form/2 %% @see parse/3 --spec quick_parse(file:io_device(), integer(), [option()]) -> +-spec quick_parse(file:io_device(), erl_anno:location(), [option()]) -> {'ok', erl_syntax:forms()}. quick_parse(Dev, L0, Options) -> @@ -333,85 +331,85 @@ parse(Dev, L0, Fs, Parser, Options) -> %% ===================================================================== -%% @spec parse_form(IODevice, StartLine) -> {ok, Form, LineNo} -%% | {eof, LineNo} -%% | {error, errorinfo(), LineNo} +%% @spec parse_form(IODevice, StartLocation) -> {ok, Form, Location} +%% | {eof, Location} +%% | {error, errorinfo(), Location} %% IODevice = pid() -%% StartLine = integer() +%% StartLocation = //stdlib/erl_anno:location() %% Form = erl_syntax:syntaxTree() -%% LineNo = integer() +%% Location = //stdlib/erl_anno:location() %% -%% @equiv parse_form(IODevice, StartLine, []) +%% @equiv parse_form(IODevice, StartLocation, []) %% %% @see quick_parse_form/2 --spec parse_form(file:io_device(), integer()) -> - {'ok', erl_syntax:forms(), integer()} - | {'eof', integer()} | {'error', errorinfo(), integer()}. +-spec parse_form(file:io_device(), erl_anno:location()) -> + {'ok', erl_syntax:forms(), erl_anno:location()} + | {'eof', erl_anno:location()} | {'error', errorinfo(), erl_anno:location()}. parse_form(Dev, L0) -> parse_form(Dev, L0, []). -%% @spec parse_form(IODevice, StartLine, Options) -> -%% {ok, Form, LineNo} -%% | {eof, LineNo} -%% | {error, errorinfo(), LineNo} +%% @spec parse_form(IODevice, StartLocation, Options) -> +%% {ok, Form, Location} +%% | {eof, Location} +%% | {error, errorinfo(), Location} %% %% IODevice = pid() -%% StartLine = integer() +%% StartLocation = //stdlib/erl_anno:location() %% Options = [term()] %% Form = erl_syntax:syntaxTree() -%% LineNo = integer() +%% Location = //stdlib/erl_anno:location() %% %% @doc Reads and parses a single program form from an I/O stream. %% Characters are read from `IODevice' until an end-of-form %% marker is found (a period character followed by whitespace), or until %% end-of-file; apart from this, the behaviour is similar to that of %% `parse/3', except that the return values also contain the -%% final line number given that `StartLine' is the initial -%% line number, and that `{eof, LineNo}' may be returned. +%% final location given that `StartLocation' is the initial +%% location, and that `{eof, Location}' may be returned. %% %% @see parse/3 %% @see parse_form/2 %% @see quick_parse_form/3 --spec parse_form(file:io_device(), integer(), [option()]) -> - {'ok', erl_syntax:forms(), integer()} - | {'eof', integer()} | {'error', errorinfo(), integer()}. +-spec parse_form(file:io_device(), erl_anno:location(), [option()]) -> + {'ok', erl_syntax:forms(), erl_anno:location()} + | {'eof', erl_anno:location()} | {'error', errorinfo(), erl_anno:location()}. parse_form(Dev, L0, Options) -> parse_form(Dev, L0, fun normal_parser/2, Options). -%% @spec quick_parse_form(IODevice, StartLine) -> -%% {ok, Form, LineNo} -%% | {eof, LineNo} -%% | {error, errorinfo(), LineNo} +%% @spec quick_parse_form(IODevice, StartLocation) -> +%% {ok, Form, Location} +%% | {eof, Location} +%% | {error, errorinfo(), Location} %% IODevice = pid() -%% StartLine = integer() +%% StartLocation = //stdlib/erl_anno:location() %% Form = erl_syntax:syntaxTree() | none -%% LineNo = integer() +%% Location = //stdlib/erl_anno:location() %% -%% @equiv quick_parse_form(IODevice, StartLine, []) +%% @equiv quick_parse_form(IODevice, StartLocation, []) %% %% @see parse_form/2 --spec quick_parse_form(file:io_device(), integer()) -> - {'ok', erl_syntax:forms(), integer()} - | {'eof', integer()} | {'error', errorinfo(), integer()}. +-spec quick_parse_form(file:io_device(), erl_anno:location()) -> + {'ok', erl_syntax:forms(), erl_anno:location()} + | {'eof', erl_anno:location()} | {'error', errorinfo(), erl_anno:location()}. quick_parse_form(Dev, L0) -> quick_parse_form(Dev, L0, []). -%% @spec quick_parse_form(IODevice, StartLine, Options) -> -%% {ok, Form, LineNo} -%% | {eof, LineNo} -%% | {error, errorinfo(), LineNo} +%% @spec quick_parse_form(IODevice, StartLocation, Options) -> +%% {ok, Form, Location} +%% | {eof, Location} +%% | {error, errorinfo(), Location} %% %% IODevice = pid() -%% StartLine = integer() +%% StartLocation = //stdlib/erl_anno:location() %% Options = [term()] %% Form = erl_syntax:syntaxTree() -%% LineNo = integer() +%% Location = //stdlib/erl_anno:location() %% %% @doc Similar to {@link parse_form/3}, but does a more quick-and-dirty %% processing of the code. See {@link quick_parse_file/2} for details. @@ -420,9 +418,9 @@ quick_parse_form(Dev, L0) -> %% @see quick_parse_form/2 %% @see parse_form/3 --spec quick_parse_form(file:io_device(), integer(), [option()]) -> - {'ok', erl_syntax:forms(), integer()} - | {'eof', integer()} | {'error', errorinfo(), integer()}. +-spec quick_parse_form(file:io_device(), erl_anno:location(), [option()]) -> + {'ok', erl_syntax:forms(), erl_anno:location()} + | {'eof', erl_anno:location()} | {'error', errorinfo(), erl_anno:location()}. quick_parse_form(Dev, L0, Options) -> parse_form(Dev, L0, fun quick_parser/2, Options). @@ -443,7 +441,7 @@ parse_form(Dev, L0, Parser, Options) -> {parse_error, _IoErr} when NoFail -> {ok, erl_syntax:set_pos( erl_syntax:text(tokens_to_string(Ts)), - start_pos(Ts, L1)), + erl_anno:new(start_pos(Ts, L1))), L1}; {parse_error, IoErr} -> {error, IoErr, L1}; @@ -459,7 +457,7 @@ io_error(L, Desc) -> {L, ?MODULE, Desc}. start_pos([T | _Ts], _L) -> - erl_anno:line(element(2, T)); + erl_anno:location(element(2, T)); start_pos([], L) -> L. @@ -490,32 +488,32 @@ parse_tokens(Ts, Fix) -> quick_parser(Ts, _Opt) -> filter_form(parse_tokens(quickscan_form(Ts))). -quickscan_form([{'-', _L}, {atom, La, define} | _Ts]) -> - kill_form(La); -quickscan_form([{'-', _L}, {atom, La, undef} | _Ts]) -> - kill_form(La); -quickscan_form([{'-', _L}, {atom, La, include} | _Ts]) -> - kill_form(La); -quickscan_form([{'-', _L}, {atom, La, include_lib} | _Ts]) -> - kill_form(La); -quickscan_form([{'-', _L}, {atom, La, ifdef} | _Ts]) -> - kill_form(La); -quickscan_form([{'-', _L}, {atom, La, ifndef} | _Ts]) -> - kill_form(La); -quickscan_form([{'-', _L}, {'if', La} | _Ts]) -> - kill_form(La); -quickscan_form([{'-', _L}, {atom, La, elif} | _Ts]) -> - kill_form(La); -quickscan_form([{'-', _L}, {atom, La, else} | _Ts]) -> - kill_form(La); -quickscan_form([{'-', _L}, {atom, La, endif} | _Ts]) -> - kill_form(La); -quickscan_form([{'-', L}, {'?', _}, {Type, _, _}=N | [{'(', _} | _]=Ts]) +quickscan_form([{'-', _Anno}, {atom, AnnoA, define} | _Ts]) -> + kill_form(AnnoA); +quickscan_form([{'-', _Anno}, {atom, AnnoA, undef} | _Ts]) -> + kill_form(AnnoA); +quickscan_form([{'-', _Anno}, {atom, AnnoA, include} | _Ts]) -> + kill_form(AnnoA); +quickscan_form([{'-', _Anno}, {atom, AnnoA, include_lib} | _Ts]) -> + kill_form(AnnoA); +quickscan_form([{'-', _Anno}, {atom, AnnoA, ifdef} | _Ts]) -> + kill_form(AnnoA); +quickscan_form([{'-', _Anno}, {atom, AnnoA, ifndef} | _Ts]) -> + kill_form(AnnoA); +quickscan_form([{'-', _Anno}, {'if', AnnoA} | _Ts]) -> + kill_form(AnnoA); +quickscan_form([{'-', _Anno}, {atom, AnnoA, elif} | _Ts]) -> + kill_form(AnnoA); +quickscan_form([{'-', _Anno}, {atom, AnnoA, else} | _Ts]) -> + kill_form(AnnoA); +quickscan_form([{'-', _Anno}, {atom, AnnoA, endif} | _Ts]) -> + kill_form(AnnoA); +quickscan_form([{'-', Anno}, {'?', _}, {Type, _, _}=N | [{'(', _} | _]=Ts]) when Type =:= atom; Type =:= var -> %% minus, macro and open parenthesis at start of form - assume that %% the macro takes no arguments; e.g. `-?foo(...).' - quickscan_macros_1(N, Ts, [{'-', L}]); -quickscan_form([{'?', _L}, {Type, _, _}=N | [{'(', _} | _]=Ts]) + quickscan_macros_1(N, Ts, [{'-', Anno}]); +quickscan_form([{'?', _Anno}, {Type, _, _}=N | [{'(', _} | _]=Ts]) when Type =:= atom; Type =:= var -> %% macro and open parenthesis at start of form - assume that the %% macro takes no arguments (see scan_macros for details) @@ -523,19 +521,19 @@ quickscan_form([{'?', _L}, {Type, _, _}=N | [{'(', _} | _]=Ts]) quickscan_form(Ts) -> quickscan_macros(Ts). -kill_form(L) -> - [{atom, L, ?pp_form}, {'(', L}, {')', L}, {'->', L}, {atom, L, kill}, - {dot, L}]. +kill_form(A) -> + [{atom, A, ?pp_form}, {'(', A}, {')', A}, {'->', A}, {atom, A, kill}, + {dot, A}]. quickscan_macros(Ts) -> quickscan_macros(Ts, []). -quickscan_macros([{'?',_}, {Type, _, A} | Ts], [{string, L, S} | As]) +quickscan_macros([{'?',_}, {Type, _, A} | Ts], [{string, AnnoS, S} | As]) when Type =:= atom; Type =:= var -> %% macro after a string literal: change to a single string {_, Ts1} = skip_macro_args(Ts), S1 = S ++ quick_macro_string(A), - quickscan_macros(Ts1, [{string, L, S1} | As]); + quickscan_macros(Ts1, [{string, AnnoS, S1} | As]); quickscan_macros([{'?',_}, {Type, _, _}=N | [{'(',_}|_]=Ts], [{':',_}|_]=As) when Type =:= atom; Type =:= var -> @@ -558,13 +556,13 @@ quickscan_macros([], As) -> lists:reverse(As). %% (after a macro has been found and the arglist skipped, if any) -quickscan_macros_1({_Type, _, A}, [{string, L, S} | Ts], As) -> +quickscan_macros_1({_Type, _, A}, [{string, AnnoS, S} | Ts], As) -> %% string literal following macro: change to single string S1 = quick_macro_string(A) ++ S, - quickscan_macros(Ts, [{string, L, S1} | As]); -quickscan_macros_1({_Type, L, A}, Ts, As) -> + quickscan_macros(Ts, [{string, AnnoS, S1} | As]); +quickscan_macros_1({_Type, AnnoA, A}, Ts, As) -> %% normal case - just replace the macro with an atom - quickscan_macros(Ts, [{atom, L, quick_macro_atom(A)} | As]). + quickscan_macros(Ts, [{atom, AnnoA, quick_macro_atom(A)} | As]). quick_macro_atom(A) -> list_to_atom("?" ++ atom_to_list(A)). @@ -625,56 +623,56 @@ normal_parser(Ts0, Opt) -> Node end. -scan_form([{'-', _L}, {atom, La, define} | Ts], Opt) -> - [{atom, La, ?pp_form}, {'(', La}, {')', La}, {'->', La}, - {atom, La, define} | scan_macros(Ts, Opt)]; -scan_form([{'-', _L}, {atom, La, undef} | Ts], Opt) -> - [{atom, La, ?pp_form}, {'(', La}, {')', La}, {'->', La}, - {atom, La, undef} | scan_macros(Ts, Opt)]; -scan_form([{'-', _L}, {atom, La, include} | Ts], Opt) -> - [{atom, La, ?pp_form}, {'(', La}, {')', La}, {'->', La}, - {atom, La, include} | scan_macros(Ts, Opt)]; -scan_form([{'-', _L}, {atom, La, include_lib} | Ts], Opt) -> - [{atom, La, ?pp_form}, {'(', La}, {')', La}, {'->', La}, - {atom, La, include_lib} | scan_macros(Ts, Opt)]; -scan_form([{'-', _L}, {atom, La, ifdef} | Ts], Opt) -> - [{atom, La, ?pp_form}, {'(', La}, {')', La}, {'->', La}, - {atom, La, ifdef} | scan_macros(Ts, Opt)]; -scan_form([{'-', _L}, {atom, La, ifndef} | Ts], Opt) -> - [{atom, La, ?pp_form}, {'(', La}, {')', La}, {'->', La}, - {atom, La, ifndef} | scan_macros(Ts, Opt)]; -scan_form([{'-', _L}, {'if', La} | Ts], Opt) -> - [{atom, La, ?pp_form}, {'(', La}, {')', La}, {'->', La}, - {atom, La, 'if'} | scan_macros(Ts, Opt)]; -scan_form([{'-', _L}, {atom, La, elif} | Ts], Opt) -> - [{atom, La, ?pp_form}, {'(', La}, {')', La}, {'->', La}, - {atom, La, 'elif'} | scan_macros(Ts, Opt)]; -scan_form([{'-', _L}, {atom, La, else} | Ts], Opt) -> - [{atom, La, ?pp_form}, {'(', La}, {')', La}, {'->', La}, - {atom, La, else} | scan_macros(Ts, Opt)]; -scan_form([{'-', _L}, {atom, La, endif} | Ts], Opt) -> - [{atom, La, ?pp_form}, {'(', La}, {')', La}, {'->', La}, - {atom, La, endif} | scan_macros(Ts, Opt)]; -scan_form([{'-', _L}, {atom, La, error} | Ts], _Opt) -> +scan_form([{'-', _Anno}, {atom, AnnoA, define} | Ts], Opt) -> + [{atom, AnnoA, ?pp_form}, {'(', AnnoA}, {')', AnnoA}, {'->', AnnoA}, + {atom, AnnoA, define} | scan_macros(Ts, Opt)]; +scan_form([{'-', _Anno}, {atom, AnnoA, undef} | Ts], Opt) -> + [{atom, AnnoA, ?pp_form}, {'(', AnnoA}, {')', AnnoA}, {'->', AnnoA}, + {atom, AnnoA, undef} | scan_macros(Ts, Opt)]; +scan_form([{'-', _Anno}, {atom, AnnoA, include} | Ts], Opt) -> + [{atom, AnnoA, ?pp_form}, {'(', AnnoA}, {')', AnnoA}, {'->', AnnoA}, + {atom, AnnoA, include} | scan_macros(Ts, Opt)]; +scan_form([{'-', _Anno}, {atom, AnnoA, include_lib} | Ts], Opt) -> + [{atom, AnnoA, ?pp_form}, {'(', AnnoA}, {')', AnnoA}, {'->', AnnoA}, + {atom, AnnoA, include_lib} | scan_macros(Ts, Opt)]; +scan_form([{'-', _Anno}, {atom, AnnoA, ifdef} | Ts], Opt) -> + [{atom, AnnoA, ?pp_form}, {'(', AnnoA}, {')', AnnoA}, {'->', AnnoA}, + {atom, AnnoA, ifdef} | scan_macros(Ts, Opt)]; +scan_form([{'-', _Anno}, {atom, AnnoA, ifndef} | Ts], Opt) -> + [{atom, AnnoA, ?pp_form}, {'(', AnnoA}, {')', AnnoA}, {'->', AnnoA}, + {atom, AnnoA, ifndef} | scan_macros(Ts, Opt)]; +scan_form([{'-', _Anno}, {'if', AnnoA} | Ts], Opt) -> + [{atom, AnnoA, ?pp_form}, {'(', AnnoA}, {')', AnnoA}, {'->', AnnoA}, + {atom, AnnoA, 'if'} | scan_macros(Ts, Opt)]; +scan_form([{'-', _Anno}, {atom, AnnoA, elif} | Ts], Opt) -> + [{atom, AnnoA, ?pp_form}, {'(', AnnoA}, {')', AnnoA}, {'->', AnnoA}, + {atom, AnnoA, 'elif'} | scan_macros(Ts, Opt)]; +scan_form([{'-', _Anno}, {atom, AnnoA, else} | Ts], Opt) -> + [{atom, AnnoA, ?pp_form}, {'(', AnnoA}, {')', AnnoA}, {'->', AnnoA}, + {atom, AnnoA, else} | scan_macros(Ts, Opt)]; +scan_form([{'-', _Anno}, {atom, AnnoA, endif} | Ts], Opt) -> + [{atom, AnnoA, ?pp_form}, {'(', AnnoA}, {')', AnnoA}, {'->', AnnoA}, + {atom, AnnoA, endif} | scan_macros(Ts, Opt)]; +scan_form([{'-', _Anno}, {atom, AnnoA, error} | Ts], _Opt) -> Desc = build_info_string("-error", Ts), - ErrorInfo = {La, ?MODULE, {error, Desc}}, + ErrorInfo = {erl_anno:location(AnnoA), ?MODULE, {error, Desc}}, erl_syntax:error_marker(ErrorInfo); -scan_form([{'-', _L}, {atom, La, warning} | Ts], _Opt) -> +scan_form([{'-', _Anno}, {atom, AnnoA, warning} | Ts], _Opt) -> Desc = build_info_string("-warning", Ts), - ErrorInfo = {La, ?MODULE, {warning, Desc}}, + ErrorInfo = {erl_anno:location(AnnoA), ?MODULE, {warning, Desc}}, erl_syntax:error_marker(ErrorInfo); -scan_form([{'-', L}, {'?', L1}, {Type, _, _}=N | [{'(', _} | _]=Ts], Opt) +scan_form([{'-', A}, {'?', A1}, {Type, _, _}=N | [{'(', _} | _]=Ts], Opt) when Type =:= atom; Type =:= var -> %% minus, macro and open parenthesis at start of form - assume that %% the macro takes no arguments; e.g. `-?foo(...).' - macro(L1, N, Ts, [{'-', L}], Opt); -scan_form([{'?', L}, {Type, _, _}=N | [{'(', _} | _]=Ts], Opt) + macro(A1, N, Ts, [{'-', A}], Opt); +scan_form([{'?', A}, {Type, _, _}=N | [{'(', _} | _]=Ts], Opt) when Type =:= atom; Type =:= var -> %% macro and open parenthesis at start of form - assume that the %% macro takes no arguments; probably a function declaration on the %% form `?m(...) -> ...', which will not parse if it is rewritten as %% `(?m(...)) -> ...', so it must be handled as `(?m)(...) -> ...' - macro(L, N, Ts, [], Opt); + macro(A, N, Ts, [], Opt); scan_form(Ts, Opt) -> scan_macros(Ts, Opt). @@ -686,12 +684,12 @@ build_info_string(Prefix, Ts0) -> scan_macros(Ts, Opt) -> scan_macros(Ts, [], Opt). -scan_macros([{'?', _}=M, {Type, _, _}=N | Ts], [{string, L, _}=S | As], +scan_macros([{'?', _}=M, {Type, _, _}=N | Ts], [{string, AnnoS, _}=S | As], #opt{clever = true}=Opt) when Type =:= atom; Type =:= var -> %% macro after a string literal: be clever and insert ++ - scan_macros([M, N | Ts], [{'++', L}, S | As], Opt); -scan_macros([{'?', L}, {Type, _, _}=N | [{'(',_}|_]=Ts], + scan_macros([M, N | Ts], [{'++', AnnoS}, S | As], Opt); +scan_macros([{'?', Anno}, {Type, _, _}=N | [{'(',_}|_]=Ts], [{':',_}|_]=As, Opt) when Type =:= atom; Type =:= var -> %% macro and open parentheses after colon - probably a call @@ -702,21 +700,21 @@ scan_macros([{'?', L}, {Type, _, _}=N | [{'(',_}|_]=Ts], {Args, Rest} = skip_macro_args(Ts), case Rest of [{'->',_} | _] -> - macro_call(Args, L, N, Rest, As, Opt); + macro_call(Args, Anno, N, Rest, As, Opt); [{'when',_} | _] -> - macro_call(Args, L, N, Rest, As, Opt); + macro_call(Args, Anno, N, Rest, As, Opt); _ -> - macro(L, N, Ts, As, Opt) + macro(Anno, N, Ts, As, Opt) end; -scan_macros([{'?', L}, {Type, _, _}=N | [{'(',_}|_]=Ts], As, Opt) +scan_macros([{'?', Anno}, {Type, _, _}=N | [{'(',_}|_]=Ts], As, Opt) when Type =:= atom; Type =:= var -> %% macro with arguments {Args, Rest} = skip_macro_args(Ts), - macro_call(Args, L, N, Rest, As, Opt); -scan_macros([{'?', L }, {Type, _, _}=N | Ts], As, Opt) + macro_call(Args, Anno, N, Rest, As, Opt); +scan_macros([{'?', Anno }, {Type, _, _}=N | Ts], As, Opt) when Type =:= atom; Type =:= var -> %% macro without arguments - macro(L, N, Ts, As, Opt); + macro(Anno, N, Ts, As, Opt); scan_macros([T | Ts], As, Opt) -> scan_macros(Ts, [T | As], Opt); scan_macros([], As, _Opt) -> @@ -725,22 +723,22 @@ scan_macros([], As, _Opt) -> %% Rewriting to a call which will be recognized by the post-parse pass %% (we insert parentheses to preserve the precedences when parsing). -macro(L, {Type, _, A}, Rest, As, Opt) -> - scan_macros_1([], Rest, [{atom,L,macro_atom(Type,A)} | As], Opt). +macro(Anno, {Type, _, A}, Rest, As, Opt) -> + scan_macros_1([], Rest, [{atom,Anno,macro_atom(Type,A)} | As], Opt). -macro_call([{'(',_}, {')',_}], L, {_, Ln, _}=N, Rest, As, Opt) -> +macro_call([{'(',_}, {')',_}], Anno, {_, AnnoN, _}=N, Rest, As, Opt) -> {Open, Close} = parentheses(As), scan_macros_1([], Rest, - lists:reverse(Open ++ [{atom,L,?macro_call}, - {'(',L}, N, {')',Ln}] ++ Close, + lists:reverse(Open ++ [{atom,Anno,?macro_call}, + {'(',Anno}, N, {')',AnnoN}] ++ Close, As), Opt); -macro_call([{'(',_} | Args], L, {_, Ln, _}=N, Rest, As, Opt) -> +macro_call([{'(',_} | Args], Anno, {_, AnnoN, _}=N, Rest, As, Opt) -> {Open, Close} = parentheses(As), %% note that we must scan the argument list; it may not be skipped scan_macros_1(Args ++ Close, Rest, - lists:reverse(Open ++ [{atom,L,?macro_call}, - {'(',L}, N, {',',Ln}], + lists:reverse(Open ++ [{atom,Anno,?macro_call}, + {'(',Anno}, N, {',',AnnoN}], As), Opt). macro_atom(atom, A) -> @@ -757,19 +755,19 @@ parentheses(_) -> {[{'(',0}], [{')',0}]}. %% (after a macro has been found and the arglist skipped, if any) -scan_macros_1(Args, [{string, L, _} | _]=Rest, As, +scan_macros_1(Args, [{string, AnnoS, _} | _]=Rest, As, #opt{clever = true}=Opt) -> %% string literal following macro: be clever and insert ++ - scan_macros(Args ++ [{'++', L} | Rest], As, Opt); + scan_macros(Args ++ [{'++', AnnoS} | Rest], As, Opt); scan_macros_1(Args, Rest, As, Opt) -> %% normal case - continue scanning scan_macros(Args ++ Rest, As, Opt). -rewrite_form({function, L, ?pp_form, _, +rewrite_form({function, Anno, ?pp_form, _, [{clause, _, [], [], [{call, _, A, As}]}]}) -> - erl_syntax:set_pos(erl_syntax:attribute(A, rewrite_list(As)), L); -rewrite_form({function, L, ?pp_form, _, [{clause, _, [], [], [A]}]}) -> - erl_syntax:set_pos(erl_syntax:attribute(A), L); + erl_syntax:set_pos(erl_syntax:attribute(A, rewrite_list(As)), Anno); +rewrite_form({function, Anno, ?pp_form, _, [{clause, _, [], [], [A]}]}) -> + erl_syntax:set_pos(erl_syntax:attribute(A), Anno); rewrite_form(T) -> rewrite(T). @@ -836,8 +834,8 @@ fix_form([{atom, _, ?pp_form}, {'(', _}, {')', _}, {'->', _}, case lists:reverse(Ts) of [{dot, _}, {')', _} | _] -> {retry, Ts, fun fix_define/1}; - [{dot, L} | Ts1] -> - Ts2 = lists:reverse([{dot, L}, {')', L} | Ts1]), + [{dot, Anno} | Ts1] -> + Ts2 = lists:reverse([{dot, Anno}, {')', Anno} | Ts1]), {retry, Ts2, fun fix_define/1}; _ -> error @@ -845,13 +843,13 @@ fix_form([{atom, _, ?pp_form}, {'(', _}, {')', _}, {'->', _}, fix_form(_Ts) -> error. -fix_define([{atom, L, ?pp_form}, {'(', _}, {')', _}, {'->', _}, - {atom, La, define}, {'(', _}, N, {',', _} | Ts]) -> +fix_define([{atom, Anno, ?pp_form}, {'(', _}, {')', _}, {'->', _}, + {atom, AnnoA, define}, {'(', _}, N, {',', _} | Ts]) -> [{dot, _}, {')', _} | Ts1] = lists:reverse(Ts), S = tokens_to_string(lists:reverse(Ts1)), - A = erl_syntax:set_pos(erl_syntax:atom(define), La), - Txt = erl_syntax:set_pos(erl_syntax:text(S), La), - {form, erl_syntax:set_pos(erl_syntax:attribute(A, [N, Txt]), L)}; + A = erl_syntax:set_pos(erl_syntax:atom(define), AnnoA), + Txt = erl_syntax:set_pos(erl_syntax:text(S), AnnoA), + {form, erl_syntax:set_pos(erl_syntax:attribute(A, [N, Txt]), Anno)}; fix_define(_Ts) -> error. diff --git a/lib/syntax_tools/src/erl_prettypr.erl b/lib/syntax_tools/src/erl_prettypr.erl index 75a5cd56bf..700d3e26a7 100644 --- a/lib/syntax_tools/src/erl_prettypr.erl +++ b/lib/syntax_tools/src/erl_prettypr.erl @@ -1509,12 +1509,16 @@ lay_clause_expressions([], _) -> empty(). is_last_and_before_empty_line(H, [], #ctxt{empty_lines = EmptyLines}) -> - try sets:is_element(erl_syntax:get_pos(H) + 1, EmptyLines) + try sets:is_element(get_line(H) + 1, EmptyLines) catch error:badarith -> false end; is_last_and_before_empty_line(H, [H2 | _], #ctxt{empty_lines = EmptyLines}) -> - try ((erl_syntax:get_pos(H2) - erl_syntax:get_pos(H)) >= 2) and sets:is_element(erl_syntax:get_pos(H) + 1, EmptyLines) + try ((get_line(H2) - get_line(H)) >= 2) and sets:is_element(get_line(H) + 1, EmptyLines) catch error:badarith -> false end. +get_line(Tree) -> + Anno = erl_syntax:get_pos(Tree), + erl_anno:line(Anno). + %% ===================================================================== diff --git a/lib/syntax_tools/src/erl_recomment.erl b/lib/syntax_tools/src/erl_recomment.erl index 4d9aaf4eed..4fba3fa4aa 100644 --- a/lib/syntax_tools/src/erl_recomment.erl +++ b/lib/syntax_tools/src/erl_recomment.erl @@ -202,7 +202,7 @@ recomment_forms_2(C, [], _Top) -> standalone_comment({L, Col, _Ind, Text}) -> leaf_node(L, L + comment_delta(Text), - erl_syntax:set_pos(erl_syntax:comment(Col - 1, Text), L)). + erl_syntax:set_pos(erl_syntax:comment(Col - 1, Text), anno(L))). %% Compute delta between first and last line of a comment, given %% the lines of text. @@ -578,8 +578,10 @@ expand_comments([]) -> expand_comment(C) -> {L, _Col, Ind, Text} = C, - erl_syntax:set_pos(erl_syntax:comment(Ind, Text), L). + erl_syntax:set_pos(erl_syntax:comment(Ind, Text), anno(L)). +anno(Location) -> + erl_anno:new(Location). %% ===================================================================== %% Abstract data type for extended syntax trees. @@ -749,6 +751,7 @@ minpos2(X) when X < 1 -> minpos2(X) -> X. +-dialyzer({no_opaque, get_line/1}). get_line(Node) -> case erl_syntax:get_pos(Node) of L when is_integer(L) -> diff --git a/lib/syntax_tools/src/erl_syntax.erl b/lib/syntax_tools/src/erl_syntax.erl index b2d8da5273..d15ffb9b40 100644 --- a/lib/syntax_tools/src/erl_syntax.erl +++ b/lib/syntax_tools/src/erl_syntax.erl @@ -369,16 +369,21 @@ %% %% All nodes are represented by tuples of arity 2 or greater, whose %% first element is an atom which uniquely identifies the type of the -%% node. (In the backwards-compatible representation, the interpretation -%% is also often dependent on the context; the second element generally -%% holds the position information - with a couple of exceptions; see -%% `get_pos' and `set_pos' for details). In the documentation of this -%% module, `Pos' is the source code position information associated with -%% a node; usually, this is a positive integer indicating the original -%% source code line, but no assumptions are made in this module -%% regarding the format or interpretation of position information. When -%% a syntax tree node is constructed, its associated position is by -%% default set to the integer zero. +%% node. (In the backwards-compatible representation, the +%% interpretation is also often dependent on the context; the second +%% element generally holds the annotation (see module {@link +%% //stdlib/erl_anno} for details) which includes the position +%% information - with a couple of exceptions; see `get_pos' and +%% `set_pos' for details.) In the documentation of this module, `Pos' +%% is the annotation associated with a node. No assumptions are made +%% in this module regarding the format or interpretation of the +%% annotations. Use module erl_anno to inspect and modify annotations. +%% In particular, use {@link //stdlib/erl_anno:location/1} to get the +%% position information, and use {@link +%% //stdlib/erl_anno:set_location/2} or {@link +%% //stdlib/erl_anno:set_line/2} to change the position information. +%% When a syntax tree node is constructed, its associated position is +%% by default set to the integer zero. %% ===================================================================== -define(NO_UNUSED, true). @@ -849,23 +854,26 @@ is_form(Node) -> %% ===================================================================== -%% @doc Returns the position information associated with -%% `Node'. This is usually a nonnegative integer (indicating -%% the source code line number), but may be any term. By default, all -%% new tree nodes have their associated position information set to the -%% integer zero. + +%% @doc Returns the annotation (see {@link //stdlib/erl_anno}) +%% associated with `Node'. By default, all new tree nodes have their +%% associated position information set to the integer zero. Use {@link +%% //stdlib/erl_anno:location/1} or {@link //stdlib/erl_anno:line/1} +%% to get the position information. %% %% @see set_pos/2 %% @see get_attrs/1 %% All `erl_parse' tree nodes are represented by tuples whose second -%% field is the position information (usually an integer), *with the +%% field is the annotation, *with the %% exceptions of* `{error, ...}' (type `error_marker') and `{warning, -%% ...}' (type `warning_marker'), which only contain the associated line -%% number *of the error descriptor*; this is all handled transparently +%% ...}' (type `warning_marker'), which only contain the associated location +%% *of the error descriptor*; this is all handled transparently %% by `get_pos' and `set_pos'. --spec get_pos(syntaxTree()) -> term(). +-type annotation_or_location() :: erl_anno:anno() | erl_anno:location(). + +-spec get_pos(syntaxTree()) -> annotation_or_location(). get_pos(#tree{attr = Attr}) -> Attr#attr.pos; @@ -876,8 +884,8 @@ get_pos({error, {Pos, _, _}}) -> get_pos({warning, {Pos, _, _}}) -> Pos; get_pos(Node) -> - %% Here, we assume that we have an `erl_parse' node with position - %% information in element 2. + %% Here, we assume that we have an `erl_parse' node with an + %% annotation in element 2. element(2, Node). @@ -887,7 +895,7 @@ get_pos(Node) -> %% @see get_pos/1 %% @see copy_pos/2 --spec set_pos(syntaxTree(), term()) -> syntaxTree(). +-spec set_pos(syntaxTree(), annotation_or_location()) -> syntaxTree(). set_pos(Node, Pos) -> case Node of @@ -903,7 +911,7 @@ set_pos(Node, Pos) -> %% ===================================================================== -%% @doc Copies the position information from `Source' to `Target'. +%% @doc Copies the annotation from `Source' to `Target'. %% %% This is equivalent to `set_pos(Target, %% get_pos(Source))', but potentially more efficient. diff --git a/lib/syntax_tools/src/erl_tidy.erl b/lib/syntax_tools/src/erl_tidy.erl index fb312bb9d4..6f0dc439e5 100644 --- a/lib/syntax_tools/src/erl_tidy.erl +++ b/lib/syntax_tools/src/erl_tidy.erl @@ -804,7 +804,7 @@ keep_form(Form, Used, Opts) -> false -> {F, A} = N, File = proplists:get_value(file, Opts, ""), - report({File, erl_syntax:get_pos(Form), + report({File, get_line(Form), "removing unused function `~tw/~w'."}, [F, A], Opts), false; @@ -869,7 +869,7 @@ update_attribute(F, Imports, Opts) -> ok; Names -> File = proplists:get_value(file, Opts, ""), - report({File, erl_syntax:get_pos(F), + report({File, get_line(F), "removing unused imports:~ts"}, [[io_lib:fwrite("\n\t`~w:~tw/~w'", [M, N, A]) || {N, A} <- Names]], Opts) @@ -1127,7 +1127,7 @@ visit_atom_application(F, As, Tree, #env{context = guard_test} = Env, end end, if N1 =/= N -> - report({Env#env.file, erl_syntax:get_pos(F), + report({Env#env.file, get_line(F), "changing guard test `~w' to `~w'."}, [N, N1], Env#env.verbosity); true -> @@ -1165,7 +1165,7 @@ visit_import_application({N, A} = Name, F, As, Tree, Env, St0) -> end, case Expand of true -> - report({Env#env.file, erl_syntax:get_pos(F), + report({Env#env.file, get_line(F), "expanding call to imported function `~w:~tw/~w'."}, [M, N, A], Env#env.verbosity), F1 = erl_syntax:module_qualifier(erl_syntax:atom(M), @@ -1179,7 +1179,7 @@ visit_import_application({N, A} = Name, F, As, Tree, Env, St0) -> visit_bif_call({apply, 2}, F, [E, Args] = As, Tree, Env, St0) -> case erl_syntax:is_proper_list(Args) of true -> - report({Env#env.file, erl_syntax:get_pos(F), + report({Env#env.file, get_line(F), "changing use of `apply/2' " "to direct function call."}, [], Env#env.verbosity), @@ -1191,7 +1191,7 @@ visit_bif_call({apply, 2}, F, [E, Args] = As, Tree, Env, St0) -> visit_bif_call({apply, 3}, F, [M, N, Args] = As, Tree, Env, St0) -> case erl_syntax:is_proper_list(Args) of true -> - report({Env#env.file, erl_syntax:get_pos(F), + report({Env#env.file, get_line(F), "changing use of `apply/3' " "to direct remote call."}, [], Env#env.verbosity), @@ -1219,7 +1219,7 @@ visit_spawn_call({N, A}, F, Ps, [A1, A2, A3] = As, Tree, #env{spawn_funs = true} = Env, St0) -> case erl_syntax:is_proper_list(A3) of true -> - report({Env#env.file, erl_syntax:get_pos(F), + report({Env#env.file, get_line(F), "changing use of `~tw/~w' to `~tw/~w' with a fun."}, [N, A, N, 1 + length(Ps)], Env#env.verbosity), F1 = case erl_syntax:is_atom(A1, Env#env.module) of @@ -1259,7 +1259,7 @@ visit_named_fun_application(F, As, Tree, Env, St0) -> %% Making this a direct call would be an error. visit_application_final(F, As, Tree, St0); false -> - report({Env#env.file, erl_syntax:get_pos(F), + report({Env#env.file, get_line(F), "changing application of implicit fun " "to direct local call."}, [], Env#env.verbosity), @@ -1276,7 +1276,7 @@ visit_lambda_application(F, As, Tree, Env, St0) -> A = erl_syntax:fun_expr_arity(F), case A =:= length(As) of true -> - report({Env#env.file, erl_syntax:get_pos(F), + report({Env#env.file, get_line(F), "changing application of fun-expression " "to local function call."}, [], Env#env.verbosity), @@ -1293,7 +1293,7 @@ visit_lambda_application(F, As, Tree, Env, St0) -> St2 = St1#st{new_forms = Forms, used = Used}, visit_application_final(F1, As ++ Free, Tree, St2); false -> - warn({Env#env.file, erl_syntax:get_pos(F), + warn({Env#env.file, get_line(F), "arity mismatch in fun-expression application."}, [], Env#env.verbosity), visit_application_final(F, As, Tree, St0) @@ -1313,7 +1313,7 @@ visit_nonlocal_application(F, As, Tree, Env, St0) -> tuple -> case erl_syntax:tuple_elements(F) of [X1, X2] -> - report({Env#env.file, erl_syntax:get_pos(F), + report({Env#env.file, get_line(F), "changing application of 2-tuple " "to direct remote call."}, [], Env#env.verbosity), @@ -1338,7 +1338,7 @@ visit_nonlocal_application(F, As, Tree, Env, St0) -> %% --- lists:append/2 and lists:subtract/2 --- visit_remote_application({lists, append, 2}, F, [A1, A2], Tree, Env, St0) -> - report({Env#env.file, erl_syntax:get_pos(F), + report({Env#env.file, get_line(F), "replacing call to `lists:append/2' " "with the `++' operator."}, [], Env#env.verbosity), @@ -1346,7 +1346,7 @@ visit_remote_application({lists, append, 2}, F, [A1, A2], Tree, Env, visit(rewrite(Tree, Tree1), Env, St0); visit_remote_application({lists, subtract, 2}, F, [A1, A2], Tree, Env, St0) -> - report({Env#env.file, erl_syntax:get_pos(F), + report({Env#env.file, get_line(F), "replacing call to `lists:subtract/2' " "with the `--' operator."}, [], Env#env.verbosity), @@ -1360,7 +1360,7 @@ visit_remote_application({lists, filter, 2}, F, [A1, A2] = As, Tree, and (get_var_exports(A1) =:= []) and (get_var_exports(A2) =:= []) of true -> - report({Env#env.file, erl_syntax:get_pos(F), + report({Env#env.file, get_line(F), "replacing call to `lists:filter/2' " "with a list comprehension."}, [], Env#env.verbosity), @@ -1380,7 +1380,7 @@ visit_remote_application({lists, map, 2}, F, [A1, A2] = As, Tree, Env, and (get_var_exports(A1) =:= []) and (get_var_exports(A2) =:= []) of true -> - report({Env#env.file, erl_syntax:get_pos(F), + report({Env#env.file, get_line(F), "replacing call to `lists:map/2' " "with a list comprehension."}, [], Env#env.verbosity), @@ -1403,7 +1403,7 @@ visit_remote_application({M, N, A} = Name, F, As, Tree, Env, St) -> false -> case rename_remote_call(Name, St) of {M1, N1} -> - report({Env#env.file, erl_syntax:get_pos(F), + report({Env#env.file, get_line(F), "updating obsolete call to `~w:~tw/~w' " "to use `~w:~tw/~w' instead."}, [M, N, A, M1, N1, A], Env#env.verbosity), @@ -1480,7 +1480,7 @@ visit_generator(G, Env, St0) -> end. visit_generator_1(G, Env, St0) -> - recommend({Env#env.file, erl_syntax:get_pos(G), + recommend({Env#env.file, get_line(G), "unfold that this nested list comprehension can be unfolded " "by hand to get better efficiency."}, [], Env#env.verbosity), @@ -1531,7 +1531,7 @@ visit_match_body(Ps, P, B, Tree, Env, St0) -> case multival_clauses(Cs, length(Ps), Ps) of {true, Cs1} -> report_export_vars(Env#env.file, - erl_syntax:get_pos(B), + get_line(B), "case", Env#env.verbosity), A = erl_syntax:case_expr_argument(B), Tree1 = erl_syntax:case_expr(A, Cs1), @@ -1544,7 +1544,7 @@ visit_match_body(Ps, P, B, Tree, Env, St0) -> case multival_clauses(Cs, length(Ps), Ps) of {true, Cs1} -> report_export_vars(Env#env.file, - erl_syntax:get_pos(B), + get_line(B), "if", Env#env.verbosity), Tree1 = erl_syntax:if_expr(Cs1), {rewrite(Tree, Tree1), St0}; @@ -1559,7 +1559,7 @@ visit_match_body(Ps, P, B, Tree, Env, St0) -> case multival_clauses([C | Cs], length(Ps), Ps) of {true, [C1 | Cs1]} -> report_export_vars(Env#env.file, - erl_syntax:get_pos(B), + get_line(B), "receive", Env#env.verbosity), T = erl_syntax:receive_expr_timeout(B), As1 = erl_syntax:clause_body(C1), @@ -1825,6 +1825,9 @@ rewrite(Source, Target) -> clone(Source, Target) -> erl_syntax:copy_pos(Source, Target). +get_line(Tree) -> + Anno = erl_syntax:get_pos(Tree), + erl_anno:line(Anno). %% ===================================================================== %% Reporting diff --git a/lib/syntax_tools/src/igor.erl b/lib/syntax_tools/src/igor.erl index 2ef3d17281..6dcfdc81cb 100644 --- a/lib/syntax_tools/src/igor.erl +++ b/lib/syntax_tools/src/igor.erl @@ -2802,7 +2802,7 @@ check_forms([F | Fs], File) -> "unknown error" end, report_error("in file `~ts' at line ~w:\n ~ts", - [filename(File), erl_syntax:get_pos(F), S]), + [filename(File), get_line(F), S]), exit(error); _ -> check_forms(Fs, File) @@ -3030,6 +3030,9 @@ split_lines([], Cs, Ls) -> split_lines_1(Cs, Cs1, Ls) -> split_lines(Cs, [], [lists:reverse(Cs1) | Ls]). +get_line(Tree) -> + Anno = erl_syntax:get_pos(Tree), + erl_anno:line(Anno). %% ===================================================================== %% Reporting diff --git a/lib/syntax_tools/src/merl.erl b/lib/syntax_tools/src/merl.erl index b503944442..97ef68ce4c 100644 --- a/lib/syntax_tools/src/merl.erl +++ b/lib/syntax_tools/src/merl.erl @@ -1229,7 +1229,7 @@ merge_comments(StartLine, Cs, [], Acc) -> merge_comments(StartLine, [C|Cs], [T|Ts], Acc) -> {Line, _Col, Indent, Text} = C, CommentLine = StartLine + Line - 1, - case erl_syntax:get_pos(T) of + case get_line(T) of Pos when Pos < CommentLine -> %% TODO: traverse sub-tree rather than only the top level nodes merge_comments(StartLine, [C|Cs], Ts, [T|Acc]); @@ -1248,3 +1248,7 @@ a0() -> anno(Location) -> erl_anno:new(Location). + +get_line(Tree) -> + Anno = erl_syntax:get_pos(Tree), + erl_anno:line(Anno). diff --git a/lib/tools/src/cover.erl b/lib/tools/src/cover.erl index 674c6b98c7..2be62a38fa 100644 --- a/lib/tools/src/cover.erl +++ b/lib/tools/src/cover.erl @@ -1847,10 +1847,10 @@ expand(Expr) -> {Expr1,_} = expand(Expr, AllVars, 1), Expr1. -expand({clause,Line,Pattern,Guards,Body}, Vs, N) -> +expand({clause,Anno,Pattern,Guards,Body}, Vs, N) -> {ExpandedBody,N2} = expand(Body, Vs, N), - {{clause,Line,Pattern,Guards,ExpandedBody},N2}; -expand({op,_Line,'andalso',ExprL,ExprR}, Vs, N) -> + {{clause,Anno,Pattern,Guards,ExpandedBody},N2}; +expand({op,_Anno,'andalso',ExprL,ExprR}, Vs, N) -> {ExpandedExprL,N2} = expand(ExprL, Vs, N), {ExpandedExprR,N3} = expand(ExprR, Vs, N2), Anno = element(2, ExpandedExprL), @@ -1859,7 +1859,7 @@ expand({op,_Line,'andalso',ExprL,ExprR}, Vs, N) -> {atom,Anno,false}, Vs, N3), N3 + 1}; -expand({op,_Line,'orelse',ExprL,ExprR}, Vs, N) -> +expand({op,_Anno,'orelse',ExprL,ExprR}, Vs, N) -> {ExpandedExprL,N2} = expand(ExprL, Vs, N), {ExpandedExprR,N3} = expand(ExprR, Vs, N2), Anno = element(2, ExpandedExprL), @@ -1888,18 +1888,18 @@ vars(A, _T) -> A. bool_switch(E, T, F, AllVars, AuxVarN) -> - Line = element(2, E), - AuxVar = {var,Line,aux_var(AllVars, AuxVarN)}, - {'case',Line,E, - [{clause,Line,[{atom,Line,true}],[],[T]}, - {clause,Line,[{atom,Line,false}],[],[F]}, + Anno = element(2, E), + AuxVar = {var,Anno,aux_var(AllVars, AuxVarN)}, + {'case',Anno,E, + [{clause,Anno,[{atom,Anno,true}],[],[T]}, + {clause,Anno,[{atom,Anno,false}],[],[F]}, %% Mark the next clause as compiler-generated to suppress %% a warning if the case expression is an obvious boolean %% value. - {clause,erl_anno:set_generated(true, Line),[AuxVar],[], - [{call,Line, - {remote,Line,{atom,Line,erlang},{atom,Line,error}}, - [{tuple,Line,[{atom,Line,badarg},AuxVar]}]}]}]}. + {clause,erl_anno:set_generated(true, Anno),[AuxVar],[], + [{call,Anno, + {remote,Anno,{atom,Anno,erlang},{atom,Anno,error}}, + [{tuple,Anno,[{atom,Anno,badarg},AuxVar]}]}]}]}. aux_var(Vars, N) -> Name = list_to_atom(lists:concat(['_', N])), @@ -1912,7 +1912,7 @@ aux_var(Vars, N) -> %% chunk in the BEAM file, as described in absform(3). %% The switch is turned off when we encounter other files than the main file. %% This way we will be able to exclude functions defined in include files. -munge({function,Line,Function,Arity,Clauses},Vars,_MainFile,on) -> +munge({function,Anno,Function,Arity,Clauses},Vars,_MainFile,on) -> Vars2 = Vars#vars{function=Function, arity=Arity, clause=1, @@ -1920,7 +1920,7 @@ munge({function,Line,Function,Arity,Clauses},Vars,_MainFile,on) -> no_bump_lines=[], depth=1}, {MungedClauses, Vars3} = munge_clauses(Clauses, Vars2), - {{function,Line,Function,Arity,MungedClauses},Vars3,on}; + {{function,Anno,Function,Arity,MungedClauses},Vars3,on}; munge(Form={attribute,_,file,{MainFile,_}},Vars,MainFile,_Switch) -> {Form,Vars,on}; % Switch on tranformation! munge(Form={attribute,_,file,{_InclFile,_}},Vars,_MainFile,_Switch) -> @@ -1935,7 +1935,7 @@ munge_clauses(Clauses, Vars) -> munge_clauses(Clauses, Vars, Vars#vars.lines, []). munge_clauses([Clause|Clauses], Vars, Lines, MClauses) -> - {clause,Line,Pattern,Guards,Body} = Clause, + {clause,Anno,Pattern,Guards,Body} = Clause, {MungedGuards, _Vars} = munge_exprs(Guards, Vars#vars{is_guard=true},[]), case Vars#vars.depth of @@ -1955,7 +1955,7 @@ munge_clauses([Clause|Clauses], Vars, Lines, MClauses) -> NewBumps = Vars2#vars.lines, NewLines = NewBumps ++ Lines, munge_clauses(Clauses, Vars3, NewLines, - [{clause,Line,Pattern,MungedGuards,MungedBody}| + [{clause,Anno,Pattern,MungedGuards,MungedBody}| MClauses]); 2 -> % receive-, case-, if-, or try-clause @@ -1965,7 +1965,7 @@ munge_clauses([Clause|Clauses], Vars, Lines, MClauses) -> NewLines = NewBumps ++ Lines, munge_clauses(Clauses, Vars2#vars{lines=Lines0}, NewLines, - [{clause,Line,Pattern,MungedGuards,MungedBody}| + [{clause,Anno,Pattern,MungedGuards,MungedBody}| MClauses]) end; munge_clauses([], Vars, Lines, MungedClauses) -> @@ -2055,27 +2055,27 @@ fix_last_expr([MungedExpr|MungedExprs], Line, Vars) -> Bump = bump_call(Vars, Line), [fix_expr(MungedExpr, Line, Bump)|MungedExprs]. -fix_expr({'if',L,Clauses}, Line, Bump) -> +fix_expr({'if',A,Clauses}, Line, Bump) -> FixedClauses = fix_clauses(Clauses, Line, Bump), - {'if',L,FixedClauses}; -fix_expr({'case',L,Expr,Clauses}, Line, Bump) -> + {'if',A,FixedClauses}; +fix_expr({'case',A,Expr,Clauses}, Line, Bump) -> FixedExpr = fix_expr(Expr, Line, Bump), FixedClauses = fix_clauses(Clauses, Line, Bump), - {'case',L,FixedExpr,FixedClauses}; -fix_expr({'receive',L,Clauses}, Line, Bump) -> + {'case',A,FixedExpr,FixedClauses}; +fix_expr({'receive',A,Clauses}, Line, Bump) -> FixedClauses = fix_clauses(Clauses, Line, Bump), - {'receive',L,FixedClauses}; -fix_expr({'receive',L,Clauses,Expr,Body}, Line, Bump) -> + {'receive',A,FixedClauses}; +fix_expr({'receive',A,Clauses,Expr,Body}, Line, Bump) -> FixedClauses = fix_clauses(Clauses, Line, Bump), FixedExpr = fix_expr(Expr, Line, Bump), FixedBody = fix_expr(Body, Line, Bump), - {'receive',L,FixedClauses,FixedExpr,FixedBody}; -fix_expr({'try',L,Exprs,Clauses,CatchClauses,After}, Line, Bump) -> + {'receive',A,FixedClauses,FixedExpr,FixedBody}; +fix_expr({'try',A,Exprs,Clauses,CatchClauses,After}, Line, Bump) -> FixedExprs = fix_expr(Exprs, Line, Bump), FixedClauses = fix_clauses(Clauses, Line, Bump), FixedCatchClauses = fix_clauses(CatchClauses, Line, Bump), FixedAfter = fix_expr(After, Line, Bump), - {'try',L,FixedExprs,FixedClauses,FixedCatchClauses,FixedAfter}; + {'try',A,FixedExprs,FixedClauses,FixedCatchClauses,FixedAfter}; fix_expr([E | Es], Line, Bump) -> [fix_expr(E, Line, Bump) | fix_expr(Es, Line, Bump)]; fix_expr(T, Line, Bump) when is_tuple(T) -> @@ -2100,13 +2100,13 @@ fix_cls([Cl | Cls], Line, Bump) -> true -> [fix_expr(C, Line, Bump) || C <- [Cl | Cls]]; false -> - {clause,CL,P,G,Body} = Cl, + {clause,CA,P,G,Body} = Cl, UniqueVarName = list_to_atom(lists:concat(["$cover$ ",Line])), A = erl_anno:new(0), V = {var,A,UniqueVarName}, [Last|Rest] = lists:reverse(Body), Body1 = lists:reverse(Rest, [{match,A,V,Last},Bump,V]), - [{clause,CL,P,G,Body1} | fix_cls(Cls, Line, Bump)] + [{clause,CA,P,G,Body1} | fix_cls(Cls, Line, Bump)] end. bumps_line(E, L) -> @@ -2129,114 +2129,114 @@ bump_call(Vars, Line) -> %%% End of fix of last expression. -munge_expr({match,Line,ExprL,ExprR}, Vars) -> +munge_expr({match,Anno,ExprL,ExprR}, Vars) -> {MungedExprL, Vars2} = munge_expr(ExprL, Vars), {MungedExprR, Vars3} = munge_expr(ExprR, Vars2), - {{match,Line,MungedExprL,MungedExprR}, Vars3}; -munge_expr({tuple,Line,Exprs}, Vars) -> + {{match,Anno,MungedExprL,MungedExprR}, Vars3}; +munge_expr({tuple,Anno,Exprs}, Vars) -> {MungedExprs, Vars2} = munge_exprs(Exprs, Vars, []), - {{tuple,Line,MungedExprs}, Vars2}; -munge_expr({record,Line,Name,Exprs}, Vars) -> + {{tuple,Anno,MungedExprs}, Vars2}; +munge_expr({record,Anno,Name,Exprs}, Vars) -> {MungedExprFields, Vars2} = munge_exprs(Exprs, Vars, []), - {{record,Line,Name,MungedExprFields}, Vars2}; -munge_expr({record,Line,Arg,Name,Exprs}, Vars) -> + {{record,Anno,Name,MungedExprFields}, Vars2}; +munge_expr({record,Anno,Arg,Name,Exprs}, Vars) -> {MungedArg, Vars2} = munge_expr(Arg, Vars), {MungedExprFields, Vars3} = munge_exprs(Exprs, Vars2, []), - {{record,Line,MungedArg,Name,MungedExprFields}, Vars3}; -munge_expr({record_field,Line,ExprL,ExprR}, Vars) -> + {{record,Anno,MungedArg,Name,MungedExprFields}, Vars3}; +munge_expr({record_field,Anno,ExprL,ExprR}, Vars) -> {MungedExprR, Vars2} = munge_expr(ExprR, Vars), - {{record_field,Line,ExprL,MungedExprR}, Vars2}; -munge_expr({map,Line,Fields}, Vars) -> + {{record_field,Anno,ExprL,MungedExprR}, Vars2}; +munge_expr({map,Anno,Fields}, Vars) -> %% EEP 43 {MungedFields, Vars2} = munge_exprs(Fields, Vars, []), - {{map,Line,MungedFields}, Vars2}; -munge_expr({map,Line,Arg,Fields}, Vars) -> + {{map,Anno,MungedFields}, Vars2}; +munge_expr({map,Anno,Arg,Fields}, Vars) -> %% EEP 43 {MungedArg, Vars2} = munge_expr(Arg, Vars), {MungedFields, Vars3} = munge_exprs(Fields, Vars2, []), - {{map,Line,MungedArg,MungedFields}, Vars3}; -munge_expr({map_field_assoc,Line,Name,Value}, Vars) -> + {{map,Anno,MungedArg,MungedFields}, Vars3}; +munge_expr({map_field_assoc,Anno,Name,Value}, Vars) -> %% EEP 43 {MungedName, Vars2} = munge_expr(Name, Vars), {MungedValue, Vars3} = munge_expr(Value, Vars2), - {{map_field_assoc,Line,MungedName,MungedValue}, Vars3}; -munge_expr({map_field_exact,Line,Name,Value}, Vars) -> + {{map_field_assoc,Anno,MungedName,MungedValue}, Vars3}; +munge_expr({map_field_exact,Anno,Name,Value}, Vars) -> %% EEP 43 {MungedName, Vars2} = munge_expr(Name, Vars), {MungedValue, Vars3} = munge_expr(Value, Vars2), - {{map_field_exact,Line,MungedName,MungedValue}, Vars3}; -munge_expr({cons,Line,ExprH,ExprT}, Vars) -> + {{map_field_exact,Anno,MungedName,MungedValue}, Vars3}; +munge_expr({cons,Anno,ExprH,ExprT}, Vars) -> {MungedExprH, Vars2} = munge_expr(ExprH, Vars), {MungedExprT, Vars3} = munge_expr(ExprT, Vars2), - {{cons,Line,MungedExprH,MungedExprT}, Vars3}; -munge_expr({op,Line,Op,ExprL,ExprR}, Vars) -> + {{cons,Anno,MungedExprH,MungedExprT}, Vars3}; +munge_expr({op,Anno,Op,ExprL,ExprR}, Vars) -> {MungedExprL, Vars2} = munge_expr(ExprL, Vars), {MungedExprR, Vars3} = munge_expr(ExprR, Vars2), - {{op,Line,Op,MungedExprL,MungedExprR}, Vars3}; -munge_expr({op,Line,Op,Expr}, Vars) -> + {{op,Anno,Op,MungedExprL,MungedExprR}, Vars3}; +munge_expr({op,Anno,Op,Expr}, Vars) -> {MungedExpr, Vars2} = munge_expr(Expr, Vars), - {{op,Line,Op,MungedExpr}, Vars2}; -munge_expr({'catch',Line,Expr}, Vars) -> + {{op,Anno,Op,MungedExpr}, Vars2}; +munge_expr({'catch',Anno,Expr}, Vars) -> {MungedExpr, Vars2} = munge_expr(Expr, Vars), - {{'catch',Line,MungedExpr}, Vars2}; -munge_expr({call,Line1,{remote,Line2,ExprM,ExprF},Exprs}, + {{'catch',Anno,MungedExpr}, Vars2}; +munge_expr({call,Anno1,{remote,Anno2,ExprM,ExprF},Exprs}, Vars) -> {MungedExprM, Vars2} = munge_expr(ExprM, Vars), {MungedExprF, Vars3} = munge_expr(ExprF, Vars2), {MungedExprs, Vars4} = munge_exprs(Exprs, Vars3, []), - {{call,Line1,{remote,Line2,MungedExprM,MungedExprF},MungedExprs}, Vars4}; -munge_expr({call,Line,Expr,Exprs}, Vars) -> + {{call,Anno1,{remote,Anno2,MungedExprM,MungedExprF},MungedExprs}, Vars4}; +munge_expr({call,Anno,Expr,Exprs}, Vars) -> {MungedExpr, Vars2} = munge_expr(Expr, Vars), {MungedExprs, Vars3} = munge_exprs(Exprs, Vars2, []), - {{call,Line,MungedExpr,MungedExprs}, Vars3}; -munge_expr({lc,Line,Expr,Qs}, Vars) -> + {{call,Anno,MungedExpr,MungedExprs}, Vars3}; +munge_expr({lc,Anno,Expr,Qs}, Vars) -> {MungedExpr, Vars2} = munge_expr(?BLOCK1(Expr), Vars), {MungedQs, Vars3} = munge_qualifiers(Qs, Vars2), - {{lc,Line,MungedExpr,MungedQs}, Vars3}; -munge_expr({bc,Line,Expr,Qs}, Vars) -> + {{lc,Anno,MungedExpr,MungedQs}, Vars3}; +munge_expr({bc,Anno,Expr,Qs}, Vars) -> {MungedExpr,Vars2} = munge_expr(?BLOCK1(Expr), Vars), {MungedQs, Vars3} = munge_qualifiers(Qs, Vars2), - {{bc,Line,MungedExpr,MungedQs}, Vars3}; -munge_expr({block,Line,Body}, Vars) -> + {{bc,Anno,MungedExpr,MungedQs}, Vars3}; +munge_expr({block,Anno,Body}, Vars) -> {MungedBody, Vars2} = munge_body(Body, Vars), - {{block,Line,MungedBody}, Vars2}; -munge_expr({'if',Line,Clauses}, Vars) -> + {{block,Anno,MungedBody}, Vars2}; +munge_expr({'if',Anno,Clauses}, Vars) -> {MungedClauses,Vars2} = munge_clauses(Clauses, Vars), - {{'if',Line,MungedClauses}, Vars2}; -munge_expr({'case',Line,Expr,Clauses}, Vars) -> + {{'if',Anno,MungedClauses}, Vars2}; +munge_expr({'case',Anno,Expr,Clauses}, Vars) -> {MungedExpr,Vars2} = munge_expr(Expr, Vars), {MungedClauses,Vars3} = munge_clauses(Clauses, Vars2), - {{'case',Line,MungedExpr,MungedClauses}, Vars3}; -munge_expr({'receive',Line,Clauses}, Vars) -> + {{'case',Anno,MungedExpr,MungedClauses}, Vars3}; +munge_expr({'receive',Anno,Clauses}, Vars) -> {MungedClauses,Vars2} = munge_clauses(Clauses, Vars), - {{'receive',Line,MungedClauses}, Vars2}; -munge_expr({'receive',Line,Clauses,Expr,Body}, Vars) -> + {{'receive',Anno,MungedClauses}, Vars2}; +munge_expr({'receive',Anno,Clauses,Expr,Body}, Vars) -> {MungedExpr, Vars1} = munge_expr(Expr, Vars), {MungedClauses,Vars2} = munge_clauses(Clauses, Vars1), {MungedBody,Vars3} = munge_body(Body, Vars2#vars{lines = Vars1#vars.lines}), Vars4 = Vars3#vars{lines = Vars2#vars.lines ++ new_bumps(Vars3, Vars2)}, - {{'receive',Line,MungedClauses,MungedExpr,MungedBody}, Vars4}; -munge_expr({'try',Line,Body,Clauses,CatchClauses,After}, Vars) -> + {{'receive',Anno,MungedClauses,MungedExpr,MungedBody}, Vars4}; +munge_expr({'try',Anno,Body,Clauses,CatchClauses,After}, Vars) -> {MungedBody, Vars1} = munge_body(Body, Vars), {MungedClauses, Vars2} = munge_clauses(Clauses, Vars1), {MungedCatchClauses, Vars3} = munge_clauses(CatchClauses, Vars2), {MungedAfter, Vars4} = munge_body(After, Vars3), - {{'try',Line,MungedBody,MungedClauses,MungedCatchClauses,MungedAfter}, + {{'try',Anno,MungedBody,MungedClauses,MungedCatchClauses,MungedAfter}, Vars4}; -munge_expr({'fun',Line,{clauses,Clauses}}, Vars) -> +munge_expr({'fun',Anno,{clauses,Clauses}}, Vars) -> {MungedClauses,Vars2}=munge_clauses(Clauses, Vars), - {{'fun',Line,{clauses,MungedClauses}}, Vars2}; -munge_expr({named_fun,Line,Name,Clauses}, Vars) -> + {{'fun',Anno,{clauses,MungedClauses}}, Vars2}; +munge_expr({named_fun,Anno,Name,Clauses}, Vars) -> {MungedClauses,Vars2}=munge_clauses(Clauses, Vars), - {{named_fun,Line,Name,MungedClauses}, Vars2}; -munge_expr({bin,Line,BinElements}, Vars) -> + {{named_fun,Anno,Name,MungedClauses}, Vars2}; +munge_expr({bin,Anno,BinElements}, Vars) -> {MungedBinElements,Vars2} = munge_exprs(BinElements, Vars, []), - {{bin,Line,MungedBinElements}, Vars2}; -munge_expr({bin_element,Line,Value,Size,TypeSpecifierList}, Vars) -> + {{bin,Anno,MungedBinElements}, Vars2}; +munge_expr({bin_element,Anno,Value,Size,TypeSpecifierList}, Vars) -> {MungedValue,Vars2} = munge_expr(Value, Vars), {MungedSize,Vars3} = munge_expr(Size, Vars2), - {{bin_element,Line,MungedValue,MungedSize,TypeSpecifierList},Vars3}; + {{bin_element,Anno,MungedValue,MungedSize,TypeSpecifierList},Vars3}; munge_expr(Form, Vars) -> {Form, Vars}. @@ -2254,27 +2254,27 @@ munge_exprs([], Vars, MungedExprs) -> munge_qualifiers(Qualifiers, Vars) -> munge_qs(Qualifiers, Vars, []). -munge_qs([{generate,Line,Pattern,Expr}|Qs], Vars, MQs) -> - L = element(2, Expr), +munge_qs([{generate,Anno,Pattern,Expr}|Qs], Vars, MQs) -> + A = element(2, Expr), {MungedExpr, Vars2} = munge_expr(Expr, Vars), - munge_qs1(Qs, L, {generate,Line,Pattern,MungedExpr}, Vars, Vars2, MQs); -munge_qs([{b_generate,Line,Pattern,Expr}|Qs], Vars, MQs) -> - L = element(2, Expr), + munge_qs1(Qs, A, {generate,Anno,Pattern,MungedExpr}, Vars, Vars2, MQs); +munge_qs([{b_generate,Anno,Pattern,Expr}|Qs], Vars, MQs) -> + A = element(2, Expr), {MExpr, Vars2} = munge_expr(Expr, Vars), - munge_qs1(Qs, L, {b_generate,Line,Pattern,MExpr}, Vars, Vars2, MQs); + munge_qs1(Qs, A, {b_generate,Anno,Pattern,MExpr}, Vars, Vars2, MQs); munge_qs([Expr|Qs], Vars, MQs) -> - L = element(2, Expr), + A = element(2, Expr), {MungedExpr, Vars2} = munge_expr(Expr, Vars), - munge_qs1(Qs, L, MungedExpr, Vars, Vars2, MQs); + munge_qs1(Qs, A, MungedExpr, Vars, Vars2, MQs); munge_qs([], Vars, MQs) -> {lists:reverse(MQs), Vars}. -munge_qs1(Qs, Line, NQ, Vars, Vars2, MQs) -> +munge_qs1(Qs, Anno, NQ, Vars, Vars2, MQs) -> case new_bumps(Vars2, Vars) of [_] -> munge_qs(Qs, Vars2, [NQ | MQs]); _ -> - {MungedTrue, Vars3} = munge_expr(?BLOCK({atom,Line,true}), Vars2), + {MungedTrue, Vars3} = munge_expr(?BLOCK({atom,Anno,true}), Vars2), munge_qs(Qs, Vars3, [NQ, MungedTrue | MQs]) end. @@ -2334,7 +2334,7 @@ patch_code(Mod, Forms, true) -> %% Go through the abstract code and replace 'BUMP' forms %% with the actual code to increment the counters. -patch_code1({'BUMP',_Line,Index}, {distributed,AbstrKey}) -> +patch_code1({'BUMP',_Anno,Index}, {distributed,AbstrKey}) -> %% Replace with counters:add(persistent_term:get(Key), Index, 1). %% This code will work on any node. A = element(2, AbstrKey), @@ -2342,7 +2342,7 @@ patch_code1({'BUMP',_Line,Index}, {distributed,AbstrKey}) -> [AbstrKey]}, {call,A,{remote,A,{atom,A,counters},{atom,A,add}}, [GetCref,{integer,A,Index},{integer,A,1}]}; -patch_code1({'BUMP',_Line,Index}, {local_only,AbstrCref}) -> +patch_code1({'BUMP',_Anno,Index}, {local_only,AbstrCref}) -> %% Replace with counters:add(Cref, Index, 1). This code %% will only work on the local node. A = element(2, AbstrCref), diff --git a/lib/tools/src/xref_reader.erl b/lib/tools/src/xref_reader.erl index a8ac4906d2..c1bb8798bb 100644 --- a/lib/tools/src/xref_reader.erl +++ b/lib/tools/src/xref_reader.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2000-2017. All Rights Reserved. +%% Copyright Ericsson AB 2000-2020. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -57,7 +57,7 @@ %% Attrs = {ALC, AXC, Bad} %% ALC, AXC and Bad are extracted from the attribute 'xref'. An experiment. module(Module, Forms, CollectBuiltins, X, DF) -> - Attrs = [{Attr,V} || {attribute,_Line,Attr,V} <- Forms], + Attrs = [{Attr,V} || {attribute,_Anno,Attr,V} <- Forms], IsAbstract = xref_utils:is_abstract_module(Attrs), S = #xrefr{module = Module, builtins_too = CollectBuiltins, is_abstr = IsAbstract, x = X, df = DF}, @@ -83,19 +83,19 @@ forms([], S) -> Attrs = {lists:reverse(AL), lists:reverse(AX), lists:reverse(B)}, {ok, M, {DefAt, LCallAt, XCallAt, LC, XC, X, Attrs, Depr, OL}, U}. -form({attribute, Line, xref, Calls}, S) -> % experimental +form({attribute, Anno, xref, Calls}, S) -> % experimental #xrefr{module = M, function = Fun, lattrs = L, xattrs = X, battrs = B} = S, - attr(Calls, erl_anno:line(Line), M, Fun, L, X, B, S); + attr(Calls, erl_anno:line(Anno), M, Fun, L, X, B, S); form({attribute, _, on_load, {F, 0}}, S) -> S#xrefr{on_load = F}; -form({attribute, _Line, _Attr, _Val}, S) -> +form({attribute, _Anno, _Attr, _Val}, S) -> S; form({function, _, module_info, 0, _Clauses}, S) -> S; form({function, _, module_info, 1, _Clauses}, S) -> S; -form({function, 0 = _Line, behaviour_info, 1, _Clauses}, S) -> +form({function, 0 = _Anno, behaviour_info, 1, _Clauses}, S) -> S; form({function, Anno, Name, Arity, Clauses}, S) -> MFA0 = {S#xrefr.module, Name, Arity}, @@ -115,7 +115,7 @@ clauses(Cls, S) -> #xrefr{funvars = FunVars, matches = Matches} = S, clauses(Cls, FunVars, Matches, S). -clauses([{clause, _Line, _H, G, B} | Cs], FunVars, Matches, S) -> +clauses([{clause, _Anno, _H, G, B} | Cs], FunVars, Matches, S) -> S1 = case S#xrefr.builtins_too of true -> expr(G, S); false -> S @@ -157,89 +157,89 @@ mfa(MFA={M,F,A}, M1) when is_atom(M), is_atom(F), is_integer(A) -> {M=:=M1, external, MFA}; mfa(_, _M) -> false. -expr({'if', _Line, Cs}, S) -> +expr({'if', _Anno, Cs}, S) -> clauses(Cs, S); -expr({'case', _Line, E, Cs}, S) -> +expr({'case', _Anno, E, Cs}, S) -> S1 = expr(E, S), clauses(Cs, S1); -expr({'receive', _Line, Cs}, S) -> +expr({'receive', _Anno, Cs}, S) -> clauses(Cs, S); -expr({'receive', _Line, Cs, To, ToEs}, S) -> +expr({'receive', _Anno, Cs, To, ToEs}, S) -> S1 = expr(To, S), S2 = expr(ToEs, S1), clauses(Cs, S2); -expr({'try',_Line,Es,Scs,Ccs,As}, S) -> +expr({'try',_Anno,Es,Scs,Ccs,As}, S) -> S1 = expr(Es, S), S2 = clauses(Scs, S1), S3 = clauses(Ccs, S2), expr(As, S3); -expr({'fun', Line, {function, {atom,_,Mod}, +expr({'fun', Anno, {function, {atom,_,Mod}, {atom,_,Name}, {integer,_,Arity}}}, S) -> %% New format in R15. M:F/A (literals). - As = lists:duplicate(Arity, {atom, Line, foo}), - external_call(Mod, Name, As, Line, false, S); -expr({'fun', Line, {function, Mod, Name, {integer,_,Arity}}}, S) -> + As = lists:duplicate(Arity, {atom, Anno, foo}), + external_call(Mod, Name, As, Anno, false, S); +expr({'fun', Anno, {function, Mod, Name, {integer,_,Arity}}}, S) -> %% New format in R15. M:F/A (one or more variables). - As = lists:duplicate(Arity, {atom, Line, foo}), - external_call(erlang, apply, [Mod, Name, list2term(As)], Line, true, S); -expr({'fun', Line, {function, Mod, Name, _Arity}}, S) -> + As = lists:duplicate(Arity, {atom, Anno, foo}), + external_call(erlang, apply, [Mod, Name, list2term(As)], Anno, true, S); +expr({'fun', Anno, {function, Mod, Name, _Arity}}, S) -> %% New format in R15. M:F/A (one or more variables). - As = {var, Line, '_'}, - external_call(erlang, apply, [Mod, Name, As], Line, true, S); + As = {var, Anno, '_'}, + external_call(erlang, apply, [Mod, Name, As], Anno, true, S); %% Only abstract_v1 and abstract_v2. -expr({'fun', Line, {function, Name, Arity}, _Extra}, S) -> +expr({'fun', Anno, {function, Name, Arity}, _Extra}, S) -> %% Added in R8. - handle_call(local, S#xrefr.module, Name, Arity, Line, S); -expr({'fun', _Line, {clauses, Cs}, _Extra}, S) -> + handle_call(local, S#xrefr.module, Name, Arity, Anno, S); +expr({'fun', _Anno, {clauses, Cs}, _Extra}, S) -> clauses(Cs, S); %% End abstract_v1 and abstract_v2. -expr({'fun', Line, {function, Name, Arity}}, S) -> +expr({'fun', Anno, {function, Name, Arity}}, S) -> %% Added in OTP 20. - handle_call(local, S#xrefr.module, Name, Arity, Line, S); -expr({'fun', _Line, {clauses, Cs}}, S) -> + handle_call(local, S#xrefr.module, Name, Arity, Anno, S); +expr({'fun', _Anno, {clauses, Cs}}, S) -> clauses(Cs, S); -expr({named_fun, _Line, '_', Cs}, S) -> +expr({named_fun, _Anno, '_', Cs}, S) -> clauses(Cs, S); -expr({named_fun, _Line, Name, Cs}, S) -> +expr({named_fun, _Anno, Name, Cs}, S) -> S1 = S#xrefr{funvars = [Name | S#xrefr.funvars]}, clauses(Cs, S1); -expr({call, Line, {atom, _, Name}, As}, S) -> - S1 = handle_call(local, S#xrefr.module, Name, length(As), Line, S), +expr({call, Anno, {atom, _, Name}, As}, S) -> + S1 = handle_call(local, S#xrefr.module, Name, length(As), Anno, S), expr(As, S1); -expr({call, Line, {remote, _Line, {atom,_,Mod}, {atom,_,Name}}, As}, S) -> - external_call(Mod, Name, As, Line, false, S); -expr({call, Line, {remote, _Line, Mod, Name}, As}, S) -> +expr({call, Anno, {remote, _Anno, {atom,_,Mod}, {atom,_,Name}}, As}, S) -> + external_call(Mod, Name, As, Anno, false, S); +expr({call, Anno, {remote, _Anno, Mod, Name}, As}, S) -> %% Added in R8. - external_call(erlang, apply, [Mod, Name, list2term(As)], Line, true, S); -expr({call, Line, F, As}, S) -> - external_call(erlang, apply, [F, list2term(As)], Line, true, S); -expr({match, _Line, {var,_,Var}, {'fun', _, {clauses, Cs}, _Extra}}, S) -> + external_call(erlang, apply, [Mod, Name, list2term(As)], Anno, true, S); +expr({call, Anno, F, As}, S) -> + external_call(erlang, apply, [F, list2term(As)], Anno, true, S); +expr({match, _Anno, {var,_,Var}, {'fun', _, {clauses, Cs}, _Extra}}, S) -> %% This is what is needed in R7 to avoid warnings for the functions %% that are passed around by the "expansion" of list comprehension. S1 = S#xrefr{funvars = [Var | S#xrefr.funvars]}, clauses(Cs, S1); -expr({match, _Line, {var,_,Var}, {'fun', _, {clauses, Cs}}}, S) -> +expr({match, _Anno, {var,_,Var}, {'fun', _, {clauses, Cs}}}, S) -> %% OTP 20. Exposed because sys_pre_expand is no longer run. S1 = S#xrefr{funvars = [Var | S#xrefr.funvars]}, clauses(Cs, S1); -expr({match, _Line, {var,_,Var}, {named_fun, _, _, _} = Fun}, S) -> +expr({match, _Anno, {var,_,Var}, {named_fun, _, _, _} = Fun}, S) -> %% OTP 20. Exposed because sys_pre_expand is no longer run. S1 = S#xrefr{funvars = [Var | S#xrefr.funvars]}, expr(Fun, S1); -expr({match, _Line, {var,_,Var}, E}, S) -> +expr({match, _Anno, {var,_,Var}, E}, S) -> %% Used for resolving code like %% Args = [A,B], apply(m, f, Args) S1 = S#xrefr{matches = [{Var, E} | S#xrefr.matches]}, expr(E, S1); -expr({op, _Line, 'orelse', Op1, Op2}, S) -> +expr({op, _Anno, 'orelse', Op1, Op2}, S) -> expr([Op1, Op2], S); -expr({op, _Line, 'andalso', Op1, Op2}, S) -> +expr({op, _Anno, 'andalso', Op1, Op2}, S) -> expr([Op1, Op2], S); -expr({op, Line, Op, Operand1, Operand2}, S) -> - external_call(erlang, Op, [Operand1, Operand2], Line, false, S); -expr({op, Line, Op, Operand}, S) -> - external_call(erlang, Op, [Operand], Line, false, S); +expr({op, Anno, Op, Operand1, Operand2}, S) -> + external_call(erlang, Op, [Operand1, Operand2], Anno, false, S); +expr({op, Anno, Op, Operand}, S) -> + external_call(erlang, Op, [Operand], Anno, false, S); expr(T, S) when is_tuple(T) -> expr(tuple_to_list(T), S); expr([E | Es], S) -> @@ -249,7 +249,7 @@ expr(_E, S) -> %% Mod and Fun may not correspond to something in the abstract code, %% which is signalled by X =:= true. -external_call(Mod, Fun, ArgsList, Line, X, S) -> +external_call(Mod, Fun, ArgsList, Anno, X, S) -> Arity = length(ArgsList), W = case xref_utils:is_funfun(Mod, Fun, Arity) of true when erlang =:= Mod, apply =:= Fun, 2 =:= Arity -> apply2; @@ -267,7 +267,7 @@ external_call(Mod, Fun, ArgsList, Line, X, S) -> W =:= type; X -> S; true -> - handle_call(external, Mod, Fun, Arity, Line, S) + handle_call(external, Mod, Fun, Arity, Anno, S) end, case {W, ArgsList} of {false, _} -> @@ -275,33 +275,33 @@ external_call(Mod, Fun, ArgsList, Line, X, S) -> {type, _} -> expr(ArgsList, S1); {apply2, [{tuple, _, [M,F]}, ArgsTerm]} -> - eval_args(M, F, ArgsTerm, Line, S1, ArgsList, []); + eval_args(M, F, ArgsTerm, Anno, S1, ArgsList, []); {1, [{tuple, _, [M,F]} | R]} -> % R = [] unless spawn_opt - eval_args(M, F, list2term([]), Line, S1, ArgsList, R); + eval_args(M, F, list2term([]), Anno, S1, ArgsList, R); {2, [Node, {tuple, _, [M,F]} | R]} -> % R = [] unless spawn_opt - eval_args(M, F, list2term([]), Line, S1, ArgsList, [Node | R]); + eval_args(M, F, list2term([]), Anno, S1, ArgsList, [Node | R]); {3, [M, F, ArgsTerm | R]} -> % R = [] unless spawn_opt - eval_args(M, F, ArgsTerm, Line, S1, ArgsList, R); + eval_args(M, F, ArgsTerm, Anno, S1, ArgsList, R); {4, [Node, M, F, ArgsTerm | R]} -> % R = [] unless spawn_opt - eval_args(M, F, ArgsTerm, Line, S1, ArgsList, [Node | R]); + eval_args(M, F, ArgsTerm, Anno, S1, ArgsList, [Node | R]); {debug4, [M, F, ArgsTerm, _]} -> - eval_args(M, F, ArgsTerm, Line, S1, ArgsList, []); + eval_args(M, F, ArgsTerm, Anno, S1, ArgsList, []); _Else -> % apply2, 1 or 2 - check_funarg(W, ArgsList, Line, S1) + check_funarg(W, ArgsList, Anno, S1) end. -eval_args(Mod, Fun, ArgsTerm, Line, S, ArgsList, Extra) -> +eval_args(Mod, Fun, ArgsTerm, Anno, S, ArgsList, Extra) -> {IsSimpleCall, M, F} = mod_fun(Mod, Fun), case term2list(ArgsTerm, [], S) of undefined -> - S1 = unresolved(M, F, -1, Line, S), + S1 = unresolved(M, F, -1, Anno, S), expr(ArgsList, S1); ArgsList2 when not IsSimpleCall -> - S1 = unresolved(M, F, length(ArgsList2), Line, S), + S1 = unresolved(M, F, length(ArgsList2), Anno, S), expr(ArgsList, S1); ArgsList2 when IsSimpleCall -> S1 = expr(Extra, S), - external_call(M, F, ArgsList2, Line, false, S1) + external_call(M, F, ArgsList2, Anno, false, S1) end. mod_fun({atom,_,M1}, {atom,_,F1}) -> {true, M1, F1}; @@ -309,19 +309,19 @@ mod_fun({atom,_,M1}, _) -> {false, M1, ?VAR_EXPR}; mod_fun(_, {atom,_,F1}) -> {false, ?MOD_EXPR, F1}; mod_fun(_, _) -> {false, ?MOD_EXPR, ?VAR_EXPR}. -check_funarg(W, ArgsList, Line, S) -> +check_funarg(W, ArgsList, Anno, S) -> {FunArg, Args} = fun_args(W, ArgsList), S1 = case funarg(FunArg, S) of true -> S; false when is_integer(W) -> % 1 or 2 - unresolved(?MOD_EXPR, ?VAR_EXPR, 0, Line, S); + unresolved(?MOD_EXPR, ?VAR_EXPR, 0, Anno, S); false -> % apply2 N = case term2list(Args, [], S) of undefined -> -1; As -> length(As) end, - unresolved(?MOD_EXPR, ?VAR_EXPR, N, Line, S) + unresolved(?MOD_EXPR, ?VAR_EXPR, N, Anno, S) end, expr(ArgsList, S1). @@ -354,9 +354,9 @@ list2term([A | As], Anno) -> list2term([], Anno) -> {nil, Anno}. -term2list({cons, _Line, H, T}, L, S) -> +term2list({cons, _Anno, H, T}, L, S) -> term2list(T, [H | L], S); -term2list({nil, _Line}, L, _S) -> +term2list({nil, _Anno}, L, _S) -> reverse(L); term2list({var, _, Var}, L, S) -> case keysearch(Var, 1, S#xrefr.matches) of @@ -368,15 +368,15 @@ term2list({var, _, Var}, L, S) -> term2list(_Else, _L, _S) -> undefined. -unresolved(M, F, A, Line, S) -> - handle_call(external, {M,F,A}, Line, S, true). +unresolved(M, F, A, Anno, S) -> + handle_call(external, {M,F,A}, Anno, S, true). -handle_call(Locality, Module, Name, Arity, Line, S) -> +handle_call(Locality, Module, Name, Arity, Anno, S) -> case xref_utils:is_builtin(Module, Name, Arity) of true when not S#xrefr.builtins_too -> S; _Else -> To = {Module, Name, Arity}, - handle_call(Locality, To, Line, S, false) + handle_call(Locality, To, Anno, S, false) end. handle_call(Locality, To0, Anno, S, IsUnres) -> diff --git a/system/doc/reference_manual/patterns.xml b/system/doc/reference_manual/patterns.xml index e2363cfd0e..f54331e091 100644 --- a/system/doc/reference_manual/patterns.xml +++ b/system/doc/reference_manual/patterns.xml @@ -44,7 +44,7 @@ <p><em>Examples:</em></p> <pre> 1> <input>X.</input> -** 1: variable 'X' is unbound ** +** 1:1: variable 'X' is unbound ** 2> <input>X = 2.</input> 2 3> <input>X + 1.</input> |