@@ -602,7 +602,9 @@ class TypeErasure(sourceLanguage: SourceLanguage, semiEraseVCs: Boolean, isConst
602602 else if (tp.isRepeatedParam) apply(tp.translateFromRepeated(toArray = sourceLanguage.isJava))
603603 else if (semiEraseVCs && isDerivedValueClass(tycon.classSymbol)) eraseDerivedValueClass(tp)
604604 else apply(tp.translucentSuperType)
605- case _ : TermRef | _ : ThisType =>
605+ case tp : TermRef =>
606+ this (underlyingOfTermRef(tp))
607+ case _ : ThisType =>
606608 this (tp.widen)
607609 case SuperType (thistpe, supertpe) =>
608610 SuperType (this (thistpe), this (supertpe))
@@ -687,6 +689,19 @@ class TypeErasure(sourceLanguage: SourceLanguage, semiEraseVCs: Boolean, isConst
687689 tp
688690 }
689691
692+ /** Widen term ref, skipping any `()` parameter of an eventual getter. Used to erase a TermRef.
693+ * Since getters are introduced after erasure, one would think that erasing a TermRef
694+ * could just use `widen`. However, it's possible that the TermRef got read from a class
695+ * file after Getters (i.e. in the backend). In that case, the reference will not get
696+ * an earlier denotation even when time travelling forward to erasure. Hence, we
697+ * need to take the extra precaution of going from nullary method types to their resuls.
698+ * A test case where this is needed is pos/i15649.scala, which fails non-deterministically
699+ * if `underlyingOfTermRef` is replaced by `widen`.
700+ */
701+ private def underlyingOfTermRef (tp : TermRef )(using Context ) = tp.widen match
702+ case tpw @ MethodType (Nil ) if tp.symbol.isGetter => tpw.resultType
703+ case tpw => tpw
704+
690705 private def eraseArray (tp : Type )(using Context ) = {
691706 val defn .ArrayOf (elemtp) = tp : @ unchecked
692707 if (isGenericArrayElement(elemtp, isScala2 = sourceLanguage.isScala2)) defn.ObjectType
@@ -832,7 +847,7 @@ class TypeErasure(sourceLanguage: SourceLanguage, semiEraseVCs: Boolean, isConst
832847 case JavaArrayType (elem) =>
833848 sigName(elem) ++ " []"
834849 case tp : TermRef =>
835- sigName(tp.widen )
850+ sigName(underlyingOfTermRef(tp) )
836851 case ExprType (rt) =>
837852 sigName(defn.FunctionOf (Nil , rt))
838853 case tp : TypeVar =>
0 commit comments