Module: Rigor::Inference::Acceptance
- Defined in:
- lib/rigor/inference/acceptance.rb
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
Class Method Details
.accepts(self_type, other_type, mode: :gradual) ⇒ Rigor::Type::AcceptsResult
43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/rigor/inference/acceptance.rb', line 43 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 return accepts_union_other(self_type, other_type, mode) if other_type.is_a?(Type::Union) accepts_one(self_type, other_type, mode) end |