Skip to content

Commit b666323

Browse files
committed
Fix types of implicit definitions in transparent closure
We need the type of the reference, not the type of the symbol. With this change, the code specialization example compiles and runs correctly.
1 parent bdf2b54 commit b666323

File tree

3 files changed

+38
-4
lines changed

3 files changed

+38
-4
lines changed

compiler/src/dotty/tools/dotc/typer/PrepareTransparent.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -265,19 +265,19 @@ object PrepareTransparent {
265265
object referenced extends TreeTraverser {
266266
val typeAtPos = mutable.Map[Position, Type]()
267267
val accessorAtPos = mutable.Map[Position, Symbol]()
268-
val implicitSyms = mutable.Set[Symbol]()
268+
val implicitRefTypes = mutable.Set[Type]()
269269
val implicitRefs = new mutable.ListBuffer[Tree]
270270

271271
def registerIfContextualImplicit(tree: Tree) = tree match {
272272
case tree: RefTree
273273
if tree.removeAttachment(ContextualImplicit).isDefined &&
274274
tree.symbol.exists &&
275275
!isLocalOrParam(tree.symbol, inlineMethod) &&
276-
!implicitSyms.contains(tree.symbol) =>
276+
!implicitRefTypes.contains(tree.tpe) =>
277277
if (tree.existsSubTree(t => isLocal(tree.symbol, inlineMethod)))
278278
ctx.warning("implicit reference $tree is dropped at inline site because it refers to local symbol(s)", tree.pos)
279279
else {
280-
implicitSyms += tree.symbol
280+
implicitRefTypes += tree.tpe
281281
implicitRefs += tree
282282
}
283283
case _ =>
@@ -386,7 +386,7 @@ object PrepareTransparent {
386386
owner = inlineMethod,
387387
name = UniqueInlineName.fresh(iref.symbol.name.asTermName),
388388
flags = Implicit | Method | Stable,
389-
info = iref.symbol.info.ensureMethodic,
389+
info = iref.tpe.widen.ensureMethodic,
390390
coord = inlineMethod.pos).asTerm
391391
polyDefDef(localImplicit, tps => vrefss =>
392392
iref.appliedToTypes(tps).appliedToArgss(vrefss))

tests/run/typelevel-numeric.check

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
-1.0

tests/run/typelevel-numeric.scala

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
2+
import math.Numeric
3+
4+
abstract class MathLib[N : Numeric] {
5+
def dotProduct(xs: Array[N], ys: Array[N]): N
6+
}
7+
8+
object MathLib {
9+
10+
transparent def apply[N](implicit n: Numeric[N]) = new MathLib[N] {
11+
import n._
12+
def dotProduct(xs: Array[N], ys: Array[N]): N = {
13+
require(xs.length == ys.length)
14+
var i = 0
15+
var s: N = n.zero
16+
while (i < xs.length) {
17+
s = s + xs(i) * ys(i)
18+
i += 1
19+
}
20+
s
21+
}
22+
}
23+
}
24+
25+
object Test extends App {
26+
27+
val mlib = MathLib.apply[Double](scala.math.Numeric.DoubleIsFractional)
28+
29+
val xs = Array(1.0, 1.0)
30+
val ys = Array(2.0, -3.0)
31+
val p = mlib.dotProduct(xs, ys)
32+
println(p)
33+
}

0 commit comments

Comments
 (0)