Skip to content

Commit 4df32fc

Browse files
KacperFKorbanKordyjan
authored andcommitted
Coverage: Do not lift applications of context functions
closes lampepfl#16502 [Cherry-picked 3e7dae8]
1 parent b8d2fd5 commit 4df32fc

File tree

3 files changed

+109
-2
lines changed

3 files changed

+109
-2
lines changed

compiler/src/dotty/tools/dotc/transform/InstrumentCoverage.scala

+13-2
Original file line numberDiff line numberDiff line change
@@ -452,8 +452,13 @@ class InstrumentCoverage extends MacroTransform with IdentityDenotTransformer:
452452
* they shouldn't be lifted.
453453
*/
454454
val sym = fun.symbol
455-
sym.exists && (isShortCircuitedOp(sym) || StringInterpolatorOpt.isCompilerIntrinsic(sym) || sym == defn.Object_synchronized)
456-
end
455+
sym.exists && (
456+
isShortCircuitedOp(sym)
457+
|| StringInterpolatorOpt.isCompilerIntrinsic(sym)
458+
|| sym == defn.Object_synchronized
459+
|| isContextFunctionApply(fun)
460+
)
461+
end isUnliftableFun
457462

458463
val fun = tree.fun
459464
val nestedApplyNeedsLift = fun match
@@ -463,6 +468,12 @@ class InstrumentCoverage extends MacroTransform with IdentityDenotTransformer:
463468
nestedApplyNeedsLift ||
464469
!isUnliftableFun(fun) && !tree.args.isEmpty && !tree.args.forall(LiftCoverage.noLift)
465470

471+
private def isContextFunctionApply(fun: Tree)(using Context): Boolean =
472+
fun match
473+
case Select(prefix, nme.apply) =>
474+
defn.isContextFunctionType(prefix.tpe.widen)
475+
case _ => false
476+
466477
/** Check if an Apply can be instrumented. Prevents this phase from generating incorrect code. */
467478
private def canInstrumentApply(tree: Apply)(using Context): Boolean =
468479
def isSecondaryCtorDelegateCall: Boolean = tree.fun match

tests/coverage/pos/i16502.scala

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import scala.concurrent.*
2+
3+
def asyncSum: ExecutionContext ?=> Future[Int] = Future(1)
4+
5+
@main
6+
def Test(): Unit =
7+
import scala.concurrent.ExecutionContext.Implicits.global
8+
asyncSum
+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# Coverage data, format version: 3.0
2+
# Statement data:
3+
# - id
4+
# - source path
5+
# - package name
6+
# - class name
7+
# - class type (Class, Object or Trait)
8+
# - full class name
9+
# - method name
10+
# - start offset
11+
# - end offset
12+
# - line number
13+
# - symbol name
14+
# - tree name
15+
# - is branch
16+
# - invocations count
17+
# - is ignored
18+
# - description (can be multi-line)
19+
# ' ' sign
20+
# ------------------------------------------
21+
0
22+
i16502.scala
23+
<empty>
24+
i16502$package$
25+
Object
26+
<empty>.i16502$package$
27+
$anonfun
28+
76
29+
85
30+
2
31+
apply
32+
Apply
33+
false
34+
0
35+
false
36+
Future(1)
37+
38+
1
39+
i16502.scala
40+
<empty>
41+
i16502$package$
42+
Object
43+
<empty>.i16502$package$
44+
asyncSum
45+
27
46+
39
47+
2
48+
asyncSum
49+
DefDef
50+
false
51+
0
52+
false
53+
def asyncSum
54+
55+
2
56+
i16502.scala
57+
<empty>
58+
i16502$package$
59+
Object
60+
<empty>.i16502$package$
61+
Test
62+
174
63+
182
64+
7
65+
apply
66+
Apply
67+
false
68+
0
69+
false
70+
asyncSum
71+
72+
3
73+
i16502.scala
74+
<empty>
75+
i16502$package$
76+
Object
77+
<empty>.i16502$package$
78+
Test
79+
87
80+
101
81+
5
82+
Test
83+
DefDef
84+
false
85+
0
86+
false
87+
@main\ndef Test
88+

0 commit comments

Comments
 (0)