@@ -410,8 +410,8 @@ object Semantic {
410
410
def select (f : Symbol , source : Tree ): Contextual [Result ] =
411
411
value.select(f, source) ++ errors
412
412
413
- def call (meth : Symbol , args : List [ArgInfo ], superType : Type , source : Tree ): Contextual [Result ] =
414
- value.call(meth, args, superType, source) ++ errors
413
+ def call (meth : Symbol , args : List [ArgInfo ], receiver : Type , superType : Type , source : Tree ): Contextual [Result ] =
414
+ value.call(meth, args, receiver, superType, source) ++ errors
415
415
416
416
def callConstructor (ctor : Symbol , args : List [ArgInfo ], source : Tree ): Contextual [Result ] =
417
417
value.callConstructor(ctor, args, source) ++ errors
@@ -587,7 +587,7 @@ object Semantic {
587
587
}
588
588
}
589
589
590
- def call (meth : Symbol , args : List [ArgInfo ], superType : Type , source : Tree , needResolve : Boolean = true ): Contextual [Result ] = log(" call " + meth.show + " , args = " + args, printer, (_ : Result ).show) {
590
+ def call (meth : Symbol , args : List [ArgInfo ], receiver : Type , superType : Type , source : Tree , needResolve : Boolean = true ): Contextual [Result ] = log(" call " + meth.show + " , args = " + args, printer, (_ : Result ).show) {
591
591
def checkArgs = args.flatMap(_.promote)
592
592
593
593
def isSyntheticApply (meth : Symbol ) =
@@ -600,6 +600,18 @@ object Semantic {
600
600
|| (meth eq defn.Object_ne )
601
601
|| (meth eq defn.Any_isInstanceOf )
602
602
603
+ def checkArgsWithParametricity () =
604
+ val methodType = atPhaseBeforeTransforms { meth.info.stripPoly }
605
+ var allArgsPromote = true
606
+ val errors = methodType.paramInfoss.flatten.zip(args).flatMap { (info, arg) =>
607
+ val isMatchable = info.repeatedToSingle <:< defn.MatchableType
608
+ val isTypeParam = info.repeatedToSingle.isInstanceOf [TypeParamRef ]
609
+ val errors = arg.promote
610
+ allArgsPromote = allArgsPromote && errors.isEmpty
611
+ if isTypeParam && ! isMatchable then Nil else errors
612
+ }
613
+ (errors, allArgsPromote)
614
+
603
615
// fast track if the current object is already initialized
604
616
if promoted.isCurrentObjectPromoted then Result (Hot , Nil )
605
617
else if isAlwaysSafe(meth) then Result (Hot , Nil )
@@ -610,7 +622,14 @@ object Semantic {
610
622
val klass = meth.owner.companionClass.asClass
611
623
instantiate(klass, klass.primaryConstructor, args, source)
612
624
else
613
- Result (Hot , checkArgs)
625
+ if meth.isStatic || receiver.isSingleton then
626
+ val (errors, allArgsPromote) = checkArgsWithParametricity()
627
+ if allArgsPromote || errors.nonEmpty then
628
+ Result (Hot , errors)
629
+ else
630
+ Result (Cold , errors)
631
+ else
632
+ Result (Hot , checkArgs)
614
633
615
634
case Cold =>
616
635
val error = CallCold (meth, source, trace.toVector)
@@ -666,7 +685,7 @@ object Semantic {
666
685
}
667
686
668
687
case RefSet (refs) =>
669
- val resList = refs.map(_.call(meth, args, superType, source))
688
+ val resList = refs.map(_.call(meth, args, receiver, superType, source))
670
689
val value2 = resList.map(_.value).join
671
690
val errors = resList.flatMap(_.errors)
672
691
Result (value2, errors)
@@ -946,7 +965,7 @@ object Semantic {
946
965
locally {
947
966
given Trace = trace2
948
967
val args = member.info.paramInfoss.flatten.map(_ => ArgInfo (Hot , EmptyTree ))
949
- val res = warm.call(member, args, superType = NoType , source = member.defTree)
968
+ val res = warm.call(member, args, receiver = NoType , superType = NoType , source = member.defTree)
950
969
buffer ++= res.ensureHot(msg, source).errors
951
970
}
952
971
else
@@ -1126,14 +1145,14 @@ object Semantic {
1126
1145
case Select (supert : Super , _) =>
1127
1146
val SuperType (thisTp, superTp) = supert.tpe
1128
1147
val thisValue2 = resolveThis(thisTp.classSymbol.asClass, thisV, klass, ref)
1129
- Result (thisValue2, errors).call(ref.symbol, args, superTp, expr)
1148
+ Result (thisValue2, errors).call(ref.symbol, args, thisTp, superTp, expr)
1130
1149
1131
1150
case Select (qual, _) =>
1132
1151
val res = eval(qual, thisV, klass) ++ errors
1133
1152
if ref.symbol.isConstructor then
1134
1153
res.callConstructor(ref.symbol, args, source = expr)
1135
1154
else
1136
- res.call(ref.symbol, args, superType = NoType , source = expr)
1155
+ res.call(ref.symbol, args, receiver = qual.tpe, superType = NoType , source = expr)
1137
1156
1138
1157
case id : Ident =>
1139
1158
id.tpe match
@@ -1142,13 +1161,13 @@ object Semantic {
1142
1161
val enclosingClass = id.symbol.owner.enclosingClass.asClass
1143
1162
val thisValue2 = resolveThis(enclosingClass, thisV, klass, id)
1144
1163
// local methods are not a member, but we can reuse the method `call`
1145
- thisValue2.call(id.symbol, args, superType = NoType , expr, needResolve = false )
1164
+ thisValue2.call(id.symbol, args, receiver = NoType , superType = NoType , expr, needResolve = false )
1146
1165
case TermRef (prefix, _) =>
1147
1166
val res = cases(prefix, thisV, klass, id) ++ errors
1148
1167
if id.symbol.isConstructor then
1149
1168
res.callConstructor(id.symbol, args, source = expr)
1150
1169
else
1151
- res.call(id.symbol, args, superType = NoType , source = expr)
1170
+ res.call(id.symbol, args, receiver = prefix, superType = NoType , source = expr)
1152
1171
1153
1172
case Select (qualifier, name) =>
1154
1173
val qualRes = eval(qualifier, thisV, klass)
0 commit comments