Skip to content

Commit be7c492

Browse files
committed
SpecializeNames: Duplicate scalac behaviour, sort tparams
1 parent f2cdf82 commit be7c492

File tree

4 files changed

+37
-5
lines changed

4 files changed

+37
-5
lines changed

src/dotty/tools/dotc/core/NameOps.scala

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ object NameOps {
236236
case nme.clone_ => nme.clone_
237237
}
238238

239-
def specializedFor(returnType: Types.Type, args: List[Types.Type])(implicit ctx: Context): name.ThisName = {
239+
def specializedFor(classTargs: List[Types.Type], classTargsNames: List[Name], methodTargs: List[Types.Type], methodTarsNames: List[Name])(implicit ctx: Context): name.ThisName = {
240240

241241
def typeToTag(tp: Types.Type): Name = {
242242
tp.classSymbol match {
@@ -253,9 +253,12 @@ object NameOps {
253253
}
254254
}
255255

256+
val methodTags: Seq[Name] = (methodTargs zip methodTarsNames).sortBy(_._2).map(x => typeToTag(x._1))
257+
val classTags: Seq[Name] = (classTargs zip classTargsNames).sortBy(_._2).map(x => typeToTag(x._1))
258+
256259
name.fromName(name ++ nme.specializedTypeNames.prefix ++
257-
args.map(typeToTag).foldRight(typeToTag(returnType))(_ ++ _) ++
258-
nme.specializedTypeNames.suffix)
260+
methodTags.fold(nme.EMPTY)(_ ++ _) ++ nme.specializedTypeNames.separator ++
261+
classTags.fold(nme.EMPTY)(_ ++ _) ++ nme.specializedTypeNames.suffix)
259262
}
260263

261264
/** If name length exceeds allowable limit, replace part of it by hash */

src/dotty/tools/dotc/core/Names.scala

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,4 +338,27 @@ object Names {
338338
StringBuilder.newBuilder.mapResult(s => from.fromChars(s.toCharArray, 0, s.length))
339339
def apply(): Builder[Char, Name] = termNameBuilder
340340
}
341+
342+
implicit val NameOrdering: Ordering[Name] = new Ordering[Name] {
343+
def compare(x: Name, y: Name): Int = {
344+
if (x.isTermName && y.isTypeName) 1
345+
else if (x.isTypeName && y.isTermName) -1
346+
else if (x.start == y.start && x.length == y.length) 0
347+
else {
348+
val until = Math.min(x.length, y.length)
349+
var i = 0
350+
351+
while (i < until && x(i) == y(i)) i = i + 1
352+
353+
if (i < until) {
354+
if (x(i) < y(i)) -1
355+
else /*(x(i) > y(i))*/ 1
356+
} else {
357+
if (x.length < y.length) 1
358+
else if (x.length > y.length) -1
359+
else 0 // shouldn't happen, but still
360+
}
361+
}
362+
}
363+
}
341364
}

src/dotty/tools/dotc/core/StdNames.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,8 @@ object StdNames {
559559
final val Void: N = "V"
560560
final val Object: N = "L"
561561

562-
final val prefix: N = "$mc"
562+
final val prefix: N = "$m"
563+
final val separator: N = "c"
563564
final val suffix: N = "$sp"
564565
}
565566

src/dotty/tools/dotc/transform/FunctionalInterfaces.scala

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,12 @@ class FunctionalInterfaces extends MiniPhaseTransform {
6363
val m = tree.meth.tpe.widen.asInstanceOf[MethodType]
6464

6565
if (shouldSpecialize(m)) {
66-
val interfaceName = (functionName ++ m.paramTypes.length.toString).specializedFor(m.resultType, m.paramTypes)
66+
val functionSymbol = tree.tpe.widenDealias.classSymbol
67+
val names = ctx.atPhase(ctx.erasurePhase.prev) {
68+
implicit ctx => functionSymbol.typeParams.map(_.name)
69+
}
70+
val interfaceName = (functionName ++ m.paramTypes.length.toString).specializedFor(m.paramTypes ::: m.resultType :: Nil, names, Nil, Nil)
71+
6772
// symbols loaded from classpath aren't defined in periods earlier than when they where loaded
6873
val interface = ctx.withPhase(ctx.typerPhase).getClassIfDefined(functionPackage ++ interfaceName)
6974
if (interface.exists) {

0 commit comments

Comments
 (0)