diff options
author | Seth Tisue <seth@tisue.net> | 2016-10-04 14:13:37 -0500 |
---|---|---|
committer | Seth Tisue <seth@tisue.net> | 2016-10-04 14:13:37 -0500 |
commit | fb53465ca7df23aa996f4bd3c03367f98f37d283 (patch) | |
tree | ecabe92379da52cdb6c5254b5062e88bca6540a6 | |
parent | a3008d5ff4871a6f4b86b48197f01027ffee4245 (diff) | |
parent | 1f6006d0d4f8edf4db04915702f8b7e3c8ca1f5e (diff) | |
download | scala-fb53465ca7df23aa996f4bd3c03367f98f37d283.tar.gz scala-fb53465ca7df23aa996f4bd3c03367f98f37d283.tar.bz2 scala-fb53465ca7df23aa996f4bd3c03367f98f37d283.zip |
Merge remote-tracking branch 'origin/2.12.0' into merge-2.12.0-to-2.12.x-sep-24
-rw-r--r-- | .travis.yml | 15 | ||||
-rw-r--r-- | build.sbt | 2 | ||||
-rw-r--r-- | project/plugins.sbt | 2 | ||||
-rw-r--r-- | spec/README.md | 2 | ||||
-rw-r--r-- | spec/_config.yml | 2 | ||||
-rw-r--r-- | spec/_layouts/default.yml | 2 | ||||
-rw-r--r-- | spec/_layouts/toc.yml | 4 | ||||
-rw-r--r-- | spec/id_dsa_travis.enc | 83 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/Fields.scala | 59 | ||||
-rw-r--r-- | src/library/scala/reflect/NameTransformer.scala | 19 | ||||
-rw-r--r-- | src/library/scala/util/Either.scala | 28 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/StdNames.scala | 19 | ||||
-rw-r--r-- | test/files/run/SD-235.scala | 39 | ||||
-rw-r--r-- | test/files/run/delambdafy_t6028.check | 17 | ||||
-rw-r--r-- | test/files/run/local_obj.scala | 9 | ||||
-rw-r--r-- | test/files/run/t6028.check | 17 | ||||
-rw-r--r-- | test/junit/scala/tools/nsc/backend/jvm/opt/ScalaInlineInfoTest.scala | 4 |
17 files changed, 215 insertions, 108 deletions
diff --git a/.travis.yml b/.travis.yml index 236e002a5e..c27b362a6c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,15 +9,20 @@ rvm: script: bundle exec jekyll build -s spec/ -d build/spec install: bundle install -# https://gist.github.com/kzap/5819745, http://docs.travis-ci.com/user/travis-pro/ +# cat /dev/urandom | head -c 10000 | openssl sha1 > ./secret +# openssl aes-256-cbc -pass "file:./secret" -in id_dsa_spec212_b4096 -out spec/id_dsa_travis.enc -a +# travis encrypt "PRIV_KEY_SECRET=`cat ./secret`" env: - - secure: "WWU490z7DWAI8MidMyTE+i+Ppgjg46mdr7PviF6P6ulrPlRRKOtKXpLvzgJoQmluwzEK6/+iH7D5ybCUYMLdKkQM9kSqaXJ0jeqjOelaaa1LmuOQ8IbuT8O9DwHzjjp/n4Lj/KRvvN4nGxCMI7HLla4gunvPA7M6WK7FA+YKCOU=" # set PRIV_KEY_SECRET to password used to encrypt spec/id_dsa_travis.enc + - secure: "TuJOUtALynPd+MV1AuMeIpVb8BUBHr7Ul7FS48XhS2PyuTRpEBkSWybYcNg3AXyzmWDAuOjUxbaNMQBvP8vvehTbIYls5H5wTGKvj0D0TNVaPIXjF8bA8KyNat9xGNzhnWm2/2BMaWpKBJWRF7Jb+zHhijMYCJEbkMtoiE5R/mY=" + +# ^^^ set PRIV_KEY_SECRET to password used to encrypt spec/id_dsa_travis.enc -# using S3 would be simpler, but we want to upload to scala-lang.org -# after_success: bundle exec s3_website push --headless # the key is restricted using forced commands so that it can only upload to the directory we need here after_success: - openssl aes-256-cbc -pass "pass:$PRIV_KEY_SECRET" -in spec/id_dsa_travis.enc -out spec/id_dsa_travis -d -a - chmod 600 spec/id_dsa_travis - eval "$(ssh-agent)" - - '[ "${TRAVIS_PULL_REQUEST}" = "false" ] && ssh-add -D && ssh-add spec/id_dsa_travis && rsync -e "ssh -o StrictHostKeyChecking=no" -rzv build/spec/ scalatest@chara.epfl.ch:/home/linuxsoft/archives/scala/spec/2.11/' + - '[ "${TRAVIS_PULL_REQUEST}" = "false" ] && ssh-add -D && ssh-add spec/id_dsa_travis && rsync -e "ssh -o StrictHostKeyChecking=no" -rzv build/spec/ scalatest@chara.epfl.ch:/home/linuxsoft/archives/scala/spec/2.12/' + +# using S3 would be simpler, but we want to upload to scala-lang.org +# after_success: bundle exec s3_website push --headless @@ -88,7 +88,7 @@ lazy val publishSettings : Seq[Setting[_]] = Seq( globalVersionSettings baseVersion in Global := "2.12.0" baseVersionSuffix in Global := "SNAPSHOT" -mimaReferenceVersion in Global := None +mimaReferenceVersion in Global := Some("2.12.0-RC1") lazy val commonSettings = clearSourceAndResourceDirectories ++ publishSettings ++ Seq[Setting[_]]( organization := "org.scala-lang", diff --git a/project/plugins.sbt b/project/plugins.sbt index 0a5b8f3dd4..da84d48915 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -19,4 +19,4 @@ buildInfoKeys := Seq[BuildInfoKey](buildClasspath) buildInfoPackage := "scalabuild" -libraryDependencies += "com.typesafe" %% "mima-reporter" % "0.1.8" +libraryDependencies += "com.typesafe" %% "mima-reporter" % "0.1.10" diff --git a/spec/README.md b/spec/README.md index 1a201fc97c..9fd7c9f6ae 100644 --- a/spec/README.md +++ b/spec/README.md @@ -12,7 +12,7 @@ We use Jekyll 2 and [Redcarpet](https://github.com/vmg/redcarpet) to generate th ## Building -Travis CI builds the spec automatically on every commit to master and publishes to http://www.scala-lang.org/files/archive/spec/2.11/. +Travis CI builds the spec automatically after every merged pull release and publishes to http://www.scala-lang.org/files/archive/spec/2.12/. To preview locally, run `bundle exec jekyll serve -d build/spec/ -s spec/ -w --baseurl=""` (in the root of your checkout of scala/scala), and open http://0.0.0.0:4000/. Jekyll will rebuild as you edit the markdown, but make sure to restart it when you change `_config.yml`. diff --git a/spec/_config.yml b/spec/_config.yml index 74ec602f8f..60e80ee05c 100644 --- a/spec/_config.yml +++ b/spec/_config.yml @@ -1,4 +1,4 @@ -baseurl: /files/archive/spec/2.11 +baseurl: /files/archive/spec/2.12 safe: true lsi: false highlighter: null diff --git a/spec/_layouts/default.yml b/spec/_layouts/default.yml index 7e205f8835..06d8c1c118 100644 --- a/spec/_layouts/default.yml +++ b/spec/_layouts/default.yml @@ -31,7 +31,7 @@ <body> <header> - <nav id="chapters"><a id="github" href="https://github.com/scala/scala/tree/2.11.x/spec"><img src="public/images/github-logo@2x.png" alt="Edit at Github"></a>{% assign sorted_pages = site.pages | sort:"name" %}{% for post in sorted_pages %}{% if post.chapter >= 0 %}<a href="{{site.baseurl}}{{ post.url }}">{{post.chapter}} {{ post.title }}</a>{% endif %}{% endfor %}</nav> + <nav id="chapters"><a id="github" href="https://github.com/scala/scala/tree/2.12.x/spec"><img src="public/images/github-logo@2x.png" alt="Edit at GitHub"></a>{% assign sorted_pages = site.pages | sort:"name" %}{% for post in sorted_pages %}{% if post.chapter >= 0 %}<a href="{{site.baseurl}}{{ post.url }}">{{post.chapter}} {{ post.title }}</a>{% endif %}{% endfor %}</nav> </header> <aside class="left"><nav id="toc"></nav></aside> diff --git a/spec/_layouts/toc.yml b/spec/_layouts/toc.yml index 4da7d41bea..dfd92eb114 100644 --- a/spec/_layouts/toc.yml +++ b/spec/_layouts/toc.yml @@ -19,9 +19,9 @@ <div id="header-main"> <img id="scala-logo" src="public/images/scala-spiral-white.png" /> <span id="title">Scala Language Specification</span> - <a id="github" href="https://github.com/scala/scala/tree/2.11.x/spec"><img src="public/images/github-logo@2x.png" alt="Edit at Github"></a> + <a id="github" href="https://github.com/scala/scala/tree/2.12.x/spec"><img src="public/images/github-logo@2x.png" alt="Edit at GitHub"></a> </div> - <div id="header-sub">Version 2.11</div> + <div id="header-sub">Version 2.12</div> </header> <main> {{ content }} diff --git a/spec/id_dsa_travis.enc b/spec/id_dsa_travis.enc index a9a4036807..16bbd569dc 100644 --- a/spec/id_dsa_travis.enc +++ b/spec/id_dsa_travis.enc @@ -1,15 +1,68 @@ -U2FsdGVkX1/RKhLZeL93vFQikKRRkoa3rqt6Kbs7cJStmcTI+DohoRUidRaeSULa -+xXQCwaSDs4+l1HdW2R4ZV62AVGhvIeKEZxc449c6qT9+wUd2PKkDghuJCy1dLTo -2OdFLDeop0X32bsauzPQGWwrpb/Llck4KeKffJq2257Hu6T/HnzSfDnvXbjAsVeH -ZLeXURAyDAdK9vFmFzFiEEztLkW8E3ZVyrk7Qa3GPNpmATiBdhVM8d0JJptKVgwQ -mZfhbItLrj490sPd5zpUFKAxJjPoKIa75n/+u4butn+ON97vr7xOy6ElX7HSJUgr -FJdVJgcO7lki0j+lfJVAP0zLnH80CgOkOJSq0Sso/ofs+lQIobo8fQqIdmoqV3z2 -KpYrgnqap1U2+ekIUKsUxk4LuO8uJhwPeMJs6FoDb+O4Aauqpy9242+P05gWkQVd -KVWRcHVE7DulS8Fp/o5GXJUdw+rdxvQ/voJ8i0HbYpp6UcmQwBheQMSmqtp5+ML9 -rBiBe2sr7pahqI5NKoF3iZCkZW74ge3/GP2d6m2tpOzD+IfdFDXQ/r8DbK2Dvwvz -eutOb0zrUtua2e2zvvpVxldPVpXA7A1hE0P3lns9o+TqNhEauTQimQ8/X51BHO6E -Ap4odrf2odocacY5VC4LFYDO3vat0wSTpi6SxkemUMX5yB7euqwD3ZrMcbpPFR1B -IU5XxW20NxUo8n+WuMUNkXTgk/Cr4OUiavVv4oLsHkmgD9LN3IYI6Rj/DSCzSbDx -hyWc7R47iu9f5okQScx62DwVK3AyAuVWer94x0Kj8AcIRwU/VwiXjnZ59I89AKTN -sjZJw1FfpJPqYs7fPtEiotUdaJHzJH8tiEWFrtOTuOg3h6fy0KJTPVh0WjcGXfb6 -Uh1SEgeHtMSUVhq8nd8LGQ== +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 diff --git a/src/compiler/scala/tools/nsc/transform/Fields.scala b/src/compiler/scala/tools/nsc/transform/Fields.scala index 6cf6a5abce..aa2ccd9788 100644 --- a/src/compiler/scala/tools/nsc/transform/Fields.scala +++ b/src/compiler/scala/tools/nsc/transform/Fields.scala @@ -193,20 +193,6 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor // not be emitted as ACC_FINAL. They are FINAL in the Scala sense, though: cannot be overridden. private final val ModuleOrLazyFieldFlags = FINAL | PrivateLocal | SYNTHETIC | NEEDS_TREES - private def newModuleVarSymbol(owner: Symbol, module: Symbol, tp: Type): TermSymbol = { -// println(s"new module var in $site for $module of type $tp") - val flags = MODULEVAR | (if (owner.isClass) ModuleOrLazyFieldFlags else 0) - - val moduleVar = - (owner.newVariable(nme.moduleVarName(module.name.toTermName), module.pos.focus, flags) - setInfo tp - addAnnotation VolatileAttr) - - moduleOrLazyVarOf(module) = moduleVar - - moduleVar - } - private def moduleInit(module: Symbol, moduleVar: Symbol) = { // println(s"moduleInit for $module in ${module.ownerChain} --> ${moduleVarOf.get(module)}") def moduleVarRef = gen.mkAttributedRef(moduleVar) @@ -380,8 +366,16 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor (existingGetter ne NoSymbol) && (tp matches (site memberInfo existingGetter).resultType) // !existingGetter.isDeferred && -- see (3) } - def newModuleVarMember(member: Symbol): TermSymbol = - newModuleVarSymbol(clazz, member, site.memberType(member).resultType) + def newModuleVarMember(module: Symbol): TermSymbol = { + val moduleVar = + (clazz.newVariable(nme.moduleVarName(module.name.toTermName), module.pos.focus, MODULEVAR | ModuleOrLazyFieldFlags) + setInfo site.memberType(module).resultType + addAnnotation VolatileAttr) + + moduleOrLazyVarOf(module) = moduleVar + + moduleVar + } def newLazyVarMember(member: Symbol): TermSymbol = Fields.this.newLazyVarMember(clazz, member, site.memberType(member).resultType) @@ -531,7 +525,9 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor def mkTypedValDef(sym: Symbol, rhs: Tree = EmptyTree) = typedPos(sym.pos)(ValDef(sym, rhs)).asInstanceOf[ValDef] /** - * Desugar a local `lazy val x: Int = rhs` into + * Desugar a local `lazy val x: Int = rhs` + * or a local `object x { ...}` (the rhs will be instantiating the module's class) into: + * * ``` * val x$lzy = new scala.runtime.LazyInt() * def x$lzycompute(): Int = @@ -541,22 +537,24 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor * } * def x(): Int = if (x$lzy.initialized()) x$lzy.value() else x$lzycompute() * ``` + * + * The expansion is the same for local lazy vals and local objects, + * except for the suffix of the underlying val's name ($lzy or $module) */ - private def mkLazyLocalDef(lazyVal: Symbol, rhs: Tree): Tree = { + private def mkLazyLocalDef(lazySym: Symbol, rhs: Tree): Tree = { import CODE._ - import scala.reflect.NameTransformer.LAZY_LOCAL_SUFFIX_STRING - val owner = lazyVal.owner + import scala.reflect.{NameTransformer => nx} + val owner = lazySym.owner - val lazyValType = lazyVal.tpe.resultType + val lazyValType = lazySym.tpe.resultType val refClass = lazyHolders.getOrElse(lazyValType.typeSymbol, LazyRefClass) val isUnit = refClass == LazyUnitClass val refTpe = if (refClass != LazyRefClass) refClass.tpe else appliedType(refClass.typeConstructor, List(lazyValType)) - val lazyName = lazyVal.name.toTermName - val pos = lazyVal.pos.focus + val lazyName = lazySym.name.toTermName + val pos = lazySym.pos.focus - // used twice: once in the same owner as the lazy val, another time inside the compute method - val localLazyName = lazyName append LAZY_LOCAL_SUFFIX_STRING + val localLazyName = lazyName append (if (lazySym.isModule) nx.MODULE_VAR_SUFFIX_STRING else nx.LAZY_LOCAL_SUFFIX_STRING) // The lazy holder val need not be mutable, as we write to its field. // In fact, it MUST not be mutable to avoid capturing it as an ObjectRef in lambdalift @@ -576,14 +574,14 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor val computerSym = owner.newMethod(lazyName append nme.LAZY_SLOW_SUFFIX, pos, ARTIFACT | PRIVATE) setInfo MethodType(Nil, lazyValType) - val rhsAtComputer = rhs.changeOwner(lazyVal -> computerSym) + val rhsAtComputer = rhs.changeOwner(lazySym -> computerSym) val computer = mkAccessor(computerSym)(gen.mkSynchronized(Ident(holderSym))( If(initialized, getValue, if (isUnit) Block(rhsAtComputer :: Nil, Apply(initialize, Nil)) else Apply(initialize, rhsAtComputer :: Nil)))) - val accessor = mkAccessor(lazyVal)( + val accessor = mkAccessor(lazySym)( If(initialized, getValue, Apply(Ident(computerSym), Nil))) @@ -591,7 +589,7 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor // remove STABLE: prevent replacing accessor call of type Unit by BoxedUnit.UNIT in erasure // remove ACCESSOR: prevent constructors from eliminating the method body if the lazy val is // lifted into a trait (TODO: not sure about the details here) - lazyVal.resetFlag(STABLE | ACCESSOR) + lazySym.resetFlag(STABLE | ACCESSOR) Thicket(mkTypedValDef(holderSym, New(refTpe)) :: computer :: accessor :: Nil) } @@ -730,8 +728,9 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor val cd = super.transform(ClassDef(statSym.moduleClass, impl) setType NoType) if (currOwner.isClass) cd else { // local module -- symbols cannot be generated by info transformer, so do it all here - val moduleVar = newModuleVarSymbol(currOwner, statSym, statSym.info.resultType) - Thicket(cd :: mkTypedValDef(moduleVar) :: mkAccessor(statSym)(moduleInit(statSym, moduleVar)) :: Nil) + val Block(stats, _) = mkLazyLocalDef(statSym, gen.newModule(statSym, statSym.info.resultType)) + + Thicket(cd :: stats) } case tree => diff --git a/src/library/scala/reflect/NameTransformer.scala b/src/library/scala/reflect/NameTransformer.scala index ae36f5edc2..bdf5165df5 100644 --- a/src/library/scala/reflect/NameTransformer.scala +++ b/src/library/scala/reflect/NameTransformer.scala @@ -13,15 +13,16 @@ package reflect * Also provides some constants. */ object NameTransformer { - // XXX Short term: providing a way to alter these without having to recompile - // the compiler before recompiling the compiler. - val MODULE_SUFFIX_STRING = sys.props.getOrElse("SCALA_MODULE_SUFFIX_STRING", "$") - val NAME_JOIN_STRING = sys.props.getOrElse("SCALA_NAME_JOIN_STRING", "$") - val MODULE_INSTANCE_NAME = "MODULE$" - val LOCAL_SUFFIX_STRING = " " - val LAZY_LOCAL_SUFFIX_STRING = "$lzy" - val SETTER_SUFFIX_STRING = "_$eq" - val TRAIT_SETTER_SEPARATOR_STRING = "$_setter_$" + // TODO: reduce duplication with and in StdNames + // I made these constants because we cannot change them without bumping our major version anyway. + final val NAME_JOIN_STRING = "$" + final val MODULE_SUFFIX_STRING = "$" + final val MODULE_INSTANCE_NAME = "MODULE$" + final val LOCAL_SUFFIX_STRING = " " + final val LAZY_LOCAL_SUFFIX_STRING = "$lzy" + final val MODULE_VAR_SUFFIX_STRING = "$module" + final val SETTER_SUFFIX_STRING = "_$eq" + final val TRAIT_SETTER_SEPARATOR_STRING = "$_setter_$" private val nops = 128 private val ncodes = 26 * 26 diff --git a/src/library/scala/util/Either.scala b/src/library/scala/util/Either.scala index 169786d31b..c332f18295 100644 --- a/src/library/scala/util/Either.scala +++ b/src/library/scala/util/Either.scala @@ -95,13 +95,15 @@ sealed abstract class Either[+A, +B] extends Product with Serializable { /** * Projects this `Either` as a `Left`. */ - @deprecated("use swap instead", "2.12.0") def left = Either.LeftProjection(this) /** * Projects this `Either` as a `Right`. + * + * Because `Either` is right-biased, this method is not normally needed. + * (It is retained in the API for now for easy cross-compilation between Scala + * 2.11 and 2.12.) */ - @deprecated("Either is now right-biased", "2.12.0") def right = Either.RightProjection(this) /** @@ -245,7 +247,7 @@ sealed abstract class Either[+A, +B] extends Product with Serializable { /** * Returns `true` if `Left` or returns the result of the application of - * the given function to the `Right` value. + * the given predicate to the `Right` value. * * {{{ * Right(12).forall(_ > 10) // true @@ -260,7 +262,7 @@ sealed abstract class Either[+A, +B] extends Product with Serializable { /** * Returns `false` if `Left` or returns the result of the application of - * the given function to the `Right` value. + * the given predicate to the `Right` value. * * {{{ * Right(12).exists(_ > 10) // true @@ -426,7 +428,10 @@ object Either { /** * Projects an `Either` into a `Left`. * - * This allows for-comprehensions over Either instances - for example {{{ + * This allows for-comprehensions over the left side of Either instances, + * reversing Either's usual right-bias. + * + * For example {{{ * for (s <- Left("flower").left) yield s.length // Left(6) * }}} * @@ -472,7 +477,6 @@ object Either { * @author <a href="mailto:research@workingmouse.com">Tony Morris</a>, Workingmouse * @version 1.0, 11/10/2008 */ - @deprecated("use swap instead", "2.12.0") final case class LeftProjection[+A, +B](e: Either[A, B]) { /** * Returns the value from this `Left` or throws `java.util.NoSuchElementException` @@ -624,19 +628,13 @@ object Either { /** * Projects an `Either` into a `Right`. * - * This allows for-comprehensions over Either instances - for example {{{ - * for (s <- Right("flower").right) yield s.length // Right(6) - * }}} - * - * Continuing the analogy with [[scala.Option]], a `RightProjection` declares - * that `Right` should be analogous to `Some` in some code. - * - * Analogous to `LeftProjection`, see example usage in its documentation above. + * Because `Either` is already right-biased, this class is not normally needed. + * (It is retained in the library for now for easy cross-compilation between Scala + * 2.11 and 2.12.) * * @author <a href="mailto:research@workingmouse.com">Tony Morris</a>, Workingmouse * @version 1.0, 11/10/2008 */ - @deprecated("Either is now right-biased", "2.12.0") final case class RightProjection[+A, +B](e: Either[A, B]) { /** diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala index 1a6c84b19e..2e820a68e0 100644 --- a/src/reflect/scala/reflect/internal/StdNames.scala +++ b/src/reflect/scala/reflect/internal/StdNames.scala @@ -92,14 +92,15 @@ trait StdNames { def flattenedName(segments: Name*): NameType = compactify(segments mkString NAME_JOIN_STRING) - val NAME_JOIN_STRING: String = NameTransformer.NAME_JOIN_STRING - val MODULE_SUFFIX_STRING: String = NameTransformer.MODULE_SUFFIX_STRING - val LOCAL_SUFFIX_STRING: String = NameTransformer.LOCAL_SUFFIX_STRING - val LAZY_LOCAL_SUFFIX_STRING: String = NameTransformer.LAZY_LOCAL_SUFFIX_STRING - - val TRAIT_SETTER_SEPARATOR_STRING: String = NameTransformer.TRAIT_SETTER_SEPARATOR_STRING - - val SINGLETON_SUFFIX: String = ".type" + // TODO: what is the purpose of all this duplication!?!?! + // I made these constants because we cannot change them without bumping our major version anyway. + final val NAME_JOIN_STRING = NameTransformer.NAME_JOIN_STRING + final val MODULE_SUFFIX_STRING = NameTransformer.MODULE_SUFFIX_STRING + final val MODULE_VAR_SUFFIX_STRING = NameTransformer.MODULE_VAR_SUFFIX_STRING + final val LOCAL_SUFFIX_STRING = NameTransformer.LOCAL_SUFFIX_STRING + final val LAZY_LOCAL_SUFFIX_STRING = NameTransformer.LAZY_LOCAL_SUFFIX_STRING + final val TRAIT_SETTER_SEPARATOR_STRING = NameTransformer.TRAIT_SETTER_SEPARATOR_STRING + final val SINGLETON_SUFFIX = ".type" val ANON_CLASS_NAME: NameType = "$anon" val DELAMBDAFY_LAMBDA_CLASS_NAME: NameType = "$lambda" @@ -108,7 +109,7 @@ trait StdNames { val EMPTY_PACKAGE_NAME: NameType = "<empty>" val IMPORT: NameType = "<import>" val MODULE_SUFFIX_NAME: NameType = MODULE_SUFFIX_STRING - val MODULE_VAR_SUFFIX: NameType = "$module" + val MODULE_VAR_SUFFIX: NameType = MODULE_VAR_SUFFIX_STRING val PACKAGE: NameType = "package" val ROOT: NameType = "<root>" val SPECIALIZED_SUFFIX: NameType = "$sp" diff --git a/test/files/run/SD-235.scala b/test/files/run/SD-235.scala new file mode 100644 index 0000000000..eb79c6fe71 --- /dev/null +++ b/test/files/run/SD-235.scala @@ -0,0 +1,39 @@ +class C { + var ORef: Object = null + def test = { + object O { + assert(!Thread.holdsLock(C.this)) + assert(Thread.holdsLock(ORef)) + } + val captor = new { def oh = O } + val refField = captor.getClass.getDeclaredFields.last + refField.setAccessible(true) + assert(refField.getType.toString.contains("LazyRef"), refField) + ORef = refField.get(captor) + O + } +} + +class D { + var ORef: Object = null + def test = { + lazy val O = { + assert(!Thread.holdsLock(D.this)) + assert(Thread.holdsLock(ORef)) + "O" + } + val captor = new { def oh = O } + val refField = captor.getClass.getDeclaredFields.last + refField.setAccessible(true) + assert(refField.getType.toString.contains("LazyRef"), refField) + ORef = refField.get(captor) + O + } +} + +object Test { + def main(args: Array[String]): Unit = { + new C().test + new D().test + } +} diff --git a/test/files/run/delambdafy_t6028.check b/test/files/run/delambdafy_t6028.check index 7b319c92dd..86cb1d5e97 100644 --- a/test/files/run/delambdafy_t6028.check +++ b/test/files/run/delambdafy_t6028.check @@ -15,7 +15,7 @@ package <empty> { } }; def bar(barParam: String): Object = { - @volatile var MethodLocalObject$module: runtime.VolatileObjectRef = scala.runtime.VolatileObjectRef.zero(); + lazy <artifact> val MethodLocalObject$module: scala.runtime.LazyRef = new scala.runtime.LazyRef(); T.this.MethodLocalObject$1(barParam, MethodLocalObject$module) }; def tryy(tryyParam: String): Function0 = { @@ -42,13 +42,14 @@ package <empty> { <synthetic> <stable> <artifact> def $outer(): T = MethodLocalObject$2.this.$outer; <synthetic> <stable> <artifact> def $outer(): T = MethodLocalObject$2.this.$outer }; - final private[this] def MethodLocalObject$lzycompute$1(barParam$1: String, MethodLocalObject$module$1: runtime.VolatileObjectRef): Unit = T.this.synchronized[Unit](if (MethodLocalObject$module$1.elem.$asInstanceOf[T#MethodLocalObject$2.type]().eq(null)) - MethodLocalObject$module$1.elem = new T#MethodLocalObject$2.type(T.this, barParam$1)); - final <stable> private[this] def MethodLocalObject$1(barParam$1: String, MethodLocalObject$module$1: runtime.VolatileObjectRef): T#MethodLocalObject$2.type = { - if (MethodLocalObject$module$1.elem.$asInstanceOf[T#MethodLocalObject$2.type]().eq(null)) - T.this.MethodLocalObject$lzycompute$1(barParam$1, MethodLocalObject$module$1); - (MethodLocalObject$module$1.elem.$asInstanceOf[T#MethodLocalObject$2.type](): T#MethodLocalObject$2.type) - }; + final <artifact> private[this] def MethodLocalObject$lzycompute$1(barParam$1: String, MethodLocalObject$module$1: scala.runtime.LazyRef): T#MethodLocalObject$2.type = MethodLocalObject$module$1.synchronized[T#MethodLocalObject$2.type](if (MethodLocalObject$module$1.initialized()) + MethodLocalObject$module$1.value().$asInstanceOf[T#MethodLocalObject$2.type]() + else + MethodLocalObject$module$1.initialize(new T#MethodLocalObject$2.type(T.this, barParam$1)).$asInstanceOf[T#MethodLocalObject$2.type]()); + final private[this] def MethodLocalObject$1(barParam$1: String, MethodLocalObject$module$1: scala.runtime.LazyRef): T#MethodLocalObject$2.type = if (MethodLocalObject$module$1.initialized()) + MethodLocalObject$module$1.value().$asInstanceOf[T#MethodLocalObject$2.type]() + else + T.this.MethodLocalObject$lzycompute$1(barParam$1, MethodLocalObject$module$1); final <artifact> private[this] def $anonfun$tryy$1(tryyParam$1: String, tryyLocal$1: runtime.ObjectRef): Unit = try { tryyLocal$1.elem = tryyParam$1 } finally () diff --git a/test/files/run/local_obj.scala b/test/files/run/local_obj.scala new file mode 100644 index 0000000000..25123f7078 --- /dev/null +++ b/test/files/run/local_obj.scala @@ -0,0 +1,9 @@ +class C { + val z = 2 + def mod = { object x { val y = z } ; x.y } +} + +object Test extends App { + val c = new C + assert(c.mod == c.z, s"${c.mod} != ${c.z}") +} diff --git a/test/files/run/t6028.check b/test/files/run/t6028.check index 903ea3b753..05634fa8eb 100644 --- a/test/files/run/t6028.check +++ b/test/files/run/t6028.check @@ -15,7 +15,7 @@ package <empty> { } }; def bar(barParam: Int): Object = { - @volatile var MethodLocalObject$module: runtime.VolatileObjectRef = scala.runtime.VolatileObjectRef.zero(); + lazy <artifact> val MethodLocalObject$module: scala.runtime.LazyRef = new scala.runtime.LazyRef(); T.this.MethodLocalObject$1(barParam, MethodLocalObject$module) }; def tryy(tryyParam: Int): Function0 = { @@ -54,13 +54,14 @@ package <empty> { <synthetic> <stable> <artifact> def $outer(): T = MethodLocalObject$2.this.$outer; <synthetic> <stable> <artifact> def $outer(): T = MethodLocalObject$2.this.$outer }; - final private[this] def MethodLocalObject$lzycompute$1(barParam$1: Int, MethodLocalObject$module$1: runtime.VolatileObjectRef): Unit = T.this.synchronized[Unit](if (MethodLocalObject$module$1.elem.$asInstanceOf[T#MethodLocalObject$2.type]().eq(null)) - MethodLocalObject$module$1.elem = new T#MethodLocalObject$2.type(T.this, barParam$1)); - final <stable> private[this] def MethodLocalObject$1(barParam$1: Int, MethodLocalObject$module$1: runtime.VolatileObjectRef): T#MethodLocalObject$2.type = { - if (MethodLocalObject$module$1.elem.$asInstanceOf[T#MethodLocalObject$2.type]().eq(null)) - T.this.MethodLocalObject$lzycompute$1(barParam$1, MethodLocalObject$module$1); - (MethodLocalObject$module$1.elem.$asInstanceOf[T#MethodLocalObject$2.type](): T#MethodLocalObject$2.type) - }; + final <artifact> private[this] def MethodLocalObject$lzycompute$1(barParam$1: Int, MethodLocalObject$module$1: scala.runtime.LazyRef): T#MethodLocalObject$2.type = MethodLocalObject$module$1.synchronized[T#MethodLocalObject$2.type](if (MethodLocalObject$module$1.initialized()) + MethodLocalObject$module$1.value().$asInstanceOf[T#MethodLocalObject$2.type]() + else + MethodLocalObject$module$1.initialize(new T#MethodLocalObject$2.type(T.this, barParam$1)).$asInstanceOf[T#MethodLocalObject$2.type]()); + final private[this] def MethodLocalObject$1(barParam$1: Int, MethodLocalObject$module$1: scala.runtime.LazyRef): T#MethodLocalObject$2.type = if (MethodLocalObject$module$1.initialized()) + MethodLocalObject$module$1.value().$asInstanceOf[T#MethodLocalObject$2.type]() + else + T.this.MethodLocalObject$lzycompute$1(barParam$1, MethodLocalObject$module$1); @SerialVersionUID(value = 0) final <synthetic> class $anonfun$tryy$1 extends scala.runtime.AbstractFunction0$mcV$sp with Serializable { def <init>($outer: T, tryyParam$1: Int, tryyLocal$1: runtime.IntRef): <$anon: Function0> = { $anonfun$tryy$1.super.<init>(); diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/ScalaInlineInfoTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/ScalaInlineInfoTest.scala index 8861577366..5cedc483cd 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/opt/ScalaInlineInfoTest.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/opt/ScalaInlineInfoTest.scala @@ -105,10 +105,10 @@ class ScalaInlineInfoTest extends BytecodeTesting { ("x4$(LT;)I", MethodInlineInfo(true ,false,false)), ("x5()I", MethodInlineInfo(true, false,false)), ("x5$(LT;)I", MethodInlineInfo(true ,false,false)), - ("L$1(Lscala/runtime/VolatileObjectRef;)LT$L$2$;", MethodInlineInfo(true, false,false)), + ("L$1(Lscala/runtime/LazyRef;)LT$L$2$;", MethodInlineInfo(true, false,false)), ("nest$1()I", MethodInlineInfo(true, false,false)), ("$init$(LT;)V", MethodInlineInfo(true,false,false)), - ("L$lzycompute$1(Lscala/runtime/VolatileObjectRef;)V", MethodInlineInfo(true,false,false)) + ("L$lzycompute$1(Lscala/runtime/LazyRef;)LT$L$2$;", MethodInlineInfo(true,false,false)) ), None // warning ) |