aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--project/Build.scala2
-rw-r--r--src/dotty/runtime/Arrays.scala2
-rw-r--r--src/dotty/tools/backend/jvm/DottyBackendInterface.scala13
-rw-r--r--src/dotty/tools/dotc/Bench.scala27
-rw-r--r--src/dotty/tools/dotc/Compiler.scala9
-rw-r--r--src/dotty/tools/dotc/Driver.scala38
-rw-r--r--src/dotty/tools/dotc/FromTasty.scala1
-rw-r--r--src/dotty/tools/dotc/Main.scala17
-rw-r--r--src/dotty/tools/dotc/Resident.scala55
-rw-r--r--src/dotty/tools/dotc/Run.scala8
-rw-r--r--src/dotty/tools/dotc/config/CompilerCommand.scala5
-rw-r--r--src/dotty/tools/dotc/config/Config.scala11
-rw-r--r--src/dotty/tools/dotc/config/ScalaSettings.scala1
-rw-r--r--src/dotty/tools/dotc/core/Constraint.scala3
-rw-r--r--src/dotty/tools/dotc/core/Flags.scala2
-rw-r--r--src/dotty/tools/dotc/core/NameOps.scala2
-rw-r--r--src/dotty/tools/dotc/core/OrderingConstraint.scala30
-rw-r--r--src/dotty/tools/dotc/core/StdNames.scala2
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala9
-rw-r--r--src/dotty/tools/dotc/core/TypeErasure.scala26
-rw-r--r--src/dotty/tools/dotc/core/TyperState.scala8
-rw-r--r--src/dotty/tools/dotc/core/Types.scala5
-rw-r--r--src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala2
-rw-r--r--src/dotty/tools/dotc/parsing/Parsers.scala2
-rw-r--r--src/dotty/tools/dotc/reporting/ConsoleReporter.scala2
-rw-r--r--src/dotty/tools/dotc/reporting/Reporter.scala2
-rw-r--r--src/dotty/tools/dotc/reporting/StoreReporter.scala2
-rw-r--r--src/dotty/tools/dotc/reporting/ThrowingReporter.scala7
-rw-r--r--src/dotty/tools/dotc/transform/AugmentScala2Traits.scala2
-rw-r--r--src/dotty/tools/dotc/transform/ClassOf.scala39
-rw-r--r--src/dotty/tools/dotc/transform/Erasure.scala26
-rw-r--r--src/dotty/tools/dotc/transform/ExtensionMethods.scala4
-rw-r--r--src/dotty/tools/dotc/transform/LambdaLift.scala3
-rw-r--r--src/dotty/tools/dotc/transform/LinkScala2ImplClasses.scala2
-rw-r--r--src/dotty/tools/dotc/transform/Mixin.scala9
-rw-r--r--src/dotty/tools/dotc/transform/TraitConstructors.scala36
-rw-r--r--src/dotty/tools/dotc/transform/TreeChecker.scala12
-rw-r--r--src/dotty/tools/dotc/transform/TypeTestsCasts.scala2
-rw-r--r--src/dotty/tools/dotc/typer/FrontEnd.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala2
-rw-r--r--src/dotty/tools/dotc/typer/RefChecks.scala35
-rw-r--r--src/dotty/tools/dotc/util/SimpleMap.scala14
-rw-r--r--src/dotty/tools/dotc/util/SourceFile.scala17
-rw-r--r--src/dotty/tools/dotc/util/SourcePosition.scala4
-rw-r--r--test/dotc/tests.scala3
-rw-r--r--test/dotty/partest/DPConfig.scala7
-rw-r--r--test/dotty/partest/DPConsoleRunner.scala29
-rw-r--r--test/dotty/partest/DPDirectCompiler.scala23
-rw-r--r--test/test/CompilerTest.scala2
-rw-r--r--tests/neg/final-sealed.scala4
-rw-r--r--tests/neg/firstError.scala4
-rw-r--r--tests/neg/i705-inner-value-class.scala22
-rw-r--r--tests/pending/run/unittest_collection.check1
-rw-r--r--tests/pos/extmethods.scala1
-rw-r--r--tests/pos/t8230a.scala (renamed from tests/pending/pos/t8230a.scala)6
-rw-r--r--tests/run/i689.scala10
-rw-r--r--tests/run/origins.check6
-rw-r--r--tests/run/t8002.scala (renamed from tests/pending/run/t8002.scala)0
-rw-r--r--tests/run/unittest_collection.scala (renamed from tests/pending/run/unittest_collection.scala)0
-rw-r--r--tests/run/valueclasses-nested-object.check1
-rw-r--r--tests/run/valueclasses-nested-object.scala16
61 files changed, 395 insertions, 242 deletions
diff --git a/project/Build.scala b/project/Build.scala
index 79cb7d9b7..473ef2443 100644
--- a/project/Build.scala
+++ b/project/Build.scala
@@ -42,7 +42,7 @@ object DottyBuild extends Build {
resolvers += Resolver.sonatypeRepo("releases"),
// get libraries onboard
- partestDeps := Seq("me.d-d" % "scala-compiler" % "2.11.5-20150506-175515-8fc7635b56",
+ partestDeps := Seq("me.d-d" % "scala-compiler" % "2.11.5-20150619-173733-3bcd390afa",
"org.scala-lang" % "scala-reflect" % scalaVersion.value,
"org.scala-lang" % "scala-library" % scalaVersion.value % "test"),
libraryDependencies ++= partestDeps.value,
diff --git a/src/dotty/runtime/Arrays.scala b/src/dotty/runtime/Arrays.scala
index 1fb4fe5eb..4469dced7 100644
--- a/src/dotty/runtime/Arrays.scala
+++ b/src/dotty/runtime/Arrays.scala
@@ -7,6 +7,8 @@ import scala.reflect.ClassTag
*/
object Arrays {
+ // note: this class is magical. Do not touch it unless you know what you are doing.`
+
/** Creates an array of some element type determined by the given `ClassTag`
* argument. The erased type of applications of this method is `Object`.
*/
diff --git a/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/src/dotty/tools/backend/jvm/DottyBackendInterface.scala
index 855147ac4..4a828c5bd 100644
--- a/src/dotty/tools/backend/jvm/DottyBackendInterface.scala
+++ b/src/dotty/tools/backend/jvm/DottyBackendInterface.scala
@@ -157,9 +157,16 @@ class DottyBackendInterface()(implicit ctx: Context) extends BackendInterface{
}.toMap
def unboxMethods: Map[Symbol, Symbol] = defn.ScalaValueClasses.map(x => (x, Erasure.Boxing.unboxMethod(x.asClass))).toMap
- private val mkArrayNames: Set[String] = Set("Byte", "Float", "Char", "Double", "Boolean", "Unit", "Long", "Int", "Short", "Ref")
+ private val mkArrayNames: Set[Name] = Set("Byte", "Float", "Char", "Double", "Boolean", "Unit", "Long", "Int", "Short", "Ref").map{ x=>
+ ("new" + x + "Array").toTermName
+ }
+
+ val dottyArraysModuleClass = toDenot(defn.DottyArraysModule).moduleClass.asClass
- override lazy val syntheticArrayConstructors: Set[Symbol] = mkArrayNames.map(nm => ctx.requiredMethod(toDenot(defn.DottyArraysModule).moduleClass.asClass, s"new${nm}Array"))
+
+ override def isSyntheticArrayConstructor(s: Symbol) = {
+ (toDenot(s).maybeOwner eq dottyArraysModuleClass) && mkArrayNames.contains(s.name)
+ }
def isBox(sym: Symbol): Boolean = Erasure.Boxing.isBox(sym)
def isUnbox(sym: Symbol): Boolean = Erasure.Boxing.isUnbox(sym)
@@ -480,7 +487,7 @@ class DottyBackendInterface()(implicit ctx: Context) extends BackendInterface{
implicit def positionHelper(a: Position): PositionHelper = new PositionHelper {
def isDefined: Boolean = a.exists
- def line: Int = sourcePos(a).line
+ def line: Int = sourcePos(a).line + 1
def finalPosition: Position = a
}
diff --git a/src/dotty/tools/dotc/Bench.scala b/src/dotty/tools/dotc/Bench.scala
index 2e0e15e83..417054dce 100644
--- a/src/dotty/tools/dotc/Bench.scala
+++ b/src/dotty/tools/dotc/Bench.scala
@@ -8,19 +8,7 @@ package dotc
import core.Contexts.Context
import reporting.Reporter
-/* To do:
- * - simplify hk types
- * - have a second look at normalization (leave at method types if pt is method type?)
- * - Don't open package objects from class files if they are present in source
- * - Revise the way classes are inherited - when not followed by [...] or (...),
- * assume the unparameterized type and forward type parameters as we do now for the synthetic head class.
- */
object Bench extends Driver {
- def resident(compiler: Compiler): Reporter = unsupported("resident") /*loop { line =>
- val command = new CompilerCommand(line split "\\s+" toList, new Settings(scalacError))
- compiler.reporter.reset()
- new compiler.Run() compile command.files
- }*/
private var numRuns = 1
@@ -30,15 +18,12 @@ object Bench extends Driver {
(emptyReporter /: (0 until n)) ((_, _) => op)
override def doCompile(compiler: Compiler, fileNames: List[String])(implicit ctx: Context): Reporter =
- if (new config.Settings.Setting.SettingDecorator[Boolean](ctx.base.settings.resident).value(ctx))
- resident(compiler)
- else
- ntimes(numRuns) {
- val start = System.nanoTime()
- val r = super.doCompile(compiler, fileNames)
- println(s"time elapsed: ${(System.nanoTime - start) / 1000000}ms")
- r
- }
+ ntimes(numRuns) {
+ val start = System.nanoTime()
+ val r = super.doCompile(compiler, fileNames)
+ println(s"time elapsed: ${(System.nanoTime - start) / 1000000}ms")
+ r
+ }
def extractNumArg(args: Array[String], name: String, default: Int = 1): (Int, Array[String]) = {
val pos = args indexOf name
diff --git a/src/dotty/tools/dotc/Compiler.scala b/src/dotty/tools/dotc/Compiler.scala
index a10201bd0..a14aa3655 100644
--- a/src/dotty/tools/dotc/Compiler.scala
+++ b/src/dotty/tools/dotc/Compiler.scala
@@ -7,7 +7,7 @@ import Periods._
import Symbols._
import Scopes._
import typer.{FrontEnd, Typer, Mode, ImportInfo, RefChecks}
-import reporting.ConsoleReporter
+import reporting.{Reporter, ConsoleReporter}
import Phases.Phase
import dotty.tools.dotc.transform._
import dotty.tools.dotc.transform.TreeTransforms.{TreeTransform, TreeTransformer}
@@ -76,8 +76,7 @@ class Compiler {
List(/*new PrivateToStatic,*/
new ExpandPrivate,
new CollectEntryPoints,
- new LabelDefs,
- new TraitConstructors),
+ new LabelDefs),
List(new GenBCode)
)
@@ -106,13 +105,15 @@ class Compiler {
.setOwner(defn.RootClass)
.setTyper(new Typer)
.setMode(Mode.ImplicitsEnabled)
- .setTyperState(new MutableTyperState(ctx.typerState, new ConsoleReporter()(ctx), isCommittable = true))
+ .setTyperState(new MutableTyperState(ctx.typerState, rootReporter(ctx), isCommittable = true))
ctx.definitions.init(start) // set context of definitions to start
def addImport(ctx: Context, symf: () => Symbol) =
ctx.fresh.setImportInfo(ImportInfo.rootImport(symf)(ctx))
(start.setRunInfo(new RunInfo(start)) /: defn.RootImportFns)(addImport)
}
+ protected def rootReporter(implicit ctx: Context): Reporter = new ConsoleReporter()(ctx)
+
def reset()(implicit ctx: Context): Unit = {
ctx.base.reset()
ctx.runInfo.clear()
diff --git a/src/dotty/tools/dotc/Driver.scala b/src/dotty/tools/dotc/Driver.scala
index dc1431aca..7e9d4a5e4 100644
--- a/src/dotty/tools/dotc/Driver.scala
+++ b/src/dotty/tools/dotc/Driver.scala
@@ -8,32 +8,40 @@ import scala.util.control.NonFatal
abstract class Driver extends DotClass {
- val prompt = "\ndotc>"
+ val prompt = "\ndotc> "
protected def newCompiler(): Compiler
protected def emptyReporter: Reporter = new StoreReporter
protected def doCompile(compiler: Compiler, fileNames: List[String])(implicit ctx: Context): Reporter =
- if (fileNames.nonEmpty) {
- val run = compiler.newRun
- run.compile(fileNames)
- run.printSummary()
- } else emptyReporter
+ if (fileNames.nonEmpty)
+ try {
+ val run = compiler.newRun
+ run.compile(fileNames)
+ run.printSummary()
+ }
+ catch {
+ case ex: FatalError =>
+ ctx.error(ex.getMessage) // signals that we should fail compilation.
+ ctx.typerState.reporter
+ }
+ else emptyReporter
protected def initCtx = (new ContextBase).initialCtx
- def process(args: Array[String], rootCtx: Context): Reporter = {
+ protected def sourcesRequired = true
+
+ def setup(args: Array[String], rootCtx: Context): (List[String], Context) = {
val summary = CompilerCommand.distill(args)(rootCtx)
implicit val ctx: Context = initCtx.fresh.setSettings(summary.sstate)
- val fileNames = CompilerCommand.checkUsage(summary)
- try {
- doCompile(newCompiler(), fileNames)
- } catch {
- case ex: FatalError =>
- ctx.error(ex.getMessage) // signals that we should fail compilation.
- ctx.typerState.reporter
- }
+ val fileNames = CompilerCommand.checkUsage(summary, sourcesRequired)
+ (fileNames, ctx)
+ }
+
+ def process(args: Array[String], rootCtx: Context): Reporter = {
+ val (fileNames, ctx) = setup(args, rootCtx)
+ doCompile(newCompiler(), fileNames)(ctx)
}
def main(args: Array[String]): Unit =
diff --git a/src/dotty/tools/dotc/FromTasty.scala b/src/dotty/tools/dotc/FromTasty.scala
index 019846396..705deedd3 100644
--- a/src/dotty/tools/dotc/FromTasty.scala
+++ b/src/dotty/tools/dotc/FromTasty.scala
@@ -12,6 +12,7 @@ import SymDenotations._
import typer.FrontEnd
import Phases.Phase
import util._
+import reporting.Reporter
import Decorators._
import dotty.tools.dotc.transform.Pickler
import tasty.DottyUnpickler
diff --git a/src/dotty/tools/dotc/Main.scala b/src/dotty/tools/dotc/Main.scala
index 0b136d72f..699a57234 100644
--- a/src/dotty/tools/dotc/Main.scala
+++ b/src/dotty/tools/dotc/Main.scala
@@ -1,7 +1,3 @@
-/* NSC -- new Scala compiler
- * Copyright 2005-2013 LAMP/EPFL
- * @author Martin Odersky
- */
package dotty.tools
package dotc
@@ -11,18 +7,5 @@ import reporting.Reporter
/* To do:
*/
object Main extends Driver {
- def resident(compiler: Compiler): Reporter = unsupported("resident") /*loop { line =>
- val command = new CompilerCommand(line split "\\s+" toList, new Settings(scalacError))
- compiler.reporter.reset()
- new compiler.Run() compile command.files
- }*/
-
override def newCompiler(): Compiler = new Compiler
-
- override def doCompile(compiler: Compiler, fileNames: List[String])(implicit ctx: Context): Reporter = {
- if (new config.Settings.Setting.SettingDecorator[Boolean](ctx.base.settings.resident).value(ctx))
- resident(compiler)
- else
- super.doCompile(compiler, fileNames)
- }
}
diff --git a/src/dotty/tools/dotc/Resident.scala b/src/dotty/tools/dotc/Resident.scala
new file mode 100644
index 000000000..d671ea259
--- /dev/null
+++ b/src/dotty/tools/dotc/Resident.scala
@@ -0,0 +1,55 @@
+package dotty.tools
+package dotc
+
+import core.Contexts.Context
+import reporting.Reporter
+import java.io.EOFException
+import scala.annotation.tailrec
+
+/** A compiler which stays resident between runs.
+ * Usage:
+ *
+ * > scala dotty.tools.dotc.Resident <options> <initial files>
+ *
+ * dotc> "more options and files to compile"
+ *
+ * ...
+ *
+ * dotc> :reset // reset all options to the ones passed on the command line
+ *
+ * ...
+ *
+ * dotc> :q // quit
+ */
+object Resident extends Driver {
+
+ object residentCompiler extends Compiler
+
+ override def newCompiler(): Compiler = ???
+
+ override def sourcesRequired = false
+
+ private val quit = ":q"
+ private val reset = ":reset"
+
+ private def getLine() = {
+ Console.print(prompt)
+ try scala.io.StdIn.readLine() catch { case _: EOFException => quit }
+ }
+
+ final override def process(args: Array[String], rootCtx: Context): Reporter = {
+ @tailrec def loop(args: Array[String], prevCtx: Context): Reporter = {
+ var (fileNames, ctx) = setup(args, prevCtx)
+ doCompile(residentCompiler, fileNames)(ctx)
+ var nextCtx = ctx
+ var line = getLine()
+ while (line == reset) {
+ nextCtx = rootCtx
+ line = getLine()
+ }
+ if (line.startsWith(quit)) ctx.typerState.reporter
+ else loop(line split "\\s+", nextCtx)
+ }
+ loop(args, rootCtx)
+ }
+}
diff --git a/src/dotty/tools/dotc/Run.scala b/src/dotty/tools/dotc/Run.scala
index 401608a73..553805d95 100644
--- a/src/dotty/tools/dotc/Run.scala
+++ b/src/dotty/tools/dotc/Run.scala
@@ -33,7 +33,7 @@ class Run(comp: Compiler)(implicit ctx: Context) {
compileSources(sources)
} catch {
case NonFatal(ex) =>
- println(i"exception occurred while compiling $units%, %")
+ ctx.println(i"exception occurred while compiling $units%, %")
throw ex
}
@@ -55,7 +55,7 @@ class Run(comp: Compiler)(implicit ctx: Context) {
ctx.usePhases(phases)
for (phase <- ctx.allPhases)
if (!ctx.reporter.hasErrors) {
- if (ctx.settings.verbose.value) println(s"[$phase]")
+ if (ctx.settings.verbose.value) ctx.println(s"[$phase]")
units = phase.runOn(units)
def foreachUnit(op: Context => Unit)(implicit ctx: Context): Unit =
for (unit <- units) op(ctx.fresh.setPhase(phase.next).setCompilationUnit(unit))
@@ -69,8 +69,8 @@ class Run(comp: Compiler)(implicit ctx: Context) {
val prevPhase = ctx.phase.prev // can be a mini-phase
val squashedPhase = ctx.squashed(prevPhase)
- println(s"result of $unit after ${squashedPhase}:")
- println(unit.tpdTree.show(ctx))
+ ctx.println(s"result of $unit after ${squashedPhase}:")
+ ctx.println(unit.tpdTree.show(ctx))
}
def compile(sourceCode: String): Unit = {
diff --git a/src/dotty/tools/dotc/config/CompilerCommand.scala b/src/dotty/tools/dotc/config/CompilerCommand.scala
index 3ba8db3ba..e34ca07f9 100644
--- a/src/dotty/tools/dotc/config/CompilerCommand.scala
+++ b/src/dotty/tools/dotc/config/CompilerCommand.scala
@@ -60,7 +60,7 @@ object CompilerCommand extends DotClass {
* are already applied in context.
* @return The list of files to compile.
*/
- def checkUsage(summary: ArgsSummary)(implicit ctx: Context): List[String] = {
+ def checkUsage(summary: ArgsSummary, sourcesRequired: Boolean)(implicit ctx: Context): List[String] = {
val settings = ctx.settings
/** Creates a help message for a subset of options based on cond */
@@ -121,8 +121,7 @@ object CompilerCommand extends DotClass {
ctx.println(infoMessage)
Nil
} else {
- if (summary.arguments.isEmpty && !settings.resident.value)
- ctx.println(usageMessage)
+ if (sourcesRequired && summary.arguments.isEmpty) ctx.println(usageMessage)
summary.arguments
}
}
diff --git a/src/dotty/tools/dotc/config/Config.scala b/src/dotty/tools/dotc/config/Config.scala
index 782a2f2d3..97893647c 100644
--- a/src/dotty/tools/dotc/config/Config.scala
+++ b/src/dotty/tools/dotc/config/Config.scala
@@ -32,6 +32,17 @@ object Config {
*/
final val checkConstraintsPropagated = false
+ /** Check that constraints of globally committable typer states are closed.
+ * NOTE: When enabled, the check can cause CyclicReference errors because
+ * it traverses all elements of a type. Such failures were observed when
+ * compiling all of dotty together (source seems to be in GenBCode which
+ * accesses javac's settings.)
+ *
+ * It is recommended to turn this option on only when chasing down
+ * a PolyParam instantiation error. See comment in Types.TypeVar.instantiate.
+ */
+ final val debugCheckConstraintsClosed = false
+
/** Check that no type appearing as the info of a SymDenotation contains
* skolem types.
*/
diff --git a/src/dotty/tools/dotc/config/ScalaSettings.scala b/src/dotty/tools/dotc/config/ScalaSettings.scala
index 2ba907084..f8c155cad 100644
--- a/src/dotty/tools/dotc/config/ScalaSettings.scala
+++ b/src/dotty/tools/dotc/config/ScalaSettings.scala
@@ -81,7 +81,6 @@ class ScalaSettings extends Settings.SettingGroup {
val Xprintpos = BooleanSetting("-Xprint-pos", "Print tree positions, as offsets.")
val printtypes = BooleanSetting("-Xprint-types", "Print tree types (debugging option).")
val prompt = BooleanSetting("-Xprompt", "Display a prompt after each error (debugging option).")
- val resident = BooleanSetting("-Xresident", "Compiler stays resident: read source filenames from standard input.")
val script = StringSetting("-Xscript", "object", "Treat the source file as a script and wrap it in a main method.", "")
val mainClass = StringSetting("-Xmain-class", "path", "Class for manifest's Main-Class entry (only useful with -d <jar>)", "")
val Xshowcls = StringSetting("-Xshow-class", "class", "Show internal representation of class.", "")
diff --git a/src/dotty/tools/dotc/core/Constraint.scala b/src/dotty/tools/dotc/core/Constraint.scala
index 5a758f144..19f93ce47 100644
--- a/src/dotty/tools/dotc/core/Constraint.scala
+++ b/src/dotty/tools/dotc/core/Constraint.scala
@@ -146,4 +146,7 @@ abstract class Constraint extends Showable {
/** Check that no constrained parameter contains itself as a bound */
def checkNonCyclic()(implicit ctx: Context): Unit
+
+ /** Check that constraint only refers to PolyParams bound by itself */
+ def checkClosed()(implicit ctx: Context): Unit
}
diff --git a/src/dotty/tools/dotc/core/Flags.scala b/src/dotty/tools/dotc/core/Flags.scala
index 759dff0d4..f39f2bac6 100644
--- a/src/dotty/tools/dotc/core/Flags.scala
+++ b/src/dotty/tools/dotc/core/Flags.scala
@@ -388,7 +388,7 @@ object Flags {
/** Symbol is a self name */
final val SelfName = termFlag(54, "<selfname>")
- /** Symbol is an implementation class */
+ /** Symbol is an implementation class of a Scala2 trait */
final val ImplClass = typeFlag(54, "<implclass>")
final val SelfNameOrImplClass = SelfName.toCommonFlags
diff --git a/src/dotty/tools/dotc/core/NameOps.scala b/src/dotty/tools/dotc/core/NameOps.scala
index dc94f6db1..4d6cca61d 100644
--- a/src/dotty/tools/dotc/core/NameOps.scala
+++ b/src/dotty/tools/dotc/core/NameOps.scala
@@ -62,7 +62,7 @@ object NameOps {
def likeTyped(n: Name): N =
(if (name.isTermName) n.toTermName else n.toTypeName).asInstanceOf[N]
- def isConstructorName = name == CONSTRUCTOR || name == IMPLCLASS_CONSTRUCTOR
+ def isConstructorName = name == CONSTRUCTOR || name == TRAIT_CONSTRUCTOR
def isExceptionResultName = name startsWith EXCEPTION_RESULT_PREFIX
def isImplClassName = name endsWith IMPL_CLASS_SUFFIX
def isLocalDummyName = name startsWith LOCALDUMMY_PREFIX
diff --git a/src/dotty/tools/dotc/core/OrderingConstraint.scala b/src/dotty/tools/dotc/core/OrderingConstraint.scala
index 21d003451..7e27ee628 100644
--- a/src/dotty/tools/dotc/core/OrderingConstraint.scala
+++ b/src/dotty/tools/dotc/core/OrderingConstraint.scala
@@ -399,7 +399,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
def removeParam(ps: List[PolyParam]) =
ps.filterNot(p => p.binder.eq(poly) && p.paramNum == idx)
- def replaceParam(tp: Type, atPoly: PolyType, atIdx: Int) = tp match {
+ def replaceParam(tp: Type, atPoly: PolyType, atIdx: Int): Type = tp match {
case bounds @ TypeBounds(lo, hi) =>
def recombine(andor: AndOrType, op: (Type, Boolean) => Type, isUpper: Boolean): Type = {
@@ -424,7 +424,8 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
}
bounds.derivedTypeBounds(replaceIn(lo, isUpper = false), replaceIn(hi, isUpper = true))
- case _ => tp
+ case _ =>
+ tp.substParam(param, replacement)
}
var current =
@@ -438,8 +439,16 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
}
}
- def remove(pt: PolyType)(implicit ctx: Context): This =
- newConstraint(boundsMap.remove(pt), lowerMap.remove(pt), upperMap.remove(pt))
+ def remove(pt: PolyType)(implicit ctx: Context): This = {
+ def removeFromOrdering(po: ParamOrdering) = {
+ def removeFromBoundss(key: PolyType, bndss: Array[List[PolyParam]]): Array[List[PolyParam]] = {
+ val bndss1 = bndss.map(_.filterConserve(_.binder ne pt))
+ if (bndss.corresponds(bndss1)(_ eq _)) bndss else bndss1
+ }
+ po.remove(pt).mapValuesNow(removeFromBoundss)
+ }
+ newConstraint(boundsMap.remove(pt), removeFromOrdering(lowerMap), removeFromOrdering(upperMap))
+ }
def isRemovable(pt: PolyType, removedParam: Int = -1): Boolean = {
val entries = boundsMap(pt)
@@ -491,6 +500,19 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
}
}
+ override def checkClosed()(implicit ctx: Context): Unit = {
+ def isFreePolyParam(tp: Type) = tp match {
+ case PolyParam(binder, _) => !contains(binder)
+ case _ => false
+ }
+ def checkClosedType(tp: Type, where: String) =
+ if (tp != null)
+ assert(!tp.existsPart(isFreePolyParam), i"unclosed constraint: $this refers to $tp in $where")
+ boundsMap.foreachBinding((_, tps) => tps.foreach(checkClosedType(_, "bounds")))
+ lowerMap.foreachBinding((_, paramss) => paramss.foreach(_.foreach(checkClosedType(_, "lower"))))
+ upperMap.foreachBinding((_, paramss) => paramss.foreach(_.foreach(checkClosedType(_, "upper"))))
+ }
+
private var myUninstVars: mutable.ArrayBuffer[TypeVar] = _
/** The uninstantiated typevars of this constraint */
diff --git a/src/dotty/tools/dotc/core/StdNames.scala b/src/dotty/tools/dotc/core/StdNames.scala
index eaf4ce1e2..eb1a73625 100644
--- a/src/dotty/tools/dotc/core/StdNames.scala
+++ b/src/dotty/tools/dotc/core/StdNames.scala
@@ -232,7 +232,6 @@ object StdNames {
val EVT2U: N = "evt2u$"
val EQEQ_LOCAL_VAR: N = "eqEqTemp$"
val FAKE_LOCAL_THIS: N = "this$"
- val IMPLCLASS_CONSTRUCTOR: N = "$init$"
val LAZY_LOCAL: N = "$lzy"
val LAZY_LOCAL_INIT: N = "$lzyINIT"
val LAZY_FIELD_OFFSET: N = "OFFSET$"
@@ -261,6 +260,7 @@ object StdNames {
val SKOLEM: N = "<skolem>"
val SPECIALIZED_INSTANCE: N = "specInstance$"
val THIS: N = "_$this"
+ val TRAIT_CONSTRUCTOR: N = "$init$"
val U2EVT: N = "u2evt$"
final val Nil: N = "Nil"
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index d8dddb082..164b0b8f3 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -530,7 +530,7 @@ object SymDenotations {
final def isClassConstructor = name == nme.CONSTRUCTOR
/** Is this the constructor of a trait? */
- final def isImplClassConstructor = name == nme.IMPLCLASS_CONSTRUCTOR
+ final def isImplClassConstructor = name == nme.TRAIT_CONSTRUCTOR
/** Is this the constructor of a trait or a class */
final def isConstructor = name.isConstructorName
@@ -1630,8 +1630,11 @@ object SymDenotations {
override def fullName(implicit ctx: Context): Name = super.fullName
override def primaryConstructor(implicit ctx: Context): Symbol = {
- val cname = if (this is ImplClass) nme.IMPLCLASS_CONSTRUCTOR else nme.CONSTRUCTOR
- info.decls.denotsNamed(cname).last.symbol // denotsNamed returns Symbols in reverse order of occurrence
+ def constrNamed(cname: TermName) = info.decls.denotsNamed(cname).last.symbol
+ // denotsNamed returns Symbols in reverse order of occurrence
+ if (this.is(ImplClass)) constrNamed(nme.TRAIT_CONSTRUCTOR) // ignore normal constructor
+ else
+ constrNamed(nme.CONSTRUCTOR).orElse(constrNamed(nme.TRAIT_CONSTRUCTOR))
}
/** The parameter accessors of this class. Term and type accessors,
diff --git a/src/dotty/tools/dotc/core/TypeErasure.scala b/src/dotty/tools/dotc/core/TypeErasure.scala
index 92e32d4b1..9b41eb982 100644
--- a/src/dotty/tools/dotc/core/TypeErasure.scala
+++ b/src/dotty/tools/dotc/core/TypeErasure.scala
@@ -110,8 +110,20 @@ object TypeErasure {
private def erasureCtx(implicit ctx: Context) =
if (ctx.erasedTypes) ctx.withPhase(ctx.erasurePhase).addMode(Mode.FutureDefsOK) else ctx
- def erasure(tp: Type, semiEraseVCs: Boolean = true)(implicit ctx: Context): Type =
- erasureFn(isJava = false, semiEraseVCs, isConstructor = false, wildcardOK = false)(tp)(erasureCtx)
+ /** The standard erasure of a Scala type. Value classes are erased as normal classes.
+ *
+ * @param tp The type to erase.
+ */
+ def erasure(tp: Type)(implicit ctx: Context): Type =
+ erasureFn(isJava = false, semiEraseVCs = false, isConstructor = false, wildcardOK = false)(tp)(erasureCtx)
+
+ /** The value class erasure of a Scala type, where value classes are semi-erased to
+ * ErasedValueType (they will be fully erased in [[ElimErasedValueType]]).
+ *
+ * @param tp The type to erase.
+ */
+ def valueErasure(tp: Type)(implicit ctx: Context): Type =
+ erasureFn(isJava = false, semiEraseVCs = true, isConstructor = false, wildcardOK = false)(tp)(erasureCtx)
def sigName(tp: Type, isJava: Boolean)(implicit ctx: Context): TypeName = {
val seqClass = if (isJava) defn.ArrayClass else defn.SeqClass
@@ -134,7 +146,7 @@ object TypeErasure {
case tp: ThisType =>
tp
case tp =>
- erasure(tp)
+ valueErasure(tp)
}
/** The symbol's erased info. This is the type's erasure, except for the following symbols:
@@ -308,12 +320,8 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
val parent = tp.parent
if (parent isRef defn.ArrayClass) eraseArray(tp)
else this(parent)
- case tp: TermRef =>
+ case _: TermRef | _: ThisType =>
this(tp.widen)
- case tp: ThisType =>
- def thisTypeErasure(tpToErase: Type) =
- erasureFn(isJava, semiEraseVCs = false, isConstructor, wildcardOK)(tpToErase)
- thisTypeErasure(tp.cls.typeRef)
case SuperType(thistpe, supertpe) =>
SuperType(this(thistpe), this(supertpe))
case ExprType(rt) =>
@@ -389,7 +397,7 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
private def eraseDerivedValueClassRef(tref: TypeRef)(implicit ctx: Context): Type = {
val cls = tref.symbol.asClass
val underlying = underlyingOfValueClass(cls)
- ErasedValueType(cls, erasure(underlying))
+ ErasedValueType(cls, valueErasure(underlying))
}
diff --git a/src/dotty/tools/dotc/core/TyperState.scala b/src/dotty/tools/dotc/core/TyperState.scala
index 91cda1dd8..5617f568a 100644
--- a/src/dotty/tools/dotc/core/TyperState.scala
+++ b/src/dotty/tools/dotc/core/TyperState.scala
@@ -9,6 +9,7 @@ import util.{SimpleMap, DotClass}
import reporting._
import printing.{Showable, Printer}
import printing.Texts._
+import config.Config
import collection.mutable
class TyperState(r: Reporter) extends DotClass with Showable {
@@ -19,7 +20,7 @@ class TyperState(r: Reporter) extends DotClass with Showable {
/** The current constraint set */
def constraint: Constraint =
new OrderingConstraint(SimpleMap.Empty, SimpleMap.Empty, SimpleMap.Empty)
- def constraint_=(c: Constraint): Unit = {}
+ def constraint_=(c: Constraint)(implicit ctx: Context): Unit = {}
/** The uninstantiated variables */
def uninstVars = constraint.uninstVars
@@ -85,7 +86,10 @@ extends TyperState(r) {
private var myConstraint: Constraint = previous.constraint
override def constraint = myConstraint
- override def constraint_=(c: Constraint) = myConstraint = c
+ override def constraint_=(c: Constraint)(implicit ctx: Context) = {
+ if (Config.debugCheckConstraintsClosed && isGlobalCommittable) c.checkClosed()
+ myConstraint = c
+ }
private var myEphemeral: Boolean = previous.ephemeral
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 026e69539..d6bb9c3c5 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -2458,6 +2458,11 @@ object Types {
if (fromBelow && isOrType(inst) && isFullyDefined(inst) && !isOrType(upperBound))
inst = inst.approximateUnion
+ if (ctx.typerState.isGlobalCommittable)
+ assert(!inst.isInstanceOf[PolyParam], i"bad inst $this := $inst, constr = ${ctx.typerState.constraint}")
+ // If this fails, you might want to turn on Config.debugCheckConstraintsClosed
+ // to help find the root of the problem.
+
instantiateWith(inst)
}
diff --git a/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala b/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala
index 9498cf43c..53e8478fa 100644
--- a/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala
+++ b/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala
@@ -438,7 +438,7 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
}
val name1 = name0.adjustIfModuleClass(flags)
- val name = if (name1 == nme.IMPLCLASS_CONSTRUCTOR) nme.CONSTRUCTOR else name1
+ val name = if (name1 == nme.TRAIT_CONSTRUCTOR) nme.CONSTRUCTOR else name1
def isClassRoot = (name == classRoot.name) && (owner == classRoot.owner) && !(flags is ModuleClass)
def isModuleClassRoot = (name == moduleClassRoot.name) && (owner == moduleClassRoot.owner) && (flags is Module)
diff --git a/src/dotty/tools/dotc/parsing/Parsers.scala b/src/dotty/tools/dotc/parsing/Parsers.scala
index b79077245..2a42a7fa9 100644
--- a/src/dotty/tools/dotc/parsing/Parsers.scala
+++ b/src/dotty/tools/dotc/parsing/Parsers.scala
@@ -192,7 +192,7 @@ object Parsers {
case _ =>
if (mustStartStat &&
in.isAfterLineEnd() &&
- isLeqIndented(in.offset, lastStatOffset))
+ isLeqIndented(in.offset, lastStatOffset max 0))
return
}
in.nextToken()
diff --git a/src/dotty/tools/dotc/reporting/ConsoleReporter.scala b/src/dotty/tools/dotc/reporting/ConsoleReporter.scala
index f07f43a63..26e6324eb 100644
--- a/src/dotty/tools/dotc/reporting/ConsoleReporter.scala
+++ b/src/dotty/tools/dotc/reporting/ConsoleReporter.scala
@@ -25,7 +25,7 @@ class ConsoleReporter(
printMessage(pos.lineContents.stripLineEnd)
def printColumnMarker(pos: SourcePosition) =
- if (pos.exists) { printMessage(" " * (pos.column - 1) + "^") }
+ if (pos.exists) { printMessage(" " * pos.column + "^") }
/** Prints the message. */
def printMessage(msg: String): Unit = { writer.print(msg + "\n"); writer.flush() }
diff --git a/src/dotty/tools/dotc/reporting/Reporter.scala b/src/dotty/tools/dotc/reporting/Reporter.scala
index 7c5bab673..7adeeac1c 100644
--- a/src/dotty/tools/dotc/reporting/Reporter.scala
+++ b/src/dotty/tools/dotc/reporting/Reporter.scala
@@ -182,7 +182,7 @@ trait Reporting { this: Context =>
abstract class Reporter {
/** Report a diagnostic */
- protected def doReport(d: Diagnostic)(implicit ctx: Context): Unit
+ def doReport(d: Diagnostic)(implicit ctx: Context): Unit
/** Whether very long lines can be truncated. This exists so important
* debugging information (like printing the classpath) is not rendered
diff --git a/src/dotty/tools/dotc/reporting/StoreReporter.scala b/src/dotty/tools/dotc/reporting/StoreReporter.scala
index 2864c01f8..51d3df110 100644
--- a/src/dotty/tools/dotc/reporting/StoreReporter.scala
+++ b/src/dotty/tools/dotc/reporting/StoreReporter.scala
@@ -14,7 +14,7 @@ class StoreReporter extends Reporter {
private var infos: mutable.ListBuffer[Diagnostic] = null
- protected def doReport(d: Diagnostic)(implicit ctx: Context): Unit = {
+ def doReport(d: Diagnostic)(implicit ctx: Context): Unit = {
typr.println(s">>>> StoredError: ${d.msg}") // !!! DEBUG
if (infos == null) infos = new mutable.ListBuffer
infos += d
diff --git a/src/dotty/tools/dotc/reporting/ThrowingReporter.scala b/src/dotty/tools/dotc/reporting/ThrowingReporter.scala
index eb854d513..026453036 100644
--- a/src/dotty/tools/dotc/reporting/ThrowingReporter.scala
+++ b/src/dotty/tools/dotc/reporting/ThrowingReporter.scala
@@ -7,11 +7,12 @@ import collection.mutable
import Reporter._
/**
- * This class implements a Reporter that stores all messages
+ * This class implements a Reporter that throws all errors and sends warnings and other
+ * info to the underlying reporter.
*/
class ThrowingReporter(reportInfo: Reporter) extends Reporter {
- protected def doReport(d: Diagnostic)(implicit ctx: Context): Unit = d match {
+ def doReport(d: Diagnostic)(implicit ctx: Context): Unit = d match {
case _: Error => throw d
- case _ => reportInfo.report(d)
+ case _ => reportInfo.doReport(d)
}
}
diff --git a/src/dotty/tools/dotc/transform/AugmentScala2Traits.scala b/src/dotty/tools/dotc/transform/AugmentScala2Traits.scala
index 9f9d2dd67..116fee899 100644
--- a/src/dotty/tools/dotc/transform/AugmentScala2Traits.scala
+++ b/src/dotty/tools/dotc/transform/AugmentScala2Traits.scala
@@ -60,7 +60,7 @@ class AugmentScala2Traits extends MiniPhaseTransform with IdentityDenotTransform
val mold =
if (meth.isConstructor)
meth.copySymDenotation(
- name = nme.IMPLCLASS_CONSTRUCTOR,
+ name = nme.TRAIT_CONSTRUCTOR,
info = MethodType(Nil, defn.UnitType))
else meth.ensureNotPrivate
meth.copy(
diff --git a/src/dotty/tools/dotc/transform/ClassOf.scala b/src/dotty/tools/dotc/transform/ClassOf.scala
index 948e0117b..4d6bf2dc9 100644
--- a/src/dotty/tools/dotc/transform/ClassOf.scala
+++ b/src/dotty/tools/dotc/transform/ClassOf.scala
@@ -9,10 +9,12 @@ import core.Symbols.TermSymbol
import core.TypeErasure
import TreeTransforms.{MiniPhaseTransform, TransformerInfo, TreeTransform}
-/** Performs rewritings as follows for `classOf` calls:
- * classOf[CustomValueClass] ~> CustomValueClass class
- * classOf[ValueClass] ~> ValueClass class, where ValueClass is Boolean, Byte, Short, etc.
- * classOf[AnyOtherClass] ~> erasure(AnyOtherClass)
+/** Rewrite `classOf` calls as follow:
+ *
+ * For every primitive class C whose boxed class is called B:
+ * classOf[C] -> B.TYPE
+ * For every non-primitive class D:
+ * classOf[D] -> Literal(Constant(erasure(D)))
*/
class ClassOf extends MiniPhaseTransform {
import tpd._
@@ -32,22 +34,19 @@ class ClassOf extends MiniPhaseTransform {
val tp = tree.args.head.tpe
val defn = ctx.definitions
val claz = tp.classSymbol
- if (ValueClasses.isDerivedValueClass(claz)) {
- Literal(Constant(ref(claz).tpe))
- } else {
- def TYPE(module: TermSymbol) = ref(module).select(nme.TYPE_).ensureConforms(tree.tpe)
- claz match {
- case defn.BooleanClass => TYPE(defn.BoxedBooleanModule)
- case defn.ByteClass => TYPE(defn.BoxedByteModule)
- case defn.ShortClass => TYPE(defn.BoxedShortModule)
- case defn.CharClass => TYPE(defn.BoxedCharModule)
- case defn.IntClass => TYPE(defn.BoxedIntModule)
- case defn.LongClass => TYPE(defn.BoxedLongModule)
- case defn.FloatClass => TYPE(defn.BoxedFloatModule)
- case defn.DoubleClass => TYPE(defn.BoxedDoubleModule)
- case defn.UnitClass => TYPE(defn.BoxedVoidModule)
- case _ => Literal(Constant(TypeErasure.erasure(tp)))
- }
+
+ def TYPE(module: TermSymbol) = ref(module).select(nme.TYPE_).ensureConforms(tree.tpe)
+ claz match {
+ case defn.BooleanClass => TYPE(defn.BoxedBooleanModule)
+ case defn.ByteClass => TYPE(defn.BoxedByteModule)
+ case defn.ShortClass => TYPE(defn.BoxedShortModule)
+ case defn.CharClass => TYPE(defn.BoxedCharModule)
+ case defn.IntClass => TYPE(defn.BoxedIntModule)
+ case defn.LongClass => TYPE(defn.BoxedLongModule)
+ case defn.FloatClass => TYPE(defn.BoxedFloatModule)
+ case defn.DoubleClass => TYPE(defn.BoxedDoubleModule)
+ case defn.UnitClass => TYPE(defn.BoxedVoidModule)
+ case _ => Literal(Constant(TypeErasure.erasure(tp)))
}
} else tree
}
diff --git a/src/dotty/tools/dotc/transform/Erasure.scala b/src/dotty/tools/dotc/transform/Erasure.scala
index 962297517..8b4c6a87d 100644
--- a/src/dotty/tools/dotc/transform/Erasure.scala
+++ b/src/dotty/tools/dotc/transform/Erasure.scala
@@ -268,30 +268,24 @@ object Erasure extends TypeTestsCasts{
class Typer extends typer.ReTyper with NoChecking {
import Boxing._
- def erasedType(tree: untpd.Tree, semiEraseVCs: Boolean = true)(implicit ctx: Context): Type =
- tree.typeOpt match {
- case tp: TermRef if tree.isTerm => erasedRef(tp)
- case tp => erasure(tp, semiEraseVCs)
- }
+ def erasedType(tree: untpd.Tree)(implicit ctx: Context): Type = {
+ val tp = tree.typeOpt
+ if (tree.isTerm) erasedRef(tp) else valueErasure(tp)
+ }
- def promote(tree: untpd.Tree, semiEraseVCs: Boolean)(implicit ctx: Context): tree.ThisTree[Type] = {
+ override def promote(tree: untpd.Tree)(implicit ctx: Context): tree.ThisTree[Type] = {
assert(tree.hasType)
- val erased = erasedType(tree, semiEraseVCs)
+ val erased = erasedType(tree)
ctx.log(s"promoting ${tree.show}: ${erased.showWithUnderlying()}")
tree.withType(erased)
}
- override def promote(tree: untpd.Tree)(implicit ctx: Context): tree.ThisTree[Type] = {
- promote(tree, true)
- }
-
/** When erasing most TypeTrees we should not semi-erase value types.
* This is not the case for [[DefDef#tpt]], [[ValDef#tpt]] and [[Typed#tpt]], they
* are handled separately by [[typedDefDef]], [[typedValDef]] and [[typedTyped]].
*/
- override def typedTypeTree(tree: untpd.TypeTree, pt: Type)(implicit ctx: Context): TypeTree = {
- promote(tree, semiEraseVCs = false)
- }
+ override def typedTypeTree(tree: untpd.TypeTree, pt: Type)(implicit ctx: Context): TypeTree =
+ tree.withType(erasure(tree.tpe))
/** This override is only needed to semi-erase type ascriptions */
override def typedTyped(tree: untpd.Typed, pt: Type)(implicit ctx: Context): Tree = {
@@ -384,7 +378,7 @@ object Erasure extends TypeTestsCasts{
}
override def typedSelectFromTypeTree(tree: untpd.SelectFromTypeTree, pt: Type)(implicit ctx: Context) =
- untpd.Ident(tree.name).withPos(tree.pos).withType(erasedType(tree, semiEraseVCs = false))
+ untpd.Ident(tree.name).withPos(tree.pos).withType(erasedType(tree))
override def typedThis(tree: untpd.This)(implicit ctx: Context): Tree =
if (tree.symbol == ctx.owner.enclosingClass || tree.symbol.isStaticOwner) promote(tree)
@@ -460,7 +454,7 @@ object Erasure extends TypeTestsCasts{
if (pt.isValueType) pt else {
if (tree.typeOpt.derivesFrom(ctx.definitions.UnitClass))
tree.typeOpt
- else erasure(tree.typeOpt)
+ else valueErasure(tree.typeOpt)
}
}
diff --git a/src/dotty/tools/dotc/transform/ExtensionMethods.scala b/src/dotty/tools/dotc/transform/ExtensionMethods.scala
index 36a1b9b30..087e15c71 100644
--- a/src/dotty/tools/dotc/transform/ExtensionMethods.scala
+++ b/src/dotty/tools/dotc/transform/ExtensionMethods.scala
@@ -14,7 +14,7 @@ import core._
import Phases.Phase
import Types._, Contexts._, Constants._, Names._, NameOps._, Flags._, DenotTransformers._
import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._, Scopes._, Denotations._
-import TypeErasure.{ erasure, ErasedValueType }
+import TypeErasure.{ valueErasure, ErasedValueType }
import TypeUtils._
import util.Positions._
import Decorators._
@@ -65,7 +65,7 @@ class ExtensionMethods extends MiniPhaseTransform with DenotTransformer with Ful
}
}
- val underlying = erasure(underlyingOfValueClass(valueClass))
+ val underlying = valueErasure(underlyingOfValueClass(valueClass))
val evt = ErasedValueType(valueClass, underlying)
val u2evtSym = ctx.newSymbol(moduleSym, nme.U2EVT, Synthetic | Method,
MethodType(List(nme.x_0), List(underlying), evt))
diff --git a/src/dotty/tools/dotc/transform/LambdaLift.scala b/src/dotty/tools/dotc/transform/LambdaLift.scala
index 043c92737..cefd283be 100644
--- a/src/dotty/tools/dotc/transform/LambdaLift.scala
+++ b/src/dotty/tools/dotc/transform/LambdaLift.scala
@@ -309,7 +309,8 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform
local.copySymDenotation(
owner = newOwner,
name = newName(local),
- initFlags = local.flags &~ InSuperCall | Private | maybeStatic,
+ initFlags = local.flags &~ (InSuperCall | Module) | Private | maybeStatic,
+ // drop Module because class is no longer a singleton in the lifted context.
info = liftedInfo(local)).installAfter(thisTransform)
if (local.isClass)
for (member <- local.asClass.info.decls)
diff --git a/src/dotty/tools/dotc/transform/LinkScala2ImplClasses.scala b/src/dotty/tools/dotc/transform/LinkScala2ImplClasses.scala
index 8c247130a..60e8edc26 100644
--- a/src/dotty/tools/dotc/transform/LinkScala2ImplClasses.scala
+++ b/src/dotty/tools/dotc/transform/LinkScala2ImplClasses.scala
@@ -50,7 +50,7 @@ class LinkScala2ImplClasses extends MiniPhaseTransform with IdentityDenotTransfo
private def implMethod(meth: Symbol)(implicit ctx: Context): Symbol =
meth.owner.implClass.info
- .decl(if (meth.isConstructor) nme.IMPLCLASS_CONSTRUCTOR else meth.name)
+ .decl(if (meth.isConstructor) nme.TRAIT_CONSTRUCTOR else meth.name)
.suchThat(c => FullParameterization.memberSignature(c.info) == meth.signature)
.symbol
diff --git a/src/dotty/tools/dotc/transform/Mixin.scala b/src/dotty/tools/dotc/transform/Mixin.scala
index de6cde8f2..bebaf44f4 100644
--- a/src/dotty/tools/dotc/transform/Mixin.scala
+++ b/src/dotty/tools/dotc/transform/Mixin.scala
@@ -100,8 +100,10 @@ class Mixin extends MiniPhaseTransform with SymTransformer { thisTransform =>
override def transformSym(sym: SymDenotation)(implicit ctx: Context): SymDenotation =
if (sym.is(Accessor, butNot = Deferred) && sym.owner.is(Trait))
sym.copySymDenotation(initFlags = sym.flags &~ ParamAccessor | Deferred).ensureNotPrivate
- else if (sym.isConstructor && sym.owner.is(Trait) && sym.info.firstParamTypes.nonEmpty)
- sym.copySymDenotation(info = MethodType(Nil, sym.info.resultType))
+ else if (sym.isConstructor && sym.owner.is(Trait))
+ sym.copySymDenotation(
+ name = nme.TRAIT_CONSTRUCTOR,
+ info = MethodType(Nil, sym.info.resultType))
else
sym
@@ -231,8 +233,7 @@ class Mixin extends MiniPhaseTransform with SymTransformer { thisTransform =>
cpy.Template(impl)(
constr =
- if (cls.is(Trait) && impl.constr.vparamss.flatten.nonEmpty)
- cpy.DefDef(impl.constr)(vparamss = Nil :: Nil)
+ if (cls.is(Trait)) cpy.DefDef(impl.constr)(vparamss = Nil :: Nil)
else impl.constr,
parents = impl.parents.map(p => TypeTree(p.tpe).withPos(p.pos)),
body =
diff --git a/src/dotty/tools/dotc/transform/TraitConstructors.scala b/src/dotty/tools/dotc/transform/TraitConstructors.scala
deleted file mode 100644
index 9fea468da..000000000
--- a/src/dotty/tools/dotc/transform/TraitConstructors.scala
+++ /dev/null
@@ -1,36 +0,0 @@
-package dotty.tools.dotc.transform
-
-import dotty.tools.dotc.ast.tpd
-import dotty.tools.dotc.core.Contexts.Context
-import dotty.tools.dotc.core.DenotTransformers.{SymTransformer, DenotTransformer}
-import dotty.tools.dotc.core.Denotations.SingleDenotation
-import dotty.tools.dotc.core.Phases.Phase
-import dotty.tools.dotc.core.StdNames._
-import dotty.tools.dotc.core.SymDenotations.SymDenotation
-import dotty.tools.dotc.core._
-import dotty.tools.dotc.transform.TreeTransforms.{MiniPhaseTransform, TransformerInfo}
-
-/***
- * Renames constructors in traits so that backend will call them with invokeInterface
- * Also makes sure that renamed constructor bodies conforms to type of method
- */
-class TraitConstructors extends MiniPhaseTransform with SymTransformer {
- import dotty.tools.dotc.ast.tpd._
- def phaseName: String = "traitConstructors"
-
- override def treeTransformPhase: Phase = this.phase
-
- def transformSym(sym: SymDenotation)(implicit ctx: Context): SymDenotation = {
- if (sym.isPrimaryConstructor && (sym.owner is Flags.Trait))
- sym.copySymDenotation(name = nme.IMPLCLASS_CONSTRUCTOR)
- else sym
- }
-
- override def transformDefDef(tree: tpd.DefDef)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
- val sym = tree.symbol
- if (sym.isPrimaryConstructor && (sym.owner is Flags.Trait))
- cpy.DefDef(tree)(rhs = Block(List(tree.rhs), This(tree.symbol.enclosingClass.asClass)))
- else tree
- }
-
-}
diff --git a/src/dotty/tools/dotc/transform/TreeChecker.scala b/src/dotty/tools/dotc/transform/TreeChecker.scala
index 19e6aca62..347eb8c01 100644
--- a/src/dotty/tools/dotc/transform/TreeChecker.scala
+++ b/src/dotty/tools/dotc/transform/TreeChecker.scala
@@ -42,8 +42,8 @@ class TreeChecker extends Phase with SymTransformer {
private val seenClasses = collection.mutable.HashMap[String, Symbol]()
private val seenModuleVals = collection.mutable.HashMap[String, Symbol]()
- def printError(str: String) = {
- println(Console.RED + "[error] " + Console.WHITE + str)
+ def printError(str: String)(implicit ctx: Context) = {
+ ctx.println(Console.RED + "[error] " + Console.WHITE + str)
}
val NoSuperClass = Trait | Package
@@ -109,7 +109,7 @@ class TreeChecker extends Phase with SymTransformer {
def check(phasesToRun: Seq[Phase], ctx: Context) = {
val prevPhase = ctx.phase.prev // can be a mini-phase
val squahsedPhase = ctx.squashed(prevPhase)
- println(s"checking ${ctx.compilationUnit} after phase ${squahsedPhase}")
+ ctx.println(s"checking ${ctx.compilationUnit} after phase ${squahsedPhase}")
val checkingCtx = ctx.fresh
.setTyperState(ctx.typerState.withReporter(new ThrowingReporter(ctx.typerState.reporter)))
val checker = new Checker(previousPhases(phasesToRun.toList)(ctx))
@@ -117,7 +117,7 @@ class TreeChecker extends Phase with SymTransformer {
catch {
case NonFatal(ex) =>
implicit val ctx: Context = checkingCtx
- println(i"*** error while checking after phase ${checkingCtx.phase.prev} ***")
+ ctx.println(i"*** error while checking after phase ${checkingCtx.phase.prev} ***")
throw ex
}
}
@@ -151,10 +151,10 @@ class TreeChecker extends Phase with SymTransformer {
}
nowDefinedSyms += tree.symbol
- //println(i"defined: ${tree.symbol}")
+ //ctx.println(i"defined: ${tree.symbol}")
val res = op
nowDefinedSyms -= tree.symbol
- //println(i"undefined: ${tree.symbol}")
+ //ctx.println(i"undefined: ${tree.symbol}")
res
case _ => op
}
diff --git a/src/dotty/tools/dotc/transform/TypeTestsCasts.scala b/src/dotty/tools/dotc/transform/TypeTestsCasts.scala
index 1be0ef39b..4ce64da33 100644
--- a/src/dotty/tools/dotc/transform/TypeTestsCasts.scala
+++ b/src/dotty/tools/dotc/transform/TypeTestsCasts.scala
@@ -96,7 +96,7 @@ trait TypeTestsCasts {
} else
derivedTree(qual, defn.Any_asInstanceOf, argType)
}
- def erasedArg = erasure(tree.args.head.tpe, semiEraseVCs = false)
+ def erasedArg = erasure(tree.args.head.tpe)
if (sym eq defn.Any_isInstanceOf)
transformIsInstanceOf(qual, erasedArg)
else if (sym eq defn.Any_asInstanceOf)
diff --git a/src/dotty/tools/dotc/typer/FrontEnd.scala b/src/dotty/tools/dotc/typer/FrontEnd.scala
index 3dda108b0..f417448bd 100644
--- a/src/dotty/tools/dotc/typer/FrontEnd.scala
+++ b/src/dotty/tools/dotc/typer/FrontEnd.scala
@@ -19,7 +19,7 @@ class FrontEnd extends Phase {
try body
catch {
case NonFatal(ex) =>
- println(s"exception occurred while $doing ${ctx.compilationUnit}")
+ ctx.println(s"exception occurred while $doing ${ctx.compilationUnit}")
throw ex
}
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala
index d5a6ec8f4..cdce11f22 100644
--- a/src/dotty/tools/dotc/typer/Namer.scala
+++ b/src/dotty/tools/dotc/typer/Namer.scala
@@ -16,6 +16,7 @@ import ErrorReporting._
import tpd.ListOfTreeDecorator
import config.Printers._
import Annotations._
+import transform.ValueClasses._
import language.implicitConversions
trait NamerContextOps { this: Context =>
@@ -580,6 +581,7 @@ class Namer { typer: Typer =>
index(rest)(inClassContext(selfInfo))
denot.info = ClassInfo(cls.owner.thisType, cls, parentRefs, decls, selfInfo)
addAnnotations(denot)
+ if (isDerivedValueClass(cls)) cls.setFlag(Final)
cls.setApplicableFlags(
(NoInitsInterface /: impl.body)((fs, stat) => fs & defKind(stat)))
}
diff --git a/src/dotty/tools/dotc/typer/RefChecks.scala b/src/dotty/tools/dotc/typer/RefChecks.scala
index 3633a7279..bb22e2045 100644
--- a/src/dotty/tools/dotc/typer/RefChecks.scala
+++ b/src/dotty/tools/dotc/typer/RefChecks.scala
@@ -71,10 +71,17 @@ object RefChecks {
}
}
- /** Check that self type of this class conforms to self types of parents */
- private def checkSelfType(clazz: Symbol)(implicit ctx: Context): Unit = clazz.info match {
+ /** Check that final and sealed restrictions on class parents
+ * and that self type of this class conforms to self types of parents.
+ */
+ private def checkParents(clazz: Symbol)(implicit ctx: Context): Unit = clazz.info match {
case cinfo: ClassInfo =>
for (parent <- cinfo.classParents) {
+ val pclazz = parent.classSymbol
+ if (pclazz.is(Final))
+ ctx.error(d"cannot extend final $pclazz", clazz.pos)
+ if (pclazz.is(Sealed) && pclazz.associatedFile != clazz.associatedFile)
+ ctx.error(d"cannot extend sealed $pclazz in different compilation unit", clazz.pos)
val pself = parent.givenSelfType.asSeenFrom(clazz.thisType, parent.classSymbol)
if (pself.exists && !(cinfo.selfType <:< pself))
ctx.error(d"illegal inheritance: self type ${cinfo.selfType} of $clazz does not conform to self type $pself of parent ${parent.classSymbol}", clazz.pos)
@@ -648,13 +655,27 @@ object RefChecks {
}
/** Verify classes extending AnyVal meet the requirements */
- private def checkAnyValSubclass(clazz: Symbol)(implicit ctx: Context) =
+ private def checkDerivedValueClass(clazz: Symbol, stats: List[Tree])(implicit ctx: Context) = {
+ def checkValueClassMember(stat: Tree) = stat match {
+ case _: ValDef if !stat.symbol.is(ParamAccessor) =>
+ ctx.error(s"value class may not define non-parameter field", stat.pos)
+ case _: DefDef if stat.symbol.isConstructor =>
+ ctx.error(s"value class may not define secondary constructor", stat.pos)
+ case _: MemberDef | _: Import | EmptyTree =>
+ // ok
+ case _ =>
+ ctx.error(s"value class may not contain initialization statements", stat.pos)
+ }
if (isDerivedValueClass(clazz)) {
if (clazz.is(Trait))
ctx.error("Only classes (not traits) are allowed to extend AnyVal", clazz.pos)
- else if (clazz.is(Abstract))
+ if (clazz.is(Abstract))
ctx.error("`abstract' modifier cannot be used with value classes", clazz.pos)
+ if (!clazz.isStatic)
+ ctx.error("value class cannot be an inner class", clazz.pos)
+ stats.foreach(checkValueClassMember)
}
+ }
type LevelAndIndex = immutable.Map[Symbol, (LevelInfo, Int)]
@@ -701,7 +722,7 @@ import RefChecks._
* - only one overloaded alternative defines default arguments
* - applyDynamic methods are not overloaded
* - all overrides conform to rules laid down by `checkAllOverrides`.
- * - any value classes conform to rules laid down by `checkAnyValSubClass`.
+ * - any value classes conform to rules laid down by `checkDerivedValueClass`.
* - this(...) constructor calls do not forward reference other definitions in their block (not even lazy vals).
* - no forward reference in a local block jumps over a non-lazy val definition.
* - a class and its companion object do not both define a class or module with the same name.
@@ -768,10 +789,10 @@ class RefChecks extends MiniPhase { thisTransformer =>
override def transformTemplate(tree: Template)(implicit ctx: Context, info: TransformerInfo) = {
val cls = ctx.owner
checkOverloadedRestrictions(cls)
- checkSelfType(cls)
+ checkParents(cls)
checkCompanionNameClashes(cls)
checkAllOverrides(cls)
- checkAnyValSubclass(cls)
+ checkDerivedValueClass(cls, tree.body)
tree
}
diff --git a/src/dotty/tools/dotc/util/SimpleMap.scala b/src/dotty/tools/dotc/util/SimpleMap.scala
index 7bd263f0f..b8668d7e4 100644
--- a/src/dotty/tools/dotc/util/SimpleMap.scala
+++ b/src/dotty/tools/dotc/util/SimpleMap.scala
@@ -8,7 +8,7 @@ abstract class SimpleMap[K <: AnyRef, +V >: Null <: AnyRef] extends (K => V) {
def remove(k: K): SimpleMap[K, V]
def updated[V1 >: V <: AnyRef](k: K, v: V1): SimpleMap[K, V1]
def contains(k: K): Boolean = apply(k) != null
- def mapValues[V1 >: V <: AnyRef](f: (K, V1) => V1): SimpleMap[K, V1]
+ def mapValuesNow[V1 >: V <: AnyRef](f: (K, V1) => V1): SimpleMap[K, V1]
def foreachBinding(f: (K, V) => Unit): Unit
def map2[T](f: (K, V) => T): List[T] = {
val buf = new ListBuffer[T]
@@ -32,7 +32,7 @@ object SimpleMap {
def apply(k: AnyRef) = null
def remove(k: AnyRef) = this
def updated[V1 >: Null <: AnyRef](k: AnyRef, v: V1) = new Map1(k, v)
- def mapValues[V1 >: Null <: AnyRef](f: (AnyRef, V1) => V1) = this
+ def mapValuesNow[V1 >: Null <: AnyRef](f: (AnyRef, V1) => V1) = this
def foreachBinding(f: (AnyRef, Null) => Unit) = ()
}
@@ -49,7 +49,7 @@ object SimpleMap {
def updated[V1 >: V <: AnyRef](k: K, v: V1) =
if (k == k1) new Map1(k, v)
else new Map2(k1, v1, k, v)
- def mapValues[V1 >: V <: AnyRef](f: (K, V1) => V1) = {
+ def mapValuesNow[V1 >: V <: AnyRef](f: (K, V1) => V1) = {
val w1 = f(k1, v1)
if (v1 eq w1) this else new Map1(k1, w1)
}
@@ -70,7 +70,7 @@ object SimpleMap {
if (k == k1) new Map2(k, v, k2, v2)
else if (k == k2) new Map2(k1, v1, k, v)
else new Map3(k1, v1, k2, v2, k, v)
- def mapValues[V1 >: V <: AnyRef](f: (K, V1) => V1) = {
+ def mapValuesNow[V1 >: V <: AnyRef](f: (K, V1) => V1) = {
val w1 = f(k1, v1); val w2 = f(k2, v2)
if ((v1 eq w1) && (v2 eq w2)) this
else new Map2(k1, w1, k2, w2)
@@ -95,7 +95,7 @@ object SimpleMap {
else if (k == k2) new Map3(k1, v1, k, v, k3, v3)
else if (k == k3) new Map3(k1, v1, k2, v2, k, v)
else new Map4(k1, v1, k2, v2, k3, v3, k, v)
- def mapValues[V1 >: V <: AnyRef](f: (K, V1) => V1) = {
+ def mapValuesNow[V1 >: V <: AnyRef](f: (K, V1) => V1) = {
val w1 = f(k1, v1); val w2 = f(k2, v2); val w3 = f(k3, v3)
if ((v1 eq w1) && (v2 eq w2) && (v3 eq w3)) this
else new Map3(k1, w1, k2, w2, k3, w3)
@@ -123,7 +123,7 @@ object SimpleMap {
else if (k == k3) new Map4(k1, v1, k2, v2, k, v, k4, v4)
else if (k == k4) new Map4(k1, v1, k2, v2, k3, v3, k, v)
else new MapMore(Array[AnyRef](k1, v1, k2, v2, k3, v3, k4, v4, k, v))
- def mapValues[V1 >: V <: AnyRef](f: (K, V1) => V1) = {
+ def mapValuesNow[V1 >: V <: AnyRef](f: (K, V1) => V1) = {
val w1 = f(k1, v1); val w2 = f(k2, v2); val w3 = f(k3, v3); val w4 = f(k4, v4)
if ((v1 eq w1) && (v2 eq w2) && (v3 eq w3) && (v4 eq w4)) this
else new Map4(k1, w1, k2, w2, k3, w3, k4, w4)
@@ -197,7 +197,7 @@ object SimpleMap {
false
}
- def mapValues[V1 >: V <: AnyRef](f: (K, V1) => V1) = {
+ def mapValuesNow[V1 >: V <: AnyRef](f: (K, V1) => V1) = {
var bindings1: Array[AnyRef] = bindings
var i = 0
while (i < bindings.length) {
diff --git a/src/dotty/tools/dotc/util/SourceFile.scala b/src/dotty/tools/dotc/util/SourceFile.scala
index 45119a881..5e8f85e28 100644
--- a/src/dotty/tools/dotc/util/SourceFile.scala
+++ b/src/dotty/tools/dotc/util/SourceFile.scala
@@ -72,7 +72,7 @@ case class SourceFile(file: AbstractFile, content: Array[Char]) {
def positionInUltimateSource(position: SourcePosition): SourcePosition =
SourcePosition(underlying, position.pos shift start)
- def isLineBreak(idx: Int) =
+ private def isLineBreak(idx: Int) =
if (idx >= length) false else {
val ch = content(idx)
// don't identify the CR in CR LF as a line break, since LF will do.
@@ -80,7 +80,7 @@ case class SourceFile(file: AbstractFile, content: Array[Char]) {
else isLineBreakChar(ch)
}
- def calculateLineIndices(cs: Array[Char]) = {
+ private def calculateLineIndices(cs: Array[Char]) = {
val buf = new ArrayBuffer[Int]
buf += 0
for (i <- 0 until cs.length) if (isLineBreak(i)) buf += i + 1
@@ -103,22 +103,29 @@ case class SourceFile(file: AbstractFile, content: Array[Char]) {
lastLine
}
- def startOfLine(offset: Int): Int = lineToOffset(offsetToLine(offset))
+ /** The index of the first character of the line containing position `offset` */
+ def startOfLine(offset: Int): Int = {
+ require(offset >= 0)
+ lineToOffset(offsetToLine(offset))
+ }
+ /** The start index of the line following the one containing position `offset` */
def nextLine(offset: Int): Int =
lineToOffset(offsetToLine(offset) + 1 min lineIndices.length - 1)
+ /** The contents of the line containing position `offset` */
def lineContents(offset: Int): String =
content.slice(startOfLine(offset), nextLine(offset)).mkString
+ /** The column corresponding to `offset`, starting at 0 */
def column(offset: Int): Int = {
var idx = startOfLine(offset)
var col = 0
while (idx != offset) {
- col += (if (content(idx) == '\t') tabInc - col % tabInc else 1)
+ col += (if (content(idx) == '\t') (tabInc - col) % tabInc else 1)
idx += 1
}
- col + 1
+ col
}
override def toString = file.toString
diff --git a/src/dotty/tools/dotc/util/SourcePosition.scala b/src/dotty/tools/dotc/util/SourcePosition.scala
index 3d6352a1a..c88cbc78b 100644
--- a/src/dotty/tools/dotc/util/SourcePosition.scala
+++ b/src/dotty/tools/dotc/util/SourcePosition.scala
@@ -10,7 +10,11 @@ case class SourcePosition(source: SourceFile, pos: Position) {
def exists = pos.exists
def lineContents: String = source.lineContents(point)
+
+ /** The line of the position, starting at 0 */
def line: Int = source.offsetToLine(point)
+
+ /** The column of the position, starting at 0 */
def column: Int = source.column(point)
override def toString =
diff --git a/test/dotc/tests.scala b/test/dotc/tests.scala
index f96e77f00..f222daca4 100644
--- a/test/dotc/tests.scala
+++ b/test/dotc/tests.scala
@@ -133,6 +133,8 @@ class tests extends CompilerTest {
@Test def neg_i0248_inherit_refined = compileFile(negDir, "i0248-inherit-refined", xerrors = 4)
@Test def neg_i0281 = compileFile(negDir, "i0281-null-primitive-conforms", xerrors = 3)
@Test def neg_i583 = compileFile(negDir, "i0583-skolemize", xerrors = 2)
+ @Test def neg_finalSealed = compileFile(negDir, "final-sealed", xerrors = 2)
+ @Test def neg_i705 = compileFile(negDir, "i705-inner-value-class", xerrors = 7)
@Test def neg_moduleSubtyping = compileFile(negDir, "moduleSubtyping", xerrors = 4)
@Test def neg_escapingRefs = compileFile(negDir, "escapingRefs", xerrors = 2)
@Test def neg_instantiateAbstract = compileFile(negDir, "instantiateAbstract", xerrors = 8)
@@ -140,6 +142,7 @@ class tests extends CompilerTest {
@Test def neg_shadowedImplicits = compileFile(negDir, "arrayclone-new", xerrors = 2)
@Test def neg_traitParamsTyper = compileFile(negDir, "traitParamsTyper", xerrors = 5)
@Test def neg_traitParamsMixin = compileFile(negDir, "traitParamsMixin", xerrors = 2)
+ @Test def neg_firstError = compileFile(negDir, "firstError", xerrors = 3)
@Test def run_all = runFiles(runDir)
diff --git a/test/dotty/partest/DPConfig.scala b/test/dotty/partest/DPConfig.scala
index ad9c271ef..640dfd021 100644
--- a/test/dotty/partest/DPConfig.scala
+++ b/test/dotty/partest/DPConfig.scala
@@ -1,7 +1,8 @@
package dotty.partest
-import java.io.File
import scala.collection.JavaConversions._
+import scala.reflect.io.Path
+import java.io.File
/** Dotty Partest runs all tests in the provided testDirs located under
@@ -14,7 +15,9 @@ import scala.collection.JavaConversions._
* otherwise pos/__defaultFlags.flags are used if the file exists).
*/
object DPConfig {
- val testRoot = "./tests/partest-generated"
+ val testRoot = (Path(".") / Path("tests") / Path("partest-generated")).toString
+ val genLog = Path(testRoot) / Path("gen.log")
+
lazy val testDirs = {
val root = new File(testRoot)
val dirs = if (!root.exists) Array.empty[String] else root.listFiles.filter(_.isDirectory).map(_.getName)
diff --git a/test/dotty/partest/DPConsoleRunner.scala b/test/dotty/partest/DPConsoleRunner.scala
index 13ffed050..fa6256398 100644
--- a/test/dotty/partest/DPConsoleRunner.scala
+++ b/test/dotty/partest/DPConsoleRunner.scala
@@ -9,7 +9,7 @@ import scala.tools.partest._
import scala.tools.partest.nest._
import scala.util.matching.Regex
import tools.nsc.io.{ File => NSCFile }
-import java.io.{ File, PrintStream, FileOutputStream }
+import java.io.{ File, PrintStream, FileOutputStream, PrintWriter, FileWriter }
import java.net.URLClassLoader
/** Runs dotty partest from the Console, discovering test sources in
@@ -91,23 +91,11 @@ extends SuiteRunner(testSourcePath, fileManager, updateCheck, failed, javaCmdPat
val state =
try {
- // IO redirection is messy, there are no concurrency guarantees.
- // Parts of test output might end up in the wrong file or get lost.
- Console.out.flush
- Console.err.flush
- val clog = runner.cLogFile
- val stream = new PrintStream(new FileOutputStream(clog.jfile), true)
- val result = Console.withOut(stream)({ Console.withErr(stream)({
- val res = runner.run()
- Console.err.flush
- Console.out.flush
- res
- })})
- result match {
+ runner.run match {
// Append compiler output to transcript if compilation failed,
// printed with --verbose option
case TestState.Fail(f, r@"compilation failed", transcript) =>
- TestState.Fail(f, r, transcript ++ clog.fileLines.dropWhile(_ == ""))
+ TestState.Fail(f, r, transcript ++ runner.cLogFile.fileLines.dropWhile(_ == ""))
case res => res
}
} catch {
@@ -261,11 +249,16 @@ class DPTestRunner(testFile: File, suiteRunner: DPSuiteRunner) extends nest.Runn
override def groupedFiles(sources: List[File]): List[List[File]] = {
val grouped = sources groupBy (_.group)
val flatGroup = List(grouped.keys.toList.sorted.map({ k => grouped(k) sortBy (_.getName) }).flatten)
- try { // try/catch because of bug in partest
+ try { // try/catch because of bug in partest that throws exception
if (flatGroup != super.groupedFiles(sources))
- NestUI.echoWarning("Warning: Overriding compilation groups for tests: " + sources)
+ throw new java.lang.UnsupportedOperationException()
} catch {
- case e: java.lang.UnsupportedOperationException => NestUI.echoWarning("Warning: Overriding compilation groups for tests: " + sources)
+ case e: java.lang.UnsupportedOperationException =>
+ val genlogFWriter = new FileWriter(DPConfig.genLog.jfile, true)
+ val genlogWriter = new PrintWriter(genlogFWriter, true)
+ genlogWriter.println("Warning: Overriding compilation groups for tests: " + sources)
+ genlogWriter.close
+ genlogFWriter.close
}
flatGroup
}
diff --git a/test/dotty/partest/DPDirectCompiler.scala b/test/dotty/partest/DPDirectCompiler.scala
index 86e766505..885de8c62 100644
--- a/test/dotty/partest/DPDirectCompiler.scala
+++ b/test/dotty/partest/DPDirectCompiler.scala
@@ -1,14 +1,17 @@
package dotty.partest
+import dotty.tools.dotc.reporting.ConsoleReporter
import scala.tools.partest.{ TestState, nest }
-import java.io.File
+import java.io.{ File, PrintWriter, FileWriter }
/* NOTE: Adapted from partest.DirectCompiler and DottyTest */
-class DPDirectCompiler(runner: nest.Runner) extends nest.DirectCompiler(runner) {
+class DPDirectCompiler(runner: DPTestRunner) extends nest.DirectCompiler(runner) {
override def compile(opts0: List[String], sources: List[File]): TestState = {
- println("\ncompiling " + sources.mkString(" ") + "\noptions: " + opts0.mkString(" "))
+ val clogFWriter = new FileWriter(runner.cLogFile.jfile, true)
+ val clogWriter = new PrintWriter(clogFWriter, true)
+ clogWriter.println("\ncompiling " + sources.mkString(" ") + "\noptions: " + opts0.mkString(" "))
implicit var ctx: dotty.tools.dotc.core.Contexts.Context = {
val base = new dotty.tools.dotc.core.Contexts.ContextBase
@@ -18,17 +21,23 @@ class DPDirectCompiler(runner: nest.Runner) extends nest.DirectCompiler(runner)
base.definitions.init(ctx)
ctx
}
-
+
try {
- val processor = if (opts0.exists(_.startsWith("#"))) dotty.tools.dotc.Bench else dotty.tools.dotc.Main
- val reporter = processor.process((sources.map(_.toString) ::: opts0).toArray, ctx)
+ val processor =
+ if (opts0.exists(_.startsWith("#"))) dotty.tools.dotc.Bench else dotty.tools.dotc.Main
+ val clogger = new ConsoleReporter(writer = clogWriter)(ctx)
+ val logCtx = ctx.fresh.setTyperState(ctx.typerState.withReporter(clogger))
+ val reporter = processor.process((sources.map(_.toString) ::: opts0).toArray, logCtx)
if (!reporter.hasErrors) runner.genPass()
else {
reporter.printSummary(ctx)
runner.genFail(s"compilation failed with ${reporter.errorCount} errors")
}
- } catch {
+ } catch {
case t: Throwable => runner.genCrash(t)
+ } finally {
+ clogFWriter.close
+ clogWriter.close
}
}
}
diff --git a/test/test/CompilerTest.scala b/test/test/CompilerTest.scala
index 4a8ec6da0..09b608f22 100644
--- a/test/test/CompilerTest.scala
+++ b/test/test/CompilerTest.scala
@@ -344,7 +344,7 @@ object CompilerTest extends App {
lazy val init: SFile = {
scala.reflect.io.Directory(DPConfig.testRoot).deleteRecursively
new JFile(DPConfig.testRoot).mkdirs
- val log = (Path(DPConfig.testRoot) / Path("gen.log")).createFile(true)
+ val log = DPConfig.genLog.createFile(true)
println(s"CompilerTest is generating tests for partest, log: $log")
log
}
diff --git a/tests/neg/final-sealed.scala b/tests/neg/final-sealed.scala
new file mode 100644
index 000000000..017afd63b
--- /dev/null
+++ b/tests/neg/final-sealed.scala
@@ -0,0 +1,4 @@
+final class A
+class B extends A
+class C extends Option[Int]
+
diff --git a/tests/neg/firstError.scala b/tests/neg/firstError.scala
new file mode 100644
index 000000000..317adcced
--- /dev/null
+++ b/tests/neg/firstError.scala
@@ -0,0 +1,4 @@
+.
+
+\u890u3084eu
+
diff --git a/tests/neg/i705-inner-value-class.scala b/tests/neg/i705-inner-value-class.scala
new file mode 100644
index 000000000..f638b0670
--- /dev/null
+++ b/tests/neg/i705-inner-value-class.scala
@@ -0,0 +1,22 @@
+class Foo {
+ class B(val a: Int) extends AnyVal // error
+}
+
+class VCwithBadMembers(val a: Int) extends AnyVal {
+ def this() = this(1) // error
+ var x = 0 // error
+ val y = 2 // error
+ println("hi") // error
+}
+
+object Test {
+ class B(val a: Int) extends AnyVal // ok
+ def f = {
+ class C(val a: Int) extends AnyVal // error
+ new C(1)
+ }
+ class B1(val b: Int) extends B(b)
+// class D extends B( { class E(val a: Int) extends AnyVal; new E(1) } ) // error
+}
+
+
diff --git a/tests/pending/run/unittest_collection.check b/tests/pending/run/unittest_collection.check
deleted file mode 100644
index df1629dd7..000000000
--- a/tests/pending/run/unittest_collection.check
+++ /dev/null
@@ -1 +0,0 @@
-warning: there was one deprecation warning; re-run with -deprecation for details
diff --git a/tests/pos/extmethods.scala b/tests/pos/extmethods.scala
index 3edfa2d75..cac1c4ec1 100644
--- a/tests/pos/extmethods.scala
+++ b/tests/pos/extmethods.scala
@@ -1,7 +1,6 @@
trait That1[A]
class T[A, This <: That1[A]](val x: Int) extends AnyVal {
self: This =>
- var next: This = _
final def loop(x: This, cnt: Int): Int = loop(x, cnt + 1)
def const[B](): Boolean = return true
}
diff --git a/tests/pending/pos/t8230a.scala b/tests/pos/t8230a.scala
index 405aa86f5..dfbae51ee 100644
--- a/tests/pending/pos/t8230a.scala
+++ b/tests/pos/t8230a.scala
@@ -15,9 +15,9 @@ object Test {
object Okay {
Arr("1")
- import I.{ arrToTrav, longArrToTrav }
- foo(Arr("2"))
- }
+ import I.{ arrToTrav, longArrToTrav }
+ val x = foo(Arr("2"))
+ }
object Fail {
import I.arrToTrav
diff --git a/tests/run/i689.scala b/tests/run/i689.scala
new file mode 100644
index 000000000..262d13852
--- /dev/null
+++ b/tests/run/i689.scala
@@ -0,0 +1,10 @@
+object Test {
+ def main(args: Array[String]): Unit = {
+ object A {
+ def a = new A
+ def y = 0
+ }
+ class A { A.y }
+ A.a
+ }
+}
diff --git a/tests/run/origins.check b/tests/run/origins.check
index 771baf9fd..db9bf29a4 100644
--- a/tests/run/origins.check
+++ b/tests/run/origins.check
@@ -1,6 +1,6 @@
>> Origins tag 'boop' logged 65 calls from 3 distinguished sources.
- 50 Test$.$anonfun$f3$1(origins.scala:21)
- 10 Test$.$anonfun$f2$1(origins.scala:20)
- 5 Test$.$anonfun$f1$1(origins.scala:19)
+ 50 Test$.$anonfun$f3$1(origins.scala:22)
+ 10 Test$.$anonfun$f2$1(origins.scala:21)
+ 5 Test$.$anonfun$f1$1(origins.scala:20)
diff --git a/tests/pending/run/t8002.scala b/tests/run/t8002.scala
index c27e83a46..c27e83a46 100644
--- a/tests/pending/run/t8002.scala
+++ b/tests/run/t8002.scala
diff --git a/tests/pending/run/unittest_collection.scala b/tests/run/unittest_collection.scala
index d10845475..d10845475 100644
--- a/tests/pending/run/unittest_collection.scala
+++ b/tests/run/unittest_collection.scala
diff --git a/tests/run/valueclasses-nested-object.check b/tests/run/valueclasses-nested-object.check
new file mode 100644
index 000000000..00750edc0
--- /dev/null
+++ b/tests/run/valueclasses-nested-object.check
@@ -0,0 +1 @@
+3
diff --git a/tests/run/valueclasses-nested-object.scala b/tests/run/valueclasses-nested-object.scala
new file mode 100644
index 000000000..3042592e4
--- /dev/null
+++ b/tests/run/valueclasses-nested-object.scala
@@ -0,0 +1,16 @@
+class M(val t: Int) extends AnyVal {
+ // Disallowed in Scala 2.11 (see SI-6359)
+ def o = {
+ object X {
+ override def toString = t.toString
+ }
+ () => X
+ }
+}
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ val x = new M(3)
+ println(x.o())
+ }
+}