Skip to content

Commit 49df19b

Browse files
fix: Fix ENFORCE triggered by implicit argument passing. (#44)
1 parent 811e4dd commit 49df19b

File tree

3 files changed

+58
-0
lines changed

3 files changed

+58
-0
lines changed

scip_indexer/SCIPIndexer.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,6 +1000,9 @@ class CFGTraversal final {
10001000

10011001
// Emit references for arguments
10021002
for (auto &arg : send->args) {
1003+
if (arg.loc == send->receiverLoc) { // See NOTE[implicit-arg-passing].
1004+
continue;
1005+
}
10031006
// NOTE: For constructs like a += b, the instruction sequence ends up being:
10041007
// $tmp = $a
10051008
// $a = $tmp.+($b)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# typed: true
2+
3+
# NOTE[implicit-arg-passing]: In this example, Sorbet generates a CFG where
4+
# a and b are implicitly passed to a method call at the 'super'.
5+
# In theory, we could emit references to a and b at the 'super'
6+
# call (following Sorbet strictly), but RubyMine doesn't do this.
7+
# So let's not emit those.
8+
#
9+
# This only seems to trigger when there are two parameters, not one.
10+
# A Sorbet bug, perhaps?
11+
#
12+
# bb0[rubyRegionId=0, firstDead=8]():
13+
# <self>: C = cast(<self>: NilClass, C);
14+
# a: T.untyped = load_arg(a)
15+
# b: T.untyped = load_arg(b)
16+
# <blk>: T.untyped = load_arg(<blk>)
17+
# <cfgAlias>$4: T.class_of(<Magic>) = alias <C <Magic>>
18+
# <statTemp>$6: Symbol(:<super>) = :<super>
19+
# <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)
20+
# <finalReturn>: T.noreturn = return <returnMethodTemp>$2: T.untyped
21+
class C
22+
def f(a, b)
23+
super
24+
end
25+
end
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# typed: true
2+
3+
# NOTE[implicit-arg-passing]: In this example, Sorbet generates a CFG where
4+
# a and b are implicitly passed to a method call at the 'super'.
5+
# In theory, we could emit references to a and b at the 'super'
6+
# call (following Sorbet strictly), but RubyMine doesn't do this.
7+
# So let's not emit those.
8+
#
9+
# This only seems to trigger when there are two parameters, not one.
10+
# A Sorbet bug, perhaps?
11+
#
12+
# bb0[rubyRegionId=0, firstDead=8]():
13+
# <self>: C = cast(<self>: NilClass, C);
14+
# a: T.untyped = load_arg(a)
15+
# b: T.untyped = load_arg(b)
16+
# <blk>: T.untyped = load_arg(<blk>)
17+
# <cfgAlias>$4: T.class_of(<Magic>) = alias <C <Magic>>
18+
# <statTemp>$6: Symbol(:<super>) = :<super>
19+
# <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)
20+
# <finalReturn>: T.noreturn = return <returnMethodTemp>$2: T.untyped
21+
class C
22+
# ^ definition [..] C#
23+
def f(a, b)
24+
# ^^^^^^^^^^^ definition [..] C#f().
25+
# ^ definition local 1~#3809224601
26+
# ^ definition local 2~#3809224601
27+
super
28+
# ^^^^^ reference [..] <Class:<Magic>>#<call-with-block>().
29+
end
30+
end

0 commit comments

Comments
 (0)