Skip to content

Commit 5cbac9d

Browse files
committed
Fix #4345: properly instantiate dependent methods
The raw paramInfoss of a method type contain parameter references that should be instantiated before using the type anywhere.
1 parent c59183f commit 5cbac9d

File tree

2 files changed

+19
-8
lines changed

2 files changed

+19
-8
lines changed

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

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -233,14 +233,15 @@ trait FullParameterization {
233233
fun.appliedToArgss(originalDef.vparamss.nestedMap(vparam => ref(vparam.symbol)))
234234
else {
235235
// this type could have changed on forwarding. Need to insert a cast.
236-
val args = (originalDef.vparamss, fun.tpe.paramInfoss).zipped.map((vparams, paramTypes) =>
237-
(vparams, paramTypes).zipped.map((vparam, paramType) => {
238-
assert(vparam.tpe <:< paramType.widen) // type should still conform to widened type
239-
ref(vparam.symbol).ensureConforms(paramType)
240-
})
241-
)
242-
fun.appliedToArgss(args)
243-
236+
originalDef.vparamss.foldLeft[Tree](fun)((acc, vparams) => {
237+
val meth = acc.tpe.asInstanceOf[MethodType]
238+
val paramTypes = meth.instantiateParamInfos(vparams.map(_.tpe))
239+
acc.appliedToArgs(
240+
(vparams, paramTypes).zipped.map((vparam, paramType) => {
241+
assert(vparam.tpe <:< paramType.widen) // type should still conform to widened type
242+
ref(vparam.symbol).ensureConforms(paramType)
243+
}))
244+
})
244245
}).withPos(originalDef.rhs.pos)
245246
}
246247
}

tests/pos/i4345.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import scala.annotation.tailrec
2+
class Context {
3+
type Tree
4+
}
5+
6+
class Test {
7+
@tailrec
8+
final def loop(c: Context)(trees: List[c.Tree]): Boolean =
9+
loop(c)(trees)
10+
}

0 commit comments

Comments
 (0)