anchor.diff:  %% self() ! {self(), ext_types, {RemMod, Name, ArgsLen}}
   %% is called, unless 'replace_by_none' is given.
   %%
  -%% It is assumed that M can be found in MR
  -
  -t_from_form({var, _L, '_'}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_any();
  -t_from_form({var, _L, Name}, _TypeNames, _ET, _M, _MR, V) ->
  +%% It is assumed that M can be found in MR.
  +
  +t_from_form(_, _TypeNames, _ET, _M, _MR, _V, D, L) when D =< 0 ; L =< 0 ->
  +  {t_any(), L};
  +t_from_form({var, _L, '_'}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_any(), L};
  +t_from_form({var, _L, Name}, _TypeNames, _ET, _M, _MR, V, _D, L) ->
     case dict:find(Name, V) of
  -    error -> t_var(Name);
  -    {ok, Val} -> Val
  -  end;
  -t_from_form({ann_type, _L, [_Var, Type]}, TypeNames, ET, M, MR, V) ->
  -  t_from_form(Type, TypeNames, ET, M, MR, V);
  -t_from_form({paren_type, _L, [Type]}, TypeNames, ET, M, MR, V) ->
  -  t_from_form(Type, TypeNames, ET, M, MR, V);
  +    error -> {t_var(Name), L};
  +    {ok, Val} -> {Val, L}
  +  end;
  +t_from_form({ann_type, _L, [_Var, Type]}, TypeNames, ET, M, MR, V, D, L) ->
  +  t_from_form(Type, TypeNames, ET, M, MR, V, D, L);
  +t_from_form({paren_type, _L, [Type]}, TypeNames, ET, M, MR, V, D, L) ->
  +  t_from_form(Type, TypeNames, ET, M, MR, V, D, L);
   t_from_form({remote_type, _L, [{atom, _, Module}, {atom, _, Type}, Args]},
  -	    TypeNames, ET, M, MR, V) ->
  -  solve_remote_type(Module, Type, Args, TypeNames, ET, M, MR, V);
  -t_from_form({atom, _L, Atom}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_atom(Atom);
  -t_from_form({integer, _L, Int}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_integer(Int);
  -t_from_form({op, _L, _Op, _Arg} = Op, _TypeNames, _ET, _M, _MR, _V) ->
  +	    TypeNames, ET, M, MR, V, D, L) ->
  +  remote_from_form(Module, Type, Args, TypeNames, ET, M, MR, V, D, L);
  +t_from_form({atom, _L, Atom}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_atom(Atom), L};
  +t_from_form({integer, _L, Int}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_integer(Int), L};
  +t_from_form({op, _L, _Op, _Arg} = Op, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
     case erl_eval:partial_eval(Op) of
       {integer, _, Val} ->
  -      t_integer(Val);
  +      {t_integer(Val), L};
       _ -> throw({error, io_lib:format("Unable to evaluate type ~w\n", [Op])})
     end;
   t_from_form({op, _L, _Op, _Arg1, _Arg2} = Op, _TypeNames,
  -            _ET, _M, _MR, _V) ->
  +            _ET, _M, _MR, _V, _D, L) ->
     case erl_eval:partial_eval(Op) of
       {integer, _, Val} ->
  -      t_integer(Val);
  +      {t_integer(Val), L};
       _ -> throw({error, io_lib:format("Unable to evaluate type ~w\n", [Op])})
     end;
  -t_from_form({type, _L, any, []}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_any();
  -t_from_form({type, _L, arity, []}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_arity();
  -t_from_form({type, _L, atom, []}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_atom();
  -t_from_form({type, _L, binary, []}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_binary();
  +t_from_form({type, _L, any, []}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_any(), L};
  +t_from_form({type, _L, arity, []}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_arity(), L};
  +t_from_form({type, _L, atom, []}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_atom(), L};
  +t_from_form({type, _L, binary, []}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_binary(), L};
   t_from_form({type, _L, binary, [Base, Unit]} = Type,
  -	    _TypeNames, _ET, _M, _MR, _V) ->
  +	    _TypeNames, _ET, _M, _MR, _V, _D, L) ->
     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);
  +      {t_bitstr(U, B), L};
       _ -> throw({error, io_lib:format("Unable to evaluate type ~w\n", [Type])})
     end;
  -t_from_form({type, _L, bitstring, []}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_bitstr();
  -t_from_form({type, _L, bool, []}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_boolean();	% XXX: Temporarily
  -t_from_form({type, _L, boolean, []}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_boolean();
  -t_from_form({type, _L, byte, []}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_byte();
  -t_from_form({type, _L, char, []}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_char();
  -t_from_form({type, _L, float, []}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_float();
  -t_from_form({type, _L, function, []}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_fun();
  -t_from_form({type, _L, 'fun', []}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_fun();
  +t_from_form({type, _L, bitstring, []}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_bitstr(), L};
  +t_from_form({type, _L, bool, []}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_boolean(), L};	% XXX: Temporarily
  +t_from_form({type, _L, boolean, []}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_boolean(), L};
  +t_from_form({type, _L, byte, []}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_byte(), L};
  +t_from_form({type, _L, char, []}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_char(), L};
  +t_from_form({type, _L, float, []}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_float(), L};
  +t_from_form({type, _L, function, []}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_fun(), L};
  +t_from_form({type, _L, 'fun', []}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_fun(), L};
   t_from_form({type, _L, 'fun', [{type, _, any}, Range]}, TypeNames,
  -            ET, M, MR, V) ->
  -  T = t_from_form(Range, TypeNames, ET, M, MR, V),
  -  t_fun(T);
  +            ET, M, MR, V, D, L) ->
  +  {T, L1} = t_from_form(Range, TypeNames, ET, M, MR, V, D - 1, L - 1),
  +  {t_fun(T), L1};
   t_from_form({type, _L, 'fun', [{type, _, product, Domain}, Range]},
  -            TypeNames, ET, M, MR, V) ->
  -  L = t_list_from_form(Domain, TypeNames, ET, M, MR, V),
  -  T = t_from_form(Range, TypeNames, ET, M, MR, V),
  -  t_fun(L, T);
  -t_from_form({type, _L, identifier, []}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_identifier();
  -t_from_form({type, _L, integer, []}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_integer();
  -t_from_form({type, _L, iodata, []}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_iodata();
  -t_from_form({type, _L, iolist, []}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_iolist();
  -t_from_form({type, _L, list, []}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_list();
  -t_from_form({type, _L, list, [Type]}, TypeNames, ET, M, MR,  V) ->
  -  T = t_from_form(Type, TypeNames, ET, M, MR, V),
  -  t_list(T);
  -t_from_form({type, _L, map, _}, TypeNames, ET, M, MR, V) ->
  -  builtin_type(map, t_map([]), TypeNames, ET, M, MR, V);
  -t_from_form({type, _L, mfa, []}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_mfa();
  -t_from_form({type, _L, module, []}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_module();
  -t_from_form({type, _L, nil, []}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_nil();
  -t_from_form({type, _L, neg_integer, []}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_neg_integer();
  +            TypeNames, ET, M, MR, V, D, L) ->
  +  {Dom1, L1} = list_from_form(Domain, TypeNames, ET, M, MR, V, D, L),
  +  {Ran1, L2} = t_from_form(Range, TypeNames, ET, M, MR, V, D - 1, L1),
  +  {t_fun(Dom1, Ran1), L2};
  +t_from_form({type, _L, identifier, []}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_identifier(), L};
  +t_from_form({type, _L, integer, []}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_integer(), L};
  +t_from_form({type, _L, iodata, []}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_iodata(), L};
  +t_from_form({type, _L, iolist, []}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_iolist(), L};
  +t_from_form({type, _L, list, []}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_list(), L};
  +t_from_form({type, _L, list, [Type]}, TypeNames, ET, M, MR, V, D, L) ->
  +  {T, L1} = t_from_form(Type, TypeNames, ET, M, MR, V, D - 1, L - 1),
  +  {t_list(T), L1};
  +t_from_form({type, _L, map, _}, TypeNames, ET, M, MR, V, D, L) ->
  +  builtin_type(map, t_map([]), TypeNames, ET, M, MR, V, D, L);
  +t_from_form({type, _L, mfa, []}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_mfa(), L};
  +t_from_form({type, _L, module, []}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_module(), L};
  +t_from_form({type, _L, nil, []}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_nil(), L};
  +t_from_form({type, _L, neg_integer, []}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_neg_integer(), L};
   t_from_form({type, _L, non_neg_integer, []}, _TypeNames, _ET, _M, _MR,
  -               _V) ->
  -  t_non_neg_integer();
  -t_from_form({type, _L, no_return, []}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_unit();
  -t_from_form({type, _L, node, []}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_node();
  -t_from_form({type, _L, none, []}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_none();
  -t_from_form({type, _L, nonempty_list, []}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_nonempty_list();
  -t_from_form({type, _L, nonempty_list, [Type]}, TypeNames, ET, M, MR, V) ->
  -  T = t_from_form(Type, TypeNames, ET, M, MR, V),
  -  t_nonempty_list(T);
  +               _V, _D, L) ->
  +  {t_non_neg_integer(), L};
  +t_from_form({type, _L, no_return, []}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_unit(), L};
  +t_from_form({type, _L, node, []}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_node(), L};
  +t_from_form({type, _L, none, []}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_none(), L};
  +t_from_form({type, _L, nonempty_list, []}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_nonempty_list(), L};
  +t_from_form({type, _L, nonempty_list, [Type]}, TypeNames, ET, M, MR, V, D, L) ->
  +  {T, L1} = t_from_form(Type, TypeNames, ET, M, MR, V, D, L - 1),
  +  {t_nonempty_list(T), L1};
   t_from_form({type, _L, nonempty_improper_list, [Cont, Term]}, TypeNames,
  -            ET, M, MR, V) ->
  -  T1 = t_from_form(Cont, TypeNames, ET, M, MR, V),
  -  T2 = t_from_form(Term, TypeNames, ET, M, MR, V),
  -  t_cons(T1, T2);
  +            ET, M, MR, V, D, L) ->
  +  {T1, L1} = t_from_form(Cont, TypeNames, ET, M, MR, V, D, L - 1),
  +  {T2, L2} = t_from_form(Term, TypeNames, ET, M, MR, V, D, L1),
  +  {t_cons(T1, T2), L2};
   t_from_form({type, _L, nonempty_maybe_improper_list, []}, _TypeNames,
  -            _ET, _M, _MR, _V) ->
  -  t_cons(?any, ?any);
  +            _ET, _M, _MR, _V, _D, L) ->
  +  {t_cons(?any, ?any), L};
   t_from_form({type, _L, nonempty_maybe_improper_list, [Cont, Term]},
  -            TypeNames, ET, M, MR, V) ->
  -  T1 = t_from_form(Cont, TypeNames, ET, M, MR, V),
  -  T2 = t_from_form(Term, TypeNames, ET, M, MR, V),
  -  t_cons(T1, T2);
  -t_from_form({type, _L, nonempty_string, []}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_nonempty_string();
  -t_from_form({type, _L, number, []}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_number();
  -t_from_form({type, _L, pid, []}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_pid();
  -t_from_form({type, _L, port, []}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_port();
  -t_from_form({type, _L, pos_integer, []}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_pos_integer();
  +            TypeNames, ET, M, MR, V, D, L) ->
  +  {T1, L1} = t_from_form(Cont, TypeNames, ET, M, MR, V, D, L - 1),
  +  {T2, L2} = t_from_form(Term, TypeNames, ET, M, MR, V, D, L1),
  +  {t_cons(T1, T2), L2};
  +t_from_form({type, _L, nonempty_string, []}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_nonempty_string(), L};
  +t_from_form({type, _L, number, []}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_number(), L};
  +t_from_form({type, _L, pid, []}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_pid(), L};
  +t_from_form({type, _L, port, []}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_port(), L};
  +t_from_form({type, _L, pos_integer, []}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_pos_integer(), L};
   t_from_form({type, _L, maybe_improper_list, []}, _TypeNames,
  -            _ET, _M, _MR, _V) ->
  -  t_maybe_improper_list();
  +            _ET, _M, _MR, _V, _D, L) ->
  +  {t_maybe_improper_list(), L};
   t_from_form({type, _L, maybe_improper_list, [Content, Termination]},
  -            TypeNames, ET, M, MR, V) ->
  -  T1 = t_from_form(Content, TypeNames, ET, M, MR, V),
  -  T2 = t_from_form(Termination, TypeNames, ET, M, MR, V),
  -  t_maybe_improper_list(T1, T2);
  -t_from_form({type, _L, product, Elements}, TypeNames, ET, M, MR, V) ->
  -  L = t_list_from_form(Elements, TypeNames, ET, M, MR, V),
  -  t_product(L);
  +            TypeNames, ET, M, MR, V, D, L) ->
  +  {T1, L1} = t_from_form(Content, TypeNames, ET, M, MR, V, D, L - 1),
  +  {T2, L2} = t_from_form(Termination, TypeNames, ET, M, MR, V, D, L1),
  +  {t_maybe_improper_list(T1, T2), L2};
  +t_from_form({type, _L, product, Elements}, TypeNames, ET, M, MR, V, D, L) ->
  +  {Lst, L1} = list_from_form(Elements, TypeNames, ET, M, MR, V, D - 1, L),
  +  {t_product(Lst), L1};
   t_from_form({type, _L, range, [From, To]} = Type,
  -	    _TypeNames, _ET, _M, _MR, _V) ->
  +	    _TypeNames, _ET, _M, _MR, _V, _D, L) ->
     case {erl_eval:partial_eval(From), erl_eval:partial_eval(To)} of
       {{integer, _, FromVal}, {integer, _, ToVal}} ->
  -      t_from_range(FromVal, ToVal);
  +      {t_from_range(FromVal, ToVal), L};
       _ -> throw({error, io_lib:format("Unable to evaluate type ~w\n", [Type])})
     end;
  -t_from_form({type, _L, record, [Name|Fields]}, TypeNames, ET, M, MR, V) ->
  -  record_from_form(Name, Fields, TypeNames, ET, M, MR, V);
  -t_from_form({type, _L, reference, []}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_reference();
  -t_from_form({type, _L, string, []}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_string();
  -t_from_form({type, _L, term, []}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_any();
  -t_from_form({type, _L, timeout, []}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_timeout();
  -t_from_form({type, _L, tuple, any}, _TypeNames, _ET, _M, _MR, _V) ->
  -  t_tuple();
  -t_from_form({type, _L, tuple, Args}, TypeNames, ET, M, MR, V) ->
  -  L = t_list_from_form(Args, TypeNames, ET, M, MR, V),
  -  t_tuple(L);
  -t_from_form({type, _L, union, Args}, TypeNames, ET, M, MR, V) ->
  -  L = t_list_from_form(Args, TypeNames, ET, M, MR, V),
  -  t_sup(L);
  -t_from_form({user_type, _L, Name, Args}, TypeNames, ET, M, MR, V) ->
  -  type_from_form(Name, Args, TypeNames, ET, M, MR, V);
  -t_from_form({type, _L, Name, Args}, TypeNames, ET, M, MR, V) ->
  +t_from_form({type, _L, record, [Name|Fields]}, TypeNames, ET, M, MR, V, D, L) ->
  +  record_from_form(Name, Fields, TypeNames, ET, M, MR, V, D, L);
  +t_from_form({type, _L, reference, []}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_reference(), L};
  +t_from_form({type, _L, string, []}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_string(), L};
  +t_from_form({type, _L, term, []}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_any(), L};
  +t_from_form({type, _L, timeout, []}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_timeout(), L};
  +t_from_form({type, _L, tuple, any}, _TypeNames, _ET, _M, _MR, _V, _D, L) ->
  +  {t_tuple(), L};
  +t_from_form({type, _L, tuple, Args}, TypeNames, ET, M, MR, V, D, L) ->
  +  {Lst, L1} = list_from_form(Args, TypeNames, ET, M, MR, V, D - 1, L),
  +  {t_tuple(Lst), L1};
  +t_from_form({type, _L, union, Args}, TypeNames, ET, M, MR, V, D, L) ->
  +  {Lst, L1} = list_from_form(Args, TypeNames, ET, M, MR, V, D, L),
  +  {t_sup(Lst), L1};
  +t_from_form({user_type, _L, Name, Args}, TypeNames, ET, M, MR, V, D, L) ->
  +  type_from_form(Name, Args, TypeNames, ET, M, MR, V, D, L);
  +t_from_form({type, _L, Name, Args}, TypeNames, ET, M, MR, V, D, L) ->
     %% Compatibility: modules compiled before Erlang/OTP 18.0.
  -  type_from_form(Name, Args, TypeNames, ET, M, MR, V);
  +  type_from_form(Name, Args, TypeNames, ET, M, MR, V, D, L);
   t_from_form({opaque, _L, Name, {Mod, Args, Rep}}, _TypeNames,
  -            _ET, _M, _MR, _V) ->
  +            _ET, _M, _MR, _V, _D, L) ->
     %% XXX. To be removed.
  -  t_opaque(Mod, Name, Args, Rep).
  -
  -builtin_type(Name, Type, TypeNames, ET, M, MR, V) ->
  +  {t_opaque(Mod, Name, Args, Rep), L}.
  +
  +builtin_type(Name, Type, TypeNames, ET, M, MR, V, D, L) ->
     case dict:find(M, MR) of
       {ok, R} ->
         case lookup_type(Name, 0, R) of
           {_, {_M, _T, _A}} ->
  -          type_from_form(Name, [], TypeNames, ET, M, MR, V);
  +          type_from_form(Name, [], TypeNames, ET, M, MR, V, D, L);
           error ->
  -          Type
  +          {Type, L}
         end;
       error ->
  -      Type
  +      {Type, L}
     end.
   
  -type_from_form(Name, Args, TypeNames, ET, M, MR, V) ->
  +type_from_form(Name, Args, TypeNames, ET, M, MR, V, D, L) ->
     ArgsLen = length(Args),
  -  ArgTypes = forms_to_types(Args, TypeNames, ET, M, MR, V),
  +  {ArgTypes, L1} = list_from_form(Args, TypeNames, ET, M, MR, V, D, L),
     {ok, R} = dict:find(M, MR),
     case lookup_type(Name, ArgsLen, R) of
       {type, {Module, Type, ArgNames}} ->
  
positive.code:      M = mod,
       D0 = dict:new(),
       MR = dict:from_list([{M, D0}]),
       T1 = t_from_form(T, [], sets:new(), M, MR, D0),
       t_to_string(T1)
    catch throw:{error, _} -> atom_to_string(Name) ++ "()"
    end;
  
negative.code:   case lists:any(fun is_any/1, Ts) of
      true -> ?any;
      false ->
        t_sup1(Ts, [])
    end.
  
  t_sup1([H1, H2|T], L) ->
  