class Steep::TypeInference::SendArgs

def zip0(params, block_type)

def zip0(params, block_type)
  case
  when params.empty? && args.empty?
    [[]]
  when params.required.any?
    if args.any?
      first_arg = args[0]
      case first_arg.type
      when :splat
        []
      else
        rest = drop_first.zip0(params.drop_first, block_type)
        pair = [first_arg, params.required[0]]
        add_pair(rest, pair)
      end
    else
      []
    end
  when params.has_keywords? && params.required_keywords.any?
    if args.any?
      rest = drop_last.zip0(params.without_keywords, block_type)
      last_arg = args.last
      return [] if last_arg.type == :splat
      add_pair(rest, last_arg) do |ps, p|
        ps + [p]
      end
    else
      []
    end
  when params.has_keywords? && params.required_keywords.empty?
    if args.any?
      rest = drop_last.zip0(params.without_keywords, block_type)
      last_arg = args.last
      no_keyword = zip0(params.without_keywords, block_type)
      if last_arg.type == :splat
        no_keyword
      else
        add_pair(rest, last_arg) do |ps, p|
          ps + [p]
        end + no_keyword
      end
    else
      zip0(params.without_keywords, block_type)
    end
  when params.optional.any?
    if args.any?
      first_arg = args[0]
      case first_arg.type
      when :splat
        rest = zip0(params.drop_first, block_type)
        pair = [args[0], AST::Builtin::Array.instance_type(params.optional[0])]
      else
        rest = drop_first.zip0(params.drop_first, block_type)
        pair = [args[0], params.optional[0]]
      end
      add_pair(rest, pair)
    else
      zip0(params.drop_first, block_type)
    end
  when params.rest
    if args.any?
      rest = drop_first.zip0(params, block_type)
      first_arg = args[0]
      case first_arg.type
      when :splat
        pair = [first_arg, AST::Builtin::Array.instance_type(params.rest)]
      else
        pair = [first_arg, params.rest]
      end
      add_pair(rest, pair)
    else
      zip0(params.drop_first, block_type)
    end
  else
    []
  end
end