rigortype 0.3.6 → 0.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (213) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/data/builtins/ruby_core/date.yml +6 -3
  4. data/data/builtins/ruby_core/enumerable.yml +1 -0
  5. data/data/builtins/ruby_core/exception.yml +2 -1
  6. data/data/builtins/ruby_core/file.yml +28 -14
  7. data/data/builtins/ruby_core/hash.yml +5 -2
  8. data/data/builtins/ruby_core/io.yml +33 -16
  9. data/data/builtins/ruby_core/random.yml +2 -1
  10. data/data/builtins/ruby_core/re.yml +6 -3
  11. data/data/builtins/ruby_core/struct.yml +2 -0
  12. data/data/builtins/ruby_core/time.yml +2 -1
  13. data/data/gem_overlay/activesupport/core_ext.rbs +409 -11
  14. data/docs/manual/02-cli-reference.md +16 -7
  15. data/docs/manual/05-inspecting-types.md +20 -8
  16. data/docs/manual/07-plugins.md +4 -0
  17. data/docs/manual/plugins/rigor-actionpack.md +61 -0
  18. data/docs/manual/plugins/rigor-activerecord.md +74 -1
  19. data/docs/manual/plugins/rigor-activesupport-core-ext.md +114 -12
  20. data/docs/manual/plugins/rigor-sidekiq.md +22 -0
  21. data/lib/rigor/analysis/check_rules/always_truthy_condition_collector.rb +12 -0
  22. data/lib/rigor/analysis/check_rules/dead_version_guard_arms.rb +98 -0
  23. data/lib/rigor/analysis/check_rules/ivar_write_collector.rb +3 -3
  24. data/lib/rigor/analysis/check_rules/published_constant_guard.rb +199 -0
  25. data/lib/rigor/analysis/check_rules/rule_walk.rb +1 -2
  26. data/lib/rigor/analysis/check_rules/self_closedness_scanner.rb +2 -2
  27. data/lib/rigor/analysis/check_rules/shadowed_rescue_collector.rb +6 -12
  28. data/lib/rigor/analysis/check_rules.rb +383 -48
  29. data/lib/rigor/analysis/crash_signature.rb +116 -0
  30. data/lib/rigor/analysis/dependency_recorder.rb +18 -3
  31. data/lib/rigor/analysis/dependency_source_inference/walker.rb +2 -1
  32. data/lib/rigor/analysis/incremental.rb +28 -0
  33. data/lib/rigor/analysis/incremental_session.rb +44 -9
  34. data/lib/rigor/analysis/plugin_fact_fingerprint.rb +1 -2
  35. data/lib/rigor/analysis/reachability/graph.rb +14 -5
  36. data/lib/rigor/analysis/reachability/scan.rb +7 -3
  37. data/lib/rigor/analysis/result.rb +32 -0
  38. data/lib/rigor/analysis/run_cache_key.rb +41 -1
  39. data/lib/rigor/analysis/runner/diagnostic_aggregator.rb +93 -1
  40. data/lib/rigor/analysis/runner/pool_coordinator.rb +34 -0
  41. data/lib/rigor/analysis/runner/project_pre_passes.rb +15 -11
  42. data/lib/rigor/analysis/runner/run_snapshots.rb +7 -2
  43. data/lib/rigor/analysis/runner.rb +147 -10
  44. data/lib/rigor/analysis/worker_session.rb +10 -1
  45. data/lib/rigor/bleeding_edge.rb +7 -6
  46. data/lib/rigor/builtins/hkt_builtins.rb +45 -6
  47. data/lib/rigor/builtins/predefined_constant_refinements.rb +108 -59
  48. data/lib/rigor/builtins/static_return_refinements.rb +20 -1
  49. data/lib/rigor/cache/descriptor.rb +42 -2
  50. data/lib/rigor/cache/incremental_snapshot.rb +40 -3
  51. data/lib/rigor/cache/rbs_environment_marshal_patch.rb +31 -8
  52. data/lib/rigor/cache/store.rb +10 -1
  53. data/lib/rigor/cli/coverage_command.rb +23 -18
  54. data/lib/rigor/cli/coverage_mutation.rb +13 -17
  55. data/lib/rigor/cli/coverage_scan.rb +47 -6
  56. data/lib/rigor/cli/fused_protection_renderer.rb +19 -2
  57. data/lib/rigor/cli/fused_protection_report.rb +23 -2
  58. data/lib/rigor/cli/measurement_integrity_warning.rb +57 -0
  59. data/lib/rigor/cli/mutation_protection_renderer.rb +22 -2
  60. data/lib/rigor/cli/mutation_protection_report.rb +31 -2
  61. data/lib/rigor/cli/sig_gen_command.rb +18 -0
  62. data/lib/rigor/cli/type_of_command.rb +188 -41
  63. data/lib/rigor/cli/type_of_renderer.rb +72 -3
  64. data/lib/rigor/cli/type_scan_command.rb +10 -1
  65. data/lib/rigor/cli.rb +1 -1
  66. data/lib/rigor/configuration.rb +7 -4
  67. data/lib/rigor/effects/plugin_facts.rb +1 -1
  68. data/lib/rigor/effects/scanner.rb +2 -3
  69. data/lib/rigor/environment/bundle_sig_discovery.rb +64 -13
  70. data/lib/rigor/environment/lockfile_resolver.rb +15 -5
  71. data/lib/rigor/environment/missing_gem_constant_index.rb +45 -4
  72. data/lib/rigor/environment/rbs_hierarchy.rb +16 -22
  73. data/lib/rigor/environment/rbs_loader.rb +525 -46
  74. data/lib/rigor/environment.rb +38 -15
  75. data/lib/rigor/inference/acceptance.rb +172 -20
  76. data/lib/rigor/inference/captured_locals.rb +62 -0
  77. data/lib/rigor/inference/content_join.rb +347 -0
  78. data/lib/rigor/inference/def_handle.rb +15 -3
  79. data/lib/rigor/inference/def_node_resolver.rb +62 -3
  80. data/lib/rigor/inference/expression_typer.rb +1020 -141
  81. data/lib/rigor/inference/fork_map.rb +6 -1
  82. data/lib/rigor/inference/hkt_reducer.rb +12 -1
  83. data/lib/rigor/inference/hkt_registry.rb +46 -0
  84. data/lib/rigor/inference/hkt_sugar_translator.rb +93 -0
  85. data/lib/rigor/inference/index_write_widening.rb +48 -0
  86. data/lib/rigor/inference/indexed_narrowing.rb +14 -0
  87. data/lib/rigor/inference/method_dispatcher/block_folding.rb +7 -5
  88. data/lib/rigor/inference/method_dispatcher/constant_folding.rb +10 -0
  89. data/lib/rigor/inference/method_dispatcher/json_folding.rb +58 -0
  90. data/lib/rigor/inference/method_dispatcher/overload_selector.rb +81 -38
  91. data/lib/rigor/inference/method_dispatcher/rbs_dispatch.rb +54 -17
  92. data/lib/rigor/inference/method_dispatcher/shape_dispatch.rb +1 -2
  93. data/lib/rigor/inference/method_dispatcher/singleton_mixin_dispatch.rb +63 -0
  94. data/lib/rigor/inference/method_dispatcher/struct_folding.rb +63 -10
  95. data/lib/rigor/inference/method_dispatcher/struct_materialization.rb +104 -0
  96. data/lib/rigor/inference/method_dispatcher/universal_object_dispatch.rb +81 -0
  97. data/lib/rigor/inference/method_dispatcher.rb +155 -14
  98. data/lib/rigor/inference/method_parameter_binder.rb +3 -3
  99. data/lib/rigor/inference/mutation_widening.rb +244 -174
  100. data/lib/rigor/inference/narrowing.rb +331 -27
  101. data/lib/rigor/inference/parameter_inference_collector.rb +1 -0
  102. data/lib/rigor/inference/pre_eval_constants.rb +15 -0
  103. data/lib/rigor/inference/precision_scanner.rb +5 -2
  104. data/lib/rigor/inference/project_patched_scanner.rb +2 -1
  105. data/lib/rigor/inference/rbs_type_translator.rb +89 -39
  106. data/lib/rigor/inference/scope_indexer.rb +1493 -140
  107. data/lib/rigor/inference/statement_evaluator.rb +276 -91
  108. data/lib/rigor/inference/struct_fold_safety.rb +186 -27
  109. data/lib/rigor/inference/version_guard.rb +229 -0
  110. data/lib/rigor/language_server/selection_range_provider.rb +1 -1
  111. data/lib/rigor/plugin/base.rb +3 -2
  112. data/lib/rigor/plugin/inflector.rb +14 -5
  113. data/lib/rigor/plugin/io_boundary.rb +107 -4
  114. data/lib/rigor/plugin/loader.rb +14 -0
  115. data/lib/rigor/protection/analysis_guard.rb +60 -0
  116. data/lib/rigor/protection/closure_kill_oracle.rb +43 -38
  117. data/lib/rigor/protection/diagnostic_oracle.rb +12 -4
  118. data/lib/rigor/protection/discovery_seed.rb +1 -1
  119. data/lib/rigor/protection/measurement_integrity.rb +36 -0
  120. data/lib/rigor/protection/mutation_scanner.rb +61 -6
  121. data/lib/rigor/protection/mutator.rb +121 -18
  122. data/lib/rigor/reflection.rb +182 -30
  123. data/lib/rigor/scope/discovery_index.rb +39 -1
  124. data/lib/rigor/scope.rb +385 -4
  125. data/lib/rigor/sig_gen/classification.rb +12 -1
  126. data/lib/rigor/sig_gen/generator.rb +254 -5
  127. data/lib/rigor/sig_gen/renderer.rb +1 -6
  128. data/lib/rigor/sig_gen/writer.rb +3 -0
  129. data/lib/rigor/source/constant_path.rb +79 -2
  130. data/lib/rigor/triage/catalogue.rb +1 -1
  131. data/lib/rigor/type/combinator.rb +10 -0
  132. data/lib/rigor/type/maybe.rb +47 -0
  133. data/lib/rigor/type/refined.rb +1 -2
  134. data/lib/rigor/type/result.rb +53 -0
  135. data/lib/rigor/type.rb +2 -0
  136. data/lib/rigor/version.rb +1 -1
  137. data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/analyzer.rb +3 -1
  138. data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_discoverer.rb +58 -8
  139. data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_index.rb +15 -2
  140. data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable.rb +4 -1
  141. data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/analyzer.rb +3 -1
  142. data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_discoverer.rb +39 -14
  143. data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_index.rb +36 -3
  144. data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer.rb +6 -2
  145. data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/analyzer.rb +21 -5
  146. data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_discoverer.rb +47 -8
  147. data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_index.rb +13 -3
  148. data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack.rb +242 -4
  149. data/plugins/rigor-activejob/lib/rigor/plugin/activejob/analyzer.rb +3 -1
  150. data/plugins/rigor-activejob/lib/rigor/plugin/activejob/effects.rb +7 -3
  151. data/plugins/rigor-activejob/lib/rigor/plugin/activejob/job_discoverer.rb +62 -11
  152. data/plugins/rigor-activejob/lib/rigor/plugin/activejob/job_index.rb +15 -2
  153. data/plugins/rigor-activejob/lib/rigor/plugin/activejob/recurring_scan.rb +3 -1
  154. data/plugins/rigor-activejob/lib/rigor/plugin/activejob.rb +5 -1
  155. data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/analyzer.rb +2 -2
  156. data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_discoverer.rb +798 -22
  157. data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_index.rb +156 -13
  158. data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord.rb +140 -40
  159. data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/analyzer.rb +2 -2
  160. data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/attachment_discoverer.rb +20 -6
  161. data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/attachment_index.rb +14 -4
  162. data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage.rb +6 -3
  163. data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext/effects.rb +23 -6
  164. data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext.rb +264 -9
  165. data/plugins/rigor-activesupport-core-ext/sig/active_support/core_ext.rbs +876 -23
  166. data/plugins/rigor-dry-monads/lib/rigor/plugin/dry_monads.rb +99 -0
  167. data/plugins/rigor-dry-monads/lib/rigor-dry-monads.rb +5 -0
  168. data/plugins/rigor-ethon/lib/rigor/plugin/ethon.rb +34 -0
  169. data/plugins/rigor-ethon/lib/rigor-ethon.rb +3 -0
  170. data/plugins/rigor-ethon/sig/ethon.rbs +27 -0
  171. data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/factory_discoverer.rb +3 -2
  172. data/plugins/rigor-ffi/lib/rigor/plugin/ffi/analyzer.rb +198 -0
  173. data/plugins/rigor-ffi/lib/rigor/plugin/ffi/binding_recognizer.rb +75 -0
  174. data/plugins/rigor-ffi/lib/rigor/plugin/ffi/catalog.rb +64 -0
  175. data/plugins/rigor-ffi/lib/rigor/plugin/ffi/discoverer.rb +173 -0
  176. data/plugins/rigor-ffi/lib/rigor/plugin/ffi/target_detector.rb +46 -0
  177. data/plugins/rigor-ffi/lib/rigor/plugin/ffi/types.rb +161 -0
  178. data/plugins/rigor-ffi/lib/rigor/plugin/ffi.rb +121 -0
  179. data/plugins/rigor-ffi/lib/rigor-ffi.rb +3 -0
  180. data/plugins/rigor-ffi/sig/ffi.rbs +67 -0
  181. data/plugins/rigor-ffi-rzmq/lib/rigor/plugin/ffi_rzmq.rb +19 -0
  182. data/plugins/rigor-ffi-rzmq/lib/rigor-ffi-rzmq.rb +3 -0
  183. data/plugins/rigor-ffi-rzmq/sig/ffi_rzmq.rbs +29 -0
  184. data/plugins/rigor-graphql/lib/rigor/plugin/graphql/type_scanner.rb +2 -4
  185. data/plugins/rigor-pundit/lib/rigor/plugin/pundit/authorization_scan.rb +2 -1
  186. data/plugins/rigor-pundit/lib/rigor/plugin/pundit/policy_discoverer.rb +2 -1
  187. data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_loader.rb +2 -1
  188. data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n.rb +2 -1
  189. data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes.rb +2 -1
  190. data/plugins/rigor-railties/lib/rigor/plugin/railties.rb +156 -11
  191. data/plugins/rigor-rbnacl/lib/rigor/plugin/rbnacl.rb +30 -0
  192. data/plugins/rigor-rbnacl/lib/rigor-rbnacl.rb +3 -0
  193. data/plugins/rigor-rbnacl/sig/rbnacl.rbs +22 -0
  194. data/plugins/rigor-sassc/lib/rigor/plugin/sassc.rb +55 -0
  195. data/plugins/rigor-sassc/lib/rigor-sassc.rb +3 -0
  196. data/plugins/rigor-sassc/sig/sassc.rbs +24 -0
  197. data/plugins/rigor-shoulda-matchers/lib/rigor/plugin/shoulda_matchers/analyzer.rb +32 -11
  198. data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/analyzer.rb +3 -1
  199. data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/schedule_scan.rb +4 -1
  200. data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/worker_discoverer.rb +63 -10
  201. data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/worker_index.rb +15 -2
  202. data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq.rb +61 -2
  203. data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog_walker.rb +2 -2
  204. data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet.rb +4 -2
  205. data/sig/rigor/analysis/baseline.rbs +1 -1
  206. data/sig/rigor/environment.rbs +3 -0
  207. data/sig/rigor/inference.rbs +4 -1
  208. data/sig/rigor/plugin/io_boundary.rbs +2 -0
  209. data/sig/rigor/reflection.rbs +3 -1
  210. data/sig/rigor/scope.rbs +25 -1
  211. data/sig/rigor/type.rbs +95 -1
  212. data/sig/rigor.rbs +16 -0
  213. metadata +69 -3
@@ -33,6 +33,11 @@ module Rigor
33
33
  # schedule and forward the rest. Mismatches emit `wrong-arity`.
34
34
  # 2. **Missing schedule** — `perform_in()` / `perform_at()` with zero arguments emit `missing-schedule`.
35
35
  #
36
+ # ## What it types
37
+ #
38
+ # `perform_async` / `perform_in` / `perform_at` on a **discovered** worker return the job id, a
39
+ # `String` (#534) — see {JID_TYPE} for why the nil arm of `Sidekiq::Client#push` is not in the answer.
40
+ #
36
41
  # ## What it contributes to `rigor unused`
37
42
  #
38
43
  # The workers a schedule file names under `class:` and nothing else (ADR-102 WD3 / #367) — see
@@ -51,8 +56,12 @@ module Rigor
51
56
  id: "sidekiq",
52
57
  # Bumped 2026-08-16 — publishes `:reachability_roots` for `rigor unused` (ADR-102 WD3): the workers
53
58
  # a schedule file enqueues by name, which no `perform_async` call site writes down.
54
- version: "0.2.0",
55
- description: "Validates Sidekiq `Worker.perform_async` argument arity.",
59
+ # Bumped 2026-09-01 (#534 item 4) — the enqueue methods return the jid `String`.
60
+ # Bumped 2026-09-02 (#621) worker keys are de-rooted at the producer and a reopened class's
61
+ # `#perform` envelope is merged rather than clobbered, so a cached 0.3.0 index can carry the
62
+ # any-arity row the merge replaces (and miss a schedule's reachability root under a rooted name).
63
+ version: "0.4.0",
64
+ description: "Validates Sidekiq `Worker.perform_async` argument arity and types the jid it returns.",
56
65
  config_schema: {
57
66
  "worker_search_paths" => { kind: :array, default: ["app/workers", "app/sidekiq"] },
58
67
  "worker_marker_modules" => { kind: :array, default: %w[Sidekiq::Job Sidekiq::Worker] },
@@ -144,6 +153,56 @@ module Rigor
144
153
  diagnostics_for(Analyzer.violations_for(call_node: node, worker_index: index), path: path, node: node)
145
154
  end
146
155
 
156
+ # Issue #534 item 4 — the enqueue methods return the job id. `Sidekiq::Client#push` ends with
157
+ # `payload["jid"]`, a 24-character hex `String`, and `perform_async` / `perform_in` / `perform_at`
158
+ # all reach it through `Setter#perform_async`. The corpus sweep counted ~90 mastodon sites reading
159
+ # `Dynamic[top]`.
160
+ #
161
+ # `perform_inline` is deliberately absent: it runs the job in-process and returns whatever the
162
+ # project's own `#perform` returns, which is a different question this plugin does not answer.
163
+ JID_ENTRY_METHODS = %i[perform_async perform_in perform_at].freeze
164
+
165
+ # ## Why `String` and not `String?` — adjudicated 2026-09-01, both arms measured
166
+ #
167
+ # `push` returns nil rather than a jid when a client middleware halts the chain
168
+ # (`payload = middleware.invoke(...) { normed }; if payload … end`), so `String | nil` is the
169
+ # complete reading. It is not the one that ships, and the reason is the same ordering that kept
170
+ # `Parameters#[]` out of rigor-actionpack (#578) — measured on a fixture of the shapes real code
171
+ # writes, in both directions:
172
+ #
173
+ # - **`String?`** puts `call.possible-nil-receiver` at ERROR severity on the assigned-then-used
174
+ # shape — `jid = W.perform_async(id); jid.length` — which is the ordinary way to record the id you
175
+ # just got. The rule restricts itself to local-variable-read receivers, so the chained
176
+ # `W.perform_async(id).to_s` stays silent while the assigned form does not; the assigned form is
177
+ # the only one worth typing at all. (It fires per *method*, not per use: `jid.to_s` is silent
178
+ # because `NilClass` has `to_s`. That makes the noise unpredictable rather than absent.)
179
+ # - **`String`** draws nothing on any shape in the fixture, including the defensive `return unless
180
+ # jid` and `if (jid = W.perform_async(id))` guards — the truthiness fold needs the flow to prove
181
+ # a constant, and it does not fire on these.
182
+ #
183
+ # The nil arm is real but reachable only through a project's own client middleware returning false
184
+ # from `#call`, which is rare, deliberate, and exactly the situation where the project knows to
185
+ # check. Claiming non-nil there costs a missed `possible-nil-receiver` on code that already has to
186
+ # be written defensively; claiming nullable costs an error on the common code that does not. The
187
+ # spec pins both directions, and the `String?` arm is verified to go red on the assigned shape.
188
+ JID_TYPE = "String"
189
+
190
+ dynamic_return methods: JID_ENTRY_METHODS do |call_node, _scope|
191
+ next nil unless call_node.is_a?(Prism::CallNode)
192
+
193
+ index = producer_value(:worker_index)
194
+ next nil if index.nil? || index.empty?
195
+
196
+ # The gate is the DISCOVERED worker set, not the method name: a project's own
197
+ # `SomeOtherThing.perform_async` that is not a Sidekiq job keeps its own answer.
198
+ class_name = Analyzer.constant_receiver_name(call_node.receiver)
199
+ next nil if class_name.nil?
200
+ # `WorkerIndex#known?` de-roots the query itself (#621) — no retry arm here.
201
+ next nil unless index.known?(class_name)
202
+
203
+ Rigor::Type::Combinator.nominal_of(JID_TYPE)
204
+ end
205
+
147
206
  private
148
207
 
149
208
  def load_error_diagnostic(path)
@@ -180,8 +180,8 @@ module Rigor
180
180
  return nil unless node.is_a?(Prism::CallNode) && node.receiver.nil?
181
181
  return nil unless VISIBILITY_MACROS.include?(node.name)
182
182
 
183
- args = node.arguments&.arguments
184
- return nil unless args&.size == 1 && args.first.is_a?(Prism::DefNode)
183
+ args = node.arguments&.arguments || []
184
+ return nil unless args.size == 1 && args.first.is_a?(Prism::DefNode)
185
185
 
186
186
  args.first
187
187
  end
@@ -450,7 +450,9 @@ module Rigor
450
450
  # `[".rbi"]` for Sorbet RBI tree).
451
451
  def harvest_path(root, catalog, sigil_by_path, parse_errors_by_path, extensions)
452
452
  absolute = canonicalize(root)
453
- if File.directory?(absolute)
453
+ # ADR-45 WD1b (#613) — boundary-probed: an `sorbet/rbi` tree (or a configured source root) that
454
+ # does not exist yet is a recorded dependency, so creating it invalidates the warm run.
455
+ if io_boundary.directory?(absolute)
454
456
  extensions.each do |ext|
455
457
  # ADR-88 WD2 — deterministic fold order matters now that the catalog VALUE is digested into the
456
458
  # incremental fact-surface fingerprint: a duplicate `(class, method, kind)` sig's last-wins winner
@@ -461,7 +463,7 @@ module Rigor
461
463
  harvest_file(canonicalize(path), catalog, sigil_by_path, parse_errors_by_path)
462
464
  end
463
465
  end
464
- elsif File.file?(absolute) && extensions.any? { |ext| absolute.end_with?(ext) }
466
+ elsif io_boundary.file?(absolute) && extensions.any? { |ext| absolute.end_with?(ext) }
465
467
  # `paths:` may list individual files (the demos do this); walk them directly rather than skipping.
466
468
  harvest_file(absolute, catalog, sigil_by_path, parse_errors_by_path)
467
469
  end
@@ -9,7 +9,7 @@ module Rigor
9
9
  # Load a baseline file from disk.
10
10
  # Returns `nil` when `path` is nil (no baseline configured).
11
11
  # Raises {LoadError} on malformed or unsupported content.
12
- def self.load: (::String? path) -> Baseline?
12
+ def self.load: (::String? path, ?project_root: ::String) -> Baseline?
13
13
 
14
14
  # Build a baseline from a current run's diagnostic stream.
15
15
  def self.from_diagnostics: (untyped diagnostics, ?match_mode: :rule | :message) -> Baseline
@@ -62,7 +62,10 @@ module Rigor
62
62
  def singleton_definition: (String | Symbol class_name) -> untyped?
63
63
  def singleton_method: (class_name: String | Symbol, method_name: String | Symbol) -> untyped?
64
64
  def class_type_param_names: (String | Symbol class_name) -> Array[Symbol]
65
+ def project_declared_classes: () -> Set[String]
66
+ def project_declared_class?: (String | Symbol class_name) -> bool
65
67
  def class_ordering: (String | Symbol lhs, String | Symbol rhs) -> ordering
68
+ def ancestor_names_for: (String | Symbol class_name) -> Array[String]
66
69
  def constant_type: (String name) -> Type::t?
67
70
  def constant_names: () -> Array[String]
68
71
  def each_known_class_name: () { (String name) -> void } -> untyped
@@ -136,7 +136,7 @@ module Rigor
136
136
  end
137
137
 
138
138
  module RbsTypeTranslator
139
- def self.translate: (untyped rbs_type, ?self_type: Type::t?, ?instance_type: Type::t?, ?type_vars: Hash[Symbol, Type::t]) -> Type::t
139
+ def self.translate: (untyped rbs_type, ?self_type: Type::t?, ?instance_type: Type::t?, ?type_vars: Hash[Symbol, Type::t], ?alias_expander: untyped) -> Type::t
140
140
  end
141
141
 
142
142
  class Fallback
@@ -173,6 +173,9 @@ module Rigor
173
173
  def self?.discovered_project_index_for_paths: (Array[String] paths, ?buffer: untyped) -> Hash[Symbol, untyped]
174
174
  def self?.discovered_project_index_incremental: (Array[String] paths, seed_bundles: Hash[String, untyped], ?buffer: untyped) -> Hash[Symbol, untyped]
175
175
  def self?.collect_class_decls: (untyped node, Array[String] qualified_prefix, Hash[String, Type::t] accumulator) -> void
176
+ def self?.constant_writes_for_file: (untyped root) -> Hash[String, untyped]
177
+ def self?.constant_literal_value: (untyped rvalue) -> Array[untyped]?
178
+ def self?.finalize_constant_writes: (Hash[String, Hash[String, untyped]] writes) -> [Hash[String, Type::t], Hash[String, Set[String]]]
176
179
  def self?.qualified_name_for: (untyped constant_path_node) -> String?
177
180
  def self?.render_constant_path: (untyped node) -> String
178
181
  def self?.propagate: (untyped node, Hash[untyped, Scope] table, Scope parent_scope) -> void
@@ -1,6 +1,8 @@
1
1
  class Rigor::Plugin::IoBoundary
2
2
  def initialize: (policy: untyped, plugin_id: untyped, ?http_client: untyped) -> void
3
3
  def read_file: (untyped) -> String
4
+ def file?: (untyped) -> bool
5
+ def directory?: (untyped) -> bool
4
6
  def open_url: (untyped url) -> String
5
7
  # Returns a frozen `Rigor::Cache::Descriptor` (no RBS yet -> untyped).
6
8
  def cache_descriptor: () -> untyped
@@ -2,11 +2,13 @@ module Rigor
2
2
  module Reflection
3
3
  def self?.class_known?: (String | Symbol class_name, ?scope: Scope) -> bool
4
4
  def self?.rbs_class_known?: (String | Symbol class_name, ?scope: Scope) -> bool
5
+ def self?.project_declared_class?: (String | Symbol class_name, ?scope: Scope?, ?environment: Environment?) -> bool
5
6
  def self?.class_ordering: (String | Symbol lhs, String | Symbol rhs, ?scope: Scope) -> Symbol
6
7
  def self?.nominal_for_name: (String | Symbol class_name, ?scope: Scope) -> Type::Nominal?
7
8
  def self?.singleton_for_name: (String | Symbol class_name, ?scope: Scope) -> Type::Singleton?
8
9
  def self?.constant_type_for: (String | Symbol constant_name, ?scope: Scope) -> Type::t?
9
- def self?.resolve_constant_type: (String | Symbol name, ?scope: Scope) -> Type::t?
10
+ def self?.resolve_constant_type: (String | Symbol name, ?scope: Scope, ?rooted: bool) -> Type::t?
11
+ def self?.lexical_nesting_chain: (Scope scope) -> Array[String]
10
12
  def self?.instance_method_definition: (String | Symbol class_name, String | Symbol method_name, ?scope: Scope) -> untyped
11
13
  def self?.singleton_method_definition: (String | Symbol class_name, String | Symbol method_name, ?scope: Scope) -> untyped
12
14
  def self?.instance_definition: (String | Symbol class_name, ?scope: Scope) -> untyped
data/sig/rigor/scope.rbs CHANGED
@@ -12,6 +12,7 @@ module Rigor
12
12
  attr_reader local_origins: Hash[Symbol, Symbol]
13
13
  attr_reader ivar_origins: Hash[Symbol, Symbol]
14
14
  attr_reader void_origins: Hash[untyped, Inference::VoidOrigin]
15
+ attr_reader plugin_typed_calls: Hash[untyped, bool]
15
16
  attr_reader optimistic_origins: Hash[untyped, Symbol]
16
17
  attr_reader optimistic_locals: Hash[Symbol, Symbol]
17
18
  attr_reader optimistic_ivars: Hash[Symbol, Symbol]
@@ -20,6 +21,7 @@ module Rigor
20
21
  attr_reader source_path: String?
21
22
  attr_reader struct_fold_safe_locals: Set[Symbol]
22
23
  attr_reader opaque_block_self: bool
24
+ attr_reader lexical_nesting: Array[String]?
23
25
 
24
26
  # ADR-53 Track A — the seed-time discovery tables live on the
25
27
  # DiscoveryIndex; Scope keeps per-table readers as delegates.
@@ -38,6 +40,11 @@ module Rigor
38
40
  def discovered_superclasses: () -> Hash[String, String]
39
41
  def discovered_includes: () -> Hash[String, Array[String]]
40
42
  def discovered_class_sources: () -> Hash[String, Set[String]]
43
+ def constant_sources: () -> Hash[String, Set[String]]
44
+ def published_constant_names: () -> Set[String]
45
+ def local_constant_names: () -> Set[String]
46
+ def published_constant?: (String name) -> bool
47
+ def record_constant_dependency: (String name) -> void
41
48
  def data_member_layouts: () -> Hash[String, Array[Symbol]]
42
49
  def struct_member_layouts: () -> Hash[String, { members: Array[Symbol], keyword_init: bool }]
43
50
  def param_inferred_types: () -> Hash[[String, Symbol, Symbol], Hash[Symbol, Type::t]]
@@ -47,6 +54,9 @@ module Rigor
47
54
 
48
55
  def record_void_origin: (untyped node, Inference::VoidOrigin origin) -> Scope
49
56
 
57
+ def record_plugin_typed_call: (untyped node) -> Scope
58
+ def plugin_typed_call?: (untyped node) -> bool
59
+
50
60
  class DiscoveryIndex
51
61
  attr_reader declared_types: Hash[untyped, Type::t]
52
62
  attr_reader class_ivars: Hash[String, Hash[Symbol, Type::t]]
@@ -56,6 +66,7 @@ module Rigor
56
66
  attr_reader in_source_constants: Hash[String, Type::t]
57
67
  attr_reader discovered_methods: Hash[String, Hash[Symbol, Symbol]]
58
68
  attr_reader discovered_def_nodes: Hash[String, Hash[Symbol, untyped]]
69
+ attr_reader discovered_def_nestings: Hash[untyped, Array[String]]
59
70
  attr_reader discovered_singleton_def_nodes: Hash[String, Hash[Symbol, untyped]]
60
71
  attr_reader discovered_def_sources: Hash[String, Hash[Symbol, String]]
61
72
  attr_reader discovered_singleton_def_sources: Hash[String, Hash[Symbol, String]]
@@ -63,6 +74,9 @@ module Rigor
63
74
  attr_reader discovered_superclasses: Hash[String, String]
64
75
  attr_reader discovered_includes: Hash[String, Array[String]]
65
76
  attr_reader discovered_class_sources: Hash[String, Set[String]]
77
+ attr_reader constant_sources: Hash[String, Set[String]]
78
+ attr_reader published_constant_names: Set[String]
79
+ attr_reader local_constant_names: Set[String]
66
80
  attr_reader data_member_layouts: Hash[String, Array[Symbol]]
67
81
  attr_reader struct_member_layouts: Hash[String, { members: Array[Symbol], keyword_init: bool }]
68
82
  attr_reader param_inferred_types: Hash[[String, Symbol, Symbol], Hash[Symbol, Type::t]]
@@ -70,7 +84,7 @@ module Rigor
70
84
 
71
85
  EMPTY: DiscoveryIndex
72
86
 
73
- def with: (?declared_types: Hash[untyped, Type::t], ?class_ivars: Hash[String, Hash[Symbol, Type::t]], ?class_cvars: Hash[String, Hash[Symbol, Type::t]], ?program_globals: Hash[Symbol, Type::t], ?discovered_classes: Hash[String, Type::Singleton], ?in_source_constants: Hash[String, Type::t], ?discovered_methods: Hash[String, Hash[Symbol, Symbol]], ?discovered_def_nodes: Hash[String, Hash[Symbol, untyped]], ?discovered_singleton_def_nodes: Hash[String, Hash[Symbol, untyped]], ?discovered_def_sources: Hash[String, Hash[Symbol, String]], ?discovered_singleton_def_sources: Hash[String, Hash[Symbol, String]], ?discovered_method_visibilities: Hash[String, Hash[Symbol, Symbol]], ?discovered_superclasses: Hash[String, String], ?discovered_includes: Hash[String, Array[String]], ?discovered_class_sources: Hash[String, Set[String]], ?data_member_layouts: Hash[String, Array[Symbol]], ?struct_member_layouts: Hash[String, { members: Array[Symbol], keyword_init: bool }], ?param_inferred_types: Hash[[String, Symbol, Symbol], Hash[Symbol, Type::t]], ?run_generation: Object?) -> DiscoveryIndex
87
+ def with: (?declared_types: Hash[untyped, Type::t], ?class_ivars: Hash[String, Hash[Symbol, Type::t]], ?class_cvars: Hash[String, Hash[Symbol, Type::t]], ?program_globals: Hash[Symbol, Type::t], ?discovered_classes: Hash[String, Type::Singleton], ?in_source_constants: Hash[String, Type::t], ?discovered_methods: Hash[String, Hash[Symbol, Symbol]], ?discovered_def_nodes: Hash[String, Hash[Symbol, untyped]], ?discovered_def_nestings: Hash[untyped, Array[String]], ?discovered_singleton_def_nodes: Hash[String, Hash[Symbol, untyped]], ?discovered_def_sources: Hash[String, Hash[Symbol, String]], ?discovered_singleton_def_sources: Hash[String, Hash[Symbol, String]], ?discovered_method_visibilities: Hash[String, Hash[Symbol, Symbol]], ?discovered_superclasses: Hash[String, String], ?discovered_includes: Hash[String, Array[String]], ?discovered_class_sources: Hash[String, Set[String]], ?constant_sources: Hash[String, Set[String]], ?published_constant_names: Set[String], ?local_constant_names: Set[String], ?data_member_layouts: Hash[String, Array[Symbol]], ?struct_member_layouts: Hash[String, { members: Array[Symbol], keyword_init: bool }], ?param_inferred_types: Hash[[String, Symbol, Symbol], Hash[Symbol, Type::t]], ?run_generation: Object?) -> DiscoveryIndex
74
88
  end
75
89
 
76
90
  class IndexedKey
@@ -90,6 +104,7 @@ module Rigor
90
104
  def initialize: (environment: Environment, locals: Hash[Symbol, Type::t], ?fact_store: Analysis::FactStore, ?self_type: Type::t?, ?ivars: Hash[Symbol, Type::t], ?cvars: Hash[Symbol, Type::t], ?globals: Hash[Symbol, Type::t], ?discovery: DiscoveryIndex, ?source_path: String?, ?dynamic_origins: Hash[untyped, Symbol]) -> void
91
105
  def with_source_path: (String? path) -> Scope
92
106
  def with_struct_fold_safe: (Set[Symbol] locals) -> Scope
107
+ def with_lexical_nesting: (Array[String]? chain) -> Scope
93
108
  def struct_fold_safe?: (String | Symbol name) -> bool
94
109
  def entering_opaque_block: () -> Scope
95
110
  def opaque_block_self?: () -> bool
@@ -123,8 +138,17 @@ module Rigor
123
138
  def class_cvars_for: (String | Symbol? class_name) -> Hash[Symbol, Type::t]
124
139
  def discovered_method?: (String | Symbol class_name, String | Symbol method_name, Symbol kind) -> bool
125
140
  def user_def_for: (String | Symbol class_name, String | Symbol method_name) -> untyped?
141
+ def user_def_through_ancestors: (String | Symbol class_name, String | Symbol method_name, ?name_memo: Hash[untyped, untyped]) -> [untyped?, String?]
142
+ def discovered_method_through_ancestors?: (String | Symbol? class_name, String | Symbol method_name, Symbol kind, ?name_memo: Hash[untyped, untyped]) -> bool
143
+ def enqueue_ancestors: (String current, Array[String] queue, Hash[untyped, untyped] name_memo, ?mixins: bool) -> void
144
+ def ancestor_name_candidates: (String | Symbol subclass_qualified, String | Symbol raw_ancestor) -> Array[String]
145
+
146
+ # Issue #530 — public so the external-gem ancestry probe asks the same question the walk does.
147
+ def known_user_class?: (String | Symbol name) -> bool
126
148
  def singleton_def_for: (String | Symbol class_name, String | Symbol method_name) -> untyped?
149
+ def singleton_def_through_ancestors: (String | Symbol class_name, String | Symbol method_name, ?name_memo: Hash[untyped, untyped]) -> [untyped?, String?]
127
150
  def user_def_site_for: (String | Symbol class_name, String | Symbol method_name) -> String?
151
+ def user_singleton_def_site_for: (String | Symbol class_name, String | Symbol method_name) -> String?
128
152
  def top_level_def_for: (String | Symbol method_name) -> untyped?
129
153
  def bindable_top_level_def_for: (String | Symbol method_name) -> untyped?
130
154
  def toplevel?: () -> bool
data/sig/rigor/type.rbs CHANGED
@@ -1,6 +1,6 @@
1
1
  module Rigor
2
2
  module Type
3
- type t = Top | Bot | Dynamic | Constant | IntegerRange | Nominal | Singleton | Union | Difference | Tuple | HashShape | DataClass | DataInstance | StructClass | StructInstance
3
+ type t = Top | Bot | Dynamic | Constant | IntegerRange | Nominal | Singleton | Union | Difference | Refined | Intersection | Tuple | HashShape | DataClass | DataInstance | StructClass | StructInstance | BoundMethod | Result | Maybe | App
4
4
 
5
5
  type accepts_mode = :strict | :gradual | :loose
6
6
 
@@ -36,6 +36,7 @@ module Rigor
36
36
  def dynamic: () -> Trinary
37
37
  def accepts: (Type::t other, ?mode: accepts_mode) -> AcceptsResult
38
38
  def ==: (untyped other) -> bool
39
+ def eql?: (untyped other) -> bool
39
40
  def hash: () -> Integer
40
41
  def inspect: () -> "#<Rigor::Type::Top>"
41
42
  end
@@ -49,6 +50,7 @@ module Rigor
49
50
  def dynamic: () -> Trinary
50
51
  def accepts: (Type::t other, ?mode: accepts_mode) -> AcceptsResult
51
52
  def ==: (untyped other) -> bool
53
+ def eql?: (untyped other) -> bool
52
54
  def hash: () -> Integer
53
55
  def inspect: () -> "#<Rigor::Type::Bot>"
54
56
  end
@@ -63,12 +65,16 @@ module Rigor
63
65
  def dynamic: () -> Trinary
64
66
  def accepts: (Type::t other, ?mode: accepts_mode) -> AcceptsResult
65
67
  def ==: (untyped other) -> bool
68
+ def eql?: (untyped other) -> bool
66
69
  def hash: () -> Integer
67
70
  def inspect: () -> String
68
71
  end
69
72
 
70
73
  class Constant
74
+ SCALAR_CLASSES: Array[Class]
75
+ RBS_LITERAL_CLASSES: Hash[Class, String]
71
76
  attr_reader value: untyped
77
+ def freezable_carrier?: (untyped value) -> bool
72
78
  def initialize: (untyped value) -> void
73
79
  def describe: (?Symbol verbosity) -> String
74
80
  def erase_to_rbs: () -> String
@@ -77,6 +83,7 @@ module Rigor
77
83
  def dynamic: () -> Trinary
78
84
  def accepts: (Type::t other, ?mode: accepts_mode) -> AcceptsResult
79
85
  def ==: (untyped other) -> bool
86
+ def eql?: (untyped other) -> bool
80
87
  def hash: () -> Integer
81
88
  def inspect: () -> String
82
89
  end
@@ -84,6 +91,8 @@ module Rigor
84
91
  class IntegerRange
85
92
  NEG_INFINITY: Symbol
86
93
  POS_INFINITY: Symbol
94
+ INFINITIES: Array[Symbol]
95
+ ALIAS_NAMES: Hash[[Integer | Symbol, Integer | Symbol], String]
87
96
  attr_reader min: (Integer | Symbol)
88
97
  attr_reader max: (Integer | Symbol)
89
98
  def initialize: ((Integer | Symbol) min, (Integer | Symbol) max) -> void
@@ -101,6 +110,7 @@ module Rigor
101
110
  def dynamic: () -> Trinary
102
111
  def accepts: (Type::t other, ?mode: accepts_mode) -> AcceptsResult
103
112
  def ==: (untyped other) -> bool
113
+ def eql?: (untyped other) -> bool
104
114
  def hash: () -> Integer
105
115
  def inspect: () -> String
106
116
  end
@@ -116,6 +126,7 @@ module Rigor
116
126
  def dynamic: () -> Trinary
117
127
  def accepts: (Type::t other, ?mode: accepts_mode) -> AcceptsResult
118
128
  def ==: (untyped other) -> bool
129
+ def eql?: (untyped other) -> bool
119
130
  def hash: () -> Integer
120
131
  def inspect: () -> String
121
132
  end
@@ -130,6 +141,7 @@ module Rigor
130
141
  def dynamic: () -> Trinary
131
142
  def accepts: (Type::t other, ?mode: accepts_mode) -> AcceptsResult
132
143
  def ==: (untyped other) -> bool
144
+ def eql?: (untyped other) -> bool
133
145
  def hash: () -> Integer
134
146
  def inspect: () -> String
135
147
  end
@@ -144,6 +156,7 @@ module Rigor
144
156
  def dynamic: () -> Trinary
145
157
  def accepts: (Type::t other, ?mode: accepts_mode) -> AcceptsResult
146
158
  def ==: (untyped other) -> bool
159
+ def eql?: (untyped other) -> bool
147
160
  def hash: () -> Integer
148
161
  def inspect: () -> String
149
162
  end
@@ -159,6 +172,7 @@ module Rigor
159
172
  def dynamic: () -> Trinary
160
173
  def accepts: (Type::t other, ?mode: accepts_mode) -> AcceptsResult
161
174
  def ==: (untyped other) -> bool
175
+ def eql?: (untyped other) -> bool
162
176
  def hash: () -> Integer
163
177
  def inspect: () -> String
164
178
  end
@@ -175,6 +189,7 @@ module Rigor
175
189
  def accepts: (Type::t other, ?mode: accepts_mode) -> AcceptsResult
176
190
  def matches?: (untyped value) -> bool?
177
191
  def ==: (untyped other) -> bool
192
+ def eql?: (untyped other) -> bool
178
193
  def hash: () -> Integer
179
194
  def inspect: () -> String
180
195
  end
@@ -190,6 +205,7 @@ module Rigor
190
205
  def dynamic: () -> Trinary
191
206
  def accepts: (Type::t other, ?mode: accepts_mode) -> AcceptsResult
192
207
  def ==: (untyped other) -> bool
208
+ def eql?: (untyped other) -> bool
193
209
  def hash: () -> Integer
194
210
  def inspect: () -> String
195
211
  end
@@ -204,6 +220,7 @@ module Rigor
204
220
  def dynamic: () -> Trinary
205
221
  def accepts: (Type::t other, ?mode: accepts_mode) -> AcceptsResult
206
222
  def ==: (untyped other) -> bool
223
+ def eql?: (untyped other) -> bool
207
224
  def hash: () -> Integer
208
225
  def inspect: () -> String
209
226
  end
@@ -218,6 +235,7 @@ module Rigor
218
235
  def dynamic: () -> Trinary
219
236
  def accepts: (Type::t other, ?mode: accepts_mode) -> AcceptsResult
220
237
  def ==: (untyped other) -> bool
238
+ def eql?: (untyped other) -> bool
221
239
  def hash: () -> Integer
222
240
  def inspect: () -> String
223
241
  end
@@ -241,6 +259,7 @@ module Rigor
241
259
  def dynamic: () -> Trinary
242
260
  def accepts: (Type::t other, ?mode: accepts_mode) -> AcceptsResult
243
261
  def ==: (untyped other) -> bool
262
+ def eql?: (untyped other) -> bool
244
263
  def hash: () -> Integer
245
264
  def inspect: () -> String
246
265
  end
@@ -256,6 +275,7 @@ module Rigor
256
275
  def dynamic: () -> Trinary
257
276
  def accepts: (Type::t other, ?mode: accepts_mode) -> AcceptsResult
258
277
  def ==: (untyped other) -> bool
278
+ def eql?: (untyped other) -> bool
259
279
  def hash: () -> Integer
260
280
  def inspect: () -> String
261
281
  end
@@ -273,6 +293,7 @@ module Rigor
273
293
  def dynamic: () -> Trinary
274
294
  def accepts: (Type::t other, ?mode: accepts_mode) -> AcceptsResult
275
295
  def ==: (untyped other) -> bool
296
+ def eql?: (untyped other) -> bool
276
297
  def hash: () -> Integer
277
298
  def inspect: () -> String
278
299
  end
@@ -289,6 +310,7 @@ module Rigor
289
310
  def dynamic: () -> Trinary
290
311
  def accepts: (Type::t other, ?mode: accepts_mode) -> AcceptsResult
291
312
  def ==: (untyped other) -> bool
313
+ def eql?: (untyped other) -> bool
292
314
  def hash: () -> Integer
293
315
  def inspect: () -> String
294
316
  end
@@ -306,8 +328,78 @@ module Rigor
306
328
  def dynamic: () -> Trinary
307
329
  def accepts: (Type::t other, ?mode: accepts_mode) -> AcceptsResult
308
330
  def ==: (untyped other) -> bool
331
+ def eql?: (untyped other) -> bool
332
+ def hash: () -> Integer
333
+ def inspect: () -> String
334
+ end
335
+
336
+ class Result
337
+ attr_reader ok_type: Type::t
338
+ attr_reader err_type: Type::t
339
+ alias success_type ok_type
340
+ alias failure_type err_type
341
+ def initialize: (Type::t ok_type, Type::t err_type) -> void
342
+ def describe: (?Symbol verbosity) -> String
343
+ def erase_to_rbs: () -> String
344
+ def top: () -> Trinary
345
+ def bot: () -> Trinary
346
+ def dynamic: () -> Trinary
347
+ def accepts: (Type::t other, ?mode: accepts_mode) -> AcceptsResult
348
+ def ==: (untyped other) -> bool
349
+ def eql?: (untyped other) -> bool
350
+ def hash: () -> Integer
351
+ def inspect: () -> String
352
+ end
353
+
354
+ class Maybe
355
+ attr_reader value_type: Type::t
356
+ def initialize: (Type::t value_type) -> void
357
+ def describe: (?Symbol verbosity) -> String
358
+ def erase_to_rbs: () -> String
359
+ def top: () -> Trinary
360
+ def bot: () -> Trinary
361
+ def dynamic: () -> Trinary
362
+ def accepts: (Type::t other, ?mode: accepts_mode) -> AcceptsResult
363
+ def ==: (untyped other) -> bool
364
+ def eql?: (untyped other) -> bool
365
+ def hash: () -> Integer
366
+ def inspect: () -> String
367
+ end
368
+
369
+ class App
370
+ URI_SEPARATOR: String
371
+ attr_reader uri: Symbol
372
+ attr_reader args: Array[Type::t]
373
+ attr_reader bound: Type::t
374
+ def initialize: (Symbol uri, Array[Type::t] args, bound: Type::t) -> void
375
+ def describe: (?Symbol verbosity) -> String
376
+ def erase_to_rbs: () -> String
377
+ def top: () -> Trinary
378
+ def bot: () -> Trinary
379
+ def dynamic: () -> Trinary
380
+ def accepts: (Type::t other, ?mode: accepts_mode) -> AcceptsResult
381
+ def ==: (untyped other) -> bool
382
+ def eql?: (untyped other) -> bool
309
383
  def hash: () -> Integer
310
384
  def inspect: () -> String
385
+ def reduce: (untyped registry, ?fuel: Integer?) -> Type::t
386
+ end
387
+
388
+ module PlainLattice
389
+ def top: () -> Trinary
390
+ def bot: () -> Trinary
391
+ def dynamic: () -> Trinary
392
+ end
393
+
394
+ module AcceptanceRouter
395
+ def accepts: (Type::t other, ?mode: accepts_mode) -> AcceptsResult
396
+ end
397
+
398
+ module AnonymousClassName
399
+ PREFIX: String
400
+ def self?.build: (String | Symbol label, String key) -> String
401
+ def self?.match?: (untyped class_name) -> bool
402
+ def self?.display: (String class_name) -> String
311
403
  end
312
404
 
313
405
  class AcceptsResult
@@ -374,6 +466,8 @@ module Rigor
374
466
  def self?.data_instance_of: (members: Hash[Symbol, Type::t], ?class_name: String?) -> DataInstance
375
467
  def self?.struct_class_of: (members: Array[Symbol], ?class_name: String?, ?keyword_init: bool) -> StructClass
376
468
  def self?.struct_instance_of: (members: Hash[Symbol, Type::t], ?class_name: String?) -> StructInstance
469
+ def self?.result_of: (Type::t ok_type, Type::t err_type) -> Result
470
+ def self?.maybe_of: (Type::t value_type) -> Maybe
377
471
  def self?.union: (*Type::t types) -> Type::t
378
472
  def self?.key_of: (Type::t type) -> Type::t
379
473
  def self?.value_of: (Type::t type) -> Type::t
data/sig/rigor.rbs CHANGED
@@ -141,6 +141,22 @@ module Rigor
141
141
  # #387 — the loaded plugins' compiled effect contributions, read by `rigor effects` so the snapshot's
142
142
  # vocabulary is the one the collection window scanned under. Same `untyped` reasoning again.
143
143
  def effect_plugin_facts: () -> untyped
144
+ # The incremental session's read surface (ADR-46 / ADR-67 / ADR-103) — `IncrementalSession`
145
+ # drives a live Runner through these between rechecks. Typed `untyped` like the cache / effects
146
+ # readers above until their namespaces are sig-covered.
147
+ def return_summaries: () -> untyped
148
+ def param_inferred_types: () -> untyped
149
+ def effect_collections_by_path: () -> untyped
150
+ def collect_param_inference_table: (untyped files) -> untyped
151
+ def evaluate_return_types: (untyped paths, untyped specs) -> untyped
152
+ end
153
+ end
154
+
155
+ module ValueSemantics
156
+ def self.included: (Module base) -> void
157
+
158
+ module ClassMethods
159
+ def value_fields: (*Symbol fields) -> void
144
160
  end
145
161
  end
146
162
  end