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
-
.lookup(name) ⇒ Rigor::Type?
Refined type, or nil to fall through.
Class Method Details
.lookup(name) ⇒ Rigor::Type?
Returns 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 |