Skip to content

Commit 8ab198d

Browse files
committed
Filter values by class before member selection
1 parent dea3d10 commit 8ab198d

File tree

1 file changed

+26
-17
lines changed

1 file changed

+26
-17
lines changed

compiler/src/dotty/tools/dotc/transform/init/Semantic.scala

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -548,9 +548,23 @@ object Semantic:
548548
value.promote(msg)
549549
value
550550

551+
def filterClass(sym: Symbol)(using Context): Value =
552+
if !sym.isClass then value
553+
else
554+
val klass = sym.asClass
555+
value match
556+
case Cold => Cold
557+
case Hot => Hot
558+
case ref: Ref => if ref.klass.isSubClass(klass) then ref else Hot
559+
case RefSet(values) => values.map(v => v.filterClass(klass)).join
560+
case fun: Fun =>
561+
if klass.isOneOf(Flags.AbstractOrTrait) && klass.baseClasses.exists(defn.isFunctionClass)
562+
then fun
563+
else Hot
564+
551565
def select(field: Symbol, receiver: Type, needResolve: Boolean = true): Contextual[Value] = log("select " + field.show + ", this = " + value, printer, (_: Value).show) {
552566
if promoted.isCurrentObjectPromoted then Hot
553-
else value match
567+
else value.filterClass(field.owner) match
554568
case Hot =>
555569
Hot
556570

@@ -588,13 +602,8 @@ object Semantic:
588602
reporter.report(error)
589603
Hot
590604
else
591-
if ref.klass.isSubClass(receiver.widenSingleton.classSymbol) then
592-
report.warning("[Internal error] Unexpected resolution failure: ref.klass = " + ref.klass.show + ", field = " + field.show + Trace.show, Trace.position)
593-
Hot
594-
else
595-
// This is possible due to incorrect type cast.
596-
// See tests/init/pos/Type.scala
597-
Hot
605+
report.warning("[Internal error] Unexpected resolution failure: ref.klass = " + ref.klass.show + ", field = " + field.show + Trace.show, Trace.position)
606+
Hot
598607

599608
case fun: Fun =>
600609
report.warning("[Internal error] unexpected tree in selecting a function, fun = " + fun.expr.show + Trace.show, fun.expr)
@@ -645,11 +654,16 @@ object Semantic:
645654
}
646655
(errors, allArgsHot)
647656

657+
def filterValue(value: Value): Value =
658+
// methods of polyfun does not have denotation
659+
if !meth.exists then value
660+
else value.filterClass(meth.owner)
661+
648662
// fast track if the current object is already initialized
649663
if promoted.isCurrentObjectPromoted then Hot
650664
else if isAlwaysSafe(meth) then Hot
651665
else if meth eq defn.Any_asInstanceOf then value
652-
else value match {
666+
else filterValue(value) match {
653667
case Hot =>
654668
if isSyntheticApply(meth) && meth.hasSource then
655669
val klass = meth.owner.companionClass.asClass
@@ -724,13 +738,8 @@ object Semantic:
724738
else
725739
value.select(target, receiver, needResolve = false)
726740
else
727-
if ref.klass.isSubClass(receiver.widenSingleton.classSymbol) then
728-
report.warning("[Internal error] Unexpected resolution failure: ref.klass = " + ref.klass.show + ", meth = " + meth.show + Trace.show, Trace.position)
729-
Hot
730-
else
731-
// This is possible due to incorrect type cast.
732-
// See tests/init/pos/Type.scala
733-
Hot
741+
report.warning("[Internal error] Unexpected resolution failure: ref.klass = " + ref.klass.show + ", meth = " + meth.show + Trace.show, Trace.position)
742+
Hot
734743

735744
case Fun(body, thisV, klass) =>
736745
// meth == NoSymbol for poly functions
@@ -822,7 +831,7 @@ object Semantic:
822831
warm
823832

824833
if promoted.isCurrentObjectPromoted then Hot
825-
else value match {
834+
else value.filterClass(klass.owner) match {
826835
case Hot =>
827836
var allHot = true
828837
val args2 = args.map { arg =>

0 commit comments

Comments
 (0)