Skip to content

Commit 71cadce

Browse files
committed
Generalize function symbol synthesis logic
We will need other synthesized symbols down the road (e.g. function types in phantom universes). With this commit one can provide for that by installing a synthesizer in a scope.
1 parent 5093126 commit 71cadce

File tree

3 files changed

+27
-6
lines changed

3 files changed

+27
-6
lines changed

compiler/src/dotty/tools/dotc/core/Definitions.scala

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ class Definitions {
108108
* def apply(implicit $x0: T0, ..., $x{N_1}: T{N-1}): R
109109
* }
110110
*/
111-
def newFunctionNTrait(name: TypeName) = {
111+
def newFunctionNTrait(name: TypeName): ClassSymbol = {
112112
val completer = new LazyType {
113113
def complete(denot: SymDenotation)(implicit ctx: Context): Unit = {
114114
val cls = denot.asClass.classSymbol
@@ -189,7 +189,14 @@ class Definitions {
189189

190190
lazy val ScalaPackageVal = ctx.requiredPackage("scala")
191191
lazy val ScalaMathPackageVal = ctx.requiredPackage("scala.math")
192-
lazy val ScalaPackageClass = ScalaPackageVal.moduleClass.asClass
192+
lazy val ScalaPackageClass = {
193+
val cls = ScalaPackageVal.moduleClass.asClass
194+
cls.info.decls.openForMutations.useSynthesizer(
195+
name => ctx =>
196+
if (name.isTypeName && name.isSyntheticFunction) newFunctionNTrait(name.asTypeName)
197+
else NoSymbol)
198+
cls
199+
}
193200
lazy val JavaPackageVal = ctx.requiredPackage("java")
194201
lazy val JavaLangPackageVal = ctx.requiredPackage("java.lang")
195202
// fundamental modules

compiler/src/dotty/tools/dotc/core/Scopes.scala

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ object Scopes {
3939
*/
4040
private final val MaxRecursions = 1000
4141

42+
/** A function that optionally produces synthesized symbols with
43+
* the given name in the given context. Returns `NoSymbol` if the
44+
* no symbol should be synthesized for the given name.
45+
*/
46+
type SymbolSynthesizer = Name => Context => Symbol
47+
4248
class ScopeEntry private[Scopes] (val name: Name, _sym: Symbol, val owner: Scope) {
4349

4450
var sym: Symbol = _sym
@@ -204,6 +210,12 @@ object Scopes {
204210
*/
205211
private var elemsCache: List[Symbol] = null
206212

213+
/** The synthesizer to be used, or `null` if no synthesis is done on this scope */
214+
private var synthesize: SymbolSynthesizer = null
215+
216+
/** Use specified synthesize for this scope */
217+
def useSynthesizer(s: SymbolSynthesizer): Unit = synthesize = s
218+
207219
protected def newScopeLikeThis() = new MutableScope()
208220

209221
/** Clone scope, taking care not to force the denotations of any symbols in the scope.
@@ -220,6 +232,7 @@ object Scopes {
220232
val e = entries(i)
221233
scope.newScopeEntry(e.name, e.sym)
222234
}
235+
scope.synthesize = synthesize
223236
scope
224237
}
225238

@@ -350,7 +363,11 @@ object Scopes {
350363
e = e.prev
351364
}
352365
}
353-
e
366+
if ((e eq null) && (synthesize != null)) {
367+
val sym = synthesize(name)(ctx)
368+
if (sym.exists) newScopeEntry(sym) else e
369+
}
370+
else e
354371
}
355372

356373
/** lookup next entry with same name as this one */

compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,6 @@ class SymbolLoaders {
167167
val mangled = name.mangled
168168
val e = super.lookupEntry(mangled)
169169
if (e != null) e
170-
else if (_sourceModule.initialDenot.name == nme.scala_ && _sourceModule == defn.ScalaPackageVal &&
171-
name.isTypeName && name.isSyntheticFunction)
172-
newScopeEntry(defn.newFunctionNTrait(name.asTypeName))
173170
else if (isFlatName(mangled.toSimpleName) && enterFlatClasses.isDefined) {
174171
Stats.record("package scopes with flatnames entered")
175172
enterFlatClasses.get(ctx)

0 commit comments

Comments
 (0)