Skip to content

RBS-Compatible Types

Rigor supports every type form documented by RBS syntax. This document is the authoritative table mapping RBS forms to Rigor’s interpretation and to their RBS erasure.

The exhaustive erasure rules, including the hash-shape erasure algorithm, are in rbs-erasure.md. Rigor-only forms that exceed RBS are listed in rigor-extensions.md. Reserved built-in refinement names are in imported-built-in-types.md.

RBS formRigor interpretationRBS erasure
C, C[A]Nominal instance typeSame
_I, _I[A]Interface typeSame
alias, alias[A]Alias reference, expanded on demandSame or expanded alias
singleton(C)Singleton class object typeSame
string, symbol, integer, true, false literalLiteral singleton typeSame
A | BUnion typeSame after erased operands
A & BIntersection typeSame after erased operands
T?T | nilOptional syntax when valid, otherwise union
{ key: T }Hash record with known keysSame
[A, B]Array tuple with fixed aritySame
type variableScoped type variable with bounds and varianceSame
selfOpen-recursive receiver type in self-contextSame when the RBS context allows it
instanceCurrent class instance type in classish-contextSame when the RBS context allows it
classCurrent class singleton type in classish-contextSame when the RBS context allows it
boolAlias for true | falsebool
nilThe singleton nil valuenil
untypedDynamic typeuntyped
topGreatest static value typetop
botEmpty typebot
voidReturn-position no-use result markervoid where valid, otherwise top with a diagnostic
proc typeCallable object typeSame after erased operands

self, instance, class, and void have context restrictions in RBS. Rigor MAY carry richer contextual information internally, but exported RBS MUST obey those restrictions.

  • self, instance, class: valid only in their respective classish or self contexts. Rigor MUST emit them only where RBS accepts them.
  • void: valid in method and proc return positions and in generic slots that carry it from imported signatures. See special-types.md for the value-context rule and the imported-RBS rule.

If an internal type contains one of these markers in an invalid RBS context, the erasure pass MUST rewrite it to the nearest valid conservative type and report the loss of precision. The diagnostic policy for precision loss during export is in diagnostic-policy.md.

T? is normalized to T | nil internally (see normalization.md). On export, Rigor SHOULD prefer the T? syntax when valid; otherwise it falls back to the explicit union.

RBS records ({ key: T }) and tuples ([A, B]) are accepted as exact forms. Rigor’s internal hash and array shapes (see structural-interfaces-and-object-shapes.md) extend these RBS forms with required/optional/extra-key policies and read-only markers; those extensions erase deterministically (see rbs-erasure.md).

Type variable bounds and declaration-site variance from RBS are preserved. Generic preservation through method bodies — for example inferring [S < _RewindableStream] (S stream) -> S when a method returns the same parameter object it received — is a Rigor inference behavior, not a new surface form. See structural-interfaces-and-object-shapes.md.

bool is the literal alias for true | false. Ruby truthiness accepts any value, and Rigor models truthiness as a flow predicate, not by widening to bool. See special-types.md and control-flow-analysis.md.

untyped is preserved at the RBS boundary in both directions. The internal precise representation is Dynamic[top], with full algebra in value-lattice.md. The round-trip from RBS to Rigor and back is exact.

© 2026 TypedDuck. Licensed under CC BY-SA 4.0.