Skip to content

Commit

Permalink
Merge pull request #9630 from SethTisue/unseal-substmap
Browse files Browse the repository at this point in the history
  • Loading branch information
SethTisue committed May 14, 2021
2 parents cefcd53 + 35a9354 commit 9468b9a
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 26 deletions.
9 changes: 5 additions & 4 deletions src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
Expand Up @@ -1439,10 +1439,11 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
to: List[Symbol],
targetClass: Symbol,
addressFields: Boolean) extends TreeSymSubstituter(from, to) {
private def matcher(sym1: Symbol, sym2: Symbol) =
if (sym2.isTypeSkolem) sym2.deSkolemize eq sym1
else sym1 eq sym2
override val symSubst = SubstSymMap(from, to, matcher)
override val symSubst = new SubstSymMap(from, to) {
override def matches(sym1: Symbol, sym2: Symbol) =
if (sym2.isTypeSkolem) sym2.deSkolemize eq sym1
else sym1 eq sym2
}

private def isAccessible(sym: Symbol): Boolean =
if (currentOwner.isAnonymousFunction) {
Expand Down
2 changes: 1 addition & 1 deletion src/reflect/scala/reflect/internal/Symbols.scala
Expand Up @@ -3766,7 +3766,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
else {
val syms1 = mapList(syms)(_.cloneSymbol)
cloneSymbolsSubstSymMap.using { (msm: SubstSymMap) =>
msm.reload(syms, syms1)
msm.reset(syms, syms1)
syms1.foreach(_.modifyInfo(msm))
}
syms1
Expand Down
2 changes: 1 addition & 1 deletion src/reflect/scala/reflect/internal/Types.scala
Expand Up @@ -4059,7 +4059,7 @@ trait Types
val resultThis = result.typeSymbol.thisType
val substThisMap = new SubstThisMap(original.typeSymbol, resultThis)
copyRefinedTypeSSM.using { (msm: SubstSymMap) =>
msm.reload(syms1, syms2)
msm.reset(syms1, syms2)
syms2.foreach(_.modifyInfo(info => msm.apply(substThisMap.apply(info))))
}
}
Expand Down
41 changes: 21 additions & 20 deletions src/reflect/scala/reflect/internal/tpe/TypeMaps.scala
Expand Up @@ -20,7 +20,6 @@ import Flags._
import scala.annotation.{nowarn, tailrec}
import Variance._
import scala.collection.mutable.ListBuffer
import scala.util.chaining._

private[internal] trait TypeMaps {
self: SymbolTable =>
Expand Down Expand Up @@ -665,24 +664,27 @@ private[internal] trait TypeMaps {
}

/** A base class to compute all substitutions. */
sealed abstract class SubstMap[T >: Null] extends TypeMap {
private[this] var _from: List[Symbol] = Nil
private[this] var _to: List[T] = Nil
abstract class SubstMap[T >: Null](from0: List[Symbol], to0: List[T]) extends TypeMap {
private[this] var from: List[Symbol] = from0
private[this] var to: List[T] = to0

private[this] var fromHasTermSymbol = false
private[this] var fromMin = Int.MaxValue
private[this] var fromMax = Int.MinValue
private[this] var fromSize = 0

final def from: List[Symbol] = _from
final def to: List[T] = _to
// So SubstTypeMap can expose them publicly
// while SubstMap can continue to access them as private fields
protected[this] final def accessFrom: List[Symbol] = from
protected[this] final def accessTo: List[T] = to

def reload(from0: List[Symbol], to0: List[T]): this.type = {
reset(from0, to0)
def reset(from0: List[Symbol], to0: List[T]): this.type = {
// OPT this check was 2-3% of some profiles, demoted to -Xdev
if (isDeveloper) assert(sameLength(from, to), "Unsound substitution from "+ from +" to "+ to)

_from = from0
_to = to0
from = from0
to = to0

fromHasTermSymbol = false
fromMin = Int.MaxValue
Expand Down Expand Up @@ -783,7 +785,11 @@ private[internal] trait TypeMaps {
}

/** A map to implement the `substSym` method. */
sealed class SubstSymMap private () extends SubstMap[Symbol] {
class SubstSymMap(from0: List[Symbol], to0: List[Symbol]) extends SubstMap[Symbol](from0, to0) {
def this(pairs: (Symbol, Symbol)*) = this(pairs.toList.map(_._1), pairs.toList.map(_._2))

private[this] final def from: List[Symbol] = accessFrom
private[this] final def to: List[Symbol] = accessTo

protected def toType(fromTpe: Type, sym: Symbol) = fromTpe match {
case TypeRef(pre, _, args) => copyTypeRef(fromTpe, pre, sym, args)
Expand Down Expand Up @@ -845,19 +851,14 @@ private[internal] trait TypeMaps {

object SubstSymMap {
def apply(): SubstSymMap = new SubstSymMap()
def apply(from: List[Symbol], to: List[Symbol]): SubstSymMap = new SubstSymMap().tap(_.reload(from, to))
def apply(from: List[Symbol], to: List[Symbol], cmp: (Symbol, Symbol) => Boolean): SubstSymMap = {
val ssm = new SubstSymMap() {
override protected def matches(sym: Symbol, sym1: Symbol): Boolean = cmp(sym, sym1)
}
ssm.tap(_.reload(from, to))
}
def apply(fromto: (Symbol, Symbol)): SubstSymMap = apply(List(fromto._1), List(fromto._2))
def apply(from: List[Symbol], to: List[Symbol]): SubstSymMap = new SubstSymMap(from, to)
def apply(fromto: (Symbol, Symbol)): SubstSymMap = new SubstSymMap(fromto)
}

/** A map to implement the `subst` method. */
class SubstTypeMap(from0: List[Symbol], to0: List[Type]) extends SubstMap[Type] {
super.reload(from0, to0)
class SubstTypeMap(from0: List[Symbol], to0: List[Type]) extends SubstMap[Type](from0, to0) {
final def from: List[Symbol] = accessFrom
final def to: List[Type] = accessTo

override protected def toType(fromtp: Type, tp: Type) = tp

Expand Down
13 changes: 13 additions & 0 deletions test/junit/scala/reflect/internal/SubstMapTest.scala
@@ -0,0 +1,13 @@
package scala.reflect.internal

import scala.tools.nsc.symtab.SymbolTableForUnitTesting

class SubstMapTest {
object symbolTable extends SymbolTableForUnitTesting
import symbolTable._

// compile-test for https://github.com/scala/community-build/pull/1413
new SubstMap[String](Nil, Nil) {
protected def toType(fromtp: Type, tp: String) = fromtp
}
}

0 comments on commit 9468b9a

Please sign in to comment.