Skip to content

Commit 5c37a38

Browse files
committed
Add new SymbolLoader: NoLoader
When a SymbolLoader gets completed, we sometimes use NoCompleter as an intermediate info, we now use NoLoader instead. This will be useful in the next commit where we restrict which completers are allowed to set `isAbsent`. We must allow SymbolLoader to set `isAbsent` , but we don't want to allow any NoCompleter to set it, so instead we use NoLoader which is a subtype of both SymbolLoader and NoCompleter. It also turns out that even without the changes to `isAbsent`, using a `SymbolLoader` here is a good idea since `SymDenotation#isCurrent` handles SymbolLoader specially and did not take into account that they were sometimes replaced by NoCompleter. This means that checking for the presence of a flag can now lead to more completion, which required adding an early exit in `Types#isArgPrefixOf` to avoid a cyclic reference.
1 parent eb8e8ff commit 5c37a38

File tree

4 files changed

+16
-5
lines changed

4 files changed

+16
-5
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2180,11 +2180,11 @@ object SymDenotations {
21802180
}
21812181

21822182
/** A missing completer */
2183-
@sharable class NoCompleter extends LazyType {
2183+
trait NoCompleter extends LazyType {
21842184
def complete(denot: SymDenotation)(implicit ctx: Context): Unit = unsupported("complete")
21852185
}
21862186

2187-
object NoCompleter extends NoCompleter
2187+
@sharable object NoCompleter extends NoCompleter
21882188

21892189
/** A lazy type for modules that points to the module class.
21902190
* Needed so that `moduleClass` works before completion.

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ abstract class SymbolLoader extends LazyType { self =>
375375
else
376376
ctx.newModuleSymbol(
377377
rootDenot.owner, rootDenot.name.toTermName, Synthetic, Synthetic,
378-
(module, _) => new NoCompleter() withDecls newScope withSourceModule (_ => module))
378+
(module, _) => NoLoader().withDecls(newScope).withSourceModule(_ => module))
379379
.moduleClass.denot.asClass
380380
}
381381
if (rootDenot.is(ModuleClass)) (linkedDenot, rootDenot)
@@ -416,3 +416,13 @@ class SourcefileLoader(val srcfile: AbstractFile) extends SymbolLoader {
416416
def doComplete(root: SymDenotation)(implicit ctx: Context): Unit =
417417
ctx.run.lateCompile(srcfile, typeCheck = ctx.settings.YretainTrees.value)
418418
}
419+
420+
/** A NoCompleter which is also a SymbolLoader. */
421+
class NoLoader extends SymbolLoader with NoCompleter {
422+
def description(implicit ctx: Context): String = "NoLoader"
423+
override def sourceFileOrNull: AbstractFile = null
424+
override def complete(root: SymDenotation)(implicit ctx: Context): Unit =
425+
super[NoCompleter].complete(root)
426+
def doComplete(root: SymDenotation)(implicit ctx: Context): Unit =
427+
unsupported("doComplete")
428+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ object Types {
235235
* from the ThisType of `symd`'s owner.
236236
*/
237237
def isArgPrefixOf(symd: SymDenotation)(implicit ctx: Context): Boolean =
238+
symd.exists && !symd.owner.is(Package) && // Early exit if possible because the next check would force SymbolLoaders
238239
symd.isAllOf(ClassTypeParam) && {
239240
this match {
240241
case tp: ThisType => tp.cls ne symd.owner

compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ class ClassfileParser(
7272

7373
private[this] var Scala2UnpicklingMode = Mode.Scala2Unpickling
7474

75-
classRoot.info = (new NoCompleter).withDecls(instanceScope)
76-
moduleRoot.info = (new NoCompleter).withDecls(staticScope).withSourceModule(_ => staticModule)
75+
classRoot.info = NoLoader().withDecls(instanceScope)
76+
moduleRoot.info = NoLoader().withDecls(staticScope).withSourceModule(_ => staticModule)
7777

7878
private def currentIsTopLevel(implicit ctx: Context) = classRoot.owner.is(Flags.PackageClass)
7979

0 commit comments

Comments
 (0)