diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index 25af385ea153..d2e789e2008c 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -1111,10 +1111,49 @@ class Definitions { * is read from a classfile. */ def patchStdLibClass(denot: ClassDenotation)(using Context): Unit = - def patch2(denot: ClassDenotation, patchCls: Symbol): Unit = val scope = denot.info.decls.openForMutations + def recurse(patch: Symbol) = patch.is(Module) && scope.lookup(patch.name).exists + + def makeClassSymbol(patch: Symbol, parents: List[Type], selfInfo: TypeOrSymbol) = + newClassSymbol( + owner = denot.symbol, + name = patch.name.asTypeName, + flags = patch.flags, + // need to rebuild a fresh ClassInfo + infoFn = cls => ClassInfo( + prefix = denot.symbol.thisType, + cls = cls, + declaredParents = parents, // assume parents in patch don't refer to symbols in the patch + decls = newScope, + selfInfo = + if patch.is(Module) + then TermRef(denot.symbol.thisType, patch.name.sourceModuleName) + else selfInfo // assume patch self type annotation does not refer to symbols in the patch + ), + privateWithin = patch.privateWithin, + coord = denot.symbol.coord, + assocFile = denot.symbol.associatedFile + ) + + def makeNonClassSymbol(patch: Symbol) = + if patch.is(Inline) then + // Inline symbols contain trees in annotations, which is coupled + // with the underlying symbol. + // Changing owner for inline symbols is a simple workaround. + patch.denot = patch.denot.copySymDenotation(owner = denot.symbol) + patch + else + // change `info` which might contain reference to the patch + patch.copy( + owner = denot.symbol, + info = + if patch.is(Module) + then TypeRef(denot.symbol.thisType, patch.name.moduleClassName) + else patch.info // assume non-object info does not refer to symbols in the patch + ) + if patchCls.exists then val patches = patchCls.info.decls.filter(patch => !patch.isConstructor && !patch.isOneOf(PrivateOrSynthetic)) @@ -1124,9 +1163,16 @@ class Definitions { for patch <- patches do patch.ensureCompleted() if !recurse(patch) then - patch.denot = patch.denot.copySymDenotation(owner = denot.symbol) - scope.enter(patch) - else if patch.isClass then + val sym = + patch.info match + case ClassInfo(_, _, parents, _, selfInfo) => + makeClassSymbol(patch, parents, selfInfo) + case _ => + makeNonClassSymbol(patch) + end match + sym.annotations = patch.annotations + scope.enter(sym) + if patch.isClass then patch2(scope.lookup(patch.name).asClass, patch) def patchWith(patchCls: Symbol) = diff --git a/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala b/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala index ad2c7000ba0f..87342f3181a7 100644 --- a/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala +++ b/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala @@ -88,8 +88,9 @@ object TypeTestsCasts { withMode(Mode.GadtConstraintInference) { // Why not widen type arguments here? Given the following program // - // trait Tree[-T] class Ident[-T] extends Tree[T] def foo1(tree: - // Tree[Int]) = tree.isInstanceOf[Ident[Int]] + // trait Tree[-T] class Ident[-T] extends Tree[T] + // + // def foo1(tree: Tree[Int]) = tree.isInstanceOf[Ident[Int]] // // In checking whether the test tree.isInstanceOf[Ident[Int]] // is realizable, we want to constrain Ident[X] <: Tree[Int], diff --git a/compiler/test/dotty/tools/dotc/BootstrappedOnlyCompilationTests.scala b/compiler/test/dotty/tools/dotc/BootstrappedOnlyCompilationTests.scala index e4fb84680123..3af7d5e676b3 100644 --- a/compiler/test/dotty/tools/dotc/BootstrappedOnlyCompilationTests.scala +++ b/compiler/test/dotty/tools/dotc/BootstrappedOnlyCompilationTests.scala @@ -149,15 +149,13 @@ class BootstrappedOnlyCompilationTests { // lower level of concurrency as to not kill their running VMs @Test def picklingWithCompiler: Unit = { - val jvmBackendFilter = FileFilter.exclude(List("BTypes.scala", "Primitives.scala")) // TODO - val runtimeFilter = FileFilter.exclude(List("Tuple.scala", "stdLibPatches")) // TODO implicit val testGroup: TestGroup = TestGroup("testPicklingWithCompiler") aggregateTests( compileDir("compiler/src/dotty/tools", picklingWithCompilerOptions, recursive = false), compileDir("compiler/src/dotty/tools/dotc", picklingWithCompilerOptions, recursive = false), compileDir("library/src/scala/runtime/function", picklingWithCompilerOptions), - compileFilesInDir("library/src/scala/runtime", picklingWithCompilerOptions, runtimeFilter), - compileFilesInDir("compiler/src/dotty/tools/backend/jvm", picklingWithCompilerOptions, jvmBackendFilter), + compileFilesInDir("library/src/scala/runtime", picklingWithCompilerOptions), + compileFilesInDir("compiler/src/dotty/tools/backend/jvm", picklingWithCompilerOptions), compileDir("compiler/src/dotty/tools/dotc/ast", picklingWithCompilerOptions), compileDir("compiler/src/dotty/tools/dotc/core", picklingWithCompilerOptions, recursive = false), compileDir("compiler/src/dotty/tools/dotc/config", picklingWithCompilerOptions), diff --git a/library/src/scala/runtime/stdLibPatches/language.scala b/library/src/scala/runtime/stdLibPatches/language.scala index 08fef20e3339..dd7e7b38a5d6 100644 --- a/library/src/scala/runtime/stdLibPatches/language.scala +++ b/library/src/scala/runtime/stdLibPatches/language.scala @@ -1,5 +1,7 @@ package scala.runtime.stdLibPatches +import scala.annotation.compileTimeOnly + /** Scala 3 additions and replacements to the `scala.language` object. */ object language: @@ -29,18 +31,21 @@ object language: * * @see [[https://dotty.epfl.ch/docs/reference/other-new-features/named-typeargs]] */ + @compileTimeOnly("`namedTypeArguments` can only be used at compile time in import statements") object namedTypeArguments /** Experimental support for generic number literals. * * @see [[https://dotty.epfl.ch/docs/reference/changed-features/numeric-literals]] */ + @compileTimeOnly("`genericNumberLiterals` can only be used at compile time in import statements") object genericNumberLiterals /** Experimental support for `erased` modifier * * @see [[https://dotty.epfl.ch/docs/reference/experimental/erased-defs]] */ + @compileTimeOnly("`erasedDefinitions` can only be used at compile time in import statements") object erasedDefinitions end experimental @@ -49,6 +54,7 @@ object language: * Features in this object are slated for removal. New code should not use them and * old code should migrate away from them. */ + @compileTimeOnly("`deprecated` can only be used at compile time in import statements") object deprecated: /** Symbol literals have been deprecated since 2.13. Since Scala 3.0 they @@ -56,6 +62,7 @@ object language: * symbol literals are still supported with a language import, but new software * should not use them. */ + @compileTimeOnly("`symbolLiterals` can only be used at compile time in import statements") object symbolLiterals end deprecated @@ -69,6 +76,7 @@ object language: * '''Why allow it?''' Not allowing auto-tupling is difficult to reconcile with * operators accepting tuples. */ + @compileTimeOnly("`noAutoTupling` can only be used at compile time in import statements") object noAutoTupling /** Where imported, loose equality using eqAny is disabled. @@ -78,6 +86,7 @@ object language: * * @see [[https://dotty.epfl.ch/docs/reference/contextual/multiversal-equality]] */ + @compileTimeOnly("`strictEquality` can only be used at compile time in import statements") object strictEquality /** Where imported, ad hoc extensions of non-open classes in other @@ -96,6 +105,7 @@ object language: * such extensions should be limited in scope and clearly documented. * That's why the language import is required for them. */ + @compileTimeOnly("`adhocExtensions` can only be used at compile time in import statements") object adhocExtensions /** Unsafe Nulls fot Explicit Nulls @@ -103,22 +113,27 @@ object language: * * @see [[http://dotty.epfl.ch/docs/reference/other-new-features/explicit-nulls.html]] */ + @compileTimeOnly("`unsafeNulls` can only be used at compile time in import statements") object unsafeNulls + @compileTimeOnly("`future` can only be used at compile time in import statements") object future + @compileTimeOnly("`future-migration` can only be used at compile time in import statements") object `future-migration` /** Set source version to 3.0-migration. * * @see [[https://scalacenter.github.io/scala-3-migration-guide/docs/scala-3-migration-mode]] */ + @compileTimeOnly("`3.0-migration` can only be used at compile time in import statements") object `3.0-migration` /** Set source version to 3.0. * * @see [[https://scalacenter.github.io/scala-3-migration-guide/docs/scala-3-migration-mode]] */ + @compileTimeOnly("`3.0` can only be used at compile time in import statements") object `3.0` /* This can be added when we go to 3.1