Skip to content

Commit 64f61f5

Browse files
committed
Move out of Defn, revert unneeded
1 parent 4bc1323 commit 64f61f5

File tree

7 files changed

+60
-61
lines changed

7 files changed

+60
-61
lines changed

compiler/src/dotty/tools/dotc/core/Definitions.scala

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -736,22 +736,6 @@ class Definitions {
736736
@tu lazy val MethodHandlesLookupClass: ClassSymbol = requiredClass("java.lang.invoke.MethodHandles.Lookup")
737737
@tu lazy val VarHandleClass: ClassSymbol = requiredClass("java.lang.invoke.VarHandle")
738738

739-
// Java language spec: https://docs.oracle.com/javase/specs/jls/se11/html/jls-15.html#jls-15.12.3
740-
// Scala 2 spec: https://scala-lang.org/files/archive/spec/2.13/06-expressions.html#signature-polymorphic-methods
741-
def isPolymorphicSignature(sym: Symbol) = sym.is(JavaDefined) && {
742-
val owner = sym.maybeOwner
743-
(owner == MethodHandleClass || owner == VarHandleClass)
744-
&& sym.hasAnnotation(NativeAnnot)
745-
&& sym.paramSymss.match
746-
case List(List(p)) => p.info.isRepeatedParam
747-
case _ => false
748-
}
749-
750-
def wasPolymorphicSignature(sym: Symbol) =
751-
val owner = sym.maybeOwner
752-
(owner == MethodHandleClass || owner == VarHandleClass)
753-
&& isPolymorphicSignature(owner.info.member(sym.name).symbol)
754-
755739
@tu lazy val StringBuilderClass: ClassSymbol = requiredClass("scala.collection.mutable.StringBuilder")
756740
@tu lazy val MatchErrorClass : ClassSymbol = requiredClass("scala.MatchError")
757741
@tu lazy val ConversionClass : ClassSymbol = requiredClass("scala.Conversion").typeRef.symbol.asClass

compiler/src/dotty/tools/dotc/core/SymDenotations.scala

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -960,6 +960,26 @@ object SymDenotations {
960960

961961
def isSkolem: Boolean = name == nme.SKOLEM
962962

963+
// Java language spec: https://docs.oracle.com/javase/specs/jls/se11/html/jls-15.html#jls-15.12.3
964+
// Scala 2 spec: https://scala-lang.org/files/archive/spec/2.13/06-expressions.html#signature-polymorphic-methods
965+
def isSignaturePolymorphic(using Context): Boolean =
966+
containsSignaturePolymorphic
967+
&& is(JavaDefined)
968+
&& hasAnnotation(defn.NativeAnnot)
969+
&& atPhase(typerPhase)(symbol.denot).paramSymss.match
970+
case List(List(p)) => p.info.isRepeatedParam
971+
case _ => false
972+
973+
def containsSignaturePolymorphic(using Context): Boolean =
974+
maybeOwner == defn.MethodHandleClass
975+
|| maybeOwner == defn.VarHandleClass
976+
977+
def originalSignaturePolymorphic(using Context): Denotation =
978+
if containsSignaturePolymorphic && !isSignaturePolymorphic then
979+
val d = owner.info.member(name)
980+
if d.symbol.isSignaturePolymorphic then d else NoDenotation
981+
else NoDenotation
982+
963983
def isInlineMethod(using Context): Boolean =
964984
isAllOf(InlineMethod, butNot = Accessor)
965985

compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1238,18 +1238,17 @@ class TreeUnpickler(reader: TastyReader,
12381238
val rdr = fork
12391239
val start = rdr.reader.currentAddr
12401240
if rdr.reader.readByte() == APPLY then
1241-
val end = rdr.reader.readEnd()
1242-
val fn = rdr.readTerm()
1243-
if defn.isPolymorphicSignature(fn.symbol) then
1244-
skipTree() // expr
1245-
skipTree() // tpt
1241+
val end = rdr.reader.readEnd()
1242+
val fn = rdr.readTerm()
1243+
if fn.symbol.isSignaturePolymorphic then
12461244
val args = rdr.reader.until(end)(rdr.readTerm())
1247-
val tpt = rdr.readTpt()
1245+
skipTree() // expr
1246+
val tpt = readTpt()
12481247
val info = MethodType(args.map(_.tpe.widen), tpt.tpe)
1249-
val fun2 = fn.withType(fn.symbol.copy(info = info).termRef)
1250-
val app = Apply(fun2, args)
1251-
rdr.setSpan(start, app)
1252-
Typed(app, tpt)
1248+
val sym2 = fn.symbol.copy(info = info) // still not entered (like simpleApply)
1249+
val fun2 = fn.withType(sym2.termRef)
1250+
val app = Apply(fun2, args)
1251+
Typed(setSpan(start, app), tpt)
12531252
else Typed(readTerm(), readTpt())
12541253
else Typed(readTerm(), readTpt())
12551254
case ASSIGN =>

compiler/src/dotty/tools/dotc/semanticdb/SemanticSymbolBuilder.scala

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,9 @@ class SemanticSymbolBuilder:
7474
def addOwner(owner: Symbol): Unit =
7575
if !owner.isRoot then addSymName(b, owner)
7676

77-
def addOverloadIdx(sym: Symbol): Unit =
77+
def addOverloadIdx(initSym: Symbol): Unit =
78+
// revert from the compiler-generated overload of the signature polymorphic method
79+
val sym = initSym.originalSignaturePolymorphic.symbol.orElse(initSym)
7880
val decls =
7981
val decls0 = sym.owner.info.decls.lookupAll(sym.name)
8082
if sym.owner.isAllOf(JavaModule) then
@@ -90,10 +92,7 @@ class SemanticSymbolBuilder:
9092
case _ =>
9193
end find
9294
val sig = sym.signature
93-
// the polymorphic signature methods (invoke/invokeExact) are never overloaded
94-
// we changed the signature at the call site, which means they won't match,
95-
// but we still shouldn't add any overload index in this case.
96-
find(_.signature == sig || defn.wasPolymorphicSignature(sym))
95+
find(_.signature == sig)
9796

9897
def addDescriptor(sym: Symbol): Unit =
9998
if sym.is(ModuleClass) then

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,8 +203,7 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
203203
return transformSelect(cpy.Select(tree)(qual.select(pobj).withSpan(qual.span), tree.name), targs)
204204
case _ =>
205205
}
206-
val tree0 = super.transform(tree)
207-
val tree1 = if defn.wasPolymorphicSignature(tree.symbol) then tree0.withType(tree.tpe) else tree0
206+
val tree1 = super.transform(tree)
208207
constToLiteral(tree1) match {
209208
case _: Literal => tree1
210209
case _ => superAcc.transformSelect(tree1, targs)

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

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -212,11 +212,9 @@ abstract class Recheck extends Phase, SymTransformer:
212212
mt.instantiate(argTypes)
213213

214214
def recheckApply(tree: Apply, pt: Type)(using Context): Type =
215-
val wasPolymorphicSignature = tree.fun.tpe match
216-
case funRef: TermRef => defn.wasPolymorphicSignature(funRef.symbol)
217-
case _ => false
218-
if wasPolymorphicSignature then tree.fun.tpe.widenTermRefExpr.finalResultType
219-
else recheck(tree.fun).widen match
215+
// reuse the tree's type if the function was a signature polymorphic method, instead of rechecking it
216+
val tpe = if tree.fun.symbol.originalSignaturePolymorphic.exists then tree.fun.tpe else recheck(tree.fun)
217+
tpe.widen match
220218
case fntpe: MethodType =>
221219
assert(fntpe.paramInfos.hasSameLengthAs(tree.args))
222220
val formals =

compiler/src/dotty/tools/dotc/typer/Applications.scala

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -937,30 +937,30 @@ trait Applications extends Compatibility {
937937
/** Type application where arguments come from prototype, and no implicits are inserted */
938938
def simpleApply(fun1: Tree, proto: FunProto)(using Context): Tree =
939939
methPart(fun1).tpe match {
940+
case funRef: TermRef if funRef.symbol.isSignaturePolymorphic =>
941+
// synthesize a method type based on the types at the call site.
942+
// one can imagine the original signature-polymorphic method as
943+
// being infinitely overloaded, with each individual overload only
944+
// being brought into existence as needed
945+
val originalResultType = funRef.symbol.info.resultType.stripNull
946+
val expectedResultType = AvoidWildcardsMap()(proto.deepenProto.resultType)
947+
val resultType =
948+
if !originalResultType.isRef(defn.ObjectClass) then originalResultType
949+
else if isFullyDefined(expectedResultType, ForceDegree.all) then expectedResultType
950+
else expectedResultType match
951+
case SelectionProto(nme.asInstanceOf_, PolyProto(_, resTp), _, _) => resTp
952+
case _ => defn.ObjectType
953+
val info = MethodType(proto.typedArgs().map(_.tpe.widen), resultType)
954+
val sym2 = funRef.symbol.copy(info = info) // not entered, to avoid overload resolution problems
955+
val fun2 = fun1.withType(sym2.termRef)
956+
val app = simpleApply(fun2, proto)
957+
Typed(app, TypeTree(resultType))
940958
case funRef: TermRef =>
941-
if defn.isPolymorphicSignature(funRef.symbol) then
942-
val originalResultType = funRef.symbol.info.resultType.stripNull
943-
val expectedResultType = AvoidWildcardsMap()(proto.deepenProto.resultType)
944-
val resultType =
945-
if !originalResultType.isRef(defn.ObjectClass) then originalResultType
946-
else if isFullyDefined(expectedResultType, ForceDegree.all) then expectedResultType
947-
else expectedResultType match
948-
case SelectionProto(nme.asInstanceOf_, PolyProto(_, resTp), _, _) => resTp
949-
case _ => defn.ObjectType
950-
// synthesize a method type based on the types at the call site.
951-
// one can imagine the original signature-polymorphic method as
952-
// being infinitely overloaded, with each individual overload only
953-
// being brought into existence as needed
954-
val info = MethodType(proto.typedArgs().map(_.tpe.widen), resultType)
955-
val fun2 = fun1.withType(funRef.symbol.copy(info = info).termRef)
956-
val app = simpleApply(fun2, proto)
957-
Typed(app, TypeTree(resultType))
958-
else
959-
val app = ApplyTo(tree, fun1, funRef, proto, pt)
960-
convertNewGenericArray(
961-
widenEnumCase(
962-
postProcessByNameArgs(funRef, app).computeNullable(),
963-
pt))
959+
val app = ApplyTo(tree, fun1, funRef, proto, pt)
960+
convertNewGenericArray(
961+
widenEnumCase(
962+
postProcessByNameArgs(funRef, app).computeNullable(),
963+
pt))
964964
case _ =>
965965
handleUnexpectedFunType(tree, fun1)
966966
}

0 commit comments

Comments
 (0)