summaryrefslogtreecommitdiff
path: root/src/reflect
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-06-16 14:15:30 -0400
committerJason Zaugg <jzaugg@gmail.com>2013-06-16 17:09:33 -0400
commit83ae74ce9d3ff56c47b39e44332daa3da2981133 (patch)
tree2dfcbdad1ecb2039fe606730f348c2bdb2267d19 /src/reflect
parent70a93f52c3efafe604d6547b335cc361deff4f29 (diff)
downloadscala-83ae74ce9d3ff56c47b39e44332daa3da2981133.tar.gz
scala-83ae74ce9d3ff56c47b39e44332daa3da2981133.tar.bz2
scala-83ae74ce9d3ff56c47b39e44332daa3da2981133.zip
SI-7584 Fix typer regression with by-name parameter types
It regressed in fada1ef6b#L4L614. Partially reverting just this change restores the correct behaviour: ``` - if (sym.isStable && pre.isStable && !isByNameParamType(tree.tpe) && + if (treeInfo.admitsTypeSelection(tree) && ``` This patch embeds the check for by-name parameter types into `TreeInfo.isStableIdentifier`. That code already checks for `Symbol#isStable`, which exludes direct references to by-name parameters. But the additional check is required to deal with by-name parameters in function types, e.g `(=> Int) => Any`. Open question: should we go further and embed this check in `isStable`? Currently: final def isStable = isTerm && !isMutable && !(hasFlag(BYNAMEPARAM)) && (!isMethod || hasStableFlag) Such function types are an underspecified corner of the language, albeit one that is pretty useful writing, for example, in the signature of a lazy foldRight that can operate over infinite structures: def foldRight[A, B](fa: F[A], z: => B)(f: (A, => B) => B): B The next commit subjects them to a little testing.
Diffstat (limited to 'src/reflect')
-rw-r--r--src/reflect/scala/reflect/internal/TreeInfo.scala9
1 files changed, 8 insertions, 1 deletions
diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala
index 3a8d3fd460..a5cf46071f 100644
--- a/src/reflect/scala/reflect/internal/TreeInfo.scala
+++ b/src/reflect/scala/reflect/internal/TreeInfo.scala
@@ -98,7 +98,7 @@ abstract class TreeInfo {
*/
def isStableIdentifier(tree: Tree, allowVolatile: Boolean): Boolean =
tree match {
- case Ident(_) => symOk(tree.symbol) && tree.symbol.isStable && !tree.symbol.hasVolatileType // TODO SPEC: not required by spec
+ case i @ Ident(_) => isStableIdent(i)
case Select(qual, _) => isStableMemberOf(tree.symbol, qual, allowVolatile) && isPath(qual, allowVolatile)
case Apply(Select(free @ Ident(_), nme.apply), _) if free.symbol.name endsWith nme.REIFY_FREE_VALUE_SUFFIX =>
// see a detailed explanation of this trick in `GenSymbols.reifyFreeTerm`
@@ -119,6 +119,13 @@ abstract class TreeInfo {
typeOk(tree.tpe) && (allowVolatile || !hasVolatileType(tree)) && !definitions.isByNameParamType(tree.tpe)
)
+ private def isStableIdent(tree: Ident): Boolean = (
+ symOk(tree.symbol)
+ && tree.symbol.isStable
+ && !definitions.isByNameParamType(tree.tpe)
+ && !tree.symbol.hasVolatileType // TODO SPEC: not required by spec
+ )
+
/** Is `tree`'s type volatile? (Ignored if its symbol has the @uncheckedStable annotation.)
*/
def hasVolatileType(tree: Tree): Boolean =