Skip to content

Commit 4b6ac78

Browse files
committed
Drop scalaShadowing after bootstrap
Instead, patch the `scala.language` object in the same way we patch `scala.Predef`. We leave a dummy file in scalaShadowing, since the build requires the package to exist. When we have a new bootstrap compiler, we should drop `scalaShadowing` entirely.
1 parent 623ddd2 commit 4b6ac78

File tree

6 files changed

+46
-20
lines changed

6 files changed

+46
-20
lines changed

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

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ class Definitions {
191191
*/
192192
def patchSource(sym: Symbol): SourceFile =
193193
if sym == ScalaPredefModuleClass then ScalaPredefModuleClassPatch.source
194+
else if sym == LanguageModuleClass then LanguageModuleClassPatch.source
194195
else NoSource
195196

196197
@tu lazy val RootClass: ClassSymbol = newPackageSymbol(
@@ -259,9 +260,18 @@ class Definitions {
259260
* or classes with the same name. But their binary artifacts are
260261
* in `scalaShadowing` so they don't clash with the same-named `scala`
261262
* members at runtime.
263+
* It is used only for non-bootstrapped code
262264
*/
263265
@tu lazy val ScalaShadowingPackage: TermSymbol = requiredPackage(nme.scalaShadowing)
264266

267+
/** The `scala.runtime.stdLibPacthes` package is contains objects
268+
* that contain defnitions that get added as members to standard library
269+
* objects with the same name.
270+
*/
271+
@tu lazy val StdLibPatchesPackage: TermSymbol = requiredPackage("scala.runtime.stdLibPatches")
272+
@tu lazy val ScalaPredefModuleClassPatch: Symbol = getModuleIfDefined("scala.runtime.stdLibPatches.Predef").moduleClass
273+
@tu lazy val LanguageModuleClassPatch: Symbol = getModuleIfDefined("scala.runtime.stdLibPatches.language").moduleClass
274+
265275
/** Note: We cannot have same named methods defined in Object and Any (and AnyVal, for that matter)
266276
* because after erasure the Any and AnyVal references get remapped to the Object methods
267277
* which would result in a double binding assertion failure.
@@ -493,10 +503,7 @@ class Definitions {
493503
@tu lazy val Predef_classOf : Symbol = ScalaPredefModule.requiredMethod(nme.classOf)
494504
@tu lazy val Predef_identity : Symbol = ScalaPredefModule.requiredMethod(nme.identity)
495505
@tu lazy val Predef_undefined: Symbol = ScalaPredefModule.requiredMethod(nme.???)
496-
497506
@tu lazy val ScalaPredefModuleClass: ClassSymbol = ScalaPredefModule.moduleClass.asClass
498-
@tu lazy val ScalaPredefModuleClassPatch: Symbol =
499-
getModuleIfDefined("scala.runtime.stdLibPatches.Predef").moduleClass
500507

501508
@tu lazy val SubTypeClass: ClassSymbol = requiredClass("scala.<:<")
502509
@tu lazy val SubType_refl: Symbol = SubTypeClass.companionModule.requiredMethod(nme.refl)

compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,9 @@ object Scala2Unpickler {
112112
denot.info = tempInfo.finalized(normalizedParents)
113113
denot.ensureTypeParamsInCorrectOrder()
114114
if denot.name == tpnme.Predef.moduleClassName && denot.symbol == defn.ScalaPredefModuleClass then
115-
denot.sourceModule.info = denot.typeRef // we run into a cyclic reference when patching if this line is omitted
116115
patchStdLibClass(denot, defn.ScalaPredefModuleClassPatch)
116+
else if denot.name == tpnme.language.moduleClassName && denot.symbol == defn.LanguageModuleClass then
117+
patchStdLibClass(denot, defn.LanguageModuleClassPatch)
117118
}
118119

119120
/** A finalizer that patches standard library classes.
@@ -126,6 +127,7 @@ object Scala2Unpickler {
126127
* is read from a classfile.
127128
*/
128129
private def patchStdLibClass(denot: ClassDenotation, patchCls: Symbol)(using Context): Unit =
130+
denot.sourceModule.info = denot.typeRef // we run into a cyclic reference when patching if this line is omitted
129131
val scope = denot.info.decls.openForMutations
130132
if patchCls.exists then
131133
val patches = patchCls.info.decls.filter(patch =>

compiler/src/dotty/tools/dotc/transform/TreeChecker.scala

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -417,13 +417,6 @@ class TreeChecker extends Phase with SymTransformer {
417417
assert(tree.qual.tpe.isInstanceOf[ThisType], i"expect prefix of Super to be This, actual = ${tree.qual}")
418418
super.typedSuper(tree, pt)
419419

420-
/** Definition of `sym` should be excluded from checks.
421-
* We need to do that for stdlib patch classes, since their symbols have been
422-
* appropriated by other stdlib classes.
423-
*/
424-
private def exclude(sym: Symbol)(using Context): Boolean =
425-
sym == defn.ScalaPredefModuleClassPatch
426-
427420
private def checkOwner(tree: untpd.Tree)(using Context): Unit = {
428421
def ownerMatches(symOwner: Symbol, ctxOwner: Symbol): Boolean =
429422
symOwner == ctxOwner ||
@@ -452,14 +445,12 @@ class TreeChecker extends Phase with SymTransformer {
452445

453446
val symbolsNotDefined = decls -- defined - constr.symbol
454447

455-
if exclude(cls) then
456-
promote(cdef)
457-
else
458-
assert(symbolsNotDefined.isEmpty,
459-
i" $cls tree does not define members: ${symbolsNotDefined.toList}%, %\n" +
460-
i"expected: ${decls.toList}%, %\n" +
461-
i"defined: ${defined}%, %")
462-
super.typedClassDef(cdef, cls)
448+
assert(symbolsNotDefined.isEmpty,
449+
i" $cls tree does not define members: ${symbolsNotDefined.toList}%, %\n" +
450+
i"expected: ${decls.toList}%, %\n" +
451+
i"defined: ${defined}%, %")
452+
453+
super.typedClassDef(cdef, cls)
463454
}
464455

465456
override def typedDefDef(ddef: untpd.DefDef, sym: Symbol)(using Context): Tree =
@@ -549,6 +540,12 @@ class TreeChecker extends Phase with SymTransformer {
549540
super.typedWhileDo(tree)
550541
}
551542

543+
override def typedPackageDef(tree: untpd.PackageDef)(using Context): Tree =
544+
if tree.symbol == defn.StdLibPatchesPackage then
545+
promote(tree) // don't check stdlib patches, since their symbols were highjacked by stdlib classes
546+
else
547+
super.typedPackageDef(tree)
548+
552549
override def ensureNoLocalRefs(tree: Tree, pt: Type, localSyms: => List[Symbol])(using Context): Tree =
553550
tree
554551

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package scalaShadowing
2+
3+
class D_u_m_m_y

library/src/scala/runtime/stdLibPatches/language.scala

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package scala.runtime.stdLibPatches
22

3-
/** Scala 3 additions to the `scala.language` object.
3+
/** Scala 3 additions and replacements to the `scala.language` object.
44
*/
55
object language:
66

@@ -18,6 +18,23 @@ object language:
1818
*/
1919
object experimental:
2020

21+
/** Where enabled, Scala 2 macro definitions are allowed. Scala 2 macro implementations and
22+
* macro applications are unaffected; they can be used anywhere. A Scala 2 macro definition
23+
* must be accompanied by a Scala 3 macro definition with the same signature.
24+
*
25+
* '''Why introduce the feature?''' Scala 2 macros promise to make the language more regular,
26+
* replacing ad-hoc language constructs with a general powerful abstraction
27+
* capability that can express them. Macros are also a more disciplined and
28+
* powerful replacement for compiler plugins.
29+
*
30+
* '''Why control it?''' For their very power, macros can lead to code that is hard
31+
* to debug and understand.
32+
*
33+
* This is not required by Scala 3 macros as `inline` controls the basic generative macros.
34+
* More add-hoc macros must contain the import of reflection in thier code, making this import redundant.
35+
*/
36+
implicit lazy val macros: languageFeature.experimental.macros = languageFeature.experimental.macros
37+
2138
/** Experimental support for richer dependent types */
2239
object dependent
2340

0 commit comments

Comments
 (0)