Module: Rigor::Builtins::PredefinedConstantRefinements

Defined in:
lib/rigor/builtins/predefined_constant_refinements.rb

Overview

Refined types for predefined Ruby / stdlib constants whose upstream RBS signatures are broader than the constants' documented runtime invariants.

Resolution is two-tiered:

Tier 1 — exact-value whitelist (FOLDED_CONSTANTS): Constants whose value is bit-for-bit identical across every Ruby version and platform are folded to Constant[T]: the Math::PI / Math::E math constants (C's M_PI / M_E) and the four IEEE 754 binary64 magnitude constants Float::INFINITY / ::MAX / ::MIN / ::EPSILON (each a single format-mandated bit pattern). Add new entries only when the value is truly cross-implementation invariant AND compares reflexively under == — the latter is why Float::NAN is deliberately EXCLUDED: NaN == NaN is false, so a Constant[NAN] would violate the Type::Constant == / eql? / hash contract (it would hash equal to itself yet compare unequal), corrupting type-equality and union dedup. The binary64 integer shape parameters (Float::DIG / MANT_DIG / MAX_EXP / …) are intentionally NOT folded: upstream RBS hedges them as "Usually defaults to …", and as plain Integers they fall through Tier 2 to the RBS type harmlessly. Complex::I is deferred (no complex-fold consumer).

Tier 2 — runtime String inspection: For any other constant, the module resolves it via const_get against the analyzer's own Ruby runtime. Core / stdlib constants (e.g. RUBY_VERSION, RUBY_PLATFORM) are always loaded into the analyzer process; project-defined constants are not (they live only in ASTs), so their const_get raises NameError and the lookup falls through to the RBS type tier.

For a successfully resolved String value:

  • empty string → no refinement (fall through to RBS String)
  • a Ruby numeric literal → numeric-string
  • non-empty otherwise → non-empty-string

Exclusion set (RUNTIME_INSPECTION_EXCLUDED): String constants that appear non-empty in the current runtime but are documented to be potentially empty in some build configuration or alternative implementation. Exclusions are populated by scanning Ruby's C source (version.c, etc.) and RBS comments for any constant whose documentation says "may be empty" or "platform-specific default". None are known today; the set exists as a safety net.

This module is consulted by Environment#constant_for_name BEFORE the RBS constant-type table (widest types) but AFTER in-source constant writes (the user's own Math::PI = 0.0 takes precedence via the lexical-candidate walk in ExpressionTyper).

Class Method Summary collapse

Class Method Details

.lookup(name) ⇒ Rigor::Type?

Returns refined type, or nil to fall through.

Parameters:

  • name (String)

    unqualified constant name (e.g. "Math::PI", "RUBY_VERSION", "Ruby::ENGINE")

Returns:

  • (Rigor::Type, nil)

    refined type, or nil to fall through



90
91
92
# File 'lib/rigor/builtins/predefined_constant_refinements.rb', line 90

def self.lookup(name)
  FOLDED_CONSTANTS[name] || inspect_runtime_string(name)
end