Skip to content

Commit 2da2c0b

Browse files
authored
Merge pull request #11006 from dotty-staging/fix-10888
Fix #10888: Avoid A.this.B for Java inner classes
2 parents 668e9a5 + b3ba79f commit 2da2c0b

File tree

2 files changed

+29
-16
lines changed

2 files changed

+29
-16
lines changed

compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -349,13 +349,19 @@ class ClassfileParser(
349349
val tag = sig(index); index += 1
350350
(tag: @switch) match {
351351
case 'L' =>
352-
def processInner(tp: Type): Type = tp match {
353-
case tp: TypeRef if !tp.symbol.owner.is(Flags.ModuleClass) =>
354-
TypeRef(processInner(tp.prefix.widen), tp.symbol.asType)
355-
case _ =>
356-
tp
357-
}
358-
def processClassType(tp: Type): Type = tp match {
352+
/** A type representation where inner classes become `A#B` instead of `A.this.B` (like with `typeRef`)
353+
*
354+
* Note: the symbol must not be nested in a generic class.
355+
*/
356+
def innerType(symbol: Symbol): Type =
357+
if symbol.is(Flags.Package) then
358+
symbol.thisType
359+
else if symbol.isType then
360+
TypeRef(innerType(symbol.owner), symbol)
361+
else
362+
throw new RuntimeException("unexpected term symbol " + symbol)
363+
364+
def processTypeArgs(tp: Type): Type = tp match {
359365
case tp: TypeRef =>
360366
if (sig(index) == '<') {
361367
accept('<')
@@ -388,13 +394,13 @@ class ClassfileParser(
388394
}
389395

390396
val classSym = classNameToSymbol(subName(c => c == ';' || c == '<'))
391-
val classTpe = if (classSym eq defn.ObjectClass) defn.FromJavaObjectType else classSym.typeRef
392-
var tpe = processClassType(processInner(classTpe))
397+
val classTpe = if (classSym eq defn.ObjectClass) defn.FromJavaObjectType else innerType(classSym)
398+
var tpe = processTypeArgs(classTpe)
393399
while (sig(index) == '.') {
394400
accept('.')
395401
val name = subName(c => c == ';' || c == '<' || c == '.').toTypeName
396-
val clazz = tpe.member(name).symbol
397-
tpe = processClassType(processInner(TypeRef(tpe, clazz)))
402+
val tp = tpe.select(name)
403+
tpe = processTypeArgs(tp)
398404
}
399405
accept(';')
400406
tpe
@@ -432,15 +438,15 @@ class ClassfileParser(
432438
paramtypes += {
433439
if isRepeatedParam(index) then
434440
index += 1
435-
val elemType = sig2type(tparams, skiptvs)
441+
val elemType = sig2type(tparams, skiptvs = false)
436442
// `ElimRepeated` is responsible for correctly erasing this.
437443
defn.RepeatedParamType.appliedTo(elemType)
438444
else
439-
sig2type(tparams, skiptvs)
445+
sig2type(tparams, skiptvs = false)
440446
}
441447

442448
index += 1
443-
val restype = sig2type(tparams, skiptvs)
449+
val restype = sig2type(tparams, skiptvs = false)
444450
JavaMethodType(paramnames.toList, paramtypes.toList, restype)
445451
case 'T' =>
446452
val n = subName(';'.==).toTypeName

compiler/test/dotty/tools/AnnotationsTests.scala

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,20 @@ class AnnotationsTest:
2929
val arrayOfString = defn.ArrayType.appliedTo(List(defn.StringType))
3030

3131
atPhase(erasurePhase.next) {
32-
val annot = cls.getAnnotation(annotCls)
3332
// Even though we're forcing the annotation after erasure,
3433
// the typed trees should be unerased, so the type of
3534
// the annotation argument should be `arrayOfString` and
3635
// not a `JavaArrayType`.
36+
val annot = cls.getAnnotation(annotCls)
3737
val arg = annot.get.argument(0).get
38-
assert(arg.tpe.isInstanceOf[AppliedType] && arg.tpe =:= arrayOfString,
38+
39+
// If we run the type check after erasure, we will have
40+
// `Array[String] =:= Array[String]` being false.
41+
// The reason is that in `TypeComparer.compareAppliedType2` we have
42+
// `tycon2.typeParams == Nil` after erasure, thus always get false.
43+
val res = atPhase(typerPhase) { arrayOfString =:= arg.tpe }
44+
45+
assert(arg.tpe.isInstanceOf[AppliedType] && res,
3946
s"Argument $arg had type:\n${arg.tpe}\nbut expected type:\n$arrayOfString")
4047
}
4148
}

0 commit comments

Comments
 (0)