module T::Private::Abstract::Validate

def self.validate_subclass(mod)

after all methods on `mod` have been defined.
Validates a class/module with an abstract class/module as an ancestor. This must be called
def self.validate_subclass(mod)
  can_have_abstract_methods = !T::Private::Abstract::Data.get(mod, :can_have_abstract_methods)
  unimplemented_methods = []
  T::AbstractUtils.declared_abstract_methods_for(mod).each do |abstract_method|
    implementation_method = mod.instance_method(abstract_method.name)
    if AbstractUtils.abstract_method?(implementation_method)
      # Note that when we end up here, implementation_method might not be the same as
      # abstract_method; the latter could've been overridden by another abstract method. In either
      # case, if we have a concrete definition in an ancestor, that will end up as the effective
      # implementation (see CallValidation.wrap_method_if_needed), so that's what we'll validate
      # against.
      implementation_method = T.unsafe(nil)
      mod.ancestors.each do |ancestor|
        if ancestor.instance_methods.include?(abstract_method.name)
          method = ancestor.instance_method(abstract_method.name)
          T::Private::Methods.maybe_run_sig_block_for_method(method)
          if !T::AbstractUtils.abstract_method?(method)
            implementation_method = method
            break
          end
        end
      end
      if !implementation_method
        # There's no implementation
        if can_have_abstract_methods
          unimplemented_methods << describe_method(abstract_method)
        end
        next # Nothing to validate
      end
    end
    implementation_signature = Methods.signature_for_method(implementation_method)
    # When a signature exists and the method is defined directly on `mod`, we skip the validation
    # here, because it will have already been done when the method was defined (by
    # T::Private::Methods._on_method_added).
    next if implementation_signature&.owner == mod
    # We validate the remaining cases here: (a) methods defined directly on `mod` without a
    # signature and (b) methods from ancestors (note that these ancestors can come before or
    # after the abstract module in the inheritance chain -- the former coming from
    # walking `mod.ancestors` above).
    abstract_signature = Methods.signature_for_method(abstract_method)
    # We allow implementation methods to be defined without a signature.
    # In that case, get its untyped signature.
    implementation_signature ||= Methods::Signature.new_untyped(
      method: implementation_method,
      mode: Methods::Modes.override
    )
    SignatureValidation.validate_override_shape(implementation_signature, abstract_signature)
    SignatureValidation.validate_override_types(implementation_signature, abstract_signature)
  end
  method_type = mod.singleton_class? ? "class" : "instance"
  if !unimplemented_methods.empty?
    raise "Missing implementation for abstract #{method_type} method(s) in #{mod}:\n" \
          "#{unimplemented_methods.join("\n")}\n" \
          "If #{mod} is meant to be an abstract class/module, you can call " \
          "`abstract!` or `interface!`. Otherwise, you must implement the method(s)."
  end
end