Skip to content

Commit aff93b1

Browse files
authored
Merge pull request #2542 from dotty-staging/fix-#i2539
Fix error when adding refined terms to SAMs
2 parents 5fbf6b4 + a0ec7b2 commit aff93b1

File tree

3 files changed

+34
-3
lines changed

3 files changed

+34
-3
lines changed

compiler/src/dotty/tools/dotc/core/Definitions.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,10 +114,11 @@ class Definitions {
114114
val cls = denot.asClass.classSymbol
115115
val decls = newScope
116116
val arity = name.functionArity
117+
val paramNamePrefix = tpnme.scala_ ++ str.NAME_JOIN ++ name ++ str.EXPAND_SEPARATOR
117118
val argParams =
118-
for (i <- List.range(0, arity)) yield
119-
enterTypeParam(cls, name ++ "$T" ++ i.toString, Contravariant, decls)
120-
val resParam = enterTypeParam(cls, name ++ "$R", Covariant, decls)
119+
for (i <- List.range(1, arity + 1)) yield
120+
enterTypeParam(cls, paramNamePrefix ++ "T" ++ i.toString, Contravariant, decls)
121+
val resParam = enterTypeParam(cls, paramNamePrefix ++ "R", Covariant, decls)
121122
val (methodType, parentTraits) =
122123
if (name.firstPart.startsWith(str.ImplicitFunction)) {
123124
val superTrait =

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

Lines changed: 13 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
@@ -34,10 +35,13 @@ class ExpandSAMs extends MiniPhaseTransform { thisTransformer =>
3435
tpt.tpe match {
3536
case NoType => tree // it's a plain function
3637
case tpe @ SAMType(_) if tpe.isRef(defn.PartialFunctionClass) =>
38+
checkRefinements(tpe, fn.pos)
3739
toPartialFunction(tree)
3840
case tpe @ SAMType(_) if isPlatformSam(tpe.classSymbol.asClass) =>
41+
checkRefinements(tpe, fn.pos)
3942
tree
4043
case tpe =>
44+
checkRefinements(tpe, fn.pos)
4145
val Seq(samDenot) = tpe.abstractTermMembers.filter(!_.symbol.isSuperAccessor)
4246
cpy.Block(tree)(stats,
4347
AnonClass(tpe :: Nil, fn.symbol.asTerm :: Nil, samDenot.symbol.asTerm.name :: Nil))
@@ -83,4 +87,13 @@ class ExpandSAMs extends MiniPhaseTransform { thisTransformer =>
8387
val anonCls = AnonClass(tpt.tpe :: Nil, List(applyFn, isDefinedAtFn), List(nme.apply, nme.isDefinedAt))
8488
cpy.Block(tree)(List(applyDef, isDefinedAtDef), anonCls)
8589
}
90+
91+
private def checkRefinements(tpe: Type, pos: Position)(implicit ctx: Context): Unit = tpe match {
92+
case RefinedType(parent, name, _) =>
93+
if (name.isTermName && tpe.member(name).symbol.ownersIterator.isEmpty) // if member defined in the refinement
94+
ctx.error("Lambda does not define " + name, pos)
95+
checkRefinements(parent, pos)
96+
case _ =>
97+
}
98+
8699
}

tests/neg/i2539.scala

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
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+
val pf: PartialFunction[Int, Int]{ def foo(): Int } = { case x1 => 42 } // error
16+
17+
}

0 commit comments

Comments
 (0)