Skip to content

Commit 157b3d4

Browse files
committed
Fix #2539: Error when adding refined terms to SAMs
1 parent 1e0d6be commit 157b3d4

File tree

2 files changed

+27
-0
lines changed

2 files changed

+27
-0
lines changed

compiler/src/dotty/tools/dotc/transform/ExpandSAMs.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import TreeTransforms._
88
import SymUtils._
99
import ast.untpd
1010
import ast.Trees._
11+
import dotty.tools.dotc.util.Positions.Position
1112

1213
/** Expand SAM closures that cannot be represented by the JVM as lambdas to anonymous classes.
1314
* These fall into five categories
@@ -36,8 +37,10 @@ class ExpandSAMs extends MiniPhaseTransform { thisTransformer =>
3637
case tpe @ SAMType(_) if tpe.isRef(defn.PartialFunctionClass) =>
3738
toPartialFunction(tree)
3839
case tpe @ SAMType(_) if isPlatformSam(tpe.classSymbol.asClass) =>
40+
checkRefinements(tpe, fn.pos)
3941
tree
4042
case tpe =>
43+
checkRefinements(tpe, fn.pos)
4144
val Seq(samDenot) = tpe.abstractTermMembers.filter(!_.symbol.isSuperAccessor)
4245
cpy.Block(tree)(stats,
4346
AnonClass(tpe :: Nil, fn.symbol.asTerm :: Nil, samDenot.symbol.asTerm.name :: Nil))
@@ -83,4 +86,13 @@ class ExpandSAMs extends MiniPhaseTransform { thisTransformer =>
8386
val anonCls = AnonClass(tpt.tpe :: Nil, List(applyFn, isDefinedAtFn), List(nme.apply, nme.isDefinedAt))
8487
cpy.Block(tree)(List(applyDef, isDefinedAtDef), anonCls)
8588
}
89+
90+
private def checkRefinements(tpe: Type, pos: Position)(implicit ctx: Context): Unit = tpe match {
91+
case RefinedType(parent, name, _) =>
92+
if (name.isTermName && tpe.member(name).symbol.ownersIterator.isEmpty) // if member defined in the refinement
93+
ctx.error(s"Cannot refine $name on a lambda", pos)
94+
checkRefinements(parent, pos)
95+
case _ =>
96+
}
97+
8698
}

tests/neg/i2539.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
object Foo {
2+
val f0: Function0[Int]{ def foo(): Int } = () => 42 // error
3+
4+
val f1: Function1[Int, Int]{ def foo(): Int } = x1 => 42 // error
5+
6+
val f26: Function26[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]{ def foo(): Int } =
7+
(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26) => 42 // error
8+
9+
val if1: ImplicitFunction1[Int, Int]{ def foo(): Int } = implicit x1 => 42 // error
10+
11+
abstract class Fun0[X] extends Function0[X]
12+
val fun0a: Fun0[Int] = () => 42
13+
val fun0b: Fun0[Int] { def foo(): Int } = () => 42 // error
14+
15+
}

0 commit comments

Comments
 (0)