Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions scip_indexer/SCIPIndexer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1000,6 +1000,9 @@ class CFGTraversal final {

// Emit references for arguments
for (auto &arg : send->args) {
if (arg.loc == send->receiverLoc) { // See NOTE[implicit-arg-passing].
continue;
}
// NOTE: For constructs like a += b, the instruction sequence ends up being:
// $tmp = $a
// $a = $tmp.+($b)
Expand Down
25 changes: 25 additions & 0 deletions test/scip/testdata/implicit_super_arg.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# typed: true

# NOTE[implicit-arg-passing]: In this example, Sorbet generates a CFG where
# a and b are implicitly passed to a method call at the 'super'.
# In theory, we could emit references to a and b at the 'super'
# call (following Sorbet strictly), but RubyMine doesn't do this.
# So let's not emit those.
#
# This only seems to trigger when there are two parameters, not one.
# A Sorbet bug, perhaps?
#
# bb0[rubyRegionId=0, firstDead=8]():
# <self>: C = cast(<self>: NilClass, C);
# a: T.untyped = load_arg(a)
# b: T.untyped = load_arg(b)
# <blk>: T.untyped = load_arg(<blk>)
# <cfgAlias>$4: T.class_of(<Magic>) = alias <C <Magic>>
# <statTemp>$6: Symbol(:<super>) = :<super>
# <returnMethodTemp>$2: T.untyped = <cfgAlias>$4: T.class_of(<Magic>).<call-with-block>(<self>: C, <statTemp>$6: Symbol(:<super>), <blk>: T.untyped, a: T.untyped, b: T.untyped)
# <finalReturn>: T.noreturn = return <returnMethodTemp>$2: T.untyped
class C
def f(a, b)
super
end
end
30 changes: 30 additions & 0 deletions test/scip/testdata/implicit_super_arg.snapshot.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# typed: true

# NOTE[implicit-arg-passing]: In this example, Sorbet generates a CFG where
# a and b are implicitly passed to a method call at the 'super'.
# In theory, we could emit references to a and b at the 'super'
# call (following Sorbet strictly), but RubyMine doesn't do this.
# So let's not emit those.
#
# This only seems to trigger when there are two parameters, not one.
# A Sorbet bug, perhaps?
#
# bb0[rubyRegionId=0, firstDead=8]():
# <self>: C = cast(<self>: NilClass, C);
# a: T.untyped = load_arg(a)
# b: T.untyped = load_arg(b)
# <blk>: T.untyped = load_arg(<blk>)
# <cfgAlias>$4: T.class_of(<Magic>) = alias <C <Magic>>
# <statTemp>$6: Symbol(:<super>) = :<super>
# <returnMethodTemp>$2: T.untyped = <cfgAlias>$4: T.class_of(<Magic>).<call-with-block>(<self>: C, <statTemp>$6: Symbol(:<super>), <blk>: T.untyped, a: T.untyped, b: T.untyped)
# <finalReturn>: T.noreturn = return <returnMethodTemp>$2: T.untyped
class C
# ^ definition [..] C#
def f(a, b)
# ^^^^^^^^^^^ definition [..] C#f().
# ^ definition local 1~#3809224601
# ^ definition local 2~#3809224601
super
# ^^^^^ reference [..] <Class:<Magic>>#<call-with-block>().
end
end