Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 20 additions & 20 deletions compiler/src/dotty/tools/dotc/transform/GenericSignatures.scala
Original file line number Diff line number Diff line change
Expand Up @@ -49,25 +49,31 @@ object GenericSignatures {
val builder = new StringBuilder(64)
val isTraitSignature = sym0.enclosingClass.is(Trait)

// Collect class-level type parameter names to avoid conflicts with method-level type parameters
val usedNames = collection.mutable.Set.empty[String]
// Collect class-level type parameter names from all enclosing classes to avoid conflicts with method-level type parameters
val usedNames = collection.mutable.Map.empty[String, Name]
if(sym0.is(Method)) {
sym0.enclosingClass.typeParams.foreach { tp =>
usedNames += sanitizeName(tp.name)
var enclosing = sym0.enclosingClass
while (enclosing.exists) {
enclosing.typeParams.foreach { tp =>
usedNames(sanitizeName(tp.name)) = tp.name
}
enclosing = enclosing.owner.enclosingClass
}
}
val methodTypeParamRenaming = collection.mutable.Map.empty[String, String]
def freshTypeParamName(sanitizedName: String): String = {
if !usedNames.contains(sanitizedName) then sanitizedName
val methodTypeParamRenaming = collection.mutable.Map.empty[Name, Name]
def freshTypeParamName(originalName: Name): Name = {
val sanitizedName = sanitizeName(originalName)
if !usedNames.contains(sanitizedName) then originalName
else {
var i = 1
var newName = sanitizedName + i
while usedNames.contains(newName) do
i += 1
newName = sanitizedName + i
methodTypeParamRenaming(sanitizedName) = newName
usedNames += newName
newName
val freshName = newName.toTypeName
methodTypeParamRenaming(originalName) = freshName
usedNames(newName) = freshName
freshName
}
}

Expand Down Expand Up @@ -161,8 +167,8 @@ object GenericSignatures {
Right(parent))

def tparamSig(param: TypeParamInfo): Unit = {
val freshName = freshTypeParamName(sanitizeName(param.paramName.lastPart))
builder.append(freshName)
val freshName = freshTypeParamName(param.paramName.lastPart)
builder.append(sanitizeName(freshName))
boundsSig(hiBounds(param.paramInfo.bounds))
}

Expand All @@ -179,12 +185,6 @@ object GenericSignatures {
builder.append(';')
}

def typeParamSigWithName(sanitizedName: String): Unit = {
builder.append(ClassfileConstants.TVAR_TAG)
builder.append(sanitizedName)
builder.append(';')
}

def methodResultSig(restpe: Type): Unit = {
val finalType = restpe.finalResultType
val sym = finalType.typeSymbol
Expand Down Expand Up @@ -274,9 +274,9 @@ object GenericSignatures {
if erasedUnderlying.isPrimitiveValueType then
jsig(erasedUnderlying, toplevel = toplevel, unboxedVCs = unboxedVCs)
else {
val name = sanitizeName(ref.paramName.lastPart)
val name = ref.paramName.lastPart
val nameToUse = methodTypeParamRenaming.getOrElse(name, name)
typeParamSigWithName(nameToUse)
typeParamSig(nameToUse)
}

case ref: TermRef if ref.symbol.isGetter =>
Expand Down
1 change: 1 addition & 0 deletions compiler/test/dotc/pos-test-pickling.excludelist
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ i11982a.scala
i17255
i17735.scala
i24134
i24134-nested

# Tree is huge and blows stack for printing Text
i7034.scala
Expand Down
2 changes: 2 additions & 0 deletions tests/pos/i24134-nested/JavaPartialFunction.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class Container[A]:
abstract class JavaPartialFunction[B] extends PartialFunction[A, B]
15 changes: 15 additions & 0 deletions tests/pos/i24134-nested/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
public class Main {
public static void main(String[] args) {
Container<String> container = new Container<>();
Container<String>.JavaPartialFunction<Integer> pf = container.new JavaPartialFunction<Integer>() {
@Override
public boolean isDefinedAt(String x) {
return x != null && !x.isEmpty();
}
@Override
public Integer apply(String x) {
return x.length();
}
};
}
}
Loading