Skip to content

scalac -Yrewrite:collectionSeq #119

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 13 commits into
base: 2.12.x
Choose a base branch
from
10 changes: 9 additions & 1 deletion src/compiler/scala/tools/nsc/Global.scala
Original file line number Diff line number Diff line change
Expand Up @@ -483,10 +483,17 @@ class Global(var currentSettings: Settings, reporter0: Reporter)
val global: Global.this.type = Global.this
} with Analyzer

// phaseName = "rewrites"
object rewrites extends {
val global: Global.this.type = Global.this
val runsAfter = List("typer")
val runsRightAfter = None
} with Rewrites

// phaseName = "patmat"
object patmat extends {
val global: Global.this.type = Global.this
val runsAfter = List("typer")
val runsAfter = List("rewrites")
val runsRightAfter = None
// patmat doesn't need to be right after typer, as long as we run before superaccessors
// (sbt does need to run right after typer, so don't conflict)
Expand Down Expand Up @@ -672,6 +679,7 @@ class Global(var currentSettings: Settings, reporter0: Reporter)
analyzer.namerFactory -> "resolve names, attach symbols to named trees",
analyzer.packageObjects -> "load package objects",
analyzer.typerFactory -> "the meat and potatoes: type the trees",
rewrites -> "source code rewrites",
patmat -> "translate match expressions",
superAccessors -> "add super accessors in traits and nested classes",
extensionMethods -> "add extension methods for inline classes",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ abstract class BTypesFromClassfile {

def nestedClasses: List[ClassBType] = classNode.innerClasses.asScala.collect({
case i if nestedInCurrentClass(i) => classBTypeFromParsedClassfile(i.name)
})(collection.breakOut)
})(collection.breakOut[scala.collection.mutable.Buffer[scala.tools.asm.tree.InnerClassNode], BTypesFromClassfile.this.postProcessor.bTypes.ClassBType, List[BTypesFromClassfile.this.postProcessor.bTypes.ClassBType]])

// if classNode is a nested class, it has an innerClass attribute for itself. in this
// case we build the NestedInfo.
Expand All @@ -129,7 +129,7 @@ abstract class BTypesFromClassfile {

val inlineInfo = inlineInfoFromClassfile(classNode)

val interfaces: List[ClassBType] = classNode.interfaces.asScala.map(classBTypeFromParsedClassfile)(collection.breakOut)
val interfaces: List[ClassBType] = classNode.interfaces.asScala.map(classBTypeFromParsedClassfile)(collection.breakOut[scala.collection.mutable.Buffer[String], BTypesFromClassfile.this.postProcessor.bTypes.ClassBType, List[BTypesFromClassfile.this.postProcessor.bTypes.ClassBType]])

Right(ClassInfo(superClass, interfaces, flags, Lazy.withoutLock(nestedClasses), Lazy.withoutLock(nestedInfo), inlineInfo))
}
Expand Down Expand Up @@ -162,7 +162,7 @@ abstract class BTypesFromClassfile {
annotatedInline = false,
annotatedNoInline = false)
((methodNode.name, methodNode.desc), info)
})(scala.collection.breakOut)
})(scala.collection.breakOut[scala.collection.mutable.Buffer[scala.tools.asm.tree.MethodNode], ((String, String), tools.nsc.backend.jvm.BTypes.MethodInlineInfo), Map[(String, String),tools.nsc.backend.jvm.BTypes.MethodInlineInfo]])
InlineInfo(
isEffectivelyFinal = BytecodeUtils.isFinalClass(classNode),
sam = inlinerHeuristics.javaSam(classNode.name),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ abstract class BTypesFromSymbols[G <: Global](val global: G) extends BTypes {
val r = exitingPickler(sym.moduleClass)
assert(r != NoSymbol, sym.fullLocationString)
r
})(collection.breakOut)
})(collection.breakOut[Iterable[BTypesFromSymbols.this.global.Symbol], BTypesFromSymbols.this.global.Symbol, List[BTypesFromSymbols.this.global.Symbol]])

private def computeClassInfo(classSym: Symbol, classBType: ClassBType): Right[Nothing, ClassInfo] = {
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,11 @@ abstract class ClassfileWriters {
val basicClassWriter = settings.outputDirs.getSingleOutput match {
case Some(dest) => new SingleClassWriter(FileWriter(global, dest, jarManifestMainClass))
case None =>
val distinctOutputs: Set[AbstractFile] = settings.outputDirs.outputs.map(_._2)(scala.collection.breakOut)
val distinctOutputs: Set[AbstractFile] = settings.outputDirs.outputs.map(_._2)(scala.collection.breakOut[List[(scala.tools.nsc.io.AbstractFile, scala.tools.nsc.io.AbstractFile)], scala.tools.nsc.io.AbstractFile, Set[tools.nsc.io.AbstractFile]])
if (distinctOutputs.size == 1) new SingleClassWriter(FileWriter(global, distinctOutputs.head, jarManifestMainClass))
else {
val sourceToOutput: Map[AbstractFile, AbstractFile] = global.currentRun.units.map(unit => (unit.source.file, frontendAccess.compilerSettings.outputDirectory(unit.source.file))).toMap
new MultiClassWriter(sourceToOutput, distinctOutputs.map { output: AbstractFile => output -> FileWriter(global, output, jarManifestMainClass) }(scala.collection.breakOut))
new MultiClassWriter(sourceToOutput, distinctOutputs.map { output: AbstractFile => output -> FileWriter(global, output, jarManifestMainClass) }(scala.collection.breakOut[scala.collection.immutable.Set[tools.nsc.io.AbstractFile], (tools.nsc.io.AbstractFile, ClassfileWriters.this.FileWriter), Map[tools.nsc.io.AbstractFile,ClassfileWriters.this.FileWriter]]))
}
}

Expand Down
14 changes: 7 additions & 7 deletions src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ abstract class CoreBTypesFromSymbols[G <: Global] extends CoreBTypes {
val bType = primitiveTypeToBType(primitive)
val name = newTermName(getName(primitive.name.toString, boxedClass(primitive).name.toString))
(bType, methodNameAndType(BoxesRunTimeClass, name))
})(collection.breakOut)
})(collection.breakOut[List[CoreBTypesFromSymbols.this.bTypes.global.ClassSymbol], (CoreBTypesFromSymbols.this.bTypes.PrimitiveBType, CoreBTypesFromSymbols.this.bTypes.MethodNameAndType), Map[CoreBTypesFromSymbols.this.bTypes.BType,CoreBTypesFromSymbols.this.bTypes.MethodNameAndType]])
}

// Z -> MethodNameAndType(boxToBoolean,(Z)Ljava/lang/Boolean;)
Expand All @@ -263,7 +263,7 @@ abstract class CoreBTypesFromSymbols[G <: Global] extends CoreBTypes {
val boxed = boxedClass(primitive)
val method = methodNameAndType(boxed, newTermName("valueOf"), static = true, filterOverload = singleParamOfClass(primitive))
(classBTypeFromSymbol(boxed).internalName, method)
})(collection.breakOut)
})(collection.breakOut[List[CoreBTypesFromSymbols.this.bTypes.global.ClassSymbol], (tools.nsc.backend.jvm.BTypes.InternalName, CoreBTypesFromSymbols.this.bTypes.MethodNameAndType), Map[tools.nsc.backend.jvm.BTypes.InternalName,CoreBTypesFromSymbols.this.bTypes.MethodNameAndType]])
}

// java/lang/Boolean -> MethodNameAndType(booleanValue,()Z)
Expand All @@ -273,15 +273,15 @@ abstract class CoreBTypesFromSymbols[G <: Global] extends CoreBTypes {
val boxed = boxedClass(primitive)
val name = primitive.name.toString.toLowerCase + "Value"
(classBTypeFromSymbol(boxed).internalName, methodNameAndType(boxed, newTermName(name)))
})(collection.breakOut)
})(collection.breakOut[List[CoreBTypesFromSymbols.this.bTypes.global.ClassSymbol], (tools.nsc.backend.jvm.BTypes.InternalName, CoreBTypesFromSymbols.this.bTypes.MethodNameAndType), Map[tools.nsc.backend.jvm.BTypes.InternalName,CoreBTypesFromSymbols.this.bTypes.MethodNameAndType]])
}

private def predefBoxingMethods(getName: (String, String) => String): Map[String, MethodBType] = {
ScalaValueClassesNoUnit.map(primitive => {
val boxed = boxedClass(primitive)
val name = getName(primitive.name.toString, boxed.name.toString)
(name, methodNameAndType(PredefModule.moduleClass, newTermName(name)).methodType)
})(collection.breakOut)
})(collection.breakOut[List[CoreBTypesFromSymbols.this.bTypes.global.ClassSymbol], (String, CoreBTypesFromSymbols.this.bTypes.MethodBType), Map[String,CoreBTypesFromSymbols.this.bTypes.MethodBType]])
}

// boolean2Boolean -> (Z)Ljava/lang/Boolean;
Expand All @@ -294,7 +294,7 @@ abstract class CoreBTypesFromSymbols[G <: Global] extends CoreBTypes {

private def staticRefMethods(name: Name): Map[InternalName, MethodNameAndType] = {
allRefClasses.map(refClass =>
(classBTypeFromSymbol(refClass).internalName, methodNameAndType(refClass, name, static = true)))(collection.breakOut)
(classBTypeFromSymbol(refClass).internalName, methodNameAndType(refClass, name, static = true)))(collection.breakOut[scala.collection.immutable.Set[CoreBTypesFromSymbols.this.bTypes.global.Symbol], (tools.nsc.backend.jvm.BTypes.InternalName, CoreBTypesFromSymbols.this.bTypes.MethodNameAndType), Map[tools.nsc.backend.jvm.BTypes.InternalName,CoreBTypesFromSymbols.this.bTypes.MethodNameAndType]])
}

// scala/runtime/BooleanRef -> MethodNameAndType(create,(Z)Lscala/runtime/BooleanRef;)
Expand All @@ -311,11 +311,11 @@ abstract class CoreBTypesFromSymbols[G <: Global] extends CoreBTypes {
ScalaValueClassesNoUnit.map(primitive => {
val boxed = boxedClass(primitive)
(classBTypeFromSymbol(boxed).internalName, methodNameAndType(boxed, nme.CONSTRUCTOR, filterOverload = singleParamOfClass(primitive)))
})(collection.breakOut)
})(collection.breakOut[List[CoreBTypesFromSymbols.this.bTypes.global.ClassSymbol], (tools.nsc.backend.jvm.BTypes.InternalName, CoreBTypesFromSymbols.this.bTypes.MethodNameAndType), Map[tools.nsc.backend.jvm.BTypes.InternalName,CoreBTypesFromSymbols.this.bTypes.MethodNameAndType]])
}

private def nonOverloadedConstructors(classes: Iterable[Symbol]): Map[InternalName, MethodNameAndType] = {
classes.map(cls => (classBTypeFromSymbol(cls).internalName, methodNameAndType(cls, nme.CONSTRUCTOR)))(collection.breakOut)
classes.map(cls => (classBTypeFromSymbol(cls).internalName, methodNameAndType(cls, nme.CONSTRUCTOR)))(collection.breakOut[Iterable[CoreBTypesFromSymbols.this.bTypes.global.Symbol], (tools.nsc.backend.jvm.BTypes.InternalName, CoreBTypesFromSymbols.this.bTypes.MethodNameAndType), Map[tools.nsc.backend.jvm.BTypes.InternalName,CoreBTypesFromSymbols.this.bTypes.MethodNameAndType]])
}

// scala/runtime/BooleanRef -> MethodNameAndType(<init>,(Z)V)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ object PostProcessorFrontendAccess {
def javaDefinedClasses: Set[InternalName] = frontendSynch {
currentRun.symSource.keys.collect{
case sym if sym.isJavaDefined => sym.javaBinaryNameString
}(scala.collection.breakOut)
}(scala.collection.breakOut[Iterable[PostProcessorFrontendAccessImpl.this.global.Symbol], String, Set[tools.nsc.backend.jvm.BTypes.InternalName]])
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ trait ProdConsAnalyzerImpl {
case ParameterProducer(local) => consumersOfValueAt(methodNode.instructions.getFirst, local)
case ExceptionProducer(handlerLabel, handlerStackTop) => consumersOfValueAt(handlerLabel, handlerStackTop)
case _ =>
_consumersOfOutputsFrom.get(insn).map(v => v.indices.flatMap(v.apply)(collection.breakOut): Set[AbstractInsnNode]).getOrElse(Set.empty)
_consumersOfOutputsFrom.get(insn).map(v => v.indices.flatMap(v.apply)(collection.breakOut[scala.collection.immutable.IndexedSeq[Int], scala.tools.asm.tree.AbstractInsnNode, Set[scala.tools.asm.tree.AbstractInsnNode]]): Set[AbstractInsnNode]).getOrElse(Set.empty)
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/scala/tools/nsc/backend/jvm/opt/BoxUnbox.scala
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ abstract class BoxUnbox {
})

if (canRewrite) {
val localSlots: Vector[(Int, Type)] = boxKind.boxedTypes.map(tp => (getLocal(tp.getSize), tp))(collection.breakOut)
val localSlots: Vector[(Int, Type)] = boxKind.boxedTypes.map(tp => (getLocal(tp.getSize), tp))(collection.breakOut[List[scala.tools.asm.Type], (Int, scala.tools.asm.Type), Vector[(Int, scala.tools.asm.Type)]])

// store boxed value(s) into localSlots
val storeOps = localSlots.toList reverseMap { case (slot, tp) =>
Expand All @@ -246,7 +246,7 @@ abstract class BoxUnbox {
if (keepBox) {
val loadOps: List[VarInsnNode] = localSlots.map({ case (slot, tp) =>
new VarInsnNode(tp.getOpcode(ILOAD), slot)
})(collection.breakOut)
})(collection.breakOut[scala.collection.immutable.Vector[(Int, scala.tools.asm.Type)], scala.tools.asm.tree.VarInsnNode, List[scala.tools.asm.tree.VarInsnNode]])
toInsertBefore(creation.valuesConsumer) = storeInitialValues ::: loadOps
} else {
toReplace(creation.valuesConsumer) = storeInitialValues
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,7 @@ abstract class ClosureOptimizer {
val local = Local(firstLocal + i + sizeTwoOffset, offset)
if (local.size == 2) sizeTwoOffset += 1
local
})(collection.breakOut)
})(collection.breakOut[scala.collection.immutable.IndexedSeq[Int], ClosureOptimizer.this.Local, List[ClosureOptimizer.this.Local]])
LocalsList(locals)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ object ZipAndJarClassPathFactory extends ZipAndJarFileLookupFactory {
val packages = collection.mutable.HashMap[String, PackageFileInfo]()

def getSubpackages(dir: AbstractFile): List[AbstractFile] =
(for (file <- dir if file.isPackage) yield file)(collection.breakOut)
(for (file <- dir if file.isPackage) yield file)(collection.breakOut[Iterable[scala.reflect.io.AbstractFile], scala.reflect.io.AbstractFile, List[scala.reflect.io.AbstractFile]])

@tailrec
def traverse(packagePrefix: String,
Expand Down Expand Up @@ -146,7 +146,7 @@ object ZipAndJarClassPathFactory extends ZipAndJarFileLookupFactory {
override private[nsc] def classes(inPackage: PackageName): Seq[ClassFileEntry] = cachedPackages.get(inPackage.dottedString) match {
case None => Seq.empty
case Some(PackageFileInfo(pkg, _)) =>
(for (file <- pkg if file.isClass) yield ClassFileEntryImpl(file))(collection.breakOut)
(for (file <- pkg if file.isClass) yield ClassFileEntryImpl(file))(collection.breakOut[Iterable[scala.reflect.io.AbstractFile], scala.tools.nsc.classpath.ClassFileEntryImpl, Seq[scala.tools.nsc.classpath.ClassFileEntry]])
}


Expand Down
8 changes: 8 additions & 0 deletions src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ trait ScalaSettings extends StandardScalaSettings with Warnings { _: MutableSett
val stopAfter = PhasesSetting ("-Ystop-after", "Stop after") withAbbreviation ("-stop") // backward compat
val stopBefore = PhasesSetting ("-Ystop-before", "Stop before")
val Yrangepos = BooleanSetting ("-Yrangepos", "Use range positions for syntax trees.")
val Yrewrites = MultiChoiceSetting("-Yrewrites", "rewrite", "Enable rewrites", domain = rewriteChoices).withPostSetHook(_ => {Yrangepos.value = true; stopAfter.value = List("rewrites")})
val Yvalidatepos = PhasesSetting ("-Yvalidate-pos", s"Validate positions after the given phases (implies ${Yrangepos.name})") withPostSetHook (_ => Yrangepos.value = true)
val Ymemberpos = StringSetting ("-Yshow-member-pos", "output style", s"Show start and end positions of members (implies ${Yrangepos.name})", "") withPostSetHook (_ => Yrangepos.value = true)
val Yreifycopypaste = BooleanSetting ("-Yreify-copypaste", "Dump the reified trees in copypasteable representation.")
Expand Down Expand Up @@ -277,6 +278,13 @@ trait ScalaSettings extends StandardScalaSettings with Warnings { _: MutableSett
def values: List[CachePolicy] = List(None, LastModified, Always)
}

object rewriteChoices extends MultiChoiceEnumeration {
val breakOutArgs = Choice("breakOutArgs", "Add explicit type argumetns to calls of `collection.breakOut`")
val collectionSeq = Choice("collectionSeq", "(Indexed)Seq => collection.(Indexed)Seq")
val varargsToSeq = Choice("varargsToSeq", "(xs: _*) => (xs.toSeq: _*) ")
val importCollectionsCompat = Choice("importCollectionsCompat", "")
}

object optChoices extends MultiChoiceEnumeration {
val unreachableCode = Choice("unreachable-code", "Eliminate unreachable code, exception handlers guarding no instructions, redundant metadata (debug information, line numbers).")
val simplifyJumps = Choice("simplify-jumps", "Simplify branching instructions, eliminate unnecessary ones.")
Expand Down
Loading