aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorHans Bolinder <[email protected]>2015-12-02 12:41:58 +0100
committerHans Bolinder <[email protected]>2016-02-17 12:58:19 +0100
commitc6135114e691a8c2f21f4d79f2566b87300857d5 (patch)
treebe7e154143ebe630e1fa55bd65bc6edc0cb19b48 /lib
parente2e216eb72477103cb5930632c9f05a5f4164fae (diff)
downloadotp-c6135114e691a8c2f21f4d79f2566b87300857d5.tar.gz
otp-c6135114e691a8c2f21f4d79f2566b87300857d5.tar.bz2
otp-c6135114e691a8c2f21f4d79f2566b87300857d5.zip
stdlib: Let the linter detect old typed records
Diffstat (limited to 'lib')
-rw-r--r--lib/stdlib/src/erl_lint.erl9
-rw-r--r--lib/stdlib/test/erl_lint_SUITE.erl17
2 files changed, 25 insertions, 1 deletions
diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl
index e821417e8e..4ca9a609a8 100644
--- a/lib/stdlib/src/erl_lint.erl
+++ b/lib/stdlib/src/erl_lint.erl
@@ -360,6 +360,9 @@ format_error({redefine_type, {TypeName, Arity}}) ->
[TypeName, gen_type_paren(Arity)]);
format_error({type_syntax, Constr}) ->
io_lib:format("bad ~w type", [Constr]);
+format_error(old_abstract_code) ->
+ io_lib:format("abstract code generated before Erlang/OTP 19.0 and "
+ "having typed record fields cannot be compiled", []);
format_error({redefine_spec, {M, F, A}}) ->
io_lib:format("spec for ~w:~w/~w already defined", [M, F, A]);
format_error({redefine_spec, {F, A}}) ->
@@ -2812,6 +2815,8 @@ check_type({user_type, L, TypeName, Args}, SeenVars, St) ->
lists:foldl(fun(T, {AccSeenVars, AccSt}) ->
check_type(T, AccSeenVars, AccSt)
end, {SeenVars, St1}, Args);
+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};
@@ -3009,7 +3014,9 @@ check_unused_types(Forms, #lint{usage=Usage, types=Ts, exp_types=ExpTs}=St) ->
L = gb_sets:to_list(ExpTs) ++ dict:fetch_keys(D),
UsedTypes = gb_sets:from_list(L),
FoldFun =
- fun(Type, #typeinfo{line = FileLine}, AccSt) ->
+ fun({{record, _}=_Type, 0}, _, AccSt) ->
+ AccSt; % Before Erlang/OTP 19.0
+ (Type, #typeinfo{line = FileLine}, AccSt) ->
case loc(FileLine, AccSt) of
{FirstFile, _} ->
case gb_sets:is_member(Type, UsedTypes) of
diff --git a/lib/stdlib/test/erl_lint_SUITE.erl b/lib/stdlib/test/erl_lint_SUITE.erl
index 32247ba492..8f0ac828ec 100644
--- a/lib/stdlib/test/erl_lint_SUITE.erl
+++ b/lib/stdlib/test/erl_lint_SUITE.erl
@@ -2607,6 +2607,23 @@ otp_5878(Config) when is_list(Config) ->
">>,
?line [] = run_test2(Config, UsedByType, [warn_unused_record]),
+ %% Abstract code generated by OTP 18. Note that the type info for
+ %% record fields has been put in a separate form.
+ OldAbstract = [{attribute,1,file,{"rec.erl",1}},
+ {attribute,1,module,rec},
+ {attribute,3,export,[{t,0}]},
+ {attribute,7,record,{r,[{record_field,7,{atom,7,f}}]}},
+ {attribute,7,type,
+ {{record,r},
+ [{typed_record_field,
+ {record_field,7,{atom,7,f}},
+ {type,7,union,[{atom,7,undefined},{type,7,atom,[]}]}}],
+ []}},
+ {function,9,t,0,[{clause,9,[],[],[{record,10,r,[]}]}]},
+ {eof,11}],
+ {error,[{"rec.erl",[{7,erl_lint,old_abstract_code}]}],[]} =
+ compile:forms(OldAbstract, [return, report]),
+
ok.
otp_6885(doc) ->