diff options
author | Lukas Rytz <lukas.rytz@gmail.com> | 2015-07-29 11:39:04 +0200 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@gmail.com> | 2015-09-22 07:15:57 +0200 |
commit | 9a47e8124aaa2a94737ea3f01ef2fa1e95f91c49 (patch) | |
tree | 428c4c8435d6dfe99b4aeef971cf83e490dc5588 /src | |
parent | 0f72dd37f85bbcaa07cfb325685dc019e6bc1c26 (diff) | |
download | scala-9a47e8124aaa2a94737ea3f01ef2fa1e95f91c49.tar.gz scala-9a47e8124aaa2a94737ea3f01ef2fa1e95f91c49.tar.bz2 scala-9a47e8124aaa2a94737ea3f01ef2fa1e95f91c49.zip |
[backport] SI-9375 add synthetic readResolve only for static modules
For inner modules, the synthetic readResolve method would cause the
module constructor to be invoked on de-serialization in certain
situations. See the discussion in the ticket.
Adds a comprehensive test around serializing and de-serializing
modules.
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/RefChecks.scala | 16 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala | 1 |
2 files changed, 15 insertions, 2 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 90ac1f466d..c5abd756f8 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -1182,11 +1182,23 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans private def eliminateModuleDefs(moduleDef: Tree): List[Tree] = exitingRefchecks { val ModuleDef(_, _, impl) = moduleDef val module = moduleDef.symbol + val moduleClass = module.moduleClass val site = module.owner val moduleName = module.name.toTermName // The typer doesn't take kindly to seeing this ClassDef; we have to // set NoType so it will be ignored. - val cdef = ClassDef(module.moduleClass, impl) setType NoType + val cdef = ClassDef(moduleClass, impl) setType NoType + + // This code is related to the fix of SI-9375, which stops adding `readResolve` methods to + // non-static (nested) modules. Before the fix, the method would cause the module accessor + // to become notPrivate. To prevent binary changes in the 2.11.x branch, we mimic that behavior. + // There is a bit of code duplication between here and SyntheticMethods. We cannot call + // makeNotPrivate already in SyntheticMethod: that is during type checking, and not all references + // are resolved yet, so we cannot rename a definition. This code doesn't exist in the 2.12.x branch. + def hasConcreteImpl(name: Name) = moduleClass.info.member(name).alternatives exists (m => !m.isDeferred) + val hadReadResolveBeforeSI9375 = moduleClass.isSerializable && !hasConcreteImpl(nme.readResolve) + if (hadReadResolveBeforeSI9375) + moduleClass.sourceModule.makeNotPrivate(moduleClass.sourceModule.owner) // Create the module var unless the immediate owner is a class and // the module var already exists there. See SI-5012, SI-6712. @@ -1210,7 +1222,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans } def matchingInnerObject() = { val newFlags = (module.flags | STABLE) & ~MODULE - val newInfo = NullaryMethodType(module.moduleClass.tpe) + val newInfo = NullaryMethodType(moduleClass.tpe) val accessor = site.newMethod(moduleName, module.pos, newFlags) setInfoAndEnter newInfo DefDef(accessor, Select(This(site), module)) :: Nil diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala index 966e8f1abe..1b3f066fc1 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala @@ -322,6 +322,7 @@ trait SyntheticMethods extends ast.TreeDSL { clazz.isModuleClass && clazz.isSerializable && !hasConcreteImpl(nme.readResolve) + && clazz.isStatic ) def synthesize(): List[Tree] = { |