-
Notifications
You must be signed in to change notification settings - Fork 227
Closed
Labels
bugSomething isn't workingSomething isn't working
Description
Description
When a module defines a constant alias that references another constant of the same name in an outer namespace (for example, B = B::C inside A::D), the Ruby LSP indexer enters infinite recursion while resolving the alias.
This leads to a SystemStackError ("stack level too deep") during constant resolution.
Ruby LSP Information
Following code is going to cause SystemStackError exception during reference search:
module A
module B
class C
end
end
end
module A
module D
B = B::C
end
endExample log:
#<Thread:0x0000000125355e00 /Users/pkondzior/Projects/ruby-lsp/lib/ruby_lsp/base_server.rb:155 run> terminated with exception (report_on_exception is true):
/Users/pkondzior/Projects/ruby-lsp/lib/ruby_indexer/lib/ruby_indexer/index.rb:427:in 'Integer#downto': stack level too deep (SystemStackError)
from /Users/pkondzior/Projects/ruby-lsp/lib/ruby_indexer/lib/ruby_indexer/index.rb:427:in 'RubyIndexer::Index#follow_aliased_namespace'
from /Users/pkondzior/Projects/ruby-lsp/lib/ruby_indexer/lib/ruby_indexer/index.rb:1034:in 'RubyIndexer::Index#direct_or_aliased_constant'
from /Users/pkondzior/Projects/ruby-lsp/lib/ruby_indexer/lib/ruby_indexer/index.rb:332:in 'RubyIndexer::Index#resolve'
from /Users/pkondzior/Projects/ruby-lsp/lib/ruby_indexer/lib/ruby_indexer/index.rb:910:in 'RubyIndexer::Index#resolve_alias'
from /Users/pkondzior/Projects/ruby-lsp/lib/ruby_indexer/lib/ruby_indexer/index.rb:436:in 'block in RubyIndexer::Index#follow_aliased_namespace'
from /Users/pkondzior/Projects/ruby-lsp/lib/ruby_indexer/lib/ruby_indexer/index.rb:427:in 'Integer#downto'
from /Users/pkondzior/Projects/ruby-lsp/lib/ruby_indexer/lib/ruby_indexer/index.rb:427:in 'RubyIndexer::Index#follow_aliased_namespace'
from /Users/pkondzior/Projects/ruby-lsp/lib/ruby_indexer/lib/ruby_indexer/index.rb:1034:in 'RubyIndexer::Index#direct_or_aliased_constant'
... 8542 levels...
from /Users/pkondzior/Projects/ruby-lsp/lib/ruby_lsp/requests/references.rb:63:in 'RubyLsp::Requests::References#perform'
from /Users/pkondzior/Projects/ruby-lsp/lib/ruby_lsp/server.rb:783:in 'RubyLsp::Server#text_document_references'
from /Users/pkondzior/Projects/ruby-lsp/lib/ruby_lsp/server.rb:78:in 'RubyLsp::Server#process_message'
from /Users/pkondzior/Projects/ruby-lsp/lib/ruby_lsp/base_server.rb:167:in 'block in RubyLsp::BaseServer#new_worker'
Reproduction steps
- Run this code in irb console where ruby-lsp is available
require "uri"
require "ruby_lsp/internal"
index = RubyIndexer::Index.new
src = <<~RUBY
module A
module B
class C; end
end
end
module A
module D
B = B::C
end
end
RUBY
uri = URI.parse("file:///test.rb")
index.index_single(uri, src)
# Triggers stack overflow
index.resolve("A::D::B", [])Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working