anchor.diff:          {Is,Ts,Ds,Fdb,Sub} ->
               D1 = D0#d{ds=Ds,sub=Sub,func_db=Fdb},
               Last1 = simplify_terminator(Last0, Sub, Ts, Ds),
  -            Last = opt_terminator(Last1, Ts, Ds),
  -            D = update_successors(Last, Ts, D1),
  +            Last2 = opt_terminator(Last1, Ts, Ds),
  +            {Last,D} = update_successors(Last2, Ts, D1),
               Blk = Blk0#b_blk{is=Is,last=Last},
               opt(Bs, D, [{L,Blk}|Acc]);
           {no_return,Ret,Is,Ds,Fdb,Sub} ->
  
positive.code:     end;
  prune_switch_list([], _, _, _) -> [].
  
  update_successors(#b_br{bool=#b_literal{val=true},succ=S}, Ts, D) ->
      update_successor(S, Ts, D);
  update_successors(#b_br{bool=#b_var{}=Bool,succ=Succ,fail=Fail}, Ts0, D0) ->
      case cerl_sets:is_element(Bool, D0#d.once) of
          true ->
              %% This variable is defined in this block and is only
              %% referenced by this br terminator. Therefore, there is
              %% no need to include it in the type database passed on to
              %% the successors of this block.
              Ts = maps:remove(Bool, Ts0),
              {SuccTs,FailTs} = infer_types_br(Bool, Ts, D0),
              D = update_successor(Fail, FailTs, D0),
              update_successor(Succ, SuccTs, D);
          false ->
              {SuccTs,FailTs} = infer_types_br(Bool, Ts0, D0),
              D = update_successor_bool(Bool, false, Fail, FailTs, D0),
              update_successor_bool(Bool, true, Succ, SuccTs, D)
      end;
  update_successors(#b_switch{arg=#b_var{}=V,fail=Fail,list=List}, Ts, D0) ->
      case cerl_sets:is_element(V, D0#d.once) of
          true ->
              %% This variable is defined in this block and is only
              %% referenced by this switch terminator. Therefore, there is
              %% no need to include it in the type database passed on to
              %% the successors of this block.
              D = update_successor(Fail, Ts, D0),
              F = fun({Val,S}, A) ->
                          SuccTs0 = infer_types_switch(V, Val, Ts, D),
                          SuccTs = maps:remove(V, SuccTs0),
                          update_successor(S, SuccTs, A)
                  end,
              foldl(F, D, List);
          false ->
              %% V can not be equal to any of the values in List at the fail
              %% block.
              FailTs = subtract_sw_list(V, List, Ts),
              D = update_successor(Fail, FailTs, D0),
              F = fun({Val,S}, A) ->
                          SuccTs = infer_types_switch(V, Val, Ts, D),
                          update_successor(S, SuccTs, A)
                  end,
              foldl(F, D, List)
      end;
  update_successors(#b_ret{arg=Arg}, Ts, D) ->
      FuncId = D#d.func_id,
      case D#d.ds of
          #{ Arg := #b_set{op=call,args=[FuncId | _]} } ->
              %% Returning a call to ourselves doesn't affect our own return
              %% type.
              D;
          #{} ->
              RetType = beam_types:join([get_type(Arg, Ts) | D#d.ret_type]),
              D#d{ret_type=[RetType]}
      end.
  
  subtract_sw_list(V, List, Ts) ->
      Ts#{ V := sub_sw_list_1(get_type(V, Ts), List, Ts) }.
  
  sub_sw_list_1(Type, [{Val,_}|T], Ts) ->
      ValType = get_type(Val, Ts),
      sub_sw_list_1(beam_types:subtract(Type, ValType), T, Ts);
  sub_sw_list_1(Type, [], _Ts) ->
      Type.
  
  update_successor_bool(#b_var{}=Var, BoolValue, S, Ts, D) ->
      case beam_types:is_boolean_type(get_type(Var, Ts)) of
          true ->
              update_successor(S, Ts#{ Var := beam_types:make_atom(BoolValue) }, D);
          false ->
              %% The `br` terminator is preceeded by an instruction that
              %% does not produce a boolean value, such a `new_try_tag`.
              update_successor(S, Ts, D)
      end.
  
  update_successor(?BADARG_BLOCK, _Ts, #d{}=D) ->
      %% We KNOW that no variables are used in the ?BADARG_BLOCK,
  
negative.code: subtract_types([{V,T0}|Vs], Ts) ->
      #{V:=T1} = Ts,
      case beam_types:subtract(T1, T0) of
          none -> none;
          T1 -> subtract_types(Vs, Ts);
          T -> subtract_types(Vs, Ts#{V:=T})
      end;
  subtract_types([], Ts) -> Ts.
  
  