diff --git a/compiler/src/dotty/tools/dotc/core/Denotations.scala b/compiler/src/dotty/tools/dotc/core/Denotations.scala index ccff9fd1c3c2..9d75b93ff334 100644 --- a/compiler/src/dotty/tools/dotc/core/Denotations.scala +++ b/compiler/src/dotty/tools/dotc/core/Denotations.scala @@ -1301,12 +1301,12 @@ object Denotations { if (owner.exists) { val result = if (isPackage) owner.info.decl(selector) else owner.info.member(selector) if (result.exists) result + else if (isPackageFromCoreLibMissing) throw new MissingCoreLibraryException(selector.toString) else { val alt = if (generateStubs) missingHook(owner.symbol.moduleClass, selector) else NoSymbol if (alt.exists) alt.denot - else if (isPackageFromCoreLibMissing) throw new MissingCoreLibraryException(selector.toString) else MissingRef(owner, selector) } } diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala index 78f5be9d8b76..185c5fad2625 100644 --- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala @@ -852,7 +852,9 @@ object SymDenotations { * During completion, references to moduleClass and sourceModules are stored in * the completers. */ - /** The class implementing this module, NoSymbol if not applicable. */ + /** If this a module, return the corresponding class, if this is a module, return itself, + * otherwise NoSymbol + */ final def moduleClass(implicit ctx: Context): Symbol = { def notFound = { if (Config.showCompletions) println(s"missing module class for $name: $myInfo") @@ -870,23 +872,34 @@ object SymDenotations { } case _ => notFound } - else NoSymbol + else if (this is ModuleClass) + symbol + else + NoSymbol } - /** The module implemented by this module class, NoSymbol if not applicable. */ - final def sourceModule(implicit ctx: Context): Symbol = myInfo match { - case ClassInfo(_, _, _, _, selfType) if this is ModuleClass => - def sourceOfSelf(tp: TypeOrSymbol): Symbol = tp match { - case tp: TermRef => tp.symbol - case tp: Symbol => sourceOfSelf(tp.info) - case tp: RefinedType => sourceOfSelf(tp.parent) + /** If this a module class, return the corresponding module, if this is a module, return itself, + * otherwise NoSymbol + */ + final def sourceModule(implicit ctx: Context): Symbol = + if (this is ModuleClass) + myInfo match { + case ClassInfo(_, _, _, _, selfType) => + def sourceOfSelf(tp: TypeOrSymbol): Symbol = tp match { + case tp: TermRef => tp.symbol + case tp: Symbol => sourceOfSelf(tp.info) + case tp: RefinedType => sourceOfSelf(tp.parent) + } + sourceOfSelf(selfType) + case info: LazyType => + info.sourceModule + case _ => + NoSymbol } - sourceOfSelf(selfType) - case info: LazyType => - info.sourceModule - case _ => + else if (this is ModuleVal) + symbol + else NoSymbol - } /** The field accessed by this getter or setter, or if it does not exist, the getter */ def accessedFieldOrGetter(implicit ctx: Context): Symbol = { diff --git a/compiler/src/dotty/tools/dotc/interactive/Completion.scala b/compiler/src/dotty/tools/dotc/interactive/Completion.scala index 79e78443378f..869d2017f161 100644 --- a/compiler/src/dotty/tools/dotc/interactive/Completion.scala +++ b/compiler/src/dotty/tools/dotc/interactive/Completion.scala @@ -254,7 +254,7 @@ object Completion { !sym.isAbsent && !sym.isPrimaryConstructor && sym.sourceSymbol.exists && - (!sym.is(Package) || !sym.moduleClass.exists) && + (!sym.is(Package) || sym.is(ModuleClass)) && !sym.is(allOf(Mutable, Accessor)) && !sym.isPackageObject && !sym.is(Artifact) && diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala index 6fc0de6b9cfa..3c4cd6194de4 100644 --- a/compiler/src/dotty/tools/dotc/typer/Checking.scala +++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala @@ -240,7 +240,7 @@ object Checking { ) case prefix: NamedType => (!sym.is(Private) && prefix.derivesFrom(sym.owner)) || - (!prefix.symbol.isStaticOwner && isInteresting(prefix.prefix)) + (!prefix.symbol.moduleClass.isStaticOwner && isInteresting(prefix.prefix)) case SuperType(thistp, _) => isInteresting(thistp) case AndType(tp1, tp2) => isInteresting(tp1) || isInteresting(tp2) case OrType(tp1, tp2) => isInteresting(tp1) && isInteresting(tp2) diff --git a/compiler/test/dotty/tools/dotc/BootstrappedOnlyCompilationTests.scala b/compiler/test/dotty/tools/dotc/BootstrappedOnlyCompilationTests.scala index 29262975d6f0..e672decb4779 100644 --- a/compiler/test/dotty/tools/dotc/BootstrappedOnlyCompilationTests.scala +++ b/compiler/test/dotty/tools/dotc/BootstrappedOnlyCompilationTests.scala @@ -48,7 +48,15 @@ class BootstrappedOnlyCompilationTests extends ParallelTesting { compileDir("compiler/src/dotty/tools/dotc/reporting", withCompilerOptions), compileDir("compiler/src/dotty/tools/dotc/typer", withCompilerOptions), compileDir("compiler/src/dotty/tools/dotc/util", withCompilerOptions), - compileDir("compiler/src/dotty/tools/io", withCompilerOptions) + compileDir("compiler/src/dotty/tools/io", withCompilerOptions), + compileList( + "testIssue6460", + List( + "compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala", + "compiler/src/dotty/tools/dotc/core/Types.scala" + ), + withCompilerOptions + ), ).checkCompile() } diff --git a/tests/neg/toplevel-cyclic/defs_1.scala b/tests/neg/toplevel-cyclic/defs_1.scala index e2a52496b659..4c78584a5bdf 100644 --- a/tests/neg/toplevel-cyclic/defs_1.scala +++ b/tests/neg/toplevel-cyclic/defs_1.scala @@ -1,2 +1,2 @@ -type A = B // error: illegal cyclic reference +type A = B // error: recursion limit exceeded diff --git a/tests/neg/toplevel-cyclic/moredefs_1.scala b/tests/neg/toplevel-cyclic/moredefs_1.scala index adca31817456..03cc49e531ec 100644 --- a/tests/neg/toplevel-cyclic/moredefs_1.scala +++ b/tests/neg/toplevel-cyclic/moredefs_1.scala @@ -1 +1 @@ -type B = A \ No newline at end of file +type B = A // error: recursion limit exceeded // error: recursion limit exceeded