class Steep::Subtyping::Check

def match_params(name, relation)

def match_params(name, relation)
  relation.params!
  sub_params, super_params = relation
  pairs = []
  sub_flat = sub_params.flat_unnamed_params
  sup_flat = super_params.flat_unnamed_params
  failure = Failure(relation, Result::Failure::ParameterMismatchError.new(name: name))
  case
  when super_params.rest
    return failure unless sub_params.rest
    while sub_flat.size > 0
      sub_type = sub_flat.shift
      sup_type = sup_flat.shift
      if sup_type
        pairs << [sub_type.last, sup_type.last]
      else
        pairs << [sub_type.last, super_params.rest]
      end
    end
    if sub_params.rest
      pairs << [sub_params.rest, super_params.rest]
    end
  when sub_params.rest
    while sub_flat.size > 0
      sub_type = sub_flat.shift
      sup_type = sup_flat.shift
      if sup_type
        pairs << [sub_type.last, sup_type.last]
      else
        break
      end
    end
    if sub_params.rest && !sup_flat.empty?
      sup_flat.each do |sup_type|
        pairs << [sub_params.rest, sup_type.last]
      end
    end
  when sub_params.required.size + sub_params.optional.size >= super_params.required.size + super_params.optional.size
    while sub_flat.size > 0
      sub_type = sub_flat.shift
      sup_type = sup_flat.shift
      if sup_type
        pairs << [sub_type.last, sup_type.last]
      else
        if sub_type.first == :required
          return failure
        else
          break
        end
      end
    end
  else
    return failure
  end
  sub_flat_kws = sub_params.flat_keywords
  sup_flat_kws = super_params.flat_keywords
  sup_flat_kws.each do |name, _|
    if sub_flat_kws.key?(name)
      pairs << [sub_flat_kws[name], sup_flat_kws[name]]
    else
      if sub_params.rest_keywords
        pairs << [sub_params.rest_keywords, sup_flat_kws[name]]
      else
        return failure
      end
    end
  end
  sub_params.required_keywords.each do |name, _|
    unless super_params.required_keywords.key?(name)
      return failure
    end
  end
  if sub_params.rest_keywords && super_params.rest_keywords
    pairs << [sub_params.rest_keywords, super_params.rest_keywords]
  end
  pairs
end