Skip to content

Commit 7d8f0d4

Browse files
authored
Extract semanticDB for lifted definitions (scala#21856)
1 parent fa85416 commit 7d8f0d4

File tree

5 files changed

+76
-15
lines changed

5 files changed

+76
-15
lines changed

Diff for: compiler/src/dotty/tools/dotc/semanticdb/ExtractSemanticDB.scala

+14
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,14 @@ object ExtractSemanticDB:
286286
|| sym.owner == defn.OpsPackageClass
287287
|| qualifier.exists(excludeQual)
288288

289+
/** This block is created by lifting i.e. EtaExpansion */
290+
private def isProbablyLifted(block: Block)(using Context) =
291+
def isSyntheticDef(t: Tree) =
292+
t match
293+
case t: (ValDef | DefDef) => t.symbol.isSyntheticWithIdent
294+
case _ => false
295+
block.stats.forall(isSyntheticDef)
296+
289297
private def traverseAnnotsOfDefinition(sym: Symbol)(using Context): Unit =
290298
for annot <- sym.annotations do
291299
if annot.tree.span.exists
@@ -438,6 +446,12 @@ object ExtractSemanticDB:
438446
registerUseGuarded(None, sym, tree.span, tree.source)
439447
case _ => ()
440448

449+
// If tree is lifted, ignore Synthetic status on all the definitions and traverse all childrens
450+
case tree: Block if isProbablyLifted(tree) =>
451+
tree.stats.foreach:
452+
case t: (ValDef | DefDef) if !excludeChildren(t.symbol) => traverseChildren(t)
453+
case _ => ()
454+
traverse(tree.expr)
441455

442456
case _ =>
443457
traverseChildren(tree)

Diff for: compiler/src/dotty/tools/dotc/typer/EtaExpansion.scala

+3-10
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,6 @@ abstract class Lifter {
3939
/** The tree of a lifted definition */
4040
protected def liftedDef(sym: TermSymbol, rhs: Tree)(using Context): MemberDef = ValDef(sym, rhs)
4141

42-
/** Is lifting performed on erased terms? */
43-
protected def isErased = false
44-
4542
private def lift(defs: mutable.ListBuffer[Tree], expr: Tree, prefix: TermName = EmptyTermName)(using Context): Tree =
4643
if (noLift(expr)) expr
4744
else {
@@ -117,8 +114,7 @@ abstract class Lifter {
117114
case Apply(fn, args) =>
118115
val fn1 = liftApp(defs, fn)
119116
val args1 = liftArgs(defs, fn.tpe, args)
120-
if isErased then untpd.cpy.Apply(tree)(fn1, args1).withType(tree.tpe) // application may be partial
121-
else cpy.Apply(tree)(fn1, args1)
117+
cpy.Apply(tree)(fn1, args1)
122118
case TypeApply(fn, targs) =>
123119
cpy.TypeApply(tree)(liftApp(defs, fn), targs)
124120
case Select(pre, name) if isPureRef(tree) =>
@@ -141,7 +137,7 @@ abstract class Lifter {
141137
*
142138
* unless `pre` is idempotent.
143139
*/
144-
def liftNonIdempotentPrefix(defs: mutable.ListBuffer[Tree], tree: Tree)(using Context): Tree =
140+
private def liftNonIdempotentPrefix(defs: mutable.ListBuffer[Tree], tree: Tree)(using Context): Tree =
145141
if (isIdempotentExpr(tree)) tree else lift(defs, tree)
146142

147143
/** Lift prefix `pre` of an application `pre.f(...)` to
@@ -154,7 +150,7 @@ abstract class Lifter {
154150
* Note that default arguments will refer to the prefix, we do not want
155151
* to re-evaluate a complex expression each time we access a getter.
156152
*/
157-
def liftPrefix(defs: mutable.ListBuffer[Tree], tree: Tree)(using Context): Tree =
153+
private def liftPrefix(defs: mutable.ListBuffer[Tree], tree: Tree)(using Context): Tree =
158154
tree match
159155
case tree: Literal => tree
160156
case tree: This => tree
@@ -218,9 +214,6 @@ object LiftCoverage extends LiftImpure {
218214
}
219215
}
220216

221-
object LiftErased extends LiftComplex:
222-
override def isErased = true
223-
224217
/** Lift all impure or complex arguments to `def`s */
225218
object LiftToDefs extends LiftComplex {
226219
override def liftedFlags: FlagSet = Method

Diff for: tests/semanticdb/expect/Synthetic.expect.scala

+9
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,13 @@ class Synthetic/*<-example::Synthetic#*/ {
5858
given Int/*->scala::Int#*/ = 1
5959
foo/*->example::Synthetic#Contexts.foo().*/(0)
6060
}
61+
62+
// Argument lifting
63+
val _ =
64+
def f/*<-local14*/(s/*<-local12*/: String/*->scala::Predef.String#*/)(i/*<-local13*/: Int/*->scala::Int#*/ = s/*->local12*/.length/*->java::lang::String#length().*/()) = i/*->local13*/ +/*->scala::Int#`+`(+4).*/ 1
65+
def g/*<-local18*/(s/*<-local16*/: String/*->scala::Predef.String#*/, t/*<-local17*/: String/*->scala::Predef.String#*/) = s/*->local16*/ +/*->java::lang::String#`+`().*/ t/*->local17*/
66+
67+
def impure/*<-local20*/(s/*<-local19*/: String/*->scala::Predef.String#*/) = { ???/*->scala::Predef.`???`().*/; s/*->local19*/ }
68+
val _ = f/*->local14*/(impure/*->local20*/(""))()
69+
val _ = g/*->local18*/(t/*->local17*/ = impure/*->local20*/(""), s/*->local16*/ = "a")
6170
}

Diff for: tests/semanticdb/expect/Synthetic.scala

+9
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,13 @@ class Synthetic {
5858
given Int = 1
5959
foo(0)
6060
}
61+
62+
// Argument lifting
63+
val _ =
64+
def f(s: String)(i: Int = s.length()) = i + 1
65+
def g(s: String, t: String) = s + t
66+
67+
def impure(s: String) = { ???; s }
68+
val _ = f(impure(""))()
69+
val _ = g(t = impure(""), s = "a")
6170
}

Diff for: tests/semanticdb/metac.expect

+41-5
Original file line numberDiff line numberDiff line change
@@ -2841,7 +2841,7 @@ Schema => SemanticDB v4
28412841
Uri => NamedApplyBlock.scala
28422842
Text => empty
28432843
Language => Scala
2844-
Symbols => 43 entries
2844+
Symbols => 41 entries
28452845
Occurrences => 41 entries
28462846

28472847
Symbols:
@@ -2886,8 +2886,6 @@ example/NamedApplyBlockMethods.foo().(b) => param b: Int
28862886
example/NamedApplyBlockMethods.foo().(c) => param c: Int
28872887
example/NamedApplyBlockMethods.local. => val method local Int
28882888
example/NamedApplyBlockMethods.recursive(). => method recursive => Int
2889-
local0 => val local c$1: Int
2890-
local1 => val local b$1: Int @uncheckedVariance
28912889

28922890
Occurrences:
28932891
[0:8..0:15): example <- example/
@@ -3533,8 +3531,8 @@ Schema => SemanticDB v4
35333531
Uri => Synthetic.scala
35343532
Text => empty
35353533
Language => Scala
3536-
Symbols => 52 entries
3537-
Occurrences => 137 entries
3534+
Symbols => 62 entries
3535+
Occurrences => 165 entries
35383536
Synthetics => 39 entries
35393537

35403538
Symbols:
@@ -3590,6 +3588,16 @@ local8 => param a: Int
35903588
local9 => param b: Int
35913589
local10 => final implicit lazy val given local x: Int
35923590
local11 => final implicit lazy val given local given_Int: Int
3591+
local12 => param s: String
3592+
local13 => param i: Int
3593+
local14 => local f: (param s: String)(param i: Int): Int
3594+
local15 => local f$default$2: (param s: String): Int @uncheckedVariance
3595+
local15(s) => param s: String
3596+
local16 => param s: String
3597+
local17 => param t: String
3598+
local18 => local g: (param s: String, param t: String): String
3599+
local19 => param s: String
3600+
local20 => local impure: (param s: String): String
35933601

35943602
Occurrences:
35953603
[0:8..0:15): example <- example/
@@ -3729,6 +3737,34 @@ Occurrences:
37293737
[56:8..56:10): m4 <- example/Synthetic#Contexts.m4().
37303738
[57:12..57:15): Int -> scala/Int#
37313739
[58:6..58:9): foo -> example/Synthetic#Contexts.foo().
3740+
[63:8..63:9): f <- local14
3741+
[63:10..63:11): s <- local12
3742+
[63:13..63:19): String -> scala/Predef.String#
3743+
[63:21..63:22): i <- local13
3744+
[63:24..63:27): Int -> scala/Int#
3745+
[63:30..63:31): s -> local12
3746+
[63:32..63:38): length -> java/lang/String#length().
3747+
[63:44..63:45): i -> local13
3748+
[63:46..63:47): + -> scala/Int#`+`(+4).
3749+
[64:8..64:9): g <- local18
3750+
[64:10..64:11): s <- local16
3751+
[64:13..64:19): String -> scala/Predef.String#
3752+
[64:21..64:22): t <- local17
3753+
[64:24..64:30): String -> scala/Predef.String#
3754+
[64:34..64:35): s -> local16
3755+
[64:36..64:37): + -> java/lang/String#`+`().
3756+
[64:38..64:39): t -> local17
3757+
[66:8..66:14): impure <- local20
3758+
[66:15..66:16): s <- local19
3759+
[66:18..66:24): String -> scala/Predef.String#
3760+
[66:30..66:33): ??? -> scala/Predef.`???`().
3761+
[66:35..66:36): s -> local19
3762+
[67:12..67:13): f -> local14
3763+
[67:14..67:20): impure -> local20
3764+
[68:12..68:13): g -> local18
3765+
[68:14..68:15): t -> local17
3766+
[68:18..68:24): impure -> local20
3767+
[68:30..68:31): s -> local16
37323768

37333769
Synthetics:
37343770
[5:2..5:13):List(1).map => *[Int]

0 commit comments

Comments
 (0)