Skip to content

Fix type inference for parent scopes and method definitions with receivers#4062

Merged
vinistock merged 3 commits intorubydex_adoption_feature_branchfrom
vs_fix_node_context_for_methods_with_receivers
Apr 30, 2026
Merged

Fix type inference for parent scopes and method definitions with receivers#4062
vinistock merged 3 commits intorubydex_adoption_feature_branchfrom
vs_fix_node_context_for_methods_with_receivers

Conversation

@vinistock
Copy link
Copy Markdown
Member

Motivation

In the original Ruby LSP indexer, we did not handle the resolution of parent scopes used in definitions. For example:

module Bar; end

module Foo
  # This defines `Bar::Baz` because the `Bar` reference gets resolved to top level `Bar`
  # through the lexical scope. Rubydex does this correctly, but the Ruby LSP doesn't
  # run resolution on its node context and misunderstands this as `Foo::Bar::Baz`
  class Bar::Baz
  end
end

Similarly this example

module Foo
  module Bar; end
end

module Baz
  include Foo

  # This doesn't define `Baz::Bar::Qux`. It has access to `Bar` through inheritance
  # and defines `Foo::Bar::Qux`.
  #
  # Note that references to `Baz::Bar::Qux` also work, but not because that's the fully
  # qualified name of the constant. `Baz::Bar` finds `Foo::Bar` through inheritance,
  # allowing you to refer to `Qux`
  class Bar::Qux; end
end

We also did not handle method definition receivers correctly, which don't advance the lexical scope, but modify the type of self. For example:

class Bar; end

class Foo
  def Bar.baz
    # self here is singleton class of Bar (Bar::<Bar>). Therefore, the var reference
    # is accessing `Bar::<Bar>#@var`
    @var
  end
end

Implementation

There are two main parts to fix, which can be found in the first commit:

  1. Started using a new object to represent the surrounding method definition in node context, which includes the receiver
  2. Stopped pushing def self.foo as a singleton entry in the node context nesting. Method receivers don't advance the lexical scope and do not influence constant resolution. They only influence the type of self

Then I made the necessary adjustments on the type inferrer.

Automated Tests

The last commit includes a bunch of tests verifying that we're correctly handling these cases in definition and hover.

@vinistock vinistock self-assigned this Apr 15, 2026
@vinistock vinistock added the bugfix This PR will fix an existing bug label Apr 15, 2026
@vinistock vinistock requested a review from a team as a code owner April 15, 2026 21:35
@vinistock vinistock added the server This pull request should be included in the server gem's release notes label Apr 15, 2026
@vinistock vinistock requested review from alexcrocha and st0012 April 15, 2026 21:35
@vinistock vinistock force-pushed the vs_fix_node_context_for_methods_with_receivers branch from 93eacb0 to 338eeee Compare April 17, 2026 13:22
@vinistock vinistock force-pushed the rubydex_adoption_feature_branch branch from 9bf9d19 to 9ca38db Compare April 21, 2026 15:02
@vinistock vinistock force-pushed the vs_fix_node_context_for_methods_with_receivers branch from 338eeee to 4c1f108 Compare April 21, 2026 15:02
@vinistock vinistock force-pushed the rubydex_adoption_feature_branch branch from 328b3db to d1435ac Compare April 28, 2026 14:34
@vinistock vinistock force-pushed the vs_fix_node_context_for_methods_with_receivers branch from 4c1f108 to 9846ab4 Compare April 28, 2026 14:34
Comment thread test/requests/definition_expectations_test.rb
Comment thread lib/ruby_lsp/node_context.rb
@vinistock vinistock force-pushed the vs_fix_node_context_for_methods_with_receivers branch from 9846ab4 to c753e32 Compare April 30, 2026 13:34
Comment thread lib/ruby_lsp/type_inferrer.rb Outdated
@vinistock vinistock force-pushed the vs_fix_node_context_for_methods_with_receivers branch from c753e32 to 2cb06f8 Compare April 30, 2026 18:02
@vinistock vinistock force-pushed the vs_fix_node_context_for_methods_with_receivers branch from 2cb06f8 to b6b596d Compare April 30, 2026 18:03
@vinistock vinistock requested a review from Morriar April 30, 2026 18:04
Comment thread test/type_inferrer_test.rb
@vinistock vinistock merged commit d7f6944 into rubydex_adoption_feature_branch Apr 30, 2026
38 checks passed
@vinistock vinistock deleted the vs_fix_node_context_for_methods_with_receivers branch April 30, 2026 19:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix This PR will fix an existing bug server This pull request should be included in the server gem's release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants