anchor.diff:  meet_types([{V,T0}|Vs], Ts) ->
       #{V:=T1} = Ts,
       case beam_types:meet(T0, T1) of
  +        none -> none;
           T1 -> meet_types(Vs, Ts);
           T -> meet_types(Vs, Ts#{V:=T})
       end;
  
positive.code:     NegTypes1 = [P || {_,T}=P <- EqTypes, beam_types:is_singleton_type(T)],
  
      PosTypes = EqTypes ++ PosTypes0,
      SuccTs = meet_types(PosTypes, Ts),
  
      NegTypes = NegTypes0 ++ NegTypes1,
      FailTs = subtract_types(NegTypes, Ts),
  
      {SuccTs,FailTs}.
  
  infer_types_switch(V, Lit, Ts, #d{ds=Ds}) ->
      Types = infer_eq_type({bif,'=:='}, [V, Lit], Ts, Ds),
  
negative.code:     end;
  prune_switch_list([], _, _, _) -> [].
  
  update_successors(#b_br{bool=#b_literal{val=true},succ=Succ}=Last, Ts, D0) ->
      {Last, update_successor(Succ, Ts, D0)};
  update_successors(#b_br{bool=#b_var{}=Bool,succ=Succ,fail=Fail}=Last0,
                    Ts0, D0) ->
      Ts = 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.
                   maps:remove(Bool, Ts0);
               false ->
                   Ts0
           end,
      case infer_types_br(Bool, Ts, D0) of
          {#{}=SuccTs, #{}=FailTs} ->
              D1 = update_successor(Succ, SuccTs, D0),
              D = update_successor(Fail, FailTs, D1),
              {Last0, D};
          {#{}=SuccTs, none} ->
              Last = Last0#b_br{bool=#b_literal{val=true},fail=Succ},
              {Last, update_successor(Succ, SuccTs, D0)};
          {none, #{}=FailTs} ->
              Last = Last0#b_br{bool=#b_literal{val=true},succ=Fail},
              {Last, update_successor(Fail, FailTs, D0)}
      end;
  update_successors(#b_switch{arg=#b_var{}=V,fail=Fail0,list=List0}=Last0,
                    Ts, D0) ->
      UsedOnce = cerl_sets:is_element(V, D0#d.once),
  
      {List1, D1} = update_switch(List0, V, UsedOnce, Ts, [], D0),
  
      FailTs = case UsedOnce of
                   true -> maps:remove(V, Ts);
                   false -> subtract_sw_list(V, List0, Ts)
               end,
  
      case FailTs of
          none ->
              [{_, Fail} | List] = List1,
              Last = Last0#b_switch{fail=Fail,list=List},
              {Last, D1};
          #{} ->
              D = update_successor(Fail0, FailTs, D1),
              Last = Last0#b_switch{list=List1},
              {Last, D}
      end;
  update_successors(#b_ret{arg=Arg}=Last, Ts, D0) ->
      FuncId = D0#d.func_id,
      D = case D0#d.ds of
              #{ Arg := #b_set{op=call,args=[FuncId | _]} } ->
                  %% Returning a call to ourselves doesn't affect our own return
                  %% type.
                  D0;
              #{} ->
                  RetType = beam_types:join([get_type(Arg, Ts) | D0#d.ret_type]),
                  D0#d{ret_type=[RetType]}
          end,
      {Last, D}.
  
  update_switch([{Val, Lbl}=Sw | List], V, UsedOnce, Ts, Acc, D0) ->
      case infer_types_switch(V, Val, Ts, D0) of
          none ->
              update_switch(List, V, UsedOnce, Ts, Acc, D0);
          SwTs0 ->
              SwTs = case UsedOnce of
                         true -> maps:remove(V, SwTs0);
                         false -> SwTs0
                     end,
              D = update_successor(Lbl, SwTs, D0),
              update_switch(List, V, UsedOnce, Ts, [Sw | Acc], D)
      end;
  update_switch([], _V, _UsedOnce, _Ts, Acc, D) ->
      {Acc, D}.
  
  subtract_sw_list(V, List, Ts) ->
      case sub_sw_list_1(get_type(V, Ts), List, Ts) of
          none -> none;
          Type -> Ts#{ V := Type }
      end.
  
  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(?BADARG_BLOCK, _Ts, #d{}=D) ->
      %% We KNOW that no variables are used in the ?BADARG_BLOCK,
  