diff options
-rw-r--r-- | CONTRIBUTING.md | 4 | ||||
-rw-r--r-- | doc/LICENSE.md | 2 | ||||
-rw-r--r-- | doc/License.rtf | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/RefChecks.scala | 66 | ||||
-rw-r--r-- | src/library/scala/collection/mutable/ListMap.scala | 2 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/Settings.scala | 2 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala | 2 | ||||
-rw-r--r-- | test/files/run/t9546.scala | 13 | ||||
-rw-r--r-- | test/files/run/t9546b.scala | 13 | ||||
-rw-r--r-- | test/files/run/t9546c.scala | 13 | ||||
-rw-r--r-- | test/files/run/t9546d.scala | 16 | ||||
-rw-r--r-- | test/files/run/t9546e.scala | 15 |
12 files changed, 114 insertions, 36 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 18f07376bd..617734210f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,13 +4,13 @@ We follow the standard GitHub [fork & pull](https://help.github.com/articles/usi You're always welcome to submit your PR straight away and start the discussion (without reading the rest of this wonderful doc, or the `READMEnot^H^H^H.md`). The goal of these notes is to make your experience contributing to Scala as smooth and pleasant as possible. We're happy to guide you through the process once you've submitted your PR. ## The Scala Community -In 2014, you -- the Scala community -- matched the core team at EPFL in number of commits contributed to Scala 2.11, doubling the percentage of commits from outside EPFL/Typesafe since 2.10. Excellent work! (The split was roughly 25/25/50 for you/EPFL/Typesafe.) +In 2014, you -- the Scala community -- matched the core team at EPFL in number of commits contributed to Scala 2.11, doubling the percentage of commits from outside EPFL/Lightbend since 2.10. Excellent work! (The split was roughly 25/25/50 for you/EPFL/Lightbend.) We are super happy about this, and are eager to make your experience contributing to Scala productive and satisfying, so that we can keep up this growth. We can't do this alone (nor do we want to)! This is why we're collecting these notes on how to contribute, and we hope you'll share your experience to improve the process for the next contributor! (Feel free to send a PR for this note, send your thoughts to scala-internals, or tweet about it to @adriaanm.) -By the way, the team at Lightbend (formerly Typesafe) is: @adriaanm, @lrytz, @retronym, @SethTisue, and @szeiger. +By the way, the team at Lightbend is: @adriaanm, @lrytz, @retronym, @SethTisue, and @szeiger. ## What kind of PR are you submitting? diff --git a/doc/LICENSE.md b/doc/LICENSE.md index 90bf842420..c56b38daa2 100644 --- a/doc/LICENSE.md +++ b/doc/LICENSE.md @@ -4,7 +4,7 @@ Scala is licensed under the [BSD 3-Clause License](http://opensource.org/license Copyright (c) 2002-2016 EPFL -Copyright (c) 2011-2016 Lightbend, Inc. (formerly Typesafe, Inc.) +Copyright (c) 2011-2016 Lightbend, Inc. All rights reserved. diff --git a/doc/License.rtf b/doc/License.rtf index 5e4403b69f..c8f24838a2 100644 --- a/doc/License.rtf +++ b/doc/License.rtf @@ -11,7 +11,7 @@ \fs40 \ \fs26 Copyright (c) 2002-2016 EPFL\ -Copyright (c) 2011-2016 Lightbend, Inc. (formerly Typesafe, Inc.)\ +Copyright (c) 2011-2016 Lightbend, Inc.\ All rights reserved.\ \ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\ diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index c5abd756f8..3b2e07bdbd 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -1503,9 +1503,8 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans } } - private def transformCaseApply(tree: Tree, ifNot: => Unit) = { + private def isSimpleCaseApply(tree: Tree): Boolean = { val sym = tree.symbol - def isClassTypeAccessible(tree: Tree): Boolean = tree match { case TypeApply(fun, targs) => isClassTypeAccessible(fun) @@ -1513,31 +1512,26 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans ( // SI-4859 `CaseClass1().InnerCaseClass2()` must not be rewritten to `new InnerCaseClass2()`; // {expr; Outer}.Inner() must not be rewritten to `new Outer.Inner()`. treeInfo.isQualifierSafeToElide(module) && - // SI-5626 Classes in refinement types cannot be constructed with `new`. In this case, - // the companion class is actually not a ClassSymbol, but a reference to an abstract type. - module.symbol.companionClass.isClass - ) + // SI-5626 Classes in refinement types cannot be constructed with `new`. In this case, + // the companion class is actually not a ClassSymbol, but a reference to an abstract type. + module.symbol.companionClass.isClass + ) } - val doTransform = - sym.isSourceMethod && + sym.isSourceMethod && sym.isCase && sym.name == nme.apply && isClassTypeAccessible(tree) && - !tree.tpe.resultType.typeSymbol.primaryConstructor.isLessAccessibleThan(tree.symbol) + !tree.tpe.finalResultType.typeSymbol.primaryConstructor.isLessAccessibleThan(tree.symbol) + } - if (doTransform) { - tree foreach { - case i@Ident(_) => - enterReference(i.pos, i.symbol) // SI-5390 need to `enterReference` for `a` in `a.B()` - case _ => - } - toConstructor(tree.pos, tree.tpe) - } - else { - ifNot - tree + private def transformCaseApply(tree: Tree) = { + tree foreach { + case i@Ident(_) => + enterReference(i.pos, i.symbol) // SI-5390 need to `enterReference` for `a` in `a.B()` + case _ => } + toConstructor(tree.pos, tree.tpe) } private def transformApply(tree: Apply): Tree = tree match { @@ -1577,12 +1571,24 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans // term should have been eliminated by super accessors assert(!(qual.symbol.isTrait && sym.isTerm && mix == tpnme.EMPTY), (qual.symbol, sym, mix)) - transformCaseApply(tree, + // Rewrite eligible calls to monomorphic case companion apply methods to the equivalent constructor call. + // + // Note: for generic case classes the rewrite needs to be handled at the enclosing `TypeApply` to transform + // `TypeApply(Select(C, apply), targs)` to `Select(New(C[targs]), <init>)`. In case such a `TypeApply` + // was deemed ineligible for transformation (e.g. the case constructor was private), the refchecks transform + // will recurse to this point with `Select(C, apply)`, which will have a type `[T](...)C[T]`. + // + // We don't need to perform the check on the Select node, and `!isHigherKinded will guard against this + // redundant (and previously buggy, SI-9546) consideration. + if (!tree.tpe.isHigherKinded && isSimpleCaseApply(tree)) { + transformCaseApply(tree) + } else { qual match { case Super(_, mix) => checkSuper(mix) case _ => } - ) + tree + } } private def transformIf(tree: If): Tree = { val If(cond, thenpart, elsepart) = tree @@ -1706,7 +1712,10 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans case TypeApply(fn, args) => checkBounds(tree, NoPrefix, NoSymbol, fn.tpe.typeParams, args map (_.tpe)) - transformCaseApply(tree, ()) + if (isSimpleCaseApply(tree)) + transformCaseApply(tree) + else + tree case x @ Apply(_, _) => transformApply(x) @@ -1725,12 +1734,11 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans case Ident(name) => checkUndesiredProperties(sym, tree.pos) - transformCaseApply(tree, - if (name != nme.WILDCARD && name != tpnme.WILDCARD_STAR) { - assert(sym != NoSymbol, "transformCaseApply: name = " + name.debugString + " tree = " + tree + " / " + tree.getClass) //debug - enterReference(tree.pos, sym) - } - ) + if (name != nme.WILDCARD && name != tpnme.WILDCARD_STAR) { + assert(sym != NoSymbol, "transformCaseApply: name = " + name.debugString + " tree = " + tree + " / " + tree.getClass) //debug + enterReference(tree.pos, sym) + } + tree case x @ Select(_, _) => transformSelect(x) diff --git a/src/library/scala/collection/mutable/ListMap.scala b/src/library/scala/collection/mutable/ListMap.scala index 2ea5b1fa7c..e963af4a8a 100644 --- a/src/library/scala/collection/mutable/ListMap.scala +++ b/src/library/scala/collection/mutable/ListMap.scala @@ -15,7 +15,7 @@ package mutable import generic._ import annotation.tailrec -/** A simple mutable map backed by a list. +/** A simple mutable map backed by a list, so it preserves insertion order. * * @tparam A the type of the keys contained in this list map. * @tparam B the type of the values assigned to keys in this list map. diff --git a/src/scaladoc/scala/tools/nsc/doc/Settings.scala b/src/scaladoc/scala/tools/nsc/doc/Settings.scala index a63ed1abe8..9679a13e74 100644 --- a/src/scaladoc/scala/tools/nsc/doc/Settings.scala +++ b/src/scaladoc/scala/tools/nsc/doc/Settings.scala @@ -45,7 +45,7 @@ class Settings(error: String => Unit, val printMsg: String => Unit = println(_)) val docfooter = StringSetting ( "-doc-footer", "footer", - "A footer on every Scaladoc page, by default the EPFL/Typesafe copyright notice. Can be overridden with a custom footer.", + "A footer on every Scaladoc page, by default the EPFL/Lightbend copyright notice. Can be overridden with a custom footer.", "" ) diff --git a/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala index 9daca10e63..f70bac8f83 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala @@ -280,7 +280,7 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp { if (Set("epfl", "EPFL").contains(tpl.universe.settings.docfooter.value)) - <div id="footer">Scala programming documentation. Copyright (c) 2003-2016 <a href="http://www.epfl.ch" target="_top">EPFL</a>, with contributions from <a href="http://typesafe.com" target="_top">Typesafe</a>.</div> + <div id="footer">Scala programming documentation. Copyright (c) 2003-2016 <a href="http://www.epfl.ch" target="_top">EPFL</a>, with contributions from <a href="http://www.lightbend.com" target="_top">Lightbend</a>.</div> else <div id="footer"> { tpl.universe.settings.docfooter.value } </div> } diff --git a/test/files/run/t9546.scala b/test/files/run/t9546.scala new file mode 100644 index 0000000000..7016881084 --- /dev/null +++ b/test/files/run/t9546.scala @@ -0,0 +1,13 @@ +package foo { + case class Opt[A] private[foo](val get: A) extends AnyVal + object Opt { + def mkOpt = Opt("") + } +} + +object Test { + def main(args: Array[String]): Unit = { + foo.Opt.mkOpt + } +} + diff --git a/test/files/run/t9546b.scala b/test/files/run/t9546b.scala new file mode 100644 index 0000000000..0b4d2d3fe5 --- /dev/null +++ b/test/files/run/t9546b.scala @@ -0,0 +1,13 @@ +package foo { + case class Opt[A](val get: A) extends AnyVal { + } + object Opt { + def mkOpt = Opt("") + } +} + +object Test { + def main(args: Array[String]): Unit = { + foo.Opt.mkOpt + } +} diff --git a/test/files/run/t9546c.scala b/test/files/run/t9546c.scala new file mode 100644 index 0000000000..ea6a5a36b4 --- /dev/null +++ b/test/files/run/t9546c.scala @@ -0,0 +1,13 @@ +package foo { + case class Opt[A] private[foo](val get: A) + object Opt { + def mkOpt = Opt("") + } +} + +object Test { + def main(args: Array[String]): Unit = { + foo.Opt.mkOpt + } +} + diff --git a/test/files/run/t9546d.scala b/test/files/run/t9546d.scala new file mode 100644 index 0000000000..00bf37dc18 --- /dev/null +++ b/test/files/run/t9546d.scala @@ -0,0 +1,16 @@ +class X { + def test: Any = { + object Opt { + def mkOpt = Opt("") + } + case class Opt[A] private[X](val get: A) + Opt.mkOpt + } +} + +object Test { + def main(args: Array[String]): Unit = { + new X().test + } +} + diff --git a/test/files/run/t9546e.scala b/test/files/run/t9546e.scala new file mode 100644 index 0000000000..b19d0871aa --- /dev/null +++ b/test/files/run/t9546e.scala @@ -0,0 +1,15 @@ +case class A private (x: Int) +case class B private (x: Int)(y: Int) + +class C { + def f = A(1) + def g = B(1)(2) // was: constructor B in class B cannot be accessed in class C +} + +object Test { + def main(args: Array[String]): Unit = { + new C().f + new C().g + } + +} |