anchor.diff:  
   %% Match context type.
   -record(ms,
  -        {id=make_ref() :: reference(),          %Unique ID.
  -         valid=0 :: non_neg_integer(),          %Valid slots
  +        {valid=0 :: non_neg_integer(),          %Valid slots
            slots=0 :: non_neg_integer()           %Number of slots
           }).
   
  
positive.code: 
  verify_local_args(-1, _Lbl, _CtxIds, _Vst) ->
      ok;
  verify_local_args(X, Lbl, CtxIds, Vst) ->
      Reg = {x, X},
      assert_not_fragile(Reg, Vst),
      case get_movable_term_type(Reg, Vst) of
          #ms{id=Id}=Type ->
              case CtxIds of
                  #{ Id := Other } ->
                      error({multiple_match_contexts, [Reg, Other]});
                  #{} ->
                      verify_arg_type(Lbl, Reg, Type, Vst),
                      verify_local_args(X - 1, Lbl, CtxIds#{ Id => Reg }, Vst)
              end;
          Type ->
              verify_arg_type(Lbl, Reg, Type, Vst),
              verify_local_args(X - 1, Lbl, CtxIds, Vst)
      end.
  
  %% Verifies that the given argument narrows to what the function expects.
  
negative.code:     bool;
  join({atom,_}, {atom,_}) ->
      {atom,[]};
  join(#ms{valid=B1,slots=Slots1},
       #ms{valid=B2,slots=Slots2}) ->
      #ms{valid=B1 band B2,slots=min(Slots1, Slots2)};
  join(T1, T2) when T1 =/= T2 ->
      %% We've exhaused all other options, so the type must either be a list or
      %% a 'term'.
  