aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorHans Bolinder <[email protected]>2011-03-22 13:57:30 +0100
committerHans Bolinder <[email protected]>2011-03-22 13:57:30 +0100
commitb420086b983b934b231323a682e676bf149e7bf8 (patch)
treeda8d5a0aa06f4642de871762ebd5abd8b76d4a84 /lib
parentf861b4fdb3fd39e35f2951c53a73b30a98c7f973 (diff)
downloadotp-b420086b983b934b231323a682e676bf149e7bf8.tar.gz
otp-b420086b983b934b231323a682e676bf149e7bf8.tar.bz2
otp-b420086b983b934b231323a682e676bf149e7bf8.zip
Fix a bug concerning record field types
The default value 'undefined' was added to records field types in such a way that the result was not always a well-formed type. This bug has been fixed. --- erl_pp has since OTP-8150 formatted types so that 'undefined' was removed from union types assigned to record fields. Since one cannot distinguish between 'undefined' added by the parser or supplied by the user, a side effect was that user supplied 'undefined's were also removed. Now the pretty printer shows 'undefined' even if added by the parser. This is a minor issue.
Diffstat (limited to 'lib')
-rw-r--r--lib/stdlib/src/erl_parse.yrl10
-rw-r--r--lib/stdlib/src/erl_pp.erl10
-rw-r--r--lib/stdlib/test/erl_pp_SUITE.erl24
3 files changed, 32 insertions, 12 deletions
diff --git a/lib/stdlib/src/erl_parse.yrl b/lib/stdlib/src/erl_parse.yrl
index bb4b18cf9b..15b45d72f4 100644
--- a/lib/stdlib/src/erl_parse.yrl
+++ b/lib/stdlib/src/erl_parse.yrl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -757,7 +757,8 @@ record_fields([{typed,Expr,TypeInfo}|Fields]) ->
{atom, La, _} ->
case has_undefined(TypeInfo) of
false ->
- lift_unions(abstract(undefined, La), TypeInfo);
+ TypeInfo2 = maybe_add_paren(TypeInfo),
+ lift_unions(abstract(undefined, La), TypeInfo2);
true ->
TypeInfo
end
@@ -778,6 +779,11 @@ has_undefined({type,_,union,Ts}) ->
has_undefined(_) ->
false.
+maybe_add_paren({ann_type,L,T}) ->
+ {paren_type,L,[{ann_type,L,T}]};
+maybe_add_paren(T) ->
+ T.
+
term(Expr) ->
try normalise(Expr)
catch _:_R -> ret_err(?line(Expr), "bad attribute")
diff --git a/lib/stdlib/src/erl_pp.erl b/lib/stdlib/src/erl_pp.erl
index df4a20b833..66c80a45cb 100644
--- a/lib/stdlib/src/erl_pp.erl
+++ b/lib/stdlib/src/erl_pp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -558,17 +558,11 @@ record_field({typed_record_field,{record_field,_,F,Val},Type}, Hook) ->
Fl = lexpr(F, L, Hook),
Vl = typed(lexpr(Val, R, Hook), Type),
{list,[{cstep,[Fl,' ='],Vl}]};
-record_field({typed_record_field,Field,Type0}, Hook) ->
- Type = remove_undefined(Type0),
+record_field({typed_record_field,Field,Type}, Hook) ->
typed(record_field(Field, Hook), Type);
record_field({record_field,_,F}, Hook) ->
lexpr(F, 0, Hook).
-remove_undefined({type,L,union,[{atom,_,undefined}|T]}) ->
- {type,L,union,T};
-remove_undefined(T) -> % cannot happen
- T.
-
list({cons,_,H,T}, Es, Hook) ->
list(T, [H|Es], Hook);
list({nil,_}, Es, Hook) ->
diff --git a/lib/stdlib/test/erl_pp_SUITE.erl b/lib/stdlib/test/erl_pp_SUITE.erl
index 822886cb8a..bc811355ab 100644
--- a/lib/stdlib/test/erl_pp_SUITE.erl
+++ b/lib/stdlib/test/erl_pp_SUITE.erl
@@ -48,7 +48,7 @@
neg_indent/1,
otp_6321/1, otp_6911/1, otp_6914/1, otp_8150/1, otp_8238/1,
- otp_8473/1, otp_8522/1, otp_8567/1, otp_8664/1]).
+ otp_8473/1, otp_8522/1, otp_8567/1, otp_8664/1, otp_9147/1]).
%% Internal export.
-export([ehook/6]).
@@ -79,7 +79,7 @@ groups() ->
{attributes, [], [misc_attrs, import_export]},
{tickets, [],
[otp_6321, otp_6911, otp_6914, otp_8150, otp_8238,
- otp_8473, otp_8522, otp_8567, otp_8664]}].
+ otp_8473, otp_8522, otp_8567, otp_8664, otp_9147]}].
init_per_suite(Config) ->
Config.
@@ -1047,6 +1047,26 @@ otp_8664(Config) when is_list(Config) ->
ok.
+otp_9147(doc) ->
+ "OTP_9147. Create well-formed types when adding 'undefined'.";
+otp_9147(suite) -> [];
+otp_9147(Config) when is_list(Config) ->
+ FileName = filename('otp_9147.erl', Config),
+ C1 = <<"-module(otp_9147).\n"
+ "-export_type([undef/0]).\n"
+ "-record(undef, {f1 :: F1 :: a | b}).\n"
+ "-type undef() :: #undef{}.\n">>,
+ ?line ok = file:write_file(FileName, C1),
+ ?line {ok, _, []} =
+ compile:file(FileName, [return,'P',{outdir,?privdir}]),
+ PFileName = filename('otp_9147.P', Config),
+ ?line {ok, Bin} = file:read_file(PFileName),
+ %% The parentheses around "F1 :: a | b" are new (bugfix).
+ ?line true =
+ lists:member("-record(undef,{f1 :: undefined | (F1 :: a | b)}).",
+ string:tokens(binary_to_list(Bin), "\n")),
+ ok.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
compile(Config, Tests) ->