module T::Private::Methods::SignatureValidation

def self.validate_override_shape(signature, super_signature)

def self.validate_override_shape(signature, super_signature)
  return if signature.override_allow_incompatible
  return if super_signature.mode == Modes.untyped
  method_name = signature.method_name
  mode_verb = super_signature.mode == Modes.abstract ? 'implements' : 'overrides'
  if !signature.has_rest && signature.arg_count < super_signature.arg_count
    raise "Your definition of `#{method_name}` must accept at least #{super_signature.arg_count} " \
          "positional arguments to be compatible with the method it #{mode_verb}: " \
          "#{base_override_loc_str(signature, super_signature)}"
  end
  if !signature.has_rest && super_signature.has_rest
    raise "Your definition of `#{method_name}` must have `*#{super_signature.rest_name}` " \
          "to be compatible with the method it #{mode_verb}: " \
          "#{base_override_loc_str(signature, super_signature)}"
  end
  if signature.req_arg_count > super_signature.req_arg_count
    raise "Your definition of `#{method_name}` must have no more than #{super_signature.req_arg_count} " \
          "required argument(s) to be compatible with the method it #{mode_verb}: " \
          "#{base_override_loc_str(signature, super_signature)}"
  end
  if !signature.has_keyrest
    # O(nm), but n and m are tiny here
    missing_kwargs = super_signature.kwarg_names - signature.kwarg_names
    if !missing_kwargs.empty?
      raise "Your definition of `#{method_name}` is missing these keyword arg(s): #{missing_kwargs} " \
            "which are defined in the method it #{mode_verb}: " \
            "#{base_override_loc_str(signature, super_signature)}"
    end
  end
  if !signature.has_keyrest && super_signature.has_keyrest
    raise "Your definition of `#{method_name}` must have `**#{super_signature.keyrest_name}` " \
          "to be compatible with the method it #{mode_verb}: " \
          "#{base_override_loc_str(signature, super_signature)}"
  end
  # O(nm), but n and m are tiny here
  extra_req_kwargs = signature.req_kwarg_names - super_signature.req_kwarg_names
  if !extra_req_kwargs.empty?
    raise "Your definition of `#{method_name}` has extra required keyword arg(s) " \
          "#{extra_req_kwargs} relative to the method it #{mode_verb}, making it incompatible: " \
          "#{base_override_loc_str(signature, super_signature)}"
  end
  if super_signature.block_name && !signature.block_name
    raise "Your definition of `#{method_name}` must accept a block parameter to be compatible " \
          "with the method it #{mode_verb}: " \
          "#{base_override_loc_str(signature, super_signature)}"
  end
end