Skip to content

Commit 83ae74c

Browse files
committed
SI-7584 Fix typer regression with by-name parameter types
It regressed in fada1ef#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.
1 parent 70a93f5 commit 83ae74c

File tree

2 files changed

+19
-1
lines changed

2 files changed

+19
-1
lines changed

src/reflect/scala/reflect/internal/TreeInfo.scala

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ abstract class TreeInfo {
9898
*/
9999
def isStableIdentifier(tree: Tree, allowVolatile: Boolean): Boolean =
100100
tree match {
101-
case Ident(_) => symOk(tree.symbol) && tree.symbol.isStable && !tree.symbol.hasVolatileType // TODO SPEC: not required by spec
101+
case i @ Ident(_) => isStableIdent(i)
102102
case Select(qual, _) => isStableMemberOf(tree.symbol, qual, allowVolatile) && isPath(qual, allowVolatile)
103103
case Apply(Select(free @ Ident(_), nme.apply), _) if free.symbol.name endsWith nme.REIFY_FREE_VALUE_SUFFIX =>
104104
// see a detailed explanation of this trick in `GenSymbols.reifyFreeTerm`
@@ -119,6 +119,13 @@ abstract class TreeInfo {
119119
typeOk(tree.tpe) && (allowVolatile || !hasVolatileType(tree)) && !definitions.isByNameParamType(tree.tpe)
120120
)
121121

122+
private def isStableIdent(tree: Ident): Boolean = (
123+
symOk(tree.symbol)
124+
&& tree.symbol.isStable
125+
&& !definitions.isByNameParamType(tree.tpe)
126+
&& !tree.symbol.hasVolatileType // TODO SPEC: not required by spec
127+
)
128+
122129
/** Is `tree`'s type volatile? (Ignored if its symbol has the @uncheckedStable annotation.)
123130
*/
124131
def hasVolatileType(tree: Tree): Boolean =

test/files/pos/t7584.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
object Test {
2+
def fold[A, B](f: (A, => B) => B) = ???
3+
def f[A, B](x: A, y: B): B = ???
4+
def bip[A, B] = fold[A, B]((x, y) => f(x, y))
5+
def bop[A, B] = fold[A, B](f)
6+
7+
// these work:
8+
fold[Int, Int]((x, y) => f(x, y))
9+
fold[Int, Int](f)
10+
}
11+

0 commit comments

Comments
 (0)