Skip to content

Commit 1b4d574

Browse files
committed
Fix erasure of implicit functions
and check at runtime that it works
1 parent 0afce7e commit 1b4d574

File tree

4 files changed

+48
-50
lines changed

4 files changed

+48
-50
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ object TypeErasure {
4444
val sym = tp.symbol
4545
sym.isClass &&
4646
sym != defn.AnyClass && sym != defn.ArrayClass &&
47-
!defn.isUnimplementedFunctionClass(sym)
47+
!defn.isUnimplementedFunctionClass(sym) && !defn.isImplicitFunctionClass(sym)
4848
case _: TermRef =>
4949
true
5050
case JavaArrayType(elem) =>

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

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -345,21 +345,23 @@ object Erasure extends TypeTestsCasts{
345345
override def typedSelect(tree: untpd.Select, pt: Type)(implicit ctx: Context): Tree = {
346346

347347
def mapOwner(sym: Symbol): Symbol = {
348-
val owner = sym.owner
349-
if ((owner eq defn.AnyClass) || (owner eq defn.AnyValClass)) {
350-
assert(sym.isConstructor, s"${sym.showLocated}")
351-
defn.ObjectClass
352-
}
353-
else if (defn.isUnimplementedFunctionClass(owner))
354-
defn.FunctionXXLClass
355-
else
356-
owner
348+
def recur(owner: Symbol): Symbol =
349+
if ((owner eq defn.AnyClass) || (owner eq defn.AnyValClass)) {
350+
assert(sym.isConstructor, s"${sym.showLocated}")
351+
defn.ObjectClass
352+
} else if (defn.isUnimplementedFunctionClass(owner))
353+
defn.FunctionXXLClass
354+
else if (defn.isImplicitFunctionClass(owner))
355+
recur(defn.FunctionClass(owner.name.functionArity))
356+
else
357+
owner
358+
recur(sym.owner)
357359
}
358360

359-
var sym = tree.symbol
360-
val owner = mapOwner(sym)
361-
if (owner ne sym.owner) sym = owner.info.decl(sym.name).symbol
362-
assert(sym.exists, owner)
361+
val origSym = tree.symbol
362+
val owner = mapOwner(origSym)
363+
val sym = if (owner eq origSym.owner) origSym else owner.info.decl(origSym.name).symbol
364+
assert(sym.exists, origSym.showLocated)
363365

364366
def select(qual: Tree, sym: Symbol): Tree = {
365367
val name = tree.typeOpt match {

tests/pending/run/implicitFuns.scala

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
object Test {
2+
def main(args: Array[String]) = {
3+
4+
implicit val world: String = "world!"
5+
6+
val i1 = (implicit (s: String) => s.length > 2)
7+
val i2 = {implicit (s: String) => s.length > 2}
8+
9+
assert(i1)
10+
assert(i2)
11+
12+
val x: implicit String => Boolean = { implicit (s: String) => s.length > 2 }
13+
14+
val xx: implicit (String, Int) => Int = implicit (x: String, y: Int) => x.length + y
15+
16+
val y: String => Boolean = x
17+
18+
val yy: (String, Int) => Any = xx
19+
20+
val b = x("hello")
21+
22+
val b1: Boolean = b
23+
24+
val bi = x
25+
26+
val bi1: Boolean = bi
27+
28+
val c = xx("hh", 22)
29+
30+
val c1: Int = c
31+
}
32+
}

tests/pos/implicitFuns.scala

Lines changed: 0 additions & 36 deletions
This file was deleted.

0 commit comments

Comments
 (0)