aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSvilen Ivanov <[email protected]>2017-06-17 15:16:50 +0300
committerHans Bolinder <[email protected]>2017-06-26 12:14:17 +0200
commit83eda421d5da52328f5c5f552967591e22a0695e (patch)
treebe5279526387644be968dc1090c85b07045297ef
parentbd2752e3d2ec91572e4d0c2fb35951f8f6bdc9f6 (diff)
downloadotp-83eda421d5da52328f5c5f552967591e22a0695e.tar.gz
otp-83eda421d5da52328f5c5f552967591e22a0695e.tar.bz2
otp-83eda421d5da52328f5c5f552967591e22a0695e.zip
Fix infinite loop in shell caused by record with recursive typespec
If record with recursive typespec such as -record(r,{f :: #r{} | undefined}). is used in interactive shell it stucks in inifinite loop when trying to find definitions for all records used in expression.
-rw-r--r--lib/stdlib/src/shell.erl16
1 files changed, 11 insertions, 5 deletions
diff --git a/lib/stdlib/src/shell.erl b/lib/stdlib/src/shell.erl
index 6eafc7b209..26b3960f4f 100644
--- a/lib/stdlib/src/shell.erl
+++ b/lib/stdlib/src/shell.erl
@@ -727,7 +727,7 @@ result_will_be_saved() ->
used_record_defs(E, RT) ->
%% Be careful to return a list where used records come before
%% records that use them. The linter wants them ordered that way.
- UR = case used_records(E, [], RT) of
+ UR = case used_records(E, [], RT, []) of
[] ->
[];
L0 ->
@@ -737,13 +737,19 @@ used_record_defs(E, RT) ->
end,
record_defs(RT, UR).
-used_records(E, U0, RT) ->
+used_records(E, U0, RT, Skip) ->
case used_records(E) of
{name,Name,E1} ->
- U = used_records(ets:lookup(RT, Name), [Name | U0], RT),
- used_records(E1, U, RT);
+ U = case lists:member(Name, Skip) of
+ true ->
+ U0;
+ false ->
+ R = ets:lookup(RT, Name),
+ used_records(R, [Name | U0], RT, [Name | Skip])
+ end,
+ used_records(E1, U, RT, Skip);
{expr,[E1 | Es]} ->
- used_records(Es, used_records(E1, U0, RT), RT);
+ used_records(Es, used_records(E1, U0, RT, Skip), RT, Skip);
_ ->
U0
end.