Module: Rigor::Inference::Acceptance

Defined in:
lib/rigor/inference/acceptance.rb,
sig/rigor/inference.rbs

Overview

Shared dispatch table for Rigor::Type#accepts(other, mode:).

The acceptance query answers "is other passable to self at a method-parameter or assignment boundary?". It uses gradual-typing rules from docs/type-specification/value-lattice.md and the acceptance contract in docs/internal-spec/internal-type-api.md.

Each concrete type's accepts method delegates here so the case-analysis stays in one place. Type instances remain thin value objects; routing logic lives in the inference layer.

Slice 4 phase 2c implements the :gradual mode in full and reserves :strict for later slices (the entry point raises ArgumentError on strict for now). The table covers the leaf and combinator types added through phase 2b: Top, Bot, Dynamic, Nominal, Singleton, Constant, and Union.

Slice 5 registers the shape carriers Tuple and HashShape. Tuple/HashShape acceptance compares per-position element types (covariant) and per-key entry types (depth covariant), including HashShape required/optional/closed-extra-key policy. When the receiver side is a generic Nominal[Array, [E]] or Nominal[Hash, [K, V]] the shape is projected to its underlying nominal so the existing generic-acceptance pipeline continues to apply; the converse direction (a Tuple receiver accepting a generic Array) stays conservative because the analyzer cannot verify arity from a raw nominal alone. rubocop:disable Metrics/ModuleLength

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.accepts(self_type, other_type, mode: :gradual) ⇒ Rigor::Type::AcceptsResult

Parameters:

  • self_type (Rigor::Type)
  • other_type (Rigor::Type)
  • mode (Symbol) (defaults to: :gradual)

    :gradual (default) or :strict.

Returns:

Raises:

  • (ArgumentError)


34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/rigor/inference/acceptance.rb', line 34

def accepts(self_type, other_type, mode: :gradual)
  raise ArgumentError, "Acceptance mode #{mode.inspect} is not implemented yet" unless mode == :gradual

  return Type::AcceptsResult.yes(mode: mode, reasons: "Bot is the empty type") if other_type.is_a?(Type::Bot)
  if other_type.is_a?(Type::Dynamic)
    return Type::AcceptsResult.yes(mode: mode, reasons: "gradual: Dynamic[T] passes any boundary")
  end

  # Structural equality short-circuit. Two identical carriers describe the same value set, so they always
  # accept each other. This is sound for any mode and covers cases where neither side has a per-class rule
  # for the other's exact carrier kind (the canonical example is `Intersection.accepts(Intersection)`,
  # where the disjunction rule below would otherwise reject equal-but-narrow LHSes).
  return Type::AcceptsResult.yes(mode: mode, reasons: "structural equality") if self_type == other_type

  return accepts_union_other(self_type, other_type, mode) if other_type.is_a?(Type::Union)
  return accepts_intersection_other(self_type, other_type, mode) if other_type.is_a?(Type::Intersection)

  accepts_one(self_type, other_type, mode)
end

Instance Method Details

#self?.acceptsType::AcceptsResult

Parameters:

  • self_type (Type::t)
  • other_type (Type::t)
  • mode: (Type::accepts_mode)

Returns:



132
# File 'sig/rigor/inference.rbs', line 132

def self?.accepts: (Type::t self_type, Type::t other_type, ?mode: Type::accepts_mode) -> Type::AcceptsResult