From 011507495dd45d188078a31b9a8f1b046a15410c Mon Sep 17 00:00:00 2001 From: Yusuke Endoh Date: Wed, 3 Dec 2025 17:28:49 +0900 Subject: [PATCH] Fix crash when rescuing non-class constants Previously, TypeProf would crash when encountering `rescue X => e` if `X` was a non-class constant (e.g., `X = 1`). This commit fixes the issue by handling cases where the rescued object is not a singleton type, preventing the unhandled exception during type inference. Fixes #351 Co-Authored-By: Takumi Shotoku Co-Authored-By: Claude --- lib/typeprof/core/graph/box.rb | 2 +- scenario/control/rescue-assign-with-class-new.rb | 15 +++++++++++++++ .../control/rescue-assign-with-non-singleton.rb | 16 ++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 scenario/control/rescue-assign-with-class-new.rb create mode 100644 scenario/control/rescue-assign-with-non-singleton.rb diff --git a/lib/typeprof/core/graph/box.rb b/lib/typeprof/core/graph/box.rb index a7d8b9f3..eeeb7734 100644 --- a/lib/typeprof/core/graph/box.rb +++ b/lib/typeprof/core/graph/box.rb @@ -1099,7 +1099,7 @@ def initialize(node, genv, singleton_ty_vtx) def run0(genv, changes) instance_tys = [] @singleton_ty_vtx.each_type do |ty| - instance_tys << ty.get_instance_type(genv) + instance_tys << ty.get_instance_type(genv) if ty.is_a?(Type::Singleton) end source_vtx = Source.new(*instance_tys) changes.add_edge(genv, source_vtx, @ret) diff --git a/scenario/control/rescue-assign-with-class-new.rb b/scenario/control/rescue-assign-with-class-new.rb new file mode 100644 index 00000000..ebfc82c7 --- /dev/null +++ b/scenario/control/rescue-assign-with-class-new.rb @@ -0,0 +1,15 @@ +## update: my_error.rb +MyError = Class.new(StandardError) + +## update: test.rb +class C + def foo + rescue MyError => e + raise ArgumentError, e.message + end +end + +## assert: test.rb +class C + def foo: -> nil +end diff --git a/scenario/control/rescue-assign-with-non-singleton.rb b/scenario/control/rescue-assign-with-non-singleton.rb new file mode 100644 index 00000000..2ff11811 --- /dev/null +++ b/scenario/control/rescue-assign-with-non-singleton.rb @@ -0,0 +1,16 @@ +## update +NonException = :foo + +def foo(n) + 1 +rescue NonException => e + e +end + +## diagnostics + +## assert +NonException: :foo +class Object + def foo: (untyped) -> Integer +end