Skip to content

Commit 9c59dc3

Browse files
natsukagamitgodzik
authored andcommitted
Extract semanticDB for lifted definitions (scala#21856)
1 parent bb549ed commit 9c59dc3

File tree

5 files changed

+195
-134
lines changed

5 files changed

+195
-134
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
}

0 commit comments

Comments
 (0)