Repository: soutaro/steep (Ruby)

Issue:
Unexpected error on constant_resolver.rb
If steep reads the following rbs, it will generate an Unexpected error.

```rbs
class Foo::Bar::Baz
end
```

```
$ bundle exec steep check
# Type checking files:

.................................................................................................................F.................................[Steep 0.52.2] [typecheck:typecheck@0] [background] [#typecheck_source(path=sample.rb)] [#type_check_file(sample.rb@sample)] sample.rb is empty source code
[Steep 0.52.2] [typecheck:typecheck@0] [background] Unexpected error: RuntimeError
[Steep 0.52.2] [typecheck:typecheck@0] [background]   /Users/ksss/.rbenv/versions/3.2.0-preview1/lib/ruby/gems/3.2.0+1/gems/rbs-2.3.2/lib/rbs/resolver/constant_resolver.rb:22:in `block in initialize'
[Steep 0.52.2] [typecheck:typecheck@0] [background]   /Users/ksss/.rbenv/versions/3.2.0-preview1/lib/ruby/gems/3.2.0+1/gems/rbs-2.3.2/lib/rbs/resolver/constant_resolver.rb:18:in `each'
[Steep 0.52.2] [typecheck:typecheck@0] [background]   /Users/ksss/.rbenv/versions/3.2.0-preview1/lib/ruby/gems/3.2.0+1/gems/rbs-2.3.2/lib/rbs/resolver/constant_resolver.rb:18:in `initialize'
[Steep 0.52.2] [typecheck:typecheck@0] [background]   /Users/ksss/.rbenv/versions/3.2.0-preview1/lib/ruby/gems/3.2.0+1/gems/rbs-2.3.2/lib/rbs/resolver/constant_resolver.rb:75:in `new'
[Steep 0.52.2] [typecheck:typecheck@0] [background]   /Users/ksss/.rbenv/versions/3.2.0-preview1/lib/ruby/gems/3.2.0+1/gems/rbs-2.3.2/lib/rbs/resolver/constant_resolver.rb:75:in `initialize'
[Steep 0.52.2] [typecheck:typecheck@0] [background]   /Users/ksss/.rbenv/versions/3.2.0-preview1/lib/ruby/gems/3.2.0+1/gems/steep-0.52.2/lib/steep/services/type_check_service.rb:345:in `new'
[Steep 0.52.2] [typecheck:typecheck@0] [background]   /Users/ksss/.rbenv/versions/3.2.0-preview1/lib/ruby/gems/3.2.0+1/gems/steep-0.52.2/lib/steep/services/type_check_service.rb:345:in `type_check'
[Steep 0.52.2] [typecheck:typecheck@0] [background]   /Users/ksss/.rbenv/versions/3.2.0-preview1/lib/ruby/gems/3.2.0+1/gems/steep-0.52.2/lib/steep/services/type_check_service.rb:327:in `block in type_check_file'
```

ruby: 3.2.0preview1
steep: 0.52.2

---

My guess is as follows.

1. `Foo::Bar::Baz` add to environment.
2. ConstantResolver will find `Foo::Bar`. But `Foo::Bar` is nothing in environment.


Discussion:

Patch:
diff --git a/lib/steep/services/type_check_service.rb b/lib/steep/services/type_check_service.rb
index 414dfa01f..17db8f8de 100644
--- a/lib/steep/services/type_check_service.rb
+++ b/lib/steep/services/type_check_service.rb
@@ -335,6 +335,9 @@ def type_check_file(target:, subtyping:, path:, text:)
         SourceFile.with_syntax_error(path: path, content: text, error: error)
       rescue EncodingError => exn
         SourceFile.no_data(path: path, content: "")
+      rescue RuntimeError => exn
+        Steep.log_error(exn)
+        SourceFile.no_data(path: path, content: text)
       end
 
       def self.type_check(source:, subtyping:)


Test patch:
diff --git a/test/type_check_service_test.rb b/test/type_check_service_test.rb
index cc382ec9f..d2c65dff5 100644
--- a/test/type_check_service_test.rb
+++ b/test/type_check_service_test.rb
@@ -474,4 +474,32 @@ def foo: () -> B
       reported_diagnostics.clear
     end
   end
+
+  def test_signature_error_unknown_outer_module
+    # Recovering from syntax error test
+    service = Services::TypeCheckService.new(project: project)
+
+    {
+      Pathname("lib.rbs") => [ContentChange.string(<<RBS)],
+class Foo::Bar::Baz
+end
+RBS
+      Pathname("lib/a.rb") => [ContentChange.string(<<RUBY)],
+1+2
+RUBY
+    }.tap do |changes|
+      service.update_and_check(changes: changes, assignment: assignment, &reporter)
+
+      reported_diagnostics[Pathname("lib.rbs")].tap do |errors|
+        assert_any!(errors, size: 1) do |error|
+          assert_equal "RBS::UnknownTypeName", error[:code]
+          assert_equal "Cannot find type `::Foo::Bar`", error[:message]
+        end
+      end
+
+      reported_diagnostics[Pathname("lib/a.rb")].tap do |errors|
+        assert_empty errors
+      end
+    end
+  end
 end