module T::Private::Methods::CallValidation

def self.create_validator_procedure_fast3(mod, original_method, method_sig, arg0_type, arg1_type, arg2_type)

def self.create_validator_procedure_fast3(mod, original_method, method_sig, arg0_type, arg1_type, arg2_type)
  mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, &blk|
    # This block is called for every `sig`. It's critical to keep it fast and
    # reduce number of allocations that happen here.
    # This method is a manually sped-up version of more general code in `validate_call`
    if method_sig.ever_failed && method_sig.generated
      return original_method.bind(self).call(arg0, arg1, arg2, &blk)
    end
    T::Profile.typecheck_sample_attempts -= 1
    should_sample = T::Profile.typecheck_sample_attempts == 0
    if should_sample
      T::Profile.typecheck_sample_attempts = T::Profile::SAMPLE_RATE
      T::Profile.typecheck_samples += 1
      t1 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
    end
    if method_sig.bind
      message = method_sig.bind.error_message_for_obj(self)
      if message
        CallValidation.report_error(
          method_sig,
          message,
          'Bind',
          nil,
          method_sig.bind,
          self
        )
      end
    end
    unless arg0.is_a?(arg0_type)
      CallValidation.report_error(
        method_sig,
        method_sig.arg_types[0][1].error_message_for_obj(arg0),
        'Parameter',
        method_sig.arg_types[0][0],
        arg0_type,
        arg0,
        caller_offset: -1
      )
    end
    unless arg1.is_a?(arg1_type)
      CallValidation.report_error(
        method_sig,
        method_sig.arg_types[1][1].error_message_for_obj(arg1),
        'Parameter',
        method_sig.arg_types[1][0],
        arg1_type,
        arg1,
        caller_offset: -1
      )
    end
    unless arg2.is_a?(arg2_type)
      CallValidation.report_error(
        method_sig,
        method_sig.arg_types[2][1].error_message_for_obj(arg2),
        'Parameter',
        method_sig.arg_types[2][0],
        arg2_type,
        arg2,
        caller_offset: -1
      )
    end
    if should_sample
      T::Profile.typecheck_duration += (Process.clock_gettime(Process::CLOCK_MONOTONIC) - t1)
    end
    # The following line breaks are intentional to show nice pry message
    # PRY note:
    # this code is sig validation code.
    # Please issue `finish` to step out of it
    original_method.bind(self).call(arg0, arg1, arg2, &blk)
    T::Private::Types::Void::VOID
  end
end