summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.xml15
-rw-r--r--src/compiler/scala/reflect/macros/runtime/Aliases.scala5
-rw-r--r--src/compiler/scala/reflect/macros/runtime/CapturedVariables.scala15
-rw-r--r--src/compiler/scala/reflect/macros/runtime/Context.scala8
-rw-r--r--src/compiler/scala/reflect/macros/runtime/Enclosures.scala3
-rw-r--r--src/compiler/scala/reflect/macros/runtime/Evals.scala2
-rw-r--r--src/compiler/scala/reflect/macros/runtime/Exprs.scala8
-rw-r--r--src/compiler/scala/reflect/macros/runtime/FrontEnds.scala26
-rw-r--r--src/compiler/scala/reflect/macros/runtime/Infrastructure.scala32
-rw-r--r--src/compiler/scala/reflect/macros/runtime/Parsers.scala5
-rw-r--r--src/compiler/scala/reflect/macros/runtime/Reifiers.scala2
-rw-r--r--src/compiler/scala/reflect/macros/runtime/Settings.scala35
-rw-r--r--src/compiler/scala/reflect/macros/runtime/TypeTags.scala9
-rw-r--r--src/compiler/scala/reflect/reify/Reifier.scala2
-rw-r--r--src/compiler/scala/reflect/reify/utils/Extractors.scala6
-rw-r--r--src/compiler/scala/reflect/reify/utils/NodePrinters.scala2
-rw-r--r--src/compiler/scala/tools/nsc/CompilationUnits.scala2
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/matching/Patterns.scala12
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala5
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Checkable.scala284
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala97
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Modes.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala24
-rw-r--r--src/compiler/scala/tools/reflect/FrontEnd.scala50
-rw-r--r--src/compiler/scala/tools/reflect/FrontEnds.scala88
-rw-r--r--src/compiler/scala/tools/reflect/StdTags.scala8
-rw-r--r--src/compiler/scala/tools/reflect/ToolBox.scala3
-rw-r--r--src/compiler/scala/tools/reflect/ToolBoxFactory.scala2
-rw-r--r--src/compiler/scala/tools/reflect/package.scala90
-rw-r--r--src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala61
-rw-r--r--src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala91
-rw-r--r--src/library/scala/StringContext.scala63
-rw-r--r--src/reflect/scala/reflect/api/BuildUtils.scala2
-rw-r--r--src/reflect/scala/reflect/api/Exprs.scala12
-rw-r--r--src/reflect/scala/reflect/api/FrontEnds.scala70
-rw-r--r--src/reflect/scala/reflect/api/JavaUniverse.scala4
-rw-r--r--src/reflect/scala/reflect/api/Mirror.scala (renamed from src/reflect/scala/reflect/api/MirrorOf.scala)4
-rw-r--r--src/reflect/scala/reflect/api/Mirrors.scala10
-rw-r--r--src/reflect/scala/reflect/api/Position.scala167
-rw-r--r--src/reflect/scala/reflect/api/Positions.scala167
-rw-r--r--src/reflect/scala/reflect/api/Symbols.scala10
-rw-r--r--src/reflect/scala/reflect/api/TreeCreator.scala2
-rw-r--r--src/reflect/scala/reflect/api/TypeCreator.scala2
-rw-r--r--src/reflect/scala/reflect/api/TypeTags.scala26
-rw-r--r--src/reflect/scala/reflect/internal/AnnotationCheckers.scala26
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Mirrors.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Printers.scala4
-rw-r--r--src/reflect/scala/reflect/internal/StdCreators.scala8
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala10
-rw-r--r--src/reflect/scala/reflect/internal/TreeInfo.scala10
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala7
-rw-r--r--src/reflect/scala/reflect/internal/package.scala6
-rw-r--r--src/reflect/scala/reflect/internal/util/Collections.scala14
-rw-r--r--src/reflect/scala/reflect/internal/util/Position.scala13
-rw-r--r--src/reflect/scala/reflect/macros/Aliases.scala7
-rw-r--r--src/reflect/scala/reflect/macros/CapturedVariables.scala21
-rw-r--r--src/reflect/scala/reflect/macros/Context.scala8
-rw-r--r--src/reflect/scala/reflect/macros/Enclosures.scala4
-rw-r--r--src/reflect/scala/reflect/macros/Exprs.scala8
-rw-r--r--src/reflect/scala/reflect/macros/FrontEnds.scala14
-rw-r--r--src/reflect/scala/reflect/macros/Infrastructure.scala79
-rw-r--r--src/reflect/scala/reflect/macros/Parsers.scala14
-rw-r--r--src/reflect/scala/reflect/macros/Reifiers.scala13
-rw-r--r--src/reflect/scala/reflect/macros/Settings.scala36
-rw-r--r--src/reflect/scala/reflect/macros/TreeBuilder.scala3
-rw-r--r--src/reflect/scala/reflect/macros/TypeTags.scala9
-rw-r--r--src/reflect/scala/reflect/macros/Universe.scala48
-rw-r--r--src/reflect/scala/reflect/macros/package.scala6
-rw-r--r--test/files/continuations-neg/t5314-missing-result-type.check4
-rw-r--r--test/files/continuations-neg/t5314-missing-result-type.scala13
-rw-r--r--test/files/continuations-neg/t5314-npe.check4
-rw-r--r--test/files/continuations-neg/t5314-npe.scala3
-rw-r--r--test/files/continuations-neg/t5314-return-reset.check4
-rw-r--r--test/files/continuations-neg/t5314-return-reset.scala21
-rw-r--r--test/files/continuations-neg/t5314-type-error.check6
-rw-r--r--test/files/continuations-neg/t5314-type-error.scala17
-rw-r--r--test/files/continuations-run/t5314-2.check5
-rw-r--r--test/files/continuations-run/t5314-2.scala44
-rw-r--r--test/files/continuations-run/t5314-3.check4
-rw-r--r--test/files/continuations-run/t5314-3.scala27
-rw-r--r--test/files/continuations-run/t5314-with-if.check1
-rw-r--r--test/files/continuations-run/t5314-with-if.scala17
-rw-r--r--test/files/continuations-run/t5314.check8
-rw-r--r--test/files/continuations-run/t5314.scala52
-rw-r--r--test/files/neg/patmat-type-check.check10
-rw-r--r--test/files/neg/t1872.check4
-rw-r--r--test/files/neg/t4302.check2
-rw-r--r--test/files/neg/t5762.check15
-rw-r--r--test/files/neg/t5762.flags1
-rw-r--r--test/files/neg/t5762.scala24
-rw-r--r--test/files/neg/unchecked-abstract.check27
-rw-r--r--test/files/neg/unchecked-abstract.flags1
-rw-r--r--test/files/neg/unchecked-abstract.scala93
-rw-r--r--test/files/neg/unchecked-impossible.check6
-rw-r--r--test/files/neg/unchecked-impossible.flags1
-rw-r--r--test/files/neg/unchecked-impossible.scala16
-rw-r--r--test/files/neg/unchecked-knowable.check6
-rw-r--r--test/files/neg/unchecked-knowable.flags1
-rw-r--r--test/files/neg/unchecked-knowable.scala20
-rw-r--r--test/files/neg/unchecked-refinement.check15
-rw-r--r--test/files/neg/unchecked-refinement.flags1
-rw-r--r--test/files/neg/unchecked-refinement.scala27
-rw-r--r--test/files/neg/unchecked.check2
-rw-r--r--test/files/neg/unchecked.scala4
-rw-r--r--test/files/neg/unchecked2.check62
-rw-r--r--test/files/neg/unchecked2.scala37
-rw-r--r--test/files/neg/unchecked3.check42
-rw-r--r--test/files/neg/unchecked3.flags1
-rw-r--r--test/files/neg/unchecked3.scala83
-rw-r--r--test/files/pos/t1107b/O.scala (renamed from test/files/pos/t1107/O.scala)0
-rw-r--r--test/files/pos/t1107b/T.scala (renamed from test/files/pos/t1107/T.scala)0
-rw-r--r--test/files/pos/t1203b/J.java (renamed from test/files/pos/t1203/J.java)0
-rw-r--r--test/files/pos/t1203b/S.scala (renamed from test/files/pos/t1203/S.scala)0
-rw-r--r--test/files/pos/t6275.flags1
-rw-r--r--test/files/pos/t6275.scala11
-rw-r--r--test/files/run/macro-openmacros/Impls_Macros_1.scala3
-rw-r--r--test/files/run/macro-reify-nested-a/Impls_Macros_1.scala3
-rw-r--r--test/files/run/macro-reify-nested-b/Impls_Macros_1.scala3
-rw-r--r--test/files/run/macro-reify-splice-outside-reify/Impls_Macros_1.scala13
-rw-r--r--test/files/run/macro-reify-unreify/Macros_1.scala5
-rw-r--r--test/files/run/macro-sip19-revised/Impls_Macros_1.scala2
-rw-r--r--test/files/run/macro-sip19/Impls_Macros_1.scala2
-rw-r--r--test/files/run/macro-typecheck-macrosdisabled.check4
-rw-r--r--test/files/run/macro-typecheck-macrosdisabled2.check4
-rw-r--r--test/files/run/t576.scala10
-rw-r--r--test/files/run/toolbox_console_reporter.check8
-rw-r--r--test/files/run/toolbox_console_reporter.scala35
-rw-r--r--test/files/run/toolbox_silent_reporter.scala4
-rw-r--r--test/files/run/toolbox_typecheck_macrosdisabled.check4
-rw-r--r--test/files/run/toolbox_typecheck_macrosdisabled2.check4
-rw-r--r--test/pending/pos/exhaust_2.scala54
134 files changed, 1859 insertions, 955 deletions
diff --git a/build.xml b/build.xml
index ac25e1e757..67d715bfe9 100644
--- a/build.xml
+++ b/build.xml
@@ -1749,7 +1749,7 @@ OSGi Artifacts
</target>
<target name="osgi.bundles" depends="osgi.init" unless="osgi.bundles.available">
- <stopwatch name="osgi.bundle.timer"/>
+ <stopwatch name="osgi.bundle.timer"/>
<make-bundle name="scala-library" version="${osgi.version.number}" />
<make-bundle name="scala-actors" version="${osgi.version.number}" />
<make-bundle name="scala-actors-migration" version="${osgi.version.number}" />
@@ -1757,7 +1757,7 @@ OSGi Artifacts
<make-bundle name="scala-compiler" version="${osgi.version.number}" />
<make-plugin-bundle name="continuations" version="${osgi.version.number}" />
<touch file="${build-osgi.dir}/bundles.complete" verbose="no"/>
- <stopwatch name="osgi.bundle.timer" action="total"/>
+ <stopwatch name="osgi.bundle.timer" action="total"/>
</target>
<target name="osgi.bundles.swing" depends="osgi.init" if="has.java6" unless="osgi.bundles.available">
@@ -1801,7 +1801,7 @@ OSGi Artifacts
</compilationpath>
</scalacfork>
<touch file="${build-osgi.dir}/test-compile.complete" verbose="no"/>
- <stopwatch name="osgi.test.comp.timer" action="total"/>
+ <stopwatch name="osgi.test.comp.timer" action="total"/>
</target>
<target name="osgi.test" depends="osgi.test.comp">
@@ -1821,7 +1821,7 @@ OSGi Artifacts
</batchtest>
<formatter type="brief" usefile="false" />
</junit>
- <stopwatch name="osgi.test.timer" action="total"/>
+ <stopwatch name="osgi.test.timer" action="total"/>
</target>
<target name="osgi.clean">
@@ -2322,6 +2322,7 @@ DOCUMENTATION
<include name="swing/**"/>
<include name="actors/**"/>
<include name="actors-migration/**"/>
+ <include name="reflect/**"/>
</source-includes>
</doc-uptodate-check>
</target>
@@ -2336,7 +2337,7 @@ DOCUMENTATION
docfooter="epfl"
docsourceurl="${scaladoc.url}€{FILE_PATH}.scala#L1"
docUncompilable="${src.dir}/library-aux"
- skipPackages="scala.reflect.macros.internal"
+ skipPackages="scala.reflect.macros.internal:scala.reflect.internal:scala.reflect.runtime:scala.reflect.io"
sourcepath="${src.dir}"
classpathref="pack.classpath"
addparams="${scalac.args.all}"
@@ -2716,14 +2717,14 @@ DISTRIBUTION
<macrodef name="copy-bundle">
<attribute name="name" />
<sequential>
- <copy file="${build-osgi.dir}/org.scala-lang.@{name}.jar"
+ <copy file="${build-osgi.dir}/org.scala-lang.@{name}.jar"
tofile="${dist.dir}/lib/@{name}.jar"/>
</sequential>
</macrodef>
<macrodef name="copy-plugin-bundle">
<attribute name="name" />
<sequential>
- <copy file="${build-osgi.dir}/org.scala-lang.plugins.@{name}.jar"
+ <copy file="${build-osgi.dir}/org.scala-lang.plugins.@{name}.jar"
tofile="${dist.dir}/misc/scala-devel/plugins/@{name}.jar"/>
</sequential>
</macrodef>
diff --git a/src/compiler/scala/reflect/macros/runtime/Aliases.scala b/src/compiler/scala/reflect/macros/runtime/Aliases.scala
index 30e72997f7..ff870e728e 100644
--- a/src/compiler/scala/reflect/macros/runtime/Aliases.scala
+++ b/src/compiler/scala/reflect/macros/runtime/Aliases.scala
@@ -10,17 +10,20 @@ trait Aliases {
override type TermName = universe.TermName
override type TypeName = universe.TypeName
override type Tree = universe.Tree
- // override type Position = universe.Position
+ override type Position = universe.Position
override type Scope = universe.Scope
override type Modifiers = universe.Modifiers
override type Expr[+T] = universe.Expr[T]
override val Expr = universe.Expr
+ def Expr[T: WeakTypeTag](tree: Tree): Expr[T] = universe.Expr[T](mirror, universe.FixedMirrorTreeCreator(mirror, tree))
override type WeakTypeTag[T] = universe.WeakTypeTag[T]
override type TypeTag[T] = universe.TypeTag[T]
override val WeakTypeTag = universe.WeakTypeTag
override val TypeTag = universe.TypeTag
+ def WeakTypeTag[T](tpe: Type): WeakTypeTag[T] = universe.WeakTypeTag[T](mirror, universe.FixedMirrorTypeCreator(mirror, tpe))
+ def TypeTag[T](tpe: Type): TypeTag[T] = universe.TypeTag[T](mirror, universe.FixedMirrorTypeCreator(mirror, tpe))
override def weakTypeTag[T](implicit attag: WeakTypeTag[T]) = attag
override def typeTag[T](implicit ttag: TypeTag[T]) = ttag
override def weakTypeOf[T](implicit attag: WeakTypeTag[T]): Type = attag.tpe
diff --git a/src/compiler/scala/reflect/macros/runtime/CapturedVariables.scala b/src/compiler/scala/reflect/macros/runtime/CapturedVariables.scala
deleted file mode 100644
index 78fb7100b0..0000000000
--- a/src/compiler/scala/reflect/macros/runtime/CapturedVariables.scala
+++ /dev/null
@@ -1,15 +0,0 @@
-package scala.reflect.macros
-package runtime
-
-trait CapturedVariables {
- self: Context =>
-
- import mirror._
- import universe._
-
- def captureVariable(vble: Symbol): Unit = universe.captureVariable(vble)
-
- def referenceCapturedVariable(vble: Symbol): Tree = universe.referenceCapturedVariable(vble)
-
- def capturedVariableType(vble: Symbol): Type = universe.capturedVariableType(vble)
-} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/macros/runtime/Context.scala b/src/compiler/scala/reflect/macros/runtime/Context.scala
index 8bbfef44a3..8e8b0fcea1 100644
--- a/src/compiler/scala/reflect/macros/runtime/Context.scala
+++ b/src/compiler/scala/reflect/macros/runtime/Context.scala
@@ -5,24 +5,20 @@ import scala.tools.nsc.Global
abstract class Context extends scala.reflect.macros.Context
with Aliases
- with CapturedVariables
- with Infrastructure
with Enclosures
with Names
with Reifiers
with FrontEnds
- with Settings
+ with Infrastructure
with Typers
with Parsers
- with Exprs
- with TypeTags
with Evals
with ExprUtils
with Traces {
val universe: Global
- val mirror: MirrorOf[universe.type] = universe.rootMirror
+ val mirror: universe.Mirror = universe.rootMirror
val callsiteTyper: universe.analyzer.Typer
diff --git a/src/compiler/scala/reflect/macros/runtime/Enclosures.scala b/src/compiler/scala/reflect/macros/runtime/Enclosures.scala
index b5c988ca83..be5f2dbe83 100644
--- a/src/compiler/scala/reflect/macros/runtime/Enclosures.scala
+++ b/src/compiler/scala/reflect/macros/runtime/Enclosures.scala
@@ -19,5 +19,6 @@ trait Enclosures {
val enclosingMacros: List[Context] = this :: universe.analyzer.openMacros // include self
val enclosingMethod: Tree = site.enclMethod.tree
val enclosingPosition: Position = if (enclPoses.isEmpty) NoPosition else enclPoses.head.pos
- val enclosingUnit: CompilationUnit = currentRun.currentUnit
+ val enclosingUnit: CompilationUnit = universe.currentRun.currentUnit
+ val enclosingRun: Run = universe.currentRun
}
diff --git a/src/compiler/scala/reflect/macros/runtime/Evals.scala b/src/compiler/scala/reflect/macros/runtime/Evals.scala
index acafeb5b02..1f7b5f2ff1 100644
--- a/src/compiler/scala/reflect/macros/runtime/Evals.scala
+++ b/src/compiler/scala/reflect/macros/runtime/Evals.scala
@@ -7,7 +7,7 @@ import scala.tools.reflect.ToolBox
trait Evals {
self: Context =>
- private lazy val evalMirror = ru.runtimeMirror(libraryClassLoader)
+ private lazy val evalMirror = ru.runtimeMirror(universe.analyzer.macroClassloader)
private lazy val evalToolBox = evalMirror.mkToolBox()
private lazy val evalImporter = ru.mkImporter(universe).asInstanceOf[ru.Importer { val from: universe.type }]
diff --git a/src/compiler/scala/reflect/macros/runtime/Exprs.scala b/src/compiler/scala/reflect/macros/runtime/Exprs.scala
deleted file mode 100644
index ebf8fa2b96..0000000000
--- a/src/compiler/scala/reflect/macros/runtime/Exprs.scala
+++ /dev/null
@@ -1,8 +0,0 @@
-package scala.reflect.macros
-package runtime
-
-trait Exprs {
- self: Context =>
-
- def Expr[T: WeakTypeTag](tree: Tree): Expr[T] = universe.Expr[T](mirror, universe.FixedMirrorTreeCreator(mirror, tree))
-}
diff --git a/src/compiler/scala/reflect/macros/runtime/FrontEnds.scala b/src/compiler/scala/reflect/macros/runtime/FrontEnds.scala
index 9f328eb82b..a6a198e1b4 100644
--- a/src/compiler/scala/reflect/macros/runtime/FrontEnds.scala
+++ b/src/compiler/scala/reflect/macros/runtime/FrontEnds.scala
@@ -1,28 +1,9 @@
package scala.reflect.macros
package runtime
-trait FrontEnds extends scala.tools.reflect.FrontEnds {
+trait FrontEnds {
self: Context =>
- import universe._
- import mirror._
-
- override type Position = universe.Position
-
- def frontEnd: FrontEnd = wrapReporter(universe.reporter)
-
- def setFrontEnd(frontEnd: FrontEnd): this.type = {
- universe.reporter = wrapFrontEnd(frontEnd)
- this
- }
-
- def withFrontEnd[T](frontEnd: FrontEnd)(op: => T): T = {
- val old = universe.reporter
- setFrontEnd(frontEnd)
- try op
- finally universe.reporter = old
- }
-
def echo(pos: Position, msg: String): Unit = universe.reporter.echo(pos, msg)
def info(pos: Position, msg: String, force: Boolean): Unit = universe.reporter.info(pos, msg, force)
@@ -36,9 +17,4 @@ trait FrontEnds extends scala.tools.reflect.FrontEnds {
def error(pos: Position, msg: String): Unit = callsiteTyper.context.error(pos, msg)
def abort(pos: Position, msg: String): Nothing = throw new AbortMacroException(pos, msg)
-
- def interactive(): Unit = universe.reporter match {
- case reporter: scala.tools.nsc.reporters.AbstractReporter => reporter.displayPrompt()
- case _ => ()
- }
}
diff --git a/src/compiler/scala/reflect/macros/runtime/Infrastructure.scala b/src/compiler/scala/reflect/macros/runtime/Infrastructure.scala
index 7157dbeaa2..7781693822 100644
--- a/src/compiler/scala/reflect/macros/runtime/Infrastructure.scala
+++ b/src/compiler/scala/reflect/macros/runtime/Infrastructure.scala
@@ -1,36 +1,16 @@
package scala.reflect.macros
package runtime
-import scala.tools.nsc.util.ScalaClassLoader
-
trait Infrastructure {
self: Context =>
- val forJVM: Boolean = universe.forJVM
-
- val forMSIL: Boolean = universe.forMSIL
-
- val forInteractive: Boolean = universe.forInteractive
-
- val forScaladoc: Boolean = universe.forScaladoc
-
- val currentRun: Run = universe.currentRun
-
- val libraryClassPath: List[java.net.URL] = universe.classPath.asURLs
-
- lazy val libraryClassLoader: ClassLoader = universe.analyzer.macroClassloader
-
- type Run = universe.Run
-
- object Run extends RunExtractor {
- def unapply(run: Run): Option[(CompilationUnit, List[CompilationUnit])] = Some((run.currentUnit, run.units.toList))
+ def settings: List[String] = {
+ val us = universe.settings
+ import us._
+ userSetSettings collectFirst { case x: MultiStringSetting if x.name == XmacroSettings.name => x.value } getOrElse Nil
}
- type CompilationUnit = universe.CompilationUnit
-
- object CompilationUnit extends CompilationUnitExtractor {
- def unapply(compilationUnit: CompilationUnit): Option[(java.io.File, Array[Char], Tree)] = Some((compilationUnit.source.file.file, compilationUnit.source.content, compilationUnit.body))
- }
+ def compilerSettings: List[String] = universe.settings.recreateArgs
- val currentMacro: Symbol = expandee.symbol
+ def classPath: List[java.net.URL] = global.classPath.asURLs
}
diff --git a/src/compiler/scala/reflect/macros/runtime/Parsers.scala b/src/compiler/scala/reflect/macros/runtime/Parsers.scala
index 5096526fdb..ab9b94ec9f 100644
--- a/src/compiler/scala/reflect/macros/runtime/Parsers.scala
+++ b/src/compiler/scala/reflect/macros/runtime/Parsers.scala
@@ -10,6 +10,7 @@ trait Parsers {
def parse(code: String): Tree =
// todo. provide decent implementation
+ // see `Typers.typedUseCase` for details
try {
import scala.reflect.runtime.{universe => ru}
val parsed = ru.rootMirror.mkToolBox().parse(code)
@@ -17,9 +18,7 @@ trait Parsers {
importer.importTree(parsed)
} catch {
case ToolBoxError(msg, cause) =>
+ // todo. provide a position
throw new ParseError(universe.NoPosition, msg)
}
-
- case class ParseError(val pos: Position, val msg: String) extends Throwable(msg)
- object ParseError extends ParseErrorExtractor
}
diff --git a/src/compiler/scala/reflect/macros/runtime/Reifiers.scala b/src/compiler/scala/reflect/macros/runtime/Reifiers.scala
index f15a7ad502..9e11e5e26d 100644
--- a/src/compiler/scala/reflect/macros/runtime/Reifiers.scala
+++ b/src/compiler/scala/reflect/macros/runtime/Reifiers.scala
@@ -13,8 +13,6 @@ trait Reifiers {
import universe._
import definitions._
- lazy val runtimeUniverse: Tree = gen.mkRuntimeUniverseRef
-
def reifyTree(universe: Tree, mirror: Tree, tree: Tree): Tree = {
assert(ExprClass != NoSymbol)
val result = scala.reflect.reify.`package`.reifyTree(self.universe)(callsiteTyper, universe, mirror, tree)
diff --git a/src/compiler/scala/reflect/macros/runtime/Settings.scala b/src/compiler/scala/reflect/macros/runtime/Settings.scala
deleted file mode 100644
index e9d9a17b81..0000000000
--- a/src/compiler/scala/reflect/macros/runtime/Settings.scala
+++ /dev/null
@@ -1,35 +0,0 @@
-package scala.reflect.macros
-package runtime
-
-trait Settings {
- self: Context =>
-
- def settings: List[String] = {
- val us = universe.settings
- import us._
- userSetSettings collectFirst { case x: MultiStringSetting if x.name == XmacroSettings.name => x.value } getOrElse Nil
- }
-
- def compilerSettings: List[String] = universe.settings.recreateArgs
-
- def setCompilerSettings(options: String): this.type =
- // SI-5925: doesn't work with arguments that contains whitespaces
- setCompilerSettings(options.split(" ").toList)
-
- def setCompilerSettings(options: List[String]): this.type = {
- val settings = new scala.tools.nsc.Settings(_ => ())
- settings.copyInto(universe.settings)
- this
- }
-
- def withCompilerSettings[T](options: String)(op: => T): T =
- // SI-5925: doesn't work with arguments that contains whitespaces
- withCompilerSettings(options.split(" ").toList)(op)
-
- def withCompilerSettings[T](options: List[String])(op: => T): T = {
- val old = options
- setCompilerSettings(options)
- try op
- finally setCompilerSettings(old)
- }
-}
diff --git a/src/compiler/scala/reflect/macros/runtime/TypeTags.scala b/src/compiler/scala/reflect/macros/runtime/TypeTags.scala
deleted file mode 100644
index 19b60159de..0000000000
--- a/src/compiler/scala/reflect/macros/runtime/TypeTags.scala
+++ /dev/null
@@ -1,9 +0,0 @@
-package scala.reflect.macros
-package runtime
-
-trait TypeTags {
- self: Context =>
-
- def WeakTypeTag[T](tpe: Type): WeakTypeTag[T] = universe.WeakTypeTag[T](mirror, universe.FixedMirrorTypeCreator(mirror, tpe))
- def TypeTag[T](tpe: Type): TypeTag[T] = universe.TypeTag[T](mirror, universe.FixedMirrorTypeCreator(mirror, tpe))
-}
diff --git a/src/compiler/scala/reflect/reify/Reifier.scala b/src/compiler/scala/reflect/reify/Reifier.scala
index 2c0d41e2a9..5d3ac8cde0 100644
--- a/src/compiler/scala/reflect/reify/Reifier.scala
+++ b/src/compiler/scala/reflect/reify/Reifier.scala
@@ -108,7 +108,7 @@ abstract class Reifier extends States
// needs to be solved some day
// maybe try `resetLocalAttrs` once the dust settles
var importantSymbols = Set[Symbol](
- NothingClass, AnyClass, SingletonClass, PredefModule, ScalaRunTimeModule, TypeCreatorClass, TreeCreatorClass, MirrorOfClass,
+ NothingClass, AnyClass, SingletonClass, PredefModule, ScalaRunTimeModule, TypeCreatorClass, TreeCreatorClass, MirrorClass,
ApiUniverseClass, JavaUniverseClass, ReflectRuntimePackage, ReflectRuntimeCurrentMirror)
importantSymbols ++= importantSymbols map (_.companionSymbol)
importantSymbols ++= importantSymbols map (_.moduleClass)
diff --git a/src/compiler/scala/reflect/reify/utils/Extractors.scala b/src/compiler/scala/reflect/reify/utils/Extractors.scala
index 91cccaee99..b7206eda0e 100644
--- a/src/compiler/scala/reflect/reify/utils/Extractors.scala
+++ b/src/compiler/scala/reflect/reify/utils/Extractors.scala
@@ -19,7 +19,7 @@ trait Extractors {
// $treecreator1.super.<init>();
// ()
// };
- // def apply[U >: Nothing <: scala.reflect.api.Universe with Singleton]($m$untyped: scala.reflect.api.MirrorOf[U]): U#Tree = {
+ // def apply[U >: Nothing <: scala.reflect.api.Universe with Singleton]($m$untyped: scala.reflect.api.Mirror[U]): U#Tree = {
// val $u: U = $m$untyped.universe;
// val $m: $u.Mirror = $m$untyped.asInstanceOf[$u.Mirror];
// $u.Apply($u.Select($u.Select($u.build.This($m.staticPackage("scala.collection.immutable").moduleClass), $u.newTermName("List")), $u.newTermName("apply")), List($u.Literal($u.Constant(1)), $u.Literal($u.Constant(2))))
@@ -32,7 +32,7 @@ trait Extractors {
// $typecreator1.super.<init>();
// ()
// };
- // def apply[U >: Nothing <: scala.reflect.api.Universe with Singleton]($m$untyped: scala.reflect.api.MirrorOf[U]): U#Type = {
+ // def apply[U >: Nothing <: scala.reflect.api.Universe with Singleton]($m$untyped: scala.reflect.api.Mirror[U]): U#Type = {
// val $u: U = $m$untyped.universe;
// val $m: $u.Mirror = $m$untyped.asInstanceOf[$u.Mirror];
// $u.TypeRef($u.ThisType($m.staticPackage("scala.collection.immutable").moduleClass), $m.staticClass("scala.collection.immutable.List"), List($m.staticClass("scala.Int").toTypeConstructor))
@@ -81,7 +81,7 @@ trait Extractors {
DefDef(NoMods,
reifierName,
List(TypeDef(Modifiers(PARAM), tparamu, List(), TypeBoundsTree(Ident(NothingClass), CompoundTypeTree(Template(List(Ident(reifierUniverse), Ident(SingletonClass)), emptyValDef, List()))))),
- List(List(ValDef(Modifiers(PARAM), nme.MIRROR_UNTYPED, AppliedTypeTree(Ident(MirrorOfClass), List(Ident(tparamu))), EmptyTree))),
+ List(List(ValDef(Modifiers(PARAM), nme.MIRROR_UNTYPED, AppliedTypeTree(Ident(MirrorClass), List(Ident(tparamu))), EmptyTree))),
reifierTpt, reifierBody))))
Block(tpec, ApplyConstructor(Ident(tpec.name), List()))
}
diff --git a/src/compiler/scala/reflect/reify/utils/NodePrinters.scala b/src/compiler/scala/reflect/reify/utils/NodePrinters.scala
index f0480e0699..000e500c69 100644
--- a/src/compiler/scala/reflect/reify/utils/NodePrinters.scala
+++ b/src/compiler/scala/reflect/reify/utils/NodePrinters.scala
@@ -75,7 +75,7 @@ trait NodePrinters {
val printout = scala.collection.mutable.ListBuffer[String]();
printout += universe.trim
- if (mirrorIsUsed) printout += mirror.replace("MirrorOf[", "scala.reflect.api.MirrorOf[").trim
+ if (mirrorIsUsed) printout += mirror.replace("Mirror[", "scala.reflect.api.Mirror[").trim
val imports = scala.collection.mutable.ListBuffer[String]();
imports += nme.UNIVERSE_SHORT
// if (buildIsUsed) imports += nme.build
diff --git a/src/compiler/scala/tools/nsc/CompilationUnits.scala b/src/compiler/scala/tools/nsc/CompilationUnits.scala
index 6d3fd2e09e..5a2d5ef165 100644
--- a/src/compiler/scala/tools/nsc/CompilationUnits.scala
+++ b/src/compiler/scala/tools/nsc/CompilationUnits.scala
@@ -23,7 +23,7 @@ trait CompilationUnits { self: Global =>
/** One unit of compilation that has been submitted to the compiler.
* It typically corresponds to a single file of source code. It includes
* error-reporting hooks. */
- class CompilationUnit(val source: SourceFile) {
+ class CompilationUnit(val source: SourceFile) extends CompilationUnitContextApi {
/** the fresh name creator */
var fresh: FreshNameCreator = new FreshNameCreator.Default
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index 9f7433796d..0252f9677c 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -1158,7 +1158,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
/** A Run is a single execution of the compiler on a sets of units
*/
- class Run {
+ class Run extends RunContextApi {
/** Have been running into too many init order issues with Run
* during erroneous conditions. Moved all these vals up to the
* top of the file so at least they're not trivially null.
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index d8dae0482b..072f4b9ef2 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -1750,7 +1750,7 @@ self =>
in.nextToken()
if (in.token == SUBTYPE || in.token == SUPERTYPE) wildcardType(start)
else atPos(start) { Bind(tpnme.WILDCARD, EmptyTree) }
- case IDENTIFIER if treeInfo.isVariableName(in.name) =>
+ case IDENTIFIER if nme.isVariableName(in.name) =>
atPos(start) { Bind(identForType(), EmptyTree) }
case _ =>
typ()
diff --git a/src/compiler/scala/tools/nsc/matching/Patterns.scala b/src/compiler/scala/tools/nsc/matching/Patterns.scala
index af77d3fe3f..40e520076a 100644
--- a/src/compiler/scala/tools/nsc/matching/Patterns.scala
+++ b/src/compiler/scala/tools/nsc/matching/Patterns.scala
@@ -21,7 +21,7 @@ trait Patterns extends ast.TreeDSL {
import definitions._
import CODE._
import Debug._
- import treeInfo.{ unbind, isStar, isVarPattern, isVariableName }
+ import treeInfo.{ unbind, isStar, isVarPattern }
type PatternMatch = MatchMatrix#PatternMatch
private type PatternVar = MatrixContext#PatternVar
@@ -366,7 +366,7 @@ trait Patterns extends ast.TreeDSL {
lazy val Select(qualifier, name) = select
def pathSegments = getPathSegments(tree)
def backticked: Option[String] = qualifier match {
- case _: This if isVariableName(name) => Some("`%s`".format(name))
+ case _: This if nme.isVariableName(name) => Some("`%s`".format(name))
case _ => None
}
override def covers(sym: Symbol) = newMatchesPattern(sym, tree.tpe)
@@ -388,11 +388,11 @@ trait Patterns extends ast.TreeDSL {
lazy val UnApply(unfn, args) = tree
lazy val Apply(fn, _) = unfn
lazy val MethodType(List(arg, _*), _) = fn.tpe
-
+
// Covers if the symbol matches the unapply method's argument type,
// and the return type of the unapply is Some.
override def covers(sym: Symbol) = newMatchesPattern(sym, arg.tpe)
-
+
// TODO: for alwaysCovers:
// fn.tpe.finalResultType.typeSymbol == SomeClass
@@ -451,7 +451,7 @@ trait Patterns extends ast.TreeDSL {
(sym.tpe.baseTypeSeq exists (_ matchesPattern pattp))
}
}
-
+
def sym = tree.symbol
def tpe = tree.tpe
def isEmpty = tree.isEmpty
@@ -496,4 +496,4 @@ trait Patterns extends ast.TreeDSL {
}
}
}
-} \ No newline at end of file
+}
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index d541b7be0a..f68cbfc141 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -185,7 +185,7 @@ abstract class UnCurry extends InfoTransform
* try {
* body
* } catch {
- * case ex: NonLocalReturnControl[_] =>
+ * case ex: NonLocalReturnControl[T @unchecked] =>
* if (ex.key().eq(key)) ex.value()
* else throw ex
* }
@@ -195,7 +195,8 @@ abstract class UnCurry extends InfoTransform
localTyper typed {
val extpe = nonLocalReturnExceptionType(meth.tpe.finalResultType)
val ex = meth.newValue(nme.ex, body.pos) setInfo extpe
- val pat = gen.mkBindForCase(ex, NonLocalReturnControlClass, List(meth.tpe.finalResultType))
+ val argType = meth.tpe.finalResultType withAnnotation (AnnotationInfo marker UncheckedClass.tpe)
+ val pat = gen.mkBindForCase(ex, NonLocalReturnControlClass, List(argType))
val rhs = (
IF ((ex DOT nme.key)() OBJ_EQ Ident(key))
THEN ((ex DOT nme.value)())
diff --git a/src/compiler/scala/tools/nsc/typechecker/Checkable.scala b/src/compiler/scala/tools/nsc/typechecker/Checkable.scala
new file mode 100644
index 0000000000..7e15cf91a7
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/typechecker/Checkable.scala
@@ -0,0 +1,284 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2012 LAMP/EPFL
+ * @author Paul Phillips
+ */
+
+package scala.tools.nsc
+package typechecker
+
+import scala.collection.{ mutable, immutable }
+import scala.collection.mutable.ListBuffer
+import scala.util.control.ControlThrowable
+import symtab.Flags._
+import scala.annotation.tailrec
+import Checkability._
+
+/** On pattern matcher checkability:
+ *
+ * Consider a pattern match of this form: (x: X) match { case _: P => }
+ *
+ * There are four possibilities to consider:
+ * [P1] X will always conform to P
+ * [P2] x will never conform to P
+ * [P3] X <: P if some runtime test is true
+ * [P4] X cannot be checked against P
+ *
+ * The first two cases correspond to those when there is enough
+ * static information to say X <: P or that (x ∈ X) ⇒ (x ∉ P).
+ * The fourth case includes unknown abstract types or structural
+ * refinements appearing within a pattern.
+ *
+ * The third case is the interesting one. We designate another type, XR,
+ * which is essentially the intersection of X and |P|, where |P| is
+ * the erasure of P. If XR <: P, then no warning is emitted.
+ *
+ * Examples of how this info is put to use:
+ * sealed trait A[T] ; class B[T] extends A[T]
+ * def f(x: B[Int]) = x match { case _: A[Int] if true => }
+ * def g(x: A[Int]) = x match { case _: B[Int] => }
+ *
+ * `f` requires no warning because X=B[Int], P=A[Int], and B[Int] <:< A[Int].
+ * `g` requires no warning because X=A[Int], P=B[Int], XR=B[Int], and B[Int] <:< B[Int].
+ * XR=B[Int] because a value of type A[Int] which is tested to be a B can
+ * only be a B[Int], due to the definition of B (B[T] extends A[T].)
+ *
+ * This is something like asSeenFrom, only rather than asking what a type looks
+ * like from the point of view of one of its base classes, we ask what it looks
+ * like from the point of view of one of its subclasses.
+ */
+trait Checkable {
+ self: Analyzer =>
+
+ import global._
+ import definitions._
+ import CheckabilityChecker.{ isNeverSubType, isNeverSubClass }
+
+ /** The applied type of class 'to' after inferring anything
+ * possible from the knowledge that 'to' must also be of the
+ * type given in 'from'.
+ */
+ def propagateKnownTypes(from: Type, to: Symbol): Type = {
+ def tparams = to.typeParams
+ val tvars = tparams map (p => TypeVar(p))
+ val tvarType = appliedType(to, tvars: _*)
+ val bases = from.baseClasses filter (to.baseClasses contains _)
+
+ bases foreach { bc =>
+ val tps1 = (from baseType bc).typeArgs
+ val tps2 = (tvarType baseType bc).typeArgs
+ (tps1, tps2).zipped foreach (_ =:= _)
+ // Alternate, variance respecting formulation causes
+ // neg/unchecked3.scala to fail (abstract types). TODO -
+ // figure it out. It seems there is more work to do if I
+ // allow for variance, because the constraints accumulate
+ // as bounds and "tvar.instValid" is false.
+ //
+ // foreach3(tps1, tps2, bc.typeParams)((tp1, tp2, tparam) =>
+ // if (tparam.initialize.isCovariant) tp1 <:< tp2
+ // else if (tparam.isContravariant) tp2 <:< tp1
+ // else tp1 =:= tp2
+ // )
+ }
+
+ val resArgs = tparams zip tvars map {
+ case (_, tvar) if tvar.instValid => tvar.constr.inst
+ case (tparam, _) => tparam.tpe
+ }
+ appliedType(to, resArgs: _*)
+ }
+
+ private def isUnwarnableTypeArgSymbol(sym: Symbol) = (
+ sym.isTypeParameter // dummy
+ || (sym.name.toTermName == nme.WILDCARD) // _
+ || nme.isVariableName(sym.name) // type variable
+ )
+ private def isUnwarnableTypeArg(arg: Type) = (
+ uncheckedOk(arg) // @unchecked T
+ || isUnwarnableTypeArgSymbol(arg.typeSymbolDirect) // has to be direct: see pos/t1439
+ )
+ private def uncheckedOk(tp: Type) = tp hasAnnotation UncheckedClass
+
+ private def typeArgsInTopLevelType(tp: Type): List[Type] = {
+ val tps = tp match {
+ case RefinedType(parents, _) => parents flatMap typeArgsInTopLevelType
+ case TypeRef(_, ArrayClass, arg :: Nil) => typeArgsInTopLevelType(arg)
+ case TypeRef(pre, sym, args) => typeArgsInTopLevelType(pre) ++ args
+ case ExistentialType(tparams, underlying) => tparams.map(_.tpe) ++ typeArgsInTopLevelType(underlying)
+ case _ => Nil
+ }
+ tps filterNot isUnwarnableTypeArg
+ }
+
+ private class CheckabilityChecker(val X: Type, val P: Type) {
+ def Xsym = X.typeSymbol
+ def Psym = P.typeSymbol
+ def XR = propagateKnownTypes(X, Psym)
+ // sadly the spec says (new java.lang.Boolean(true)).isInstanceOf[scala.Boolean]
+ def P1 = X matchesPattern P
+ def P2 = !Psym.isPrimitiveValueClass && isNeverSubType(X, P)
+ def P3 = isNonRefinementClassType(P) && (XR matchesPattern P)
+ def P4 = !(P1 || P2 || P3)
+
+ def summaryString = f"""
+ |Checking checkability of (x: $X) against pattern $P
+ |[P1] $P1%-6s X <: P // $X <: $P
+ |[P2] $P2%-6s x ∉ P // (x ∈ $X) ⇒ (x ∉ $P)
+ |[P3] $P3%-6s XR <: P // $XR <: $P
+ |[P4] $P4%-6s None of the above // !(P1 || P2 || P3)
+ """.stripMargin.trim
+
+ val result = (
+ if (X.isErroneous || P.isErroneous) CheckabilityError
+ else if (P1) StaticallyTrue
+ else if (P2) StaticallyFalse
+ else if (P3) RuntimeCheckable
+ else if (uncheckableType == NoType) {
+ // Avoid warning (except ourselves) if we can't pinpoint the uncheckable type
+ debugwarn("Checkability checker says 'Uncheckable', but uncheckable type cannot be found:\n" + summaryString)
+ CheckabilityError
+ }
+ else Uncheckable
+ )
+ lazy val uncheckableType = if (Psym.isAbstractType) P else {
+ val possibles = typeArgsInTopLevelType(P).toSet
+ val opt = possibles find { targ =>
+ // Create a derived type with every possibly uncheckable type replaced
+ // with a WildcardType, except for 'targ'. If !(XR <: derived) then
+ // 'targ' is uncheckable.
+ val derived = P map (tp => if (possibles(tp) && !(tp =:= targ)) WildcardType else tp)
+ !(XR <:< derived)
+ }
+ opt getOrElse NoType
+ }
+
+ def neverSubClass = isNeverSubClass(Xsym, Psym)
+ def neverMatches = result == StaticallyFalse
+ def isUncheckable = result == Uncheckable
+ def uncheckableMessage = uncheckableType match {
+ case NoType => "something"
+ case tp @ RefinedType(_, _) => "refinement " + tp
+ case TypeRef(_, sym, _) if sym.isAbstractType => "abstract type " + sym.name
+ case tp => "non-variable type argument " + tp
+ }
+ }
+
+ /** X, P, [P1], etc. are all explained at the top of the file.
+ */
+ private object CheckabilityChecker {
+ /** A knowable class is one which is either effectively final
+ * itself, or sealed with only knowable children.
+ */
+ def isKnowable(sym: Symbol): Boolean = /*logResult(s"isKnowable($sym)")*/(
+ sym.initialize.isEffectivelyFinal // pesky .initialize requirement, or we receive lies about isSealed
+ || sym.isSealed && (sym.children forall isKnowable)
+ )
+ def knownSubclasses(sym: Symbol): List[Symbol] = /*logResult(s"knownSubclasses($sym)")*/(sym :: {
+ if (sym.isSealed) sym.children.toList flatMap knownSubclasses
+ else Nil
+ })
+ def excludable(s1: Symbol, s2: Symbol) = /*logResult(s"excludable($s1, $s2)")*/(
+ isKnowable(s1)
+ && !(s2 isSubClass s1)
+ && knownSubclasses(s1).forall(child => !(child isSubClass s2))
+ )
+
+ /** Given classes A and B, can it be shown that nothing which is
+ * an A will ever be a subclass of something which is a B? This
+ * entails not only showing that !(A isSubClass B) but that the
+ * same is true of all their subclasses. Restated for symmetry:
+ * the same value cannot be a member of both A and B.
+ *
+ * 1) A must not be a subclass of B, nor B of A (the trivial check)
+ * 2) One of A or B must be completely knowable (see isKnowable)
+ * 3) Assuming A is knowable, the proposition is true if
+ * !(A' isSubClass B) for all A', where A' is a subclass of A.
+ *
+ * Due to symmetry, the last condition applies as well in reverse.
+ */
+ def isNeverSubClass(sym1: Symbol, sym2: Symbol) = /*logResult(s"isNeverSubClass($sym1, $sym2)")*/(
+ sym1.isClass
+ && sym2.isClass
+ && (excludable(sym1, sym2) || excludable(sym2, sym1))
+ )
+ private def isNeverSubArgs(tps1: List[Type], tps2: List[Type], tparams: List[Symbol]): Boolean = /*logResult(s"isNeverSubArgs($tps1, $tps2, $tparams)")*/ {
+ def isNeverSubArg(t1: Type, t2: Type, variance: Int) = {
+ if (variance > 0) isNeverSubType(t2, t1)
+ else if (variance < 0) isNeverSubType(t1, t2)
+ else isNeverSameType(t1, t2)
+ }
+ exists3(tps1, tps2, tparams map (_.variance))(isNeverSubArg)
+ }
+ private def isNeverSameType(tp1: Type, tp2: Type): Boolean = (tp1, tp2) match {
+ case (TypeRef(_, sym1, args1), TypeRef(_, sym2, args2)) =>
+ ( isNeverSubClass(sym1, sym2)
+ || isNeverSubClass(sym2, sym1)
+ || ((sym1 == sym2) && isNeverSubArgs(args1, args2, sym1.typeParams))
+ )
+ case _ =>
+ false
+ }
+ // Important to dealias at any entry point (this is the only one at this writing.)
+ def isNeverSubType(tp1: Type, tp2: Type): Boolean = /*logResult(s"isNeverSubType($tp1, $tp2)")*/((tp1.dealias, tp2.dealias) match {
+ case (TypeRef(_, sym1, args1), TypeRef(_, sym2, args2)) =>
+ isNeverSubClass(sym1, sym2) || {
+ (sym1 isSubClass sym2) && {
+ val tp1seen = tp1 baseType sym2
+ isNeverSubArgs(tp1seen.typeArgs, args2, sym2.typeParams)
+ }
+ }
+ case _ => false
+ })
+ }
+
+ trait InferCheckable {
+ self: Inferencer =>
+
+ /** TODO: much better error positions.
+ * Kind of stuck right now because they just pass us the one tree.
+ * TODO: Eliminate inPattern, canRemedy, which have no place here.
+ */
+ def checkCheckable(tree: Tree, P0: Type, X0: Type, inPattern: Boolean, canRemedy: Boolean = false) {
+ if (uncheckedOk(P0)) return
+ def where = if (inPattern) "pattern " else ""
+
+ // singleton types not considered here
+ val P = P0.widen
+ val X = X0.widen
+
+ P match {
+ // Prohibit top-level type tests for these, but they are ok nested (e.g. case Foldable[Nothing] => ... )
+ case TypeRef(_, NothingClass | NullClass | AnyValClass, _) =>
+ InferErrorGen.TypePatternOrIsInstanceTestError(tree, P)
+ // If top-level abstract types can be checked using a classtag extractor, don't warn about them
+ case TypeRef(_, sym, _) if sym.isAbstractType && canRemedy =>
+ ;
+ // Matching on types like case _: AnyRef { def bippy: Int } => doesn't work -- yet.
+ case RefinedType(_, decls) if !decls.isEmpty =>
+ getContext.unit.warning(tree.pos, s"a pattern match on a refinement type is unchecked")
+ case _ =>
+ val checker = new CheckabilityChecker(X, P)
+ log(checker.summaryString)
+ if (checker.neverMatches) {
+ val addendum = if (checker.neverSubClass) "" else " (but still might match its erasure)"
+ getContext.unit.warning(tree.pos, s"fruitless type test: a value of type $X cannot also be a $P$addendum")
+ }
+ else if (checker.isUncheckable) {
+ val msg = (
+ if (checker.uncheckableType =:= P) s"abstract type $where$P"
+ else s"${checker.uncheckableMessage} in type $where$P"
+ )
+ getContext.unit.warning(tree.pos, s"$msg is unchecked since it is eliminated by erasure")
+ }
+ }
+ }
+ }
+}
+
+private[typechecker] final class Checkability(val value: Int) extends AnyVal { }
+private[typechecker] object Checkability {
+ val StaticallyTrue = new Checkability(0)
+ val StaticallyFalse = new Checkability(1)
+ val RuntimeCheckable = new Checkability(2)
+ val Uncheckable = new Checkability(3)
+ val CheckabilityError = new Checkability(4)
+}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index db16bd02ab..48abfd7a2c 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -17,7 +17,7 @@ import scala.annotation.tailrec
* @author Martin Odersky
* @version 1.0
*/
-trait Infer {
+trait Infer extends Checkable {
self: Analyzer =>
import global._
@@ -253,7 +253,7 @@ trait Infer {
private val stdErrorValue = stdErrorClass.newErrorValue(nme.ERROR)
/** The context-dependent inferencer part */
- class Inferencer(context: Context) extends InferencerContextErrors {
+ class Inferencer(context: Context) extends InferencerContextErrors with InferCheckable {
import InferErrorGen._
/* -- Error Messages --------------------------------------------------- */
@@ -1361,99 +1361,6 @@ trait Infer {
check(tp, Nil)
}
- // if top-level abstract types can be checked using a classtag extractor, don't warn about them
- def checkCheckable(tree: Tree, typeToTest: Type, typeEnsured: Type, inPattern: Boolean, canRemedy: Boolean = false) = {
- log(s"checkCheckable($tree, $typeToTest, $typeEnsured, inPattern = $inPattern, canRemedy = $canRemedy")
-
- sealed abstract class TypeConformance(check: (Type, Type) => Boolean) {
- def apply(t1: Type, t2: Type): Boolean = check(t1, t2) && {
- log(s"Skipping unchecked for statically verifiable condition $t1 ${this} $t2")
- true
- }
- }
- // I tried to use varianceInType to track the variance implications
- // but I could not make it work.
- case object =:= extends TypeConformance(_ =:= _)
- case object <:< extends TypeConformance(_ <:< _)
- case object >:> extends TypeConformance((t1, t2) => t2 <:< t1)
- case object =!= extends TypeConformance((t1, t2) => false)
-
- var bound: List[Symbol] = Nil
- var warningMessages: List[String] = Nil
-
- def isLocalBinding(sym: Symbol) = (
- sym.isAbstractType && (
- (bound contains sym)
- || (sym.name == tpnme.WILDCARD)
- || {
- val e = context.scope.lookupEntry(sym.name)
- (e ne null) && e.sym == sym && !e.sym.isTypeParameterOrSkolem && e.owner == context.scope
- }
- )
- )
- def check(tp0: Type, pt: Type, conformance: TypeConformance): Boolean = {
- val tp = tp0.normalize
- // Set the warning message to be issued when the top-level call fails.
- def warn(what: String): Boolean = {
- warningMessages ::= what
- false
- }
- def checkArg(param: Symbol, arg: Type) = {
- def conforms = (
- if (param.isCovariant) <:<
- else if (param.isContravariant) >:>
- else =:=
- )
- (arg hasAnnotation UncheckedClass) || {
- arg.withoutAnnotations match {
- case TypeRef(_, sym, args) =>
- ( isLocalBinding(sym)
- || arg.typeSymbol.isTypeParameterOrSkolem
- || (sym.name == tpnme.WILDCARD) // avoid spurious warnings on HK types
- || check(arg, param.tpeHK, conforms)
- || warn("non-variable type argument " + arg)
- )
- case _ =>
- warn("non-variable type argument " + arg)
- }
- }
- }
-
- // Checking if pt (the expected type of the pattern, and the type
- // we are guaranteed) conforms to tp (the type expressed in the pattern's
- // type test.) If it does, then even if the type being checked for appears
- // to be uncheckable, it is not a warning situation, because it is indeed
- // checked: not at runtime, but statically.
- conformance.apply(pt, tp) || (tp match {
- case SingleType(pre, _) => check(pre, pt, =:=)
- case ExistentialType(quantified, tp1) => bound :::= quantified ; check(tp1, pt, <:<)
- case ThisType(_) | NoPrefix => true
- case RefinedType(parents, decls) if decls.isEmpty => parents forall (p => check(p, pt, <:<))
- case RefinedType(_, _) => warn("refinement " + tp)
- case TypeRef(_, ArrayClass, arg :: Nil) => check(arg, NoType, =!=)
- case TypeRef(_, NonLocalReturnControlClass, _) => true // no way to suppress unchecked warnings on try/catch
- // we only use the extractor for top-level type tests, type arguments remain unchecked
- case TypeRef(_, sym, _) if sym.isAbstractType => isLocalBinding(sym) || canRemedy || warn("abstract type " + tp)
- case TypeRef(_, _, Nil) => false // leaf node
- case TypeRef(pre, sym, args) => forall2(sym.typeParams, args)(checkArg) && check(pre, pt.prefix, =:=)
- case _ => warn("type " + tp)
- })
- }
- typeToTest match {
- // Prohibit top-level type tests for these, but they are
- // acceptable nested (e.g. case Foldable[Nothing] => ... )
- case TypeRef(_, NothingClass | NullClass | AnyValClass, _) =>
- TypePatternOrIsInstanceTestError(tree, typeToTest)
- case _ =>
- def where = ( if (inPattern) "pattern " else "" ) + typeToTest
- if (check(typeToTest, typeEnsured, =:=)) ()
- // Note that this is a regular warning, not an uncheckedWarning,
- // which is now the province of such notifications as "pattern matcher
- // exceeded its analysis budget."
- else warningMessages foreach (m =>
- context.unit.warning(tree.pos, s"$m in type $where is unchecked since it is eliminated by erasure"))
- }
- }
/** Type intersection of simple type tp1 with general type tp2.
* The result eliminates some redundancies.
diff --git a/src/compiler/scala/tools/nsc/typechecker/Modes.scala b/src/compiler/scala/tools/nsc/typechecker/Modes.scala
index e9ea99faab..d942d080cb 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Modes.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Modes.scala
@@ -86,6 +86,10 @@ trait Modes {
*/
final val TYPEPATmode = 0x10000
+ /** RETmode is set when we are typing a return expression.
+ */
+ final val RETmode = 0x20000
+
final private val StickyModes = EXPRmode | PATTERNmode | TYPEmode | ALTmode
final def onlyStickyModes(mode: Int) =
@@ -133,4 +137,4 @@ trait Modes {
def modeString(mode: Int): String =
if (mode == 0) "NOmode"
else (modeNameMap filterKeys (bit => inAllModes(mode, bit))).values mkString " "
-} \ No newline at end of file
+}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 6e222459c9..3a443ea2c0 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -253,12 +253,6 @@ trait Typers extends Modes with Adaptations with Tags {
result
}
}
- def isNonRefinementClassType(tpe: Type) = tpe match {
- case SingleType(_, sym) => sym.isModuleClass
- case TypeRef(_, sym, _) => sym.isClass && !sym.isRefinementClass
- case ErrorType => true
- case _ => false
- }
private def errorNotClass(tpt: Tree, found: Type) = { ClassTypeRequiredError(tpt, found); false }
private def errorNotStable(tpt: Tree, found: Type) = { TypeNotAStablePrefixError(tpt, found); false }
@@ -3772,9 +3766,13 @@ trait Typers extends Modes with Adaptations with Tags {
if (fun.symbol == Predef_classOf)
typedClassOf(tree, args.head, true)
else {
- if (!isPastTyper && fun.symbol == Any_isInstanceOf && !targs.isEmpty)
- checkCheckable(tree, targs.head, AnyClass.tpe, inPattern = false)
-
+ if (!isPastTyper && fun.symbol == Any_isInstanceOf && targs.nonEmpty) {
+ val scrutineeType = fun match {
+ case Select(qual, _) => qual.tpe
+ case _ => AnyClass.tpe
+ }
+ checkCheckable(tree, targs.head, scrutineeType, inPattern = false)
+ }
val resultpe = restpe.instantiateTypeParams(tparams, targs)
//@M substitution in instantiateParams needs to be careful!
//@M example: class Foo[a] { def foo[m[x]]: m[a] = error("") } (new Foo[Int]).foo[List] : List[Int]
@@ -3784,7 +3782,8 @@ trait Typers extends Modes with Adaptations with Tags {
//println("instantiating type params "+restpe+" "+tparams+" "+targs+" = "+resultpe)
treeCopy.TypeApply(tree, fun, args) setType resultpe
}
- } else {
+ }
+ else {
TypedApplyWrongNumberOfTpeParametersError(tree, fun)
}
case ErrorType =>
@@ -4181,7 +4180,7 @@ trait Typers extends Modes with Adaptations with Tags {
ReturnWithoutTypeError(tree, enclMethod.owner)
} else {
context.enclMethod.returnsSeen = true
- val expr1: Tree = typed(expr, EXPRmode | BYVALmode, restpt.tpe)
+ val expr1: Tree = typed(expr, EXPRmode | BYVALmode | RETmode, restpt.tpe)
// Warn about returning a value if no value can be returned.
if (restpt.tpe.typeSymbol == UnitClass) {
// The typing in expr1 says expr is Unit (it has already been coerced if
@@ -4190,7 +4189,8 @@ trait Typers extends Modes with Adaptations with Tags {
if (typed(expr).tpe.typeSymbol != UnitClass)
unit.warning(tree.pos, "enclosing method " + name + " has result type Unit: return value discarded")
}
- treeCopy.Return(tree, checkDead(expr1)) setSymbol enclMethod.owner setType NothingClass.tpe
+ treeCopy.Return(tree, checkDead(expr1)).setSymbol(enclMethod.owner)
+ .setType(adaptTypeOfReturn(expr1, restpt.tpe, NothingClass.tpe))
}
}
}
diff --git a/src/compiler/scala/tools/reflect/FrontEnd.scala b/src/compiler/scala/tools/reflect/FrontEnd.scala
new file mode 100644
index 0000000000..f0d3d5973d
--- /dev/null
+++ b/src/compiler/scala/tools/reflect/FrontEnd.scala
@@ -0,0 +1,50 @@
+package scala.tools
+package reflect
+
+import scala.reflect.internal.util.Position
+
+trait FrontEnd {
+ object severity extends Enumeration
+ class Severity(val id: Int) extends severity.Value {
+ var count: Int = 0
+ override def toString() = this match {
+ case INFO => "INFO"
+ case WARNING => "WARNING"
+ case ERROR => "ERROR"
+ case _ => "<unknown>"
+ }
+ }
+ val INFO = new Severity(0)
+ val WARNING = new Severity(1)
+ val ERROR = new Severity(2)
+
+ def hasErrors = ERROR.count > 0
+ def hasWarnings = WARNING.count > 0
+
+ case class Info(val pos: Position, val msg: String, val severity: Severity)
+ val infos = new scala.collection.mutable.LinkedHashSet[Info]
+
+ /** Handles incoming info */
+ def log(pos: Position, msg: String, severity: Severity) {
+ infos += new Info(pos, msg, severity)
+ severity.count += 1
+ display(infos.last)
+ }
+
+ /** Displays incoming info */
+ def display(info: Info): Unit
+
+ /** Services a request to drop into interactive mode */
+ def interactive(): Unit
+
+ /** Refreshes the UI */
+ def flush(): Unit = {}
+
+ /** Resets the reporter */
+ def reset(): Unit = {
+ INFO.count = 0
+ WARNING.count = 0
+ ERROR.count = 0
+ infos.clear()
+ }
+}
diff --git a/src/compiler/scala/tools/reflect/FrontEnds.scala b/src/compiler/scala/tools/reflect/FrontEnds.scala
deleted file mode 100644
index d0c3c1c774..0000000000
--- a/src/compiler/scala/tools/reflect/FrontEnds.scala
+++ /dev/null
@@ -1,88 +0,0 @@
-package scala.tools
-package reflect
-
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import scala.reflect.ClassTag
-
-trait FrontEnds extends scala.reflect.api.FrontEnds {
-
- type Position = scala.reflect.internal.util.Position
-
- def mkConsoleFrontEnd(minSeverity: Int = 1): FrontEnd = {
- val settings = new Settings()
- if (minSeverity <= 0) settings.verbose.value = true
- if (minSeverity > 1) settings.nowarn.value = true
- wrapReporter(new ConsoleReporter(settings))
- }
-
- abstract class FrontEndToReporterProxy(val frontEnd: FrontEnd) extends AbstractReporter {
- import frontEnd.{Severity => ApiSeverity}
- val API_INFO = frontEnd.INFO
- val API_WARNING = frontEnd.WARNING
- val API_ERROR = frontEnd.ERROR
-
- type NscSeverity = Severity
- val NSC_INFO = INFO
- val NSC_WARNING = WARNING
- val NSC_ERROR = ERROR
-
- def display(pos: Position, msg: String, nscSeverity: NscSeverity): Unit =
- frontEnd.log(pos, msg, nscSeverity match {
- case NSC_INFO => API_INFO
- case NSC_WARNING => API_WARNING
- case NSC_ERROR => API_ERROR
- })
-
- def displayPrompt(): Unit =
- frontEnd.interactive()
-
- override def flush(): Unit = {
- super.flush()
- frontEnd.flush()
- }
-
- override def reset(): Unit = {
- super.reset()
- frontEnd.reset()
- }
- }
-
- def wrapFrontEnd(frontEnd: FrontEnd): Reporter = new FrontEndToReporterProxy(frontEnd) {
- val settings = new Settings()
- settings.verbose.value = true
- settings.nowarn.value = false
- }
-
- class ReporterToFrontEndProxy(val reporter: Reporter) extends FrontEnd {
- val API_INFO = INFO
- val API_WARNING = WARNING
- val API_ERROR = ERROR
-
- override def hasErrors = reporter.hasErrors
- override def hasWarnings = reporter.hasWarnings
-
- def display(info: Info): Unit = info.severity match {
- case API_INFO => reporter.info(info.pos, info.msg, false)
- case API_WARNING => reporter.warning(info.pos, info.msg)
- case API_ERROR => reporter.error(info.pos, info.msg)
- }
-
- def interactive(): Unit = reporter match {
- case reporter: AbstractReporter => reporter.displayPrompt()
- case _ => // do nothing
- }
-
- override def flush(): Unit = {
- super.flush()
- reporter.flush()
- }
-
- override def reset(): Unit = {
- super.reset()
- reporter.reset()
- }
- }
-
- def wrapReporter(reporter: Reporter): FrontEnd = new ReporterToFrontEndProxy(reporter)
-}
diff --git a/src/compiler/scala/tools/reflect/StdTags.scala b/src/compiler/scala/tools/reflect/StdTags.scala
index 94fd8e1fe8..a3bc9b9bd1 100644
--- a/src/compiler/scala/tools/reflect/StdTags.scala
+++ b/src/compiler/scala/tools/reflect/StdTags.scala
@@ -3,7 +3,7 @@ package reflect
import java.lang.{Class => jClass}
import scala.reflect.{ClassTag, classTag}
-import scala.reflect.api.{MirrorOf, TypeCreator, Universe => ApiUniverse}
+import scala.reflect.api.{Mirror, TypeCreator, Universe => ApiUniverse}
// [Eugene++] Before 2.10 is released, I suggest we don't rely on automated type tag generation
// sure, it's convenient, but then refactoring reflection / reification becomes a pain
@@ -11,13 +11,13 @@ import scala.reflect.api.{MirrorOf, TypeCreator, Universe => ApiUniverse}
trait StdTags {
val u: ApiUniverse with Singleton
- val m: MirrorOf[u.type]
+ val m: Mirror[u.type]
lazy val tagOfListOfString: u.TypeTag[List[String]] =
u.TypeTag[List[String]](
m,
new TypeCreator {
- def apply[U <: ApiUniverse with Singleton](m: MirrorOf[U]): U # Type = {
+ def apply[U <: ApiUniverse with Singleton](m: Mirror[U]): U # Type = {
val u = m.universe
val pre = u.ThisType(m.staticPackage("scala.collection.immutable").moduleClass.asInstanceOf[u.Symbol])
u.TypeRef(pre, u.definitions.ListClass, List(u.definitions.StringClass.toTypeConstructor))
@@ -28,7 +28,7 @@ trait StdTags {
u.TypeTag[T](
m,
new TypeCreator {
- def apply[U <: ApiUniverse with Singleton](m: MirrorOf[U]): U # Type =
+ def apply[U <: ApiUniverse with Singleton](m: Mirror[U]): U # Type =
m.staticClass(classTag[T].runtimeClass.getName).toTypeConstructor.asInstanceOf[U # Type]
})
lazy val tagOfInt = u.TypeTag.Int
diff --git a/src/compiler/scala/tools/reflect/ToolBox.scala b/src/compiler/scala/tools/reflect/ToolBox.scala
index f627699597..ab814b617d 100644
--- a/src/compiler/scala/tools/reflect/ToolBox.scala
+++ b/src/compiler/scala/tools/reflect/ToolBox.scala
@@ -15,6 +15,9 @@ trait ToolBox[U <: scala.reflect.api.Universe] {
*
* Accumulates and displays warnings and errors, can drop to interactive mode (if supported).
* The latter can be useful to study the typechecker or to debug complex macros.
+ *
+ * [[scala.tools.reflect]] provides two predefined front ends that can be created using
+ * [[scala.tools.reflect.mkSilentFrontEnd]] and [[scala.tools.reflect.mkConsoleFrontEnd]].
*/
def frontEnd: FrontEnd
diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
index 17d69cf94b..95135b84e0 100644
--- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
+++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
@@ -334,7 +334,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
val errorFn: String => Unit = msg => frontEnd.log(scala.reflect.internal.util.NoPosition, msg, frontEnd.ERROR)
val command = new CompilerCommand(arguments.toList, errorFn)
command.settings.outputDirs setSingleOutput virtualDirectory
- val instance = new ToolBoxGlobal(command.settings, new FrontEndToReporterProxy(frontEnd) { val settings = command.settings })
+ val instance = new ToolBoxGlobal(command.settings, frontEndToReporter(frontEnd, command.settings))
if (frontEnd.hasErrors) {
var msg = "reflective compilation has failed: cannot initialize the compiler: " + EOL + EOL
msg += frontEnd.infos map (_.msg) mkString EOL
diff --git a/src/compiler/scala/tools/reflect/package.scala b/src/compiler/scala/tools/reflect/package.scala
index 901071d91a..8a1e3628e2 100644
--- a/src/compiler/scala/tools/reflect/package.scala
+++ b/src/compiler/scala/tools/reflect/package.scala
@@ -6,9 +6,12 @@
package scala.tools
import scala.reflect.api.JavaUniverse
+import scala.reflect.internal.util.Position
import scala.language.implicitConversions
+import scala.tools.nsc.reporters._
+import scala.tools.nsc.Settings
-package object reflect extends FrontEnds {
+package object reflect {
// [todo: can we generalize this?
import scala.reflect.runtime.{universe => ru}
implicit def ToolBox(mirror0: ru.Mirror): ToolBoxFactory[ru.type] =
@@ -17,9 +20,92 @@ package object reflect extends FrontEnds {
}
// todo. replace this with an implicit class, once the pesky warning is gone
+ // we don't provide `Eval` for trees, because it's unclear where to get an evaluation mirror from
implicit def Eval[T](expr: JavaUniverse # Expr[T]): Eval[T] = new Eval[T](expr)
- // we don't provide `Eval` for trees, because it's unclear where to get an evaluation mirror from
+ /** Creates a UI-less reporter that simply accumulates all the messages
+ */
+ def mkSilentFrontEnd(): FrontEnd = new FrontEnd {
+ def display(info: Info) {}
+ def interactive() {}
+ }
+
+ /** Creates a reporter that prints messages to the console according to the settings.
+ *
+ * ``minSeverity'' determines minimum severity of the messages to be printed.
+ * 0 stands for INFO, 1 stands for WARNING and 2 stands for ERROR.
+ */
+ // todo. untangle warningsAsErrors from Reporters. I don't feel like moving this flag here!
+ def mkConsoleFrontEnd(minSeverity: Int = 1): FrontEnd = {
+ val settings = new Settings()
+ if (minSeverity <= 0) settings.verbose.value = true
+ if (minSeverity > 1) settings.nowarn.value = true
+ reporterToFrontEnd(new ConsoleReporter(settings))
+ }
+
+ private[reflect] def reporterToFrontEnd(reporter: Reporter): FrontEnd = new FrontEnd {
+ val API_INFO = INFO
+ val API_WARNING = WARNING
+ val API_ERROR = ERROR
+
+ override def hasErrors = reporter.hasErrors
+ override def hasWarnings = reporter.hasWarnings
+
+ def display(info: Info): Unit = info.severity match {
+ case API_INFO => reporter.info(info.pos, info.msg, false)
+ case API_WARNING => reporter.warning(info.pos, info.msg)
+ case API_ERROR => reporter.error(info.pos, info.msg)
+ }
+
+ def interactive(): Unit = reporter match {
+ case reporter: AbstractReporter => reporter.displayPrompt()
+ case _ => // do nothing
+ }
+
+ override def flush(): Unit = {
+ super.flush()
+ reporter.flush()
+ }
+
+ override def reset(): Unit = {
+ super.reset()
+ reporter.reset()
+ }
+ }
+
+ private[reflect] def frontEndToReporter(frontEnd: FrontEnd, settings0: Settings): Reporter = new AbstractReporter {
+ val settings = settings0
+
+ import frontEnd.{Severity => ApiSeverity}
+ val API_INFO = frontEnd.INFO
+ val API_WARNING = frontEnd.WARNING
+ val API_ERROR = frontEnd.ERROR
+
+ type NscSeverity = Severity
+ val NSC_INFO = INFO
+ val NSC_WARNING = WARNING
+ val NSC_ERROR = ERROR
+
+ def display(pos: Position, msg: String, nscSeverity: NscSeverity): Unit =
+ frontEnd.log(pos, msg, nscSeverity match {
+ case NSC_INFO => API_INFO
+ case NSC_WARNING => API_WARNING
+ case NSC_ERROR => API_ERROR
+ })
+
+ def displayPrompt(): Unit =
+ frontEnd.interactive()
+
+ override def flush(): Unit = {
+ super.flush()
+ frontEnd.flush()
+ }
+
+ override def reset(): Unit = {
+ super.reset()
+ frontEnd.reset()
+ }
+ }
}
package reflect {
diff --git a/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala b/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala
index a20ff1667b..b373b3d0de 100644
--- a/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala
+++ b/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala
@@ -150,10 +150,8 @@ abstract class CPSAnnotationChecker extends CPSUtils with Modes {
if ((mode & global.analyzer.EXPRmode) != 0) {
if ((annots1 corresponds annots2)(_.atp <:< _.atp)) {
vprintln("already same, can't adapt further")
- return false
- }
-
- if (annots1.isEmpty && !annots2.isEmpty && ((mode & global.analyzer.BYVALmode) == 0)) {
+ false
+ } else if (annots1.isEmpty && !annots2.isEmpty && ((mode & global.analyzer.BYVALmode) == 0)) {
//println("can adapt annotations? " + tree + " / " + tree.tpe + " / " + Integer.toHexString(mode) + " / " + pt)
if (!hasPlusMarker(tree.tpe)) {
// val base = tree.tpe <:< removeAllCPSAnnotations(pt)
@@ -163,17 +161,26 @@ abstract class CPSAnnotationChecker extends CPSUtils with Modes {
// TBD: use same or not?
//if (same) {
vprintln("yes we can!! (unit)")
- return true
+ true
//}
- }
- } else if (!annots1.isEmpty && ((mode & global.analyzer.BYVALmode) != 0)) {
- if (!hasMinusMarker(tree.tpe)) {
+ } else false
+ } else if (!hasPlusMarker(tree.tpe) && annots1.isEmpty && !annots2.isEmpty && ((mode & global.analyzer.RETmode) != 0)) {
+ vprintln("checking enclosing method's result type without annotations")
+ tree.tpe <:< pt.withoutAnnotations
+ } else if (!hasMinusMarker(tree.tpe) && !annots1.isEmpty && ((mode & global.analyzer.BYVALmode) != 0)) {
+ val optCpsTypes: Option[(Type, Type)] = cpsParamTypes(tree.tpe)
+ val optExpectedCpsTypes: Option[(Type, Type)] = cpsParamTypes(pt)
+ if (optCpsTypes.isEmpty || optExpectedCpsTypes.isEmpty) {
vprintln("yes we can!! (byval)")
- return true
+ true
+ } else { // check cps param types
+ val cpsTpes = optCpsTypes.get
+ val cpsPts = optExpectedCpsTypes.get
+ // class cpsParam[-B,+C], therefore:
+ cpsPts._1 <:< cpsTpes._1 && cpsTpes._2 <:< cpsPts._2
}
- }
- }
- false
+ } else false
+ } else false
}
override def adaptAnnotations(tree: Tree, mode: Int, pt: Type): Tree = {
@@ -184,6 +191,7 @@ abstract class CPSAnnotationChecker extends CPSUtils with Modes {
val patMode = (mode & global.analyzer.PATTERNmode) != 0
val exprMode = (mode & global.analyzer.EXPRmode) != 0
val byValMode = (mode & global.analyzer.BYVALmode) != 0
+ val retMode = (mode & global.analyzer.RETmode) != 0
val annotsTree = cpsParamAnnotation(tree.tpe)
val annotsExpected = cpsParamAnnotation(pt)
@@ -210,9 +218,38 @@ abstract class CPSAnnotationChecker extends CPSUtils with Modes {
val res = tree modifyType addMinusMarker
vprintln("adapted annotations (by val) of " + tree + " to " + res.tpe)
res
+ } else if (retMode && !hasPlusMarker(tree.tpe) && annotsTree.isEmpty && annotsExpected.nonEmpty) {
+ // add a marker annotation that will make tree.tpe behave as pt, subtyping wise
+ // tree will look like having any possible annotation
+
+ // note 1: we are only adding a plus marker if the method's result type is a cps type
+ // (annotsExpected.nonEmpty == cpsParamAnnotation(pt).nonEmpty)
+ // note 2: we are not adding the expected cps annotations, since they will be added
+ // by adaptTypeOfReturn (see below).
+ val res = tree modifyType (_ withAnnotations List(newPlusMarker()))
+ vprintln("adapted annotations (return) of " + tree + " to " + res.tpe)
+ res
} else tree
}
+ /** Returns an adapted type for a return expression if the method's result type (pt) is a CPS type.
+ * Otherwise, it returns the `default` type (`typedReturn` passes `NothingClass.tpe`).
+ *
+ * A return expression in a method that has a CPS result type is an error unless the return
+ * is in tail position. Therefore, we are making sure that only the types of return expressions
+ * are adapted which will either be removed, or lead to an error.
+ */
+ override def adaptTypeOfReturn(tree: Tree, pt: Type, default: => Type): Type = {
+ // only adapt if method's result type (pt) is cps type
+ val annots = cpsParamAnnotation(pt)
+ if (annots.nonEmpty) {
+ // return type of `tree` without plus marker, but only if it doesn't have other cps annots
+ if (hasPlusMarker(tree.tpe) && !hasCpsParamTypes(tree.tpe))
+ tree.setType(removeAttribs(tree.tpe, MarkerCPSAdaptPlus))
+ tree.tpe
+ } else default
+ }
+
def updateAttributesFromChildren(tpe: Type, childAnnots: List[AnnotationInfo], byName: List[Tree]): Type = {
tpe match {
// Would need to push annots into each alternative of overloaded type
diff --git a/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala b/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala
index 51760d2807..ba87cadfeb 100644
--- a/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala
+++ b/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala
@@ -32,6 +32,55 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
implicit val _unit = unit // allow code in CPSUtils.scala to report errors
var cpsAllowed: Boolean = false // detect cps code in places we do not handle (yet)
+ object RemoveTailReturnsTransformer extends Transformer {
+ override def transform(tree: Tree): Tree = tree match {
+ case Block(stms, r @ Return(expr)) =>
+ treeCopy.Block(tree, stms, expr)
+
+ case Block(stms, expr) =>
+ treeCopy.Block(tree, stms, transform(expr))
+
+ case If(cond, r1 @ Return(thenExpr), r2 @ Return(elseExpr)) =>
+ treeCopy.If(tree, cond, transform(thenExpr), transform(elseExpr))
+
+ case If(cond, r1 @ Return(thenExpr), elseExpr) =>
+ treeCopy.If(tree, cond, transform(thenExpr), transform(elseExpr))
+
+ case If(cond, thenExpr, r2 @ Return(elseExpr)) =>
+ treeCopy.If(tree, cond, transform(thenExpr), transform(elseExpr))
+
+ case If(cond, thenExpr, elseExpr) =>
+ treeCopy.If(tree, cond, transform(thenExpr), transform(elseExpr))
+
+ case Try(block, catches, finalizer) =>
+ treeCopy.Try(tree,
+ transform(block),
+ (catches map (t => transform(t))).asInstanceOf[List[CaseDef]],
+ transform(finalizer))
+
+ case CaseDef(pat, guard, r @ Return(expr)) =>
+ treeCopy.CaseDef(tree, pat, guard, expr)
+
+ case CaseDef(pat, guard, body) =>
+ treeCopy.CaseDef(tree, pat, guard, transform(body))
+
+ case Return(_) =>
+ unit.error(tree.pos, "return expressions in CPS code must be in tail position")
+ tree
+
+ case _ =>
+ super.transform(tree)
+ }
+ }
+
+ def removeTailReturns(body: Tree): Tree = {
+ // support body with single return expression
+ body match {
+ case Return(expr) => expr
+ case _ => RemoveTailReturnsTransformer.transform(body)
+ }
+ }
+
override def transform(tree: Tree): Tree = {
if (!cpsEnabled) return tree
@@ -46,11 +95,14 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
// this would cause infinite recursion. But we could remove the
// ValDef case here.
- case dd @ DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
+ case dd @ DefDef(mods, name, tparams, vparamss, tpt, rhs0) =>
debuglog("transforming " + dd.symbol)
atOwner(dd.symbol) {
- val rhs1 = transExpr(rhs, None, getExternalAnswerTypeAnn(tpt.tpe))
+ val rhs =
+ if (cpsParamTypes(tpt.tpe).nonEmpty) removeTailReturns(rhs0)
+ else rhs0
+ val rhs1 = transExpr(rhs, None, getExternalAnswerTypeAnn(tpt.tpe))(getExternalAnswerTypeAnn(tpt.tpe).isDefined)
debuglog("result "+rhs1)
debuglog("result is of type "+rhs1.tpe)
@@ -75,6 +127,7 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
val ext = getExternalAnswerTypeAnn(body.tpe)
val pureBody = getAnswerTypeAnn(body.tpe).isEmpty
+ implicit val isParentImpure = ext.isDefined
def transformPureMatch(tree: Tree, selector: Tree, cases: List[CaseDef]) = {
val caseVals = cases map { case cd @ CaseDef(pat, guard, body) =>
@@ -154,8 +207,8 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
}
- def transExpr(tree: Tree, cpsA: CPSInfo, cpsR: CPSInfo): Tree = {
- transTailValue(tree, cpsA, cpsR) match {
+ def transExpr(tree: Tree, cpsA: CPSInfo, cpsR: CPSInfo)(implicit isAnyParentImpure: Boolean = false): Tree = {
+ transTailValue(tree, cpsA, cpsR)(cpsR.isDefined || isAnyParentImpure) match {
case (Nil, b) => b
case (a, b) =>
treeCopy.Block(tree, a,b)
@@ -163,7 +216,7 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
}
- def transArgList(fun: Tree, args: List[Tree], cpsA: CPSInfo): (List[List[Tree]], List[Tree], CPSInfo) = {
+ def transArgList(fun: Tree, args: List[Tree], cpsA: CPSInfo)(implicit isAnyParentImpure: Boolean): (List[List[Tree]], List[Tree], CPSInfo) = {
val formals = fun.tpe.paramTypes
val overshoot = args.length - formals.length
@@ -172,7 +225,8 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
val (stm,expr) = (for ((a,tp) <- args.zip(formals ::: List.fill(overshoot)(NoType))) yield {
tp match {
case TypeRef(_, ByNameParamClass, List(elemtp)) =>
- (Nil, transExpr(a, None, getAnswerTypeAnn(elemtp)))
+ // note that we're not passing just isAnyParentImpure
+ (Nil, transExpr(a, None, getAnswerTypeAnn(elemtp))(getAnswerTypeAnn(elemtp).isDefined || isAnyParentImpure))
case _ =>
val (valStm, valExpr, valSpc) = transInlineValue(a, spc)
spc = valSpc
@@ -184,7 +238,8 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
}
- def transValue(tree: Tree, cpsA: CPSInfo, cpsR: CPSInfo): (List[Tree], Tree, CPSInfo) = {
+ // precondition: cpsR.isDefined "implies" isAnyParentImpure
+ def transValue(tree: Tree, cpsA: CPSInfo, cpsR: CPSInfo)(implicit isAnyParentImpure: Boolean): (List[Tree], Tree, CPSInfo) = {
// return value: (stms, expr, spc), where spc is CPSInfo after stms but *before* expr
implicit val pos = tree.pos
tree match {
@@ -192,7 +247,7 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
val (cpsA2, cpsR2) = (cpsA, linearize(cpsA, getAnswerTypeAnn(tree.tpe))) // tbd
// val (cpsA2, cpsR2) = (None, getAnswerTypeAnn(tree.tpe))
- val (a, b) = transBlock(stms, expr, cpsA2, cpsR2)
+ val (a, b) = transBlock(stms, expr, cpsA2, cpsR2)(cpsR2.isDefined || isAnyParentImpure)
val tree1 = (treeCopy.Block(tree, a, b)) // no updateSynthFlag here!!!
(Nil, tree1, cpsA)
@@ -206,8 +261,8 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
val (cpsA2, cpsR2) = if (hasSynthMarker(tree.tpe))
(spc, linearize(spc, getAnswerTypeAnn(tree.tpe))) else
(None, getAnswerTypeAnn(tree.tpe)) // if no cps in condition, branches must conform to tree.tpe directly
- val thenVal = transExpr(thenp, cpsA2, cpsR2)
- val elseVal = transExpr(elsep, cpsA2, cpsR2)
+ val thenVal = transExpr(thenp, cpsA2, cpsR2)(cpsR2.isDefined || isAnyParentImpure)
+ val elseVal = transExpr(elsep, cpsA2, cpsR2)(cpsR2.isDefined || isAnyParentImpure)
// check that then and else parts agree (not necessary any more, but left as sanity check)
if (cpsR.isDefined) {
@@ -227,7 +282,7 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
else (None, getAnswerTypeAnn(tree.tpe))
val caseVals = cases map { case cd @ CaseDef(pat, guard, body) =>
- val bodyVal = transExpr(body, cpsA2, cpsR2)
+ val bodyVal = transExpr(body, cpsA2, cpsR2)(cpsR2.isDefined || isAnyParentImpure)
treeCopy.CaseDef(cd, transform(pat), transform(guard), bodyVal)
}
@@ -245,7 +300,7 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
// currentOwner.newMethod(name, tree.pos, Flags.SYNTHETIC) setInfo ldef.symbol.info
val sym = ldef.symbol resetFlag Flags.LABEL
val rhs1 = rhs //new TreeSymSubstituter(List(ldef.symbol), List(sym)).transform(rhs)
- val rhsVal = transExpr(rhs1, None, getAnswerTypeAnn(tree.tpe)) changeOwner (currentOwner -> sym)
+ val rhsVal = transExpr(rhs1, None, getAnswerTypeAnn(tree.tpe))(getAnswerTypeAnn(tree.tpe).isDefined || isAnyParentImpure) changeOwner (currentOwner -> sym)
val stm1 = localTyper.typed(DefDef(sym, rhsVal))
// since virtpatmat does not rely on fall-through, don't call the labels it emits
@@ -284,6 +339,8 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
(stms, updateSynthFlag(treeCopy.Assign(tree, transform(lhs), expr)), spc)
case Return(expr0) =>
+ if (isAnyParentImpure)
+ unit.error(tree.pos, "return expression not allowed, since method calls CPS method")
val (stms, expr, spc) = transInlineValue(expr0, cpsA)
(stms, updateSynthFlag(treeCopy.Return(tree, expr)), spc)
@@ -321,7 +378,8 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
}
}
- def transTailValue(tree: Tree, cpsA: CPSInfo, cpsR: CPSInfo): (List[Tree], Tree) = {
+ // precondition: cpsR.isDefined "implies" isAnyParentImpure
+ def transTailValue(tree: Tree, cpsA: CPSInfo, cpsR: CPSInfo)(implicit isAnyParentImpure: Boolean): (List[Tree], Tree) = {
val (stms, expr, spc) = transValue(tree, cpsA, cpsR)
@@ -398,7 +456,7 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
(stms, expr)
}
- def transInlineValue(tree: Tree, cpsA: CPSInfo): (List[Tree], Tree, CPSInfo) = {
+ def transInlineValue(tree: Tree, cpsA: CPSInfo)(implicit isAnyParentImpure: Boolean): (List[Tree], Tree, CPSInfo) = {
val (stms, expr, spc) = transValue(tree, cpsA, None) // never required to be cps
@@ -425,7 +483,7 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
- def transInlineStm(stm: Tree, cpsA: CPSInfo): (List[Tree], CPSInfo) = {
+ def transInlineStm(stm: Tree, cpsA: CPSInfo)(implicit isAnyParentImpure: Boolean): (List[Tree], CPSInfo) = {
stm match {
// TODO: what about DefDefs?
@@ -455,7 +513,8 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
}
}
- def transBlock(stms: List[Tree], expr: Tree, cpsA: CPSInfo, cpsR: CPSInfo): (List[Tree], Tree) = {
+ // precondition: cpsR.isDefined "implies" isAnyParentImpure
+ def transBlock(stms: List[Tree], expr: Tree, cpsA: CPSInfo, cpsR: CPSInfo)(implicit isAnyParentImpure: Boolean): (List[Tree], Tree) = {
def rec(currStats: List[Tree], currAns: CPSInfo, accum: List[Tree]): (List[Tree], Tree) =
currStats match {
case Nil =>
diff --git a/src/library/scala/StringContext.scala b/src/library/scala/StringContext.scala
index 8b478f6845..e381c09398 100644
--- a/src/library/scala/StringContext.scala
+++ b/src/library/scala/StringContext.scala
@@ -8,10 +8,43 @@
package scala
-/** A class to support string interpolation.
- * This class supports string interpolation as outlined in Scala SIP-11.
- * It needs to be fully documented once the SIP is accepted.
+/** This class provides the basic mechanism to do String Interpolation.
+ * String Interpolation allows users
+ * to embed variable references directly in *processed* string literals.
+ * Here's an example:
+ * {{{
+ * val name = "James"
+ * println(s"Hello, $name") // Hello, James
+ * }}}
*
+ * Any processed string literal is rewritten as an instantiation and
+ * method call against this class. For example:
+ * {{{
+ * s"Hello, $name"
+ * }}}
+ *
+ * is rewritten to be:
+ *
+ * {{{
+ * new StringContext("Hello, ", "").s(name)
+ * }}}
+ *
+ * By default, this class provides the `raw`, `s` and `f` methods as
+ * available interpolators.
+ *
+ * To provide your own string interpolator, create an implicit class
+ * which adds a method to `StringContext`. Here's an example:
+ * {{{
+ * implicit class JsonHelper(val sc: StringContext) extends AnyVal {
+ * def json(args: Any*): JSONObject = ...
+ * }
+ * val x: JSONObject = json"{ a: $a }"
+ * }}}
+ *
+ * Here the `JsonHelper` extenion class implicitly adds the `json` method to
+ * `StringContext` which can be used for `json` string literals.
+ *
+ * @since 2.10.0
* @param parts The parts that make up the interpolated string,
* without the expressions that get inserted by interpolation.
*/
@@ -33,6 +66,20 @@ case class StringContext(parts: String*) {
*
* It inserts its arguments between corresponding parts of the string context.
* It also treats standard escape sequences as defined in the Scala specification.
+ * Here's an example of usage:
+ * {{{
+ * val name = "James"
+ * println(s"Hello, $name") // Hello, James
+ * }}}
+ * In this example, the expression $name is replaced with the `toString` of the
+ * variable `name`.
+ * The `s` interpolator can take the `toString` of any arbitrary expression within
+ * a `${}` block, for example:
+ * {{{
+ * println(s"1 + 1 = ${1 + 1}")
+ * }}}
+ * will print the string `1 + 1 = 2`.
+ *
* @param `args` The arguments to be inserted into the resulting string.
* @throws An `IllegalArgumentException`
* if the number of `parts` in the enclosing `StringContext` does not exceed
@@ -47,6 +94,9 @@ case class StringContext(parts: String*) {
* It inserts its arguments between corresponding parts of the string context.
* As opposed to the simple string interpolator `s`, this one does not treat
* standard escape sequences as defined in the Scala specification.
+ *
+ * For example, the raw processed string `raw"a\nb"` is equal to the scala string `"a\\nb"`.
+ *
* @param `args` The arguments to be inserted into the resulting string.
* @throws An `IllegalArgumentException`
* if the number of `parts` in the enclosing `StringContext` does not exceed
@@ -77,6 +127,13 @@ case class StringContext(parts: String*) {
* specifier. All specifiers allowed in Java format strings are handled, and in the same
* way they are treated in Java.
*
+ * For example:
+ * {{{
+ * val height = 1.9d
+ * val name = "James"
+ * println(f"$name%s is $height%2.2f meters tall") // James is 1.90 meters tall
+ * }}}
+ *
* @param `args` The arguments to be inserted into the resulting string.
* @throws An `IllegalArgumentException`
* if the number of `parts` in the enclosing `StringContext` does not exceed
diff --git a/src/reflect/scala/reflect/api/BuildUtils.scala b/src/reflect/scala/reflect/api/BuildUtils.scala
index 2bb0cc3c76..b0de7f8d5a 100644
--- a/src/reflect/scala/reflect/api/BuildUtils.scala
+++ b/src/reflect/scala/reflect/api/BuildUtils.scala
@@ -4,7 +4,7 @@ package api
/**
* This is an internal implementation class.
*/
-trait BuildUtils { self: Universe =>
+private[reflect] trait BuildUtils { self: Universe =>
val build: BuildApi
diff --git a/src/reflect/scala/reflect/api/Exprs.scala b/src/reflect/scala/reflect/api/Exprs.scala
index 65b0eb9301..b86f36420d 100644
--- a/src/reflect/scala/reflect/api/Exprs.scala
+++ b/src/reflect/scala/reflect/api/Exprs.scala
@@ -12,14 +12,18 @@ trait Exprs { self: Universe =>
/** Expr wraps an expression tree and tags it with its type. */
trait Expr[+T] extends Equals with Serializable {
+ /**
+ * Underlying mirror of this expr.
+ */
val mirror: Mirror
+
/**
* Migrates the expression into another mirror, jumping into a different universe if necessary.
*
* This means that all symbolic references to classes/objects/packages in the expression
* will be re-resolved within the new mirror (typically using that mirror's classloader).
*/
- def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # Expr[T]
+ def in[U <: Universe with Singleton](otherMirror: scala.reflect.api.Mirror[U]): U # Expr[T]
/**
* The Scala syntax tree representing the wrapped expression.
@@ -91,13 +95,13 @@ trait Exprs { self: Universe =>
* in which case the tree first needs to be wrapped in an expr.
*/
object Expr {
- def apply[T: WeakTypeTag](mirror: MirrorOf[self.type], treec: TreeCreator): Expr[T] = new ExprImpl[T](mirror.asInstanceOf[Mirror], treec)
+ def apply[T: WeakTypeTag](mirror: scala.reflect.api.Mirror[self.type], treec: TreeCreator): Expr[T] = new ExprImpl[T](mirror.asInstanceOf[Mirror], treec)
def unapply[T](expr: Expr[T]): Option[Tree] = Some(expr.tree)
}
private class ExprImpl[+T: WeakTypeTag](val mirror: Mirror, val treec: TreeCreator) extends Expr[T] {
- def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # Expr[T] = {
- val otherMirror1 = otherMirror.asInstanceOf[MirrorOf[otherMirror.universe.type]]
+ def in[U <: Universe with Singleton](otherMirror: scala.reflect.api.Mirror[U]): U # Expr[T] = {
+ val otherMirror1 = otherMirror.asInstanceOf[scala.reflect.api.Mirror[otherMirror.universe.type]]
val tag1 = (implicitly[WeakTypeTag[T]] in otherMirror).asInstanceOf[otherMirror.universe.WeakTypeTag[T]]
otherMirror.universe.Expr[T](otherMirror1, treec)(tag1)
}
diff --git a/src/reflect/scala/reflect/api/FrontEnds.scala b/src/reflect/scala/reflect/api/FrontEnds.scala
deleted file mode 100644
index 61ea227c47..0000000000
--- a/src/reflect/scala/reflect/api/FrontEnds.scala
+++ /dev/null
@@ -1,70 +0,0 @@
-package scala.reflect
-package api
-
-trait FrontEnds {
-
- type Position >: Null
-
- trait FrontEnd {
- object severity extends Enumeration
- class Severity(val id: Int) extends severity.Value {
- var count: Int = 0
- override def toString() = this match {
- case INFO => "INFO"
- case WARNING => "WARNING"
- case ERROR => "ERROR"
- case _ => "<unknown>"
- }
- }
- val INFO = new Severity(0)
- val WARNING = new Severity(1)
- val ERROR = new Severity(2)
-
- def hasErrors = ERROR.count > 0
- def hasWarnings = WARNING.count > 0
-
- case class Info(val pos: Position, val msg: String, val severity: Severity)
- val infos = new scala.collection.mutable.LinkedHashSet[Info]
-
- /** Handles incoming info */
- def log(pos: Position, msg: String, severity: Severity) {
- infos += new Info(pos, msg, severity)
- severity.count += 1
- display(infos.last)
- }
-
- /** Displays incoming info */
- def display(info: Info): Unit
-
- /** Services a request to drop into interactive mode */
- def interactive(): Unit
-
- /** Refreshes the UI */
- def flush(): Unit = {}
-
- /** Resets the reporter */
- def reset(): Unit = {
- INFO.count = 0
- WARNING.count = 0
- ERROR.count = 0
- infos.clear()
- }
- }
-
- class SilentFrontEnd extends FrontEnd {
- def display(info: Info) {}
- def interactive() {}
- }
-
- /** Creates a UI-less reporter that simply accumulates all the messages
- */
- def mkSilentFrontEnd(): FrontEnd = new SilentFrontEnd()
-
- /** Creates a reporter that prints messages to the console according to the settings.
- *
- * ``minSeverity'' determines minimum severity of the messages to be printed.
- * 0 stands for INFO, 1 stands for WARNING and 2 stands for ERROR.
- */
- // todo. untangle warningsAsErrors from Reporters. I don't feel like moving this flag here!
- def mkConsoleFrontEnd(minSeverity: Int = 1): FrontEnd
-}
diff --git a/src/reflect/scala/reflect/api/JavaUniverse.scala b/src/reflect/scala/reflect/api/JavaUniverse.scala
index ba38381561..cc703e833d 100644
--- a/src/reflect/scala/reflect/api/JavaUniverse.scala
+++ b/src/reflect/scala/reflect/api/JavaUniverse.scala
@@ -7,7 +7,7 @@ trait JavaUniverse extends Universe with Mirrors { self =>
override type Mirror >: Null <: JavaMirror
- trait JavaMirror extends MirrorOf[self.type] with RuntimeMirror {
+ trait JavaMirror extends scala.reflect.api.Mirror[self.type] with RuntimeMirror {
val classLoader: ClassLoader
override def toString = s"JavaMirror with ${runtime.ReflectionUtils.show(classLoader)}"
}
@@ -23,7 +23,7 @@ trait JavaUniverse extends Universe with Mirrors { self =>
override def manifestToTypeTag[T](mirror0: Any, manifest: Manifest[T]): Universe # TypeTag[T] =
TypeTag(mirror0.asInstanceOf[Mirror], new TypeCreator {
- def apply[U <: Universe with Singleton](mirror: MirrorOf[U]): U # Type = {
+ def apply[U <: Universe with Singleton](mirror: scala.reflect.api.Mirror[U]): U # Type = {
mirror.universe match {
case ju: JavaUniverse =>
val jm = mirror.asInstanceOf[ju.Mirror]
diff --git a/src/reflect/scala/reflect/api/MirrorOf.scala b/src/reflect/scala/reflect/api/Mirror.scala
index cd5641e692..2de0d7120e 100644
--- a/src/reflect/scala/reflect/api/MirrorOf.scala
+++ b/src/reflect/scala/reflect/api/Mirror.scala
@@ -8,13 +8,13 @@ package api
*
* This is defined outside the reflection universe cake pattern implementation
* so that it can be referenced from outside. For example TypeCreator and TreeCreator
- * reference MirrorOf and also need to be defined outside the cake as they are
+ * reference Mirror and also need to be defined outside the cake as they are
* used by type tags, which can be migrated between different universes and consequently
* cannot be bound to a fixed one.
*
* @see [[Mirrors]]
*/
-abstract class MirrorOf[U <: Universe with Singleton] {
+abstract class Mirror[U <: Universe with Singleton] {
/** The universe this mirror belongs to. */
val universe: U
diff --git a/src/reflect/scala/reflect/api/Mirrors.scala b/src/reflect/scala/reflect/api/Mirrors.scala
index c935533027..bff899daa4 100644
--- a/src/reflect/scala/reflect/api/Mirrors.scala
+++ b/src/reflect/scala/reflect/api/Mirrors.scala
@@ -11,8 +11,12 @@ package api
*/
trait Mirrors { self: Universe =>
- /** The base type of all mirrors of this universe */
- type Mirror >: Null <: MirrorOf[self.type]
+ /** The base type of all mirrors of this universe.
+ *
+ * This abstract type conforms the base interface for all mirrors defined in [[scala.reflect.api.Mirror]]
+ * and is gradually refined in specific universes (e.g. `Mirror` of a [[scala.reflect.api.JavaUniverse]] is capable of reflection).
+ */
+ type Mirror >: Null <: scala.reflect.api.Mirror[self.type]
/** The root mirror of this universe. This mirror contains standard Scala classes and types such as `Any`, `AnyRef`, `AnyVal`,
* `Nothing`, `Null`, and all classes loaded from scala-library, which are shared across all mirrors within the enclosing universe.
@@ -239,7 +243,7 @@ trait Mirrors { self: Universe =>
}
/** A mirror that reflects instances and static classes */
- trait ReflectiveMirror extends MirrorOf[Mirrors.this.type] {
+ trait ReflectiveMirror extends scala.reflect.api.Mirror[Mirrors.this.type] {
/** A reflective mirror for the given object.
*
diff --git a/src/reflect/scala/reflect/api/Position.scala b/src/reflect/scala/reflect/api/Position.scala
new file mode 100644
index 0000000000..9c63e4becf
--- /dev/null
+++ b/src/reflect/scala/reflect/api/Position.scala
@@ -0,0 +1,167 @@
+package scala.reflect
+package api
+
+/** The Position class and its subclasses represent positions of ASTs and symbols.
+ * Except for NoPosition and FakePos, every position refers to a SourceFile
+ * and to an offset in the sourcefile (its `point`). For batch compilation,
+ * that's all. For interactive IDE's there are also RangePositions
+ * and TransparentPositions. A RangePosition indicates a start and an end
+ * in addition to its point. TransparentPositions are a subclass of RangePositions.
+ * Range positions that are not transparent are called opaque.
+ * Trees with RangePositions need to satisfy the following invariants.
+ *
+ * INV1: A tree with an offset position never contains a child
+ * with a range position
+ * INV2: If the child of a tree with a range position also has a range position,
+ * then the child's range is contained in the parent's range.
+ * INV3: Opaque range positions of children of the same node are non-overlapping
+ * (this means their overlap is at most a single point).
+ *
+ * The following tests are useful on positions:
+ *
+ * pos.isDefined true if position is not a NoPosition nor a FakePosition
+ * pos.isRange true if position is a range
+ * pos.isOpaqueRange true if position is an opaque range
+ *
+ * The following accessor methods are provided:
+ *
+ * pos.source The source file of the position, which must be defined
+ * pos.point The offset of the position's point, which must be defined
+ * pos.start The start of the position, which must be a range
+ * pos.end The end of the position, which must be a range
+ *
+ * There are also convenience methods, such as
+ *
+ * pos.startOrPoint
+ * pos.endOrPoint
+ * pos.pointOrElse(default)
+ *
+ * These are less strict about the kind of position on which they can be applied.
+ *
+ * The following conversion methods are often used:
+ *
+ * pos.focus converts a range position to an offset position, keeping its point;
+ * returns all other positions unchanged.
+ * pos.makeTransparent converts an opaque range position into a transparent one.
+ * returns all other positions unchanged.
+ */
+trait Position extends Attachments {
+
+ type Pos >: Null <: Position
+
+ /** Java file corresponding to the source file of this position.
+ *
+ * The return type is [[scala.reflect.io.AbstractFile]], which belongs to an experimental part of Scala reflection.
+ * It should not be used unless you know what you are doing. In subsequent releases, this API will be refined
+ * and exposed as a part of scala.reflect.api.
+ */
+ def source: scala.reflect.internal.util.SourceFile
+
+ /** Is this position neither a NoPosition nor a FakePosition?
+ * If isDefined is true, offset and source are both defined.
+ */
+ def isDefined: Boolean
+
+ /** Is this position a range position? */
+ def isRange: Boolean
+
+ /** Is this position a transparent position? */
+ def isTransparent: Boolean
+
+ /** Is this position a non-transparent range position? */
+ def isOpaqueRange: Boolean
+
+ /** if opaque range, make this position transparent */
+ def makeTransparent: Pos
+
+ /** The start of the position's range, error if not a range position */
+ def start: Int
+
+ /** The start of the position's range, or point if not a range position */
+ def startOrPoint: Int
+
+ /** The point (where the ^ is) of the position */
+ def point: Int
+
+ /** The point (where the ^ is) of the position, or else `default` if undefined */
+ def pointOrElse(default: Int): Int
+
+ /** The end of the position's range, error if not a range position */
+ def end: Int
+
+ /** The end of the position's range, or point if not a range position */
+ def endOrPoint: Int
+
+ /** The same position with a different start value (if a range) */
+ def withStart(off: Int): Pos
+
+ /** The same position with a different end value (if a range) */
+ def withEnd(off: Int): Pos
+
+ /** The same position with a different point value (if a range or offset) */
+ def withPoint(off: Int): Pos
+
+ /** If this is a range, the union with the other range, with the point of this position.
+ * Otherwise, this position
+ */
+ def union(pos: Pos): Pos
+
+ /** If this is a range position, the offset position of its point.
+ * Otherwise the position itself
+ */
+ def focus: Pos
+
+ /** If this is a range position, the offset position of its start.
+ * Otherwise the position itself
+ */
+ def focusStart: Pos
+
+ /** If this is a range position, the offset position of its end.
+ * Otherwise the position itself
+ */
+ def focusEnd: Pos
+
+ /** Does this position include the given position `pos`.
+ * This holds if `this` is a range position and its range [start..end]
+ * is the same or covers the range of the given position, which may or may not be a range position.
+ */
+ def includes(pos: Pos): Boolean
+
+ /** Does this position properly include the given position `pos` ("properly" meaning their
+ * ranges are not the same)?
+ */
+ def properlyIncludes(pos: Pos): Boolean
+
+ /** Does this position precede that position?
+ * This holds if both positions are defined and the end point of this position
+ * is not larger than the start point of the given position.
+ */
+ def precedes(pos: Pos): Boolean
+
+ /** Does this position properly precede the given position `pos` ("properly" meaning their ranges
+ * do not share a common point).
+ */
+ def properlyPrecedes(pos: Pos): Boolean
+
+ /** Does this position overlap with that position?
+ * This holds if both positions are ranges and there is an interval of
+ * non-zero length that is shared by both position ranges.
+ */
+ def overlaps(pos: Pos): Boolean
+
+ /** Does this position cover the same range as that position?
+ * Holds only if both position are ranges
+ */
+ def sameRange(pos: Pos): Boolean
+
+ def line: Int
+
+ def column: Int
+
+ /** Convert this to a position around `point` that spans a single source line */
+ def toSingleLine: Pos
+
+ def lineContent: String
+
+ def show: String
+}
diff --git a/src/reflect/scala/reflect/api/Positions.scala b/src/reflect/scala/reflect/api/Positions.scala
index 0eddc88fc4..5c530e7e70 100644
--- a/src/reflect/scala/reflect/api/Positions.scala
+++ b/src/reflect/scala/reflect/api/Positions.scala
@@ -10,7 +10,7 @@ trait Positions {
self: Universe =>
/** .. */
- type Position >: Null <: PositionApi { type Pos = Position }
+ type Position >: Null <: scala.reflect.api.Position { type Pos = Position }
/** A tag that preserves the identity of the `Position` abstract type from erasure.
* Can be used for pattern matching, instance tests, serialization and likes.
@@ -38,168 +38,3 @@ trait Positions {
*/
def wrappingPos(trees: List[Tree]): Position
}
-
-/** The Position class and its subclasses represent positions of ASTs and symbols.
- * Except for NoPosition and FakePos, every position refers to a SourceFile
- * and to an offset in the sourcefile (its `point`). For batch compilation,
- * that's all. For interactive IDE's there are also RangePositions
- * and TransparentPositions. A RangePosition indicates a start and an end
- * in addition to its point. TransparentPositions are a subclass of RangePositions.
- * Range positions that are not transparent are called opaque.
- * Trees with RangePositions need to satisfy the following invariants.
- *
- * INV1: A tree with an offset position never contains a child
- * with a range position
- * INV2: If the child of a tree with a range position also has a range position,
- * then the child's range is contained in the parent's range.
- * INV3: Opaque range positions of children of the same node are non-overlapping
- * (this means their overlap is at most a single point).
- *
- * The following tests are useful on positions:
- *
- * pos.isDefined true if position is not a NoPosition nor a FakePosition
- * pos.isRange true if position is a range
- * pos.isOpaqueRange true if position is an opaque range
- *
- * The following accessor methods are provided:
- *
- * pos.source The source file of the position, which must be defined
- * pos.point The offset of the position's point, which must be defined
- * pos.start The start of the position, which must be a range
- * pos.end The end of the position, which must be a range
- *
- * There are also convenience methods, such as
- *
- * pos.startOrPoint
- * pos.endOrPoint
- * pos.pointOrElse(default)
- *
- * These are less strict about the kind of position on which they can be applied.
- *
- * The following conversion methods are often used:
- *
- * pos.focus converts a range position to an offset position, keeping its point;
- * returns all other positions unchanged.
- * pos.makeTransparent converts an opaque range position into a transparent one.
- * returns all other positions unchanged.
- */
-trait PositionApi extends Attachments {
-
- type Pos >: Null <: PositionApi
-
- /** Java file corresponding to the source file of this position.
- */
- def fileInfo: java.io.File
-
- /** Content of the source file that contains this position.
- */
- def fileContent: Array[Char]
-
- /** Is this position neither a NoPosition nor a FakePosition?
- * If isDefined is true, offset and source are both defined.
- */
- def isDefined: Boolean
-
- /** Is this position a range position? */
- def isRange: Boolean
-
- /** Is this position a transparent position? */
- def isTransparent: Boolean
-
- /** Is this position a non-transparent range position? */
- def isOpaqueRange: Boolean
-
- /** if opaque range, make this position transparent */
- def makeTransparent: Pos
-
- /** The start of the position's range, error if not a range position */
- def start: Int
-
- /** The start of the position's range, or point if not a range position */
- def startOrPoint: Int
-
- /** The point (where the ^ is) of the position */
- def point: Int
-
- /** The point (where the ^ is) of the position, or else `default` if undefined */
- def pointOrElse(default: Int): Int
-
- /** The end of the position's range, error if not a range position */
- def end: Int
-
- /** The end of the position's range, or point if not a range position */
- def endOrPoint: Int
-
- /** The same position with a different start value (if a range) */
- def withStart(off: Int): Pos
-
- /** The same position with a different end value (if a range) */
- def withEnd(off: Int): Pos
-
- /** The same position with a different point value (if a range or offset) */
- def withPoint(off: Int): Pos
-
- /** If this is a range, the union with the other range, with the point of this position.
- * Otherwise, this position
- */
- def union(pos: Pos): Pos
-
- /** If this is a range position, the offset position of its point.
- * Otherwise the position itself
- */
- def focus: Pos
-
- /** If this is a range position, the offset position of its start.
- * Otherwise the position itself
- */
- def focusStart: Pos
-
- /** If this is a range position, the offset position of its end.
- * Otherwise the position itself
- */
- def focusEnd: Pos
-
- /** Does this position include the given position `pos`.
- * This holds if `this` is a range position and its range [start..end]
- * is the same or covers the range of the given position, which may or may not be a range position.
- */
- def includes(pos: Pos): Boolean
-
- /** Does this position properly include the given position `pos` ("properly" meaning their
- * ranges are not the same)?
- */
- def properlyIncludes(pos: Pos): Boolean
-
- /** Does this position precede that position?
- * This holds if both positions are defined and the end point of this position
- * is not larger than the start point of the given position.
- */
- def precedes(pos: Pos): Boolean
-
- /** Does this position properly precede the given position `pos` ("properly" meaning their ranges
- * do not share a common point).
- */
- def properlyPrecedes(pos: Pos): Boolean
-
- /** Does this position overlap with that position?
- * This holds if both positions are ranges and there is an interval of
- * non-zero length that is shared by both position ranges.
- */
- def overlaps(pos: Pos): Boolean
-
- /** Does this position cover the same range as that position?
- * Holds only if both position are ranges
- */
- def sameRange(pos: Pos): Boolean
-
- def line: Int
-
- def column: Int
-
- /** Convert this to a position around `point` that spans a single source line */
- def toSingleLine: Pos
-
- def lineContent: String
-
- def show: String
-}
diff --git a/src/reflect/scala/reflect/api/Symbols.scala b/src/reflect/scala/reflect/api/Symbols.scala
index d8f955ddf3..8b24b953ae 100644
--- a/src/reflect/scala/reflect/api/Symbols.scala
+++ b/src/reflect/scala/reflect/api/Symbols.scala
@@ -86,10 +86,10 @@ trait Symbols { self: Universe =>
* that directly contains the current symbol's definition.
* The `NoSymbol` symbol does not have an owner, and calling this method
* on one causes an internal error.
- * The owner of the Scala root class [[scala.reflect.api.MirrorOf.RootClass]]
- * and the Scala root object [[scala.reflect.api.MirrorOf.RootPackage]] is `NoSymbol`.
+ * The owner of the Scala root class [[scala.reflect.api.Mirror.RootClass]]
+ * and the Scala root object [[scala.reflect.api.Mirror.RootPackage]] is `NoSymbol`.
* Every other symbol has a chain of owners that ends in
- * [[scala.reflect.api.MirrorOf.RootClass]].
+ * [[scala.reflect.api.Mirror.RootClass]].
*/
def owner: Symbol
@@ -209,6 +209,10 @@ trait Symbols { self: Universe =>
/** Source file if this symbol is created during this compilation run,
* or a class file if this symbol is loaded from a *.class or *.jar.
+ *
+ * The return type is [[scala.reflect.io.AbstractFile]], which belongs to an experimental part of Scala reflection.
+ * It should not be used unless you know what you are doing. In subsequent releases, this API will be refined
+ * and exposed as a part of scala.reflect.api.
*/
def associatedFile: scala.reflect.io.AbstractFile
diff --git a/src/reflect/scala/reflect/api/TreeCreator.scala b/src/reflect/scala/reflect/api/TreeCreator.scala
index 0c8701775c..a8e8ae1b58 100644
--- a/src/reflect/scala/reflect/api/TreeCreator.scala
+++ b/src/reflect/scala/reflect/api/TreeCreator.scala
@@ -22,5 +22,5 @@ package api
* `TreeCreator` can't have a functional type, so it's implemented as class with an apply method.
*/
abstract class TreeCreator {
- def apply[U <: Universe with Singleton](m: MirrorOf[U]): U # Tree
+ def apply[U <: Universe with Singleton](m: scala.reflect.api.Mirror[U]): U # Tree
}
diff --git a/src/reflect/scala/reflect/api/TypeCreator.scala b/src/reflect/scala/reflect/api/TypeCreator.scala
index cc6d38c548..2b3ef4320b 100644
--- a/src/reflect/scala/reflect/api/TypeCreator.scala
+++ b/src/reflect/scala/reflect/api/TypeCreator.scala
@@ -22,5 +22,5 @@ package api
* `TypeCreator` can't have a functional type, so it's implemented as class with an apply method.
*/
abstract class TypeCreator {
- def apply[U <: Universe with Singleton](m: MirrorOf[U]): U # Type
+ def apply[U <: Universe with Singleton](m: scala.reflect.api.Mirror[U]): U # Type
}
diff --git a/src/reflect/scala/reflect/api/TypeTags.scala b/src/reflect/scala/reflect/api/TypeTags.scala
index a7e58d2bcb..fc3f067a96 100644
--- a/src/reflect/scala/reflect/api/TypeTags.scala
+++ b/src/reflect/scala/reflect/api/TypeTags.scala
@@ -154,19 +154,17 @@ trait TypeTags { self: Universe =>
@annotation.implicitNotFound(msg = "No WeakTypeTag available for ${T}")
trait WeakTypeTag[T] extends Equals with Serializable {
/**
- * Mirror corresponding to the universe of this WeakTypeTag.
+ * Underlying mirror of this type tag.
*/
val mirror: Mirror
+
/**
- * Migrates type tag to another universe.
- *
- * Type tags are path dependent on their universe. This methods allows migration
- * given the mirror corresponding to the target universe.
+ * Migrates the expression into another mirror, jumping into a different universe if necessary.
*
* Migration means that all symbolic references to classes/objects/packages in the expression
* will be re-resolved within the new mirror (typically using that mirror's classloader).
*/
- def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # WeakTypeTag[T]
+ def in[U <: Universe with Singleton](otherMirror: scala.reflect.api.Mirror[U]): U # WeakTypeTag[T]
/**
* Reflective representation of type T.
@@ -201,7 +199,7 @@ trait TypeTags { self: Universe =>
val Null : WeakTypeTag[scala.Null] = TypeTag.Null
- def apply[T](mirror1: MirrorOf[self.type], tpec1: TypeCreator): WeakTypeTag[T] =
+ def apply[T](mirror1: scala.reflect.api.Mirror[self.type], tpec1: TypeCreator): WeakTypeTag[T] =
tpec1(mirror1) match {
case ByteTpe => WeakTypeTag.Byte.asInstanceOf[WeakTypeTag[T]]
case ShortTpe => WeakTypeTag.Short.asInstanceOf[WeakTypeTag[T]]
@@ -226,8 +224,8 @@ trait TypeTags { self: Universe =>
private class WeakTypeTagImpl[T](val mirror: Mirror, val tpec: TypeCreator) extends WeakTypeTag[T] {
lazy val tpe: Type = tpec(mirror)
- def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # WeakTypeTag[T] = {
- val otherMirror1 = otherMirror.asInstanceOf[MirrorOf[otherMirror.universe.type]]
+ def in[U <: Universe with Singleton](otherMirror: scala.reflect.api.Mirror[U]): U # WeakTypeTag[T] = {
+ val otherMirror1 = otherMirror.asInstanceOf[scala.reflect.api.Mirror[otherMirror.universe.type]]
otherMirror.universe.WeakTypeTag[T](otherMirror1, tpec)
}
private def writeReplace(): AnyRef = new SerializedTypeTag(tpec, concrete = false)
@@ -245,7 +243,7 @@ trait TypeTags { self: Universe =>
/**
* @inheritdoc
*/
- override def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # TypeTag[T]
+ override def in[U <: Universe with Singleton](otherMirror: scala.reflect.api.Mirror[U]): U # TypeTag[T]
// case class accessories
override def canEqual(x: Any) = x.isInstanceOf[TypeTag[_]]
@@ -271,7 +269,7 @@ trait TypeTags { self: Universe =>
val Nothing: TypeTag[scala.Nothing] = new PredefTypeTag[scala.Nothing] (NothingTpe, _.TypeTag.Nothing)
val Null: TypeTag[scala.Null] = new PredefTypeTag[scala.Null] (NullTpe, _.TypeTag.Null)
- def apply[T](mirror1: MirrorOf[self.type], tpec1: TypeCreator): TypeTag[T] =
+ def apply[T](mirror1: scala.reflect.api.Mirror[self.type], tpec1: TypeCreator): TypeTag[T] =
tpec1(mirror1) match {
case ByteTpe => TypeTag.Byte.asInstanceOf[TypeTag[T]]
case ShortTpe => TypeTag.Short.asInstanceOf[TypeTag[T]]
@@ -295,15 +293,15 @@ trait TypeTags { self: Universe =>
}
private class TypeTagImpl[T](mirror: Mirror, tpec: TypeCreator) extends WeakTypeTagImpl[T](mirror, tpec) with TypeTag[T] {
- override def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # TypeTag[T] = {
- val otherMirror1 = otherMirror.asInstanceOf[MirrorOf[otherMirror.universe.type]]
+ override def in[U <: Universe with Singleton](otherMirror: scala.reflect.api.Mirror[U]): U # TypeTag[T] = {
+ val otherMirror1 = otherMirror.asInstanceOf[scala.reflect.api.Mirror[otherMirror.universe.type]]
otherMirror.universe.TypeTag[T](otherMirror1, tpec)
}
private def writeReplace(): AnyRef = new SerializedTypeTag(tpec, concrete = true)
}
private class PredefTypeCreator[T](copyIn: Universe => Universe#TypeTag[T]) extends TypeCreator {
- def apply[U <: Universe with Singleton](m: MirrorOf[U]): U # Type = {
+ def apply[U <: Universe with Singleton](m: scala.reflect.api.Mirror[U]): U # Type = {
copyIn(m.universe).asInstanceOf[U # TypeTag[T]].tpe
}
}
diff --git a/src/reflect/scala/reflect/internal/AnnotationCheckers.scala b/src/reflect/scala/reflect/internal/AnnotationCheckers.scala
index 9f102c5712..05f80c8a0c 100644
--- a/src/reflect/scala/reflect/internal/AnnotationCheckers.scala
+++ b/src/reflect/scala/reflect/internal/AnnotationCheckers.scala
@@ -47,6 +47,13 @@ trait AnnotationCheckers {
* before. If the implementing class cannot do the adaptiong, it
* should return the tree unchanged.*/
def adaptAnnotations(tree: Tree, mode: Int, pt: Type): Tree = tree
+
+ /** Adapt the type of a return expression. The decision of an annotation checker
+ * whether the type should be adapted is based on the type of the expression
+ * which is returned, as well as the result type of the method (pt).
+ * By default, this method simply returns the passed `default` type.
+ */
+ def adaptTypeOfReturn(tree: Tree, pt: Type, default: => Type): Type = default
}
// Syncnote: Annotation checkers inaccessible to reflection, so no sync in var necessary.
@@ -118,4 +125,23 @@ trait AnnotationCheckers {
annotationCheckers.foldLeft(tree)((tree, checker) =>
checker.adaptAnnotations(tree, mode, pt))
}
+
+ /** Let a registered annotation checker adapt the type of a return expression.
+ * Annotation checkers that cannot do the adaptation should simply return
+ * the `default` argument.
+ *
+ * Note that the result is undefined if more than one annotation checker
+ * returns an adapted type which is not a subtype of `default`.
+ */
+ def adaptTypeOfReturn(tree: Tree, pt: Type, default: => Type): Type = {
+ val adaptedTypes = annotationCheckers flatMap { checker =>
+ val adapted = checker.adaptTypeOfReturn(tree, pt, default)
+ if (!(adapted <:< default)) List(adapted)
+ else List()
+ }
+ adaptedTypes match {
+ case fst :: _ => fst
+ case List() => default
+ }
+ }
}
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala
index dc0c002ea7..abf11020fa 100644
--- a/src/reflect/scala/reflect/internal/Definitions.scala
+++ b/src/reflect/scala/reflect/internal/Definitions.scala
@@ -520,7 +520,7 @@ trait Definitions extends api.StandardDefinitions {
def ApiUniverseReify = if (ApiUniverseClass != NoSymbol) getMemberMethod(ApiUniverseClass, nme.reify) else NoSymbol
lazy val JavaUniverseClass = getClassIfDefined("scala.reflect.api.JavaUniverse") // defined in scala-reflect.jar, so we need to be careful
- lazy val MirrorOfClass = getClassIfDefined("scala.reflect.api.MirrorOf") // defined in scala-reflect.jar, so we need to be careful
+ lazy val MirrorClass = getClassIfDefined("scala.reflect.api.Mirror") // defined in scala-reflect.jar, so we need to be careful
lazy val TypeCreatorClass = getClassIfDefined("scala.reflect.api.TypeCreator") // defined in scala-reflect.jar, so we need to be careful
lazy val TreeCreatorClass = getClassIfDefined("scala.reflect.api.TreeCreator") // defined in scala-reflect.jar, so we need to be careful
diff --git a/src/reflect/scala/reflect/internal/Mirrors.scala b/src/reflect/scala/reflect/internal/Mirrors.scala
index 4836db5db0..019cf7f908 100644
--- a/src/reflect/scala/reflect/internal/Mirrors.scala
+++ b/src/reflect/scala/reflect/internal/Mirrors.scala
@@ -19,7 +19,7 @@ trait Mirrors extends api.Mirrors {
// if there are any symbols created by that mirror
trait RootSymbol extends Symbol { def mirror: Mirror }
- abstract class RootsBase(rootOwner: Symbol) extends MirrorOf[Mirrors.this.type] { thisMirror =>
+ abstract class RootsBase(rootOwner: Symbol) extends scala.reflect.api.Mirror[Mirrors.this.type] { thisMirror =>
protected[scala] def rootLoader: LazyType
diff --git a/src/reflect/scala/reflect/internal/Printers.scala b/src/reflect/scala/reflect/internal/Printers.scala
index 4c423e0bc2..cb8dc4b197 100644
--- a/src/reflect/scala/reflect/internal/Printers.scala
+++ b/src/reflect/scala/reflect/internal/Printers.scala
@@ -580,7 +580,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
else print(sym.name)
if (printIds) print("#", sym.id)
if (printKinds) print("#", sym.abbreviatedKindString)
- if (printMirrors) print("%M", footnotes.put[MirrorOf[_]](mirrorThatLoaded(sym)))
+ if (printMirrors) print("%M", footnotes.put[scala.reflect.api.Mirror[_]](mirrorThatLoaded(sym)))
case NoType =>
print("NoType")
case NoPrefix =>
@@ -609,7 +609,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
if (depth == 0 && !printingFootnotes) {
printingFootnotes = true
footnotes.print[Type](this)
- footnotes.print[MirrorOf[_]](this)
+ footnotes.print[scala.reflect.api.Mirror[_]](this)
printingFootnotes = false
}
}
diff --git a/src/reflect/scala/reflect/internal/StdCreators.scala b/src/reflect/scala/reflect/internal/StdCreators.scala
index eba583d4b5..5e5e4f9043 100644
--- a/src/reflect/scala/reflect/internal/StdCreators.scala
+++ b/src/reflect/scala/reflect/internal/StdCreators.scala
@@ -7,14 +7,14 @@ import scala.reflect.api.{Universe => ApiUniverse}
trait StdCreators {
self: SymbolTable =>
- case class FixedMirrorTreeCreator(mirror: MirrorOf[StdCreators.this.type], tree: Tree) extends TreeCreator {
- def apply[U <: ApiUniverse with Singleton](m: MirrorOf[U]): U # Tree =
+ case class FixedMirrorTreeCreator(mirror: scala.reflect.api.Mirror[StdCreators.this.type], tree: Tree) extends TreeCreator {
+ def apply[U <: ApiUniverse with Singleton](m: scala.reflect.api.Mirror[U]): U # Tree =
if (m eq mirror) tree.asInstanceOf[U # Tree]
else throw new IllegalArgumentException(s"Expr defined in $mirror cannot be migrated to other mirrors.")
}
- case class FixedMirrorTypeCreator(mirror: MirrorOf[StdCreators.this.type], tpe: Type) extends TypeCreator {
- def apply[U <: ApiUniverse with Singleton](m: MirrorOf[U]): U # Type =
+ case class FixedMirrorTypeCreator(mirror: scala.reflect.api.Mirror[StdCreators.this.type], tpe: Type) extends TypeCreator {
+ def apply[U <: ApiUniverse with Singleton](m: scala.reflect.api.Mirror[U]): U # Type =
if (m eq mirror) tpe.asInstanceOf[U # Type]
else throw new IllegalArgumentException(s"Type tag defined in $mirror cannot be migrated to other mirrors.")
}
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index 2cdfb05e77..eacbf6a0cc 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -346,6 +346,16 @@ trait StdNames {
def isSingletonName(name: Name) = name endsWith SINGLETON_SUFFIX
def isModuleName(name: Name) = name endsWith MODULE_SUFFIX_NAME
+ /** Is name a variable name? */
+ def isVariableName(name: Name): Boolean = {
+ val first = name.startChar
+ ( ((first.isLower && first.isLetter) || first == '_')
+ && (name != nme.false_)
+ && (name != nme.true_)
+ && (name != nme.null_)
+ )
+ }
+
def isDeprecatedIdentifierName(name: Name) = name.toTermName match {
case nme.`then` | nme.`macro` => true
case _ => false
diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala
index 77cbbd936b..db062d138f 100644
--- a/src/reflect/scala/reflect/internal/TreeInfo.scala
+++ b/src/reflect/scala/reflect/internal/TreeInfo.scala
@@ -247,7 +247,7 @@ abstract class TreeInfo {
/** Is tree a variable pattern? */
def isVarPattern(pat: Tree): Boolean = pat match {
- case x: Ident => !x.isBackquoted && isVariableName(x.name)
+ case x: Ident => !x.isBackquoted && nme.isVariableName(x.name)
case _ => false
}
def isDeprecatedIdentifier(tree: Tree): Boolean = tree match {
@@ -312,14 +312,6 @@ abstract class TreeInfo {
/** Is name a left-associative operator? */
def isLeftAssoc(operator: Name) = operator.nonEmpty && (operator.endChar != ':')
- private val reserved = Set[Name](nme.false_, nme.true_, nme.null_)
-
- /** Is name a variable name? */
- def isVariableName(name: Name): Boolean = {
- val first = name.startChar
- ((first.isLower && first.isLetter) || first == '_') && !reserved(name)
- }
-
/** Is tree a `this` node which belongs to `enclClass`? */
def isSelf(tree: Tree, enclClass: Symbol): Boolean = tree match {
case This(_) => tree.symbol == enclClass
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index f6af515fa3..2c036b3308 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -5748,6 +5748,13 @@ trait Types extends api.Types { self: SymbolTable =>
case _ => false
}
+ def isNonRefinementClassType(tpe: Type) = tpe match {
+ case SingleType(_, sym) => sym.isModuleClass
+ case TypeRef(_, sym, _) => sym.isClass && !sym.isRefinementClass
+ case ErrorType => true
+ case _ => false
+ }
+
// @assume tp1.isHigherKinded || tp2.isHigherKinded
def isHKSubType0(tp1: Type, tp2: Type, depth: Int): Boolean = (
tp1.typeSymbol == NothingClass
diff --git a/src/reflect/scala/reflect/internal/package.scala b/src/reflect/scala/reflect/internal/package.scala
deleted file mode 100644
index 63568f6a6b..0000000000
--- a/src/reflect/scala/reflect/internal/package.scala
+++ /dev/null
@@ -1,6 +0,0 @@
-package scala.reflect
-
-package object internal {
-
- type MirrorOf[U <: scala.reflect.api.Universe with Singleton] = scala.reflect.api.MirrorOf[U]
-}
diff --git a/src/reflect/scala/reflect/internal/util/Collections.scala b/src/reflect/scala/reflect/internal/util/Collections.scala
index 14b5d3003d..201b4dfe0a 100644
--- a/src/reflect/scala/reflect/internal/util/Collections.scala
+++ b/src/reflect/scala/reflect/internal/util/Collections.scala
@@ -175,6 +175,20 @@ trait Collections {
}
false
}
+ final def exists3[A, B, C](xs1: List[A], xs2: List[B], xs3: List[C])(f: (A, B, C) => Boolean): Boolean = {
+ var ys1 = xs1
+ var ys2 = xs2
+ var ys3 = xs3
+ while (!ys1.isEmpty && !ys2.isEmpty && !ys3.isEmpty) {
+ if (f(ys1.head, ys2.head, ys3.head))
+ return true
+
+ ys1 = ys1.tail
+ ys2 = ys2.tail
+ ys3 = ys3.tail
+ }
+ false
+ }
final def forall2[A, B](xs1: List[A], xs2: List[B])(f: (A, B) => Boolean): Boolean = {
var ys1 = xs1
var ys2 = xs2
diff --git a/src/reflect/scala/reflect/internal/util/Position.scala b/src/reflect/scala/reflect/internal/util/Position.scala
index 1621fb84d4..151a64daff 100644
--- a/src/reflect/scala/reflect/internal/util/Position.scala
+++ b/src/reflect/scala/reflect/internal/util/Position.scala
@@ -8,7 +8,6 @@ package scala.reflect.internal.util
import scala.reflect.ClassTag
import scala.reflect.api.Attachments
-import scala.reflect.api.PositionApi
object Position {
val tabInc = 8
@@ -36,7 +35,7 @@ object Position {
}
}
-abstract class Position extends PositionApi { self =>
+abstract class Position extends scala.reflect.api.Position { self =>
type Pos = Position
@@ -44,16 +43,6 @@ abstract class Position extends PositionApi { self =>
def withPos(newPos: Position): Attachments { type Pos = self.Pos } = newPos
- /** Java file corresponding to the source file of this position.
- */
- // necessary for conformance with scala.reflect.api.Position
- def fileInfo: java.io.File = source.file.file
-
- /** Contents of the source file that contains this position.
- */
- // necessary for conformance with scala.reflect.api.Position
- def fileContent: Array[Char] = source.content
-
/** An optional value containing the source file referred to by this position, or
* None if not defined.
*/
diff --git a/src/reflect/scala/reflect/macros/Aliases.scala b/src/reflect/scala/reflect/macros/Aliases.scala
index eff7f34b02..754335d50d 100644
--- a/src/reflect/scala/reflect/macros/Aliases.scala
+++ b/src/reflect/scala/reflect/macros/Aliases.scala
@@ -10,17 +10,22 @@ trait Aliases {
type TermName = universe.TermName
type TypeName = universe.TypeName
type Tree = universe.Tree
- // type Position = universe.Position
+ type Position = universe.Position
type Scope = universe.Scope
type Modifiers = universe.Modifiers
+ type Run = universe.Run
+ type CompilationUnit = universe.CompilationUnit
type Expr[+T] = universe.Expr[T]
val Expr = universe.Expr
+ def Expr[T: WeakTypeTag](tree: Tree): Expr[T]
type WeakTypeTag[T] = universe.WeakTypeTag[T]
type TypeTag[T] = universe.TypeTag[T]
val WeakTypeTag = universe.WeakTypeTag
val TypeTag = universe.TypeTag
+ def WeakTypeTag[T](tpe: Type): WeakTypeTag[T]
+ def TypeTag[T](tpe: Type): TypeTag[T]
def weakTypeTag[T](implicit attag: WeakTypeTag[T]) = attag
def typeTag[T](implicit ttag: TypeTag[T]) = ttag
def weakTypeOf[T](implicit attag: WeakTypeTag[T]): Type = attag.tpe
diff --git a/src/reflect/scala/reflect/macros/CapturedVariables.scala b/src/reflect/scala/reflect/macros/CapturedVariables.scala
deleted file mode 100644
index 60ed6f5e7b..0000000000
--- a/src/reflect/scala/reflect/macros/CapturedVariables.scala
+++ /dev/null
@@ -1,21 +0,0 @@
-package scala.reflect
-package macros
-
-trait CapturedVariables {
- self: Context =>
-
- import mirror._
-
- /** Mark a variable as captured; i.e. force boxing in a *Ref type.
- */
- def captureVariable(vble: Symbol): Unit
-
- /** Mark given identifier as a reference to a captured variable itself
- * suppressing dereferencing with the `elem` field.
- */
- def referenceCapturedVariable(vble: Symbol): Tree
-
- /** Convert type of a captured variable to *Ref type.
- */
- def capturedVariableType(vble: Symbol): Type
-} \ No newline at end of file
diff --git a/src/reflect/scala/reflect/macros/Context.scala b/src/reflect/scala/reflect/macros/Context.scala
index 37c8f9057e..7a365ed37b 100644
--- a/src/reflect/scala/reflect/macros/Context.scala
+++ b/src/reflect/scala/reflect/macros/Context.scala
@@ -6,17 +6,13 @@ package macros
// the full context should include all traits from scala.reflect.macros (and probably reside in scala-compiler.jar)
trait Context extends Aliases
- with CapturedVariables
with Enclosures
- with Infrastructure
with Names
with Reifiers
with FrontEnds
- with Settings
+ with Infrastructure
with Typers
with Parsers
- with Exprs
- with TypeTags
with Evals
with ExprUtils {
@@ -24,7 +20,7 @@ trait Context extends Aliases
val universe: Universe
/** The mirror of the compile-time universe */
- val mirror: MirrorOf[universe.type]
+ val mirror: universe.Mirror
/** The type of the prefix tree from which the macro is selected */
type PrefixType
diff --git a/src/reflect/scala/reflect/macros/Enclosures.scala b/src/reflect/scala/reflect/macros/Enclosures.scala
index a07ff85a08..218cf6ebb3 100644
--- a/src/reflect/scala/reflect/macros/Enclosures.scala
+++ b/src/reflect/scala/reflect/macros/Enclosures.scala
@@ -47,4 +47,8 @@ trait Enclosures {
/** Compilation unit that contains this macro application.
*/
val enclosingUnit: CompilationUnit
+
+ /** Compilation run that contains this macro application.
+ */
+ val enclosingRun: Run
} \ No newline at end of file
diff --git a/src/reflect/scala/reflect/macros/Exprs.scala b/src/reflect/scala/reflect/macros/Exprs.scala
deleted file mode 100644
index 280d5508c8..0000000000
--- a/src/reflect/scala/reflect/macros/Exprs.scala
+++ /dev/null
@@ -1,8 +0,0 @@
-package scala.reflect
-package macros
-
-trait Exprs {
- self: Context =>
-
- def Expr[T: WeakTypeTag](tree: Tree): Expr[T]
-}
diff --git a/src/reflect/scala/reflect/macros/FrontEnds.scala b/src/reflect/scala/reflect/macros/FrontEnds.scala
index d15db0725f..e6b67cfc87 100644
--- a/src/reflect/scala/reflect/macros/FrontEnds.scala
+++ b/src/reflect/scala/reflect/macros/FrontEnds.scala
@@ -1,18 +1,9 @@
package scala.reflect
package macros
-trait FrontEnds extends scala.reflect.api.FrontEnds {
+trait FrontEnds {
self: Context =>
- import mirror._
-
- type Position = universe.Position
-
- /** Exposes means to control the compiler UI */
- def frontEnd: FrontEnd
- def setFrontEnd(frontEnd: FrontEnd): this.type
- def withFrontEnd[T](frontEnd: FrontEnd)(op: => T): T
-
/** For sending a message which should not be labeled as a warning/error,
* but also shouldn't require -verbose to be visible.
* Use ``enclosingPosition'' if you're in doubt what position to pass to ``pos''.
@@ -36,7 +27,4 @@ trait FrontEnds extends scala.reflect.api.FrontEnds {
* Use ``enclosingPosition'' if you're in doubt what position to pass to ``pos''.
*/
def abort(pos: Position, msg: String): Nothing
-
- /** Drops into interactive mode if supported by the compiler UI */
- def interactive(): Unit
} \ No newline at end of file
diff --git a/src/reflect/scala/reflect/macros/Infrastructure.scala b/src/reflect/scala/reflect/macros/Infrastructure.scala
index 80153ff257..a1ef1c87a3 100644
--- a/src/reflect/scala/reflect/macros/Infrastructure.scala
+++ b/src/reflect/scala/reflect/macros/Infrastructure.scala
@@ -4,77 +4,16 @@ package macros
trait Infrastructure {
self: Context =>
- /** Determines whether the compiler expanding a macro targets JVM.
+ /** Exposes macro-specific settings as a list of strings.
+ * These settings are passed to the compiler via the "-Xmacro-settings:setting1,setting2...,settingN" command-line option.
*/
- val forJVM: Boolean
+ def settings: List[String]
- /** Determines whether the compiler expanding a macro targets CLR.
+ /** Exposes current compiler settings as a list of options.
+ * Use `scalac -help`, `scalac -X` and `scalac -Y` to learn about currently supported options.
*/
- val forMSIL: Boolean
+ def compilerSettings: List[String]
- /** Determines whether the compiler expanding a macro is a presentation compiler.
- */
- val forInteractive: Boolean
-
- /** Determines whether the compiler expanding a macro is a Scaladoc compiler.
- */
- val forScaladoc: Boolean
-
- /** Exposes current compilation run.
- */
- val currentRun: Run
-
- /** Exposes library classpath.
- */
- val libraryClassPath: List[java.net.URL]
-
- /** Exposes a classloader that corresponds to the library classpath.
- *
- * With this classloader you can perform on-the-fly evaluation of macro arguments.
- * For example, consider this code snippet:
- *
- * def staticEval[T](x: T) = macro staticEval[T]
- *
- * def staticEval[T](c: Context)(x: c.Expr[T]) = {
- * import scala.reflect.runtime.{universe => ru}
- * val mirror = ru.runtimeMirror(c.libraryClassLoader)
- * import scala.tools.reflect.ToolBox
- * val toolBox = mirror.mkToolBox()
- * val importer = ru.mkImporter(c.universe).asInstanceOf[ru.Importer { val from: c.universe.type }]
- * val tree = c.resetAllAttrs(x.tree.duplicate)
- * val imported = importer.importTree(tree)
- * val valueOfX = toolBox.eval(imported).asInstanceOf[T]
- * ...
- * }
- */
- def libraryClassLoader: ClassLoader
-
- /** As seen by macro API, compilation run is an opaque type that can be deconstructed into:
- * 1) Current compilation unit
- * 2) List of all compilation units that comprise the run
- */
- type Run
-
- val Run: RunExtractor
-
- abstract class RunExtractor {
- def unapply(run: Run): Option[(CompilationUnit, List[CompilationUnit])]
- }
-
- /** As seen by macro API, compilation unit is an opaque type that can be deconstructed into:
- * 1) File that corresponds to the unit (if not applicable, null)
- * 2) Content of the file (if not applicable, empty array)
- * 3) Body, i.e. the AST that represents the compilation unit
- */
- type CompilationUnit
-
- val CompilationUnit: CompilationUnitExtractor
-
- abstract class CompilationUnitExtractor {
- def unapply(compilationUnit: CompilationUnit): Option[(java.io.File, Array[Char], Tree)]
- }
-
- /** Returns a macro definition which triggered this macro expansion.
- */
- val currentMacro: Symbol
-}
+ /** Exposes current classpath. */
+ def classPath: List[java.net.URL]
+} \ No newline at end of file
diff --git a/src/reflect/scala/reflect/macros/Parsers.scala b/src/reflect/scala/reflect/macros/Parsers.scala
index 1742d07b60..c2d4d8a3ab 100644
--- a/src/reflect/scala/reflect/macros/Parsers.scala
+++ b/src/reflect/scala/reflect/macros/Parsers.scala
@@ -5,14 +5,10 @@ trait Parsers {
self: Context =>
/** .. */
- // todo. distinguish between `parse` and `parse`
+ // todo. distinguish between parsing an expression and parsing arbitrary code
+ // for example, parsing in expression mode will fail on packages
def parse(code: String): Tree
+}
- /** Represents an error during parsing
- */
- type ParseError <: Throwable
- val ParseError: ParseErrorExtractor
- abstract class ParseErrorExtractor {
- def unapply(error: ParseError): Option[(Position, String)]
- }
-} \ No newline at end of file
+// should be path-dependent, otherwise exception handling becomes a mess
+case class ParseError(val pos: scala.reflect.api.Position, val msg: String) extends Throwable(msg)
diff --git a/src/reflect/scala/reflect/macros/Reifiers.scala b/src/reflect/scala/reflect/macros/Reifiers.scala
index c2a6c5be05..ed31663c68 100644
--- a/src/reflect/scala/reflect/macros/Reifiers.scala
+++ b/src/reflect/scala/reflect/macros/Reifiers.scala
@@ -1,21 +1,14 @@
package scala.reflect
package macros
-import scala.reflect.api.PositionApi
-
trait Reifiers {
self: Context =>
- /** Reification prefix that refers to the runtime reflexive universe, ``scala.reflect.runtime.universe''.
- * Providing it for the ``prefix'' parameter of ``reifyTree'' or ``reifyType'' will create a full-fledged tree that can be inspected at runtime.
- */
- val runtimeUniverse: Tree
-
/** Given a tree, generate a tree that when compiled and executed produces the original tree.
* For more information and examples see the documentation for ``Universe.reify''.
*
* The produced tree will be bound to the specified ``universe'' and ``mirror''.
- * Possible values for ``universe'' include ``runtimeUniverse''.
+ * Possible values for ``universe'' include ``universe.treeBuild.mkRuntimeUniverseRef''.
* Possible values for ``mirror'' include ``EmptyTree'' (in that case the reifier will automatically pick an appropriate mirror).
*
* This function is deeply connected to ``Universe.reify'', a macro that reifies arbitrary expressions into runtime trees.
@@ -83,6 +76,6 @@ trait Reifiers {
// made these guys non path-dependent, otherwise exception handling quickly becomes a mess
-case class ReificationError(val pos: PositionApi, val msg: String) extends Throwable(msg)
+case class ReificationError(val pos: scala.reflect.api.Position, val msg: String) extends Throwable(msg)
-case class UnexpectedReificationError(val pos: PositionApi, val msg: String, val cause: Throwable = null) extends Throwable(msg, cause)
+case class UnexpectedReificationError(val pos: scala.reflect.api.Position, val msg: String, val cause: Throwable = null) extends Throwable(msg, cause)
diff --git a/src/reflect/scala/reflect/macros/Settings.scala b/src/reflect/scala/reflect/macros/Settings.scala
deleted file mode 100644
index a2cdb4c8e1..0000000000
--- a/src/reflect/scala/reflect/macros/Settings.scala
+++ /dev/null
@@ -1,36 +0,0 @@
-package scala.reflect
-package macros
-
-trait Settings {
- self: Context =>
-
- /** Exposes macro-specific settings as a list of strings.
- * These settings are passed to the compiler via the "-Xmacro-settings:setting1,setting2...,settingN" command-line option.
- */
- def settings: List[String]
-
- /** Exposes current compiler settings as a list of options.
- * Use `scalac -help`, `scalac -X` and `scalac -Y` to learn about currently supported options.
- */
- def compilerSettings: List[String]
-
- /** Updates current compiler settings with an option string.
- * Use `scalac -help`, `scalac -X` and `scalac -Y` to learn about currently supported options.
- */
- def setCompilerSettings(options: String): this.type
-
- /** Updates current compiler settings with a list of options.
- * Use `scalac -help`, `scalac -X` and `scalac -Y` to learn about currently supported options.
- */
- def setCompilerSettings(options: List[String]): this.type
-
- /** Temporarily sets compiler settings to a given option string and executes a given closure.
- * Use `scalac -help`, `scalac -X` and `scalac -Y` to learn about currently supported options.
- */
- def withCompilerSettings[T](options: String)(op: => T): T
-
- /** Temporarily sets compiler settings to a given list of options and executes a given closure.
- * Use `scalac -help`, `scalac -X` and `scalac -Y` to learn about currently supported options.
- */
- def withCompilerSettings[T](options: List[String])(op: => T): T
-} \ No newline at end of file
diff --git a/src/reflect/scala/reflect/macros/TreeBuilder.scala b/src/reflect/scala/reflect/macros/TreeBuilder.scala
index ca29194859..5f18ab9ee8 100644
--- a/src/reflect/scala/reflect/macros/TreeBuilder.scala
+++ b/src/reflect/scala/reflect/macros/TreeBuilder.scala
@@ -53,4 +53,7 @@ abstract class TreeBuilder {
def mkMethodCall(receiver: Tree, method: Symbol, targs: List[Type], args: List[Tree]): Tree
def mkMethodCall(target: Tree, targs: List[Type], args: List[Tree]): Tree
def mkNullaryCall(method: Symbol, targs: List[Type]): Tree
+
+ /** A tree that refers to the runtime reflexive universe, ``scala.reflect.runtime.universe''. */
+ def mkRuntimeUniverseRef: Tree
}
diff --git a/src/reflect/scala/reflect/macros/TypeTags.scala b/src/reflect/scala/reflect/macros/TypeTags.scala
deleted file mode 100644
index 2f15e37f6a..0000000000
--- a/src/reflect/scala/reflect/macros/TypeTags.scala
+++ /dev/null
@@ -1,9 +0,0 @@
-package scala.reflect
-package macros
-
-trait TypeTags {
- self: Context =>
-
- def WeakTypeTag[T](tpe: Type): WeakTypeTag[T]
- def TypeTag[T](tpe: Type): TypeTag[T]
-}
diff --git a/src/reflect/scala/reflect/macros/Universe.scala b/src/reflect/scala/reflect/macros/Universe.scala
index f84c11ee63..97d0a8d98a 100644
--- a/src/reflect/scala/reflect/macros/Universe.scala
+++ b/src/reflect/scala/reflect/macros/Universe.scala
@@ -109,4 +109,52 @@ abstract class Universe extends scala.reflect.api.Universe {
trait IdentContextApi extends IdentApi { this: Ident =>
def isBackquoted: Boolean
}
+
+ /** Mark a variable as captured; i.e. force boxing in a *Ref type.
+ */
+ def captureVariable(vble: Symbol): Unit
+
+ /** Mark given identifier as a reference to a captured variable itself
+ * suppressing dereferencing with the `elem` field.
+ */
+ def referenceCapturedVariable(vble: Symbol): Tree
+
+ /** Convert type of a captured variable to *Ref type.
+ */
+ def capturedVariableType(vble: Symbol): Type
+
+ type Run <: RunContextApi
+
+ /** Compilation run uniquely identifies current invocation of the compiler
+ * (e.g. can be used to implement per-run caches for macros) and provides access to units of work
+ * of the invocation (currently processed unit of work and the list of all units).
+ */
+ trait RunContextApi {
+ /** Currently processed unit of work (a real or a virtual file). */
+ def currentUnit: CompilationUnit
+
+ /** All units of work comprising this compilation run. */
+ def units: Iterator[CompilationUnit]
+ }
+
+ type CompilationUnit <: CompilationUnitContextApi
+
+ /** Compilation unit describes a unit of work of the compilation run.
+ * It provides such information as file name, textual representation of the unit and the underlying AST.
+ */
+ trait CompilationUnitContextApi {
+ /** Source file corresponding to this compilation unit.
+ *
+ * Exposes information about the file as a part of a real or virtual file system
+ * along with the contents of that file.
+ *
+ * The return type is [[scala.reflect.io.AbstractFile]], which belongs to an experimental part of Scala reflection.
+ * It should not be used unless you know what you are doing. In subsequent releases, this API will be refined
+ * and exposed as a part of scala.reflect.api.
+ */
+ def source: scala.reflect.internal.util.SourceFile
+
+ /** The AST that corresponds to this compilation unit. */
+ def body: Tree
+ }
} \ No newline at end of file
diff --git a/src/reflect/scala/reflect/macros/package.scala b/src/reflect/scala/reflect/macros/package.scala
deleted file mode 100644
index df93785d40..0000000000
--- a/src/reflect/scala/reflect/macros/package.scala
+++ /dev/null
@@ -1,6 +0,0 @@
-package scala.reflect
-
-package object macros {
-
- type MirrorOf[U <: scala.reflect.api.Universe with Singleton] = scala.reflect.api.MirrorOf[U]
-}
diff --git a/test/files/continuations-neg/t5314-missing-result-type.check b/test/files/continuations-neg/t5314-missing-result-type.check
new file mode 100644
index 0000000000..341e580cf3
--- /dev/null
+++ b/test/files/continuations-neg/t5314-missing-result-type.check
@@ -0,0 +1,4 @@
+t5314-missing-result-type.scala:6: error: method bar has return statement; needs result type
+ def bar(x:Int) = return foo(x)
+ ^
+one error found
diff --git a/test/files/continuations-neg/t5314-missing-result-type.scala b/test/files/continuations-neg/t5314-missing-result-type.scala
new file mode 100644
index 0000000000..d7c5043a86
--- /dev/null
+++ b/test/files/continuations-neg/t5314-missing-result-type.scala
@@ -0,0 +1,13 @@
+import scala.util.continuations._
+
+object Test extends App {
+ def foo(x:Int): Int @cps[Int] = x
+
+ def bar(x:Int) = return foo(x)
+
+ reset {
+ val res = bar(8)
+ println(res)
+ res
+ }
+}
diff --git a/test/files/continuations-neg/t5314-npe.check b/test/files/continuations-neg/t5314-npe.check
new file mode 100644
index 0000000000..b5f024aa89
--- /dev/null
+++ b/test/files/continuations-neg/t5314-npe.check
@@ -0,0 +1,4 @@
+t5314-npe.scala:2: error: method bar has return statement; needs result type
+ def bar(x:Int) = { return x; x } // NPE
+ ^
+one error found
diff --git a/test/files/continuations-neg/t5314-npe.scala b/test/files/continuations-neg/t5314-npe.scala
new file mode 100644
index 0000000000..2b5966e07c
--- /dev/null
+++ b/test/files/continuations-neg/t5314-npe.scala
@@ -0,0 +1,3 @@
+object Test extends App {
+ def bar(x:Int) = { return x; x } // NPE
+}
diff --git a/test/files/continuations-neg/t5314-return-reset.check b/test/files/continuations-neg/t5314-return-reset.check
new file mode 100644
index 0000000000..4c817ae14d
--- /dev/null
+++ b/test/files/continuations-neg/t5314-return-reset.check
@@ -0,0 +1,4 @@
+t5314-return-reset.scala:14: error: return expression not allowed, since method calls CPS method
+ if (rnd.nextInt(100) > 50) return 5 // not allowed, since method is calling `reset`
+ ^
+one error found
diff --git a/test/files/continuations-neg/t5314-return-reset.scala b/test/files/continuations-neg/t5314-return-reset.scala
new file mode 100644
index 0000000000..df9d58e4cb
--- /dev/null
+++ b/test/files/continuations-neg/t5314-return-reset.scala
@@ -0,0 +1,21 @@
+import scala.util.continuations._
+import scala.util.Random
+
+object Test extends App {
+ val rnd = new Random
+
+ def foo(x: Int): Int @cps[Int] = shift { k => k(x) }
+
+ def bar(x: Int): Int @cps[Int] = return foo(x)
+
+ def caller(): Int = {
+ val v: Int = reset {
+ val res: Int = bar(8)
+ if (rnd.nextInt(100) > 50) return 5 // not allowed, since method is calling `reset`
+ 42
+ }
+ v
+ }
+
+ caller()
+}
diff --git a/test/files/continuations-neg/t5314-type-error.check b/test/files/continuations-neg/t5314-type-error.check
new file mode 100644
index 0000000000..1f4e46a7f2
--- /dev/null
+++ b/test/files/continuations-neg/t5314-type-error.check
@@ -0,0 +1,6 @@
+t5314-type-error.scala:7: error: type mismatch;
+ found : Int @util.continuations.cps[Int]
+ required: Int @util.continuations.cps[String]
+ def bar(x:Int): Int @cps[String] = return foo(x)
+ ^
+one error found
diff --git a/test/files/continuations-neg/t5314-type-error.scala b/test/files/continuations-neg/t5314-type-error.scala
new file mode 100644
index 0000000000..e36ce6c203
--- /dev/null
+++ b/test/files/continuations-neg/t5314-type-error.scala
@@ -0,0 +1,17 @@
+import scala.util.continuations._
+
+object Test extends App {
+ def foo(x:Int): Int @cps[Int] = shift { k => k(x) }
+
+ // should be a type error
+ def bar(x:Int): Int @cps[String] = return foo(x)
+
+ def caller(): Unit = {
+ val v: String = reset {
+ val res: Int = bar(8)
+ "hello"
+ }
+ }
+
+ caller()
+}
diff --git a/test/files/continuations-run/t5314-2.check b/test/files/continuations-run/t5314-2.check
new file mode 100644
index 0000000000..35b3c93780
--- /dev/null
+++ b/test/files/continuations-run/t5314-2.check
@@ -0,0 +1,5 @@
+8
+hi
+8
+from try
+8
diff --git a/test/files/continuations-run/t5314-2.scala b/test/files/continuations-run/t5314-2.scala
new file mode 100644
index 0000000000..8a896dec2c
--- /dev/null
+++ b/test/files/continuations-run/t5314-2.scala
@@ -0,0 +1,44 @@
+import scala.util.continuations._
+
+class ReturnRepro {
+ def s1: Int @cps[Any] = shift { k => k(5) }
+ def caller = reset { println(p(3)) }
+ def caller2 = reset { println(p2(3)) }
+ def caller3 = reset { println(p3(3)) }
+
+ def p(i: Int): Int @cps[Any] = {
+ val v= s1 + 3
+ return v
+ }
+
+ def p2(i: Int): Int @cps[Any] = {
+ val v = s1 + 3
+ if (v > 0) {
+ println("hi")
+ return v
+ } else {
+ println("hi")
+ return 8
+ }
+ }
+
+ def p3(i: Int): Int @cps[Any] = {
+ val v = s1 + 3
+ try {
+ println("from try")
+ return v
+ } catch {
+ case e: Exception =>
+ println("from catch")
+ return 7
+ }
+ }
+
+}
+
+object Test extends App {
+ val repro = new ReturnRepro
+ repro.caller
+ repro.caller2
+ repro.caller3
+}
diff --git a/test/files/continuations-run/t5314-3.check b/test/files/continuations-run/t5314-3.check
new file mode 100644
index 0000000000..71489f097c
--- /dev/null
+++ b/test/files/continuations-run/t5314-3.check
@@ -0,0 +1,4 @@
+enter return expr
+8
+hi
+8
diff --git a/test/files/continuations-run/t5314-3.scala b/test/files/continuations-run/t5314-3.scala
new file mode 100644
index 0000000000..62c547f5a2
--- /dev/null
+++ b/test/files/continuations-run/t5314-3.scala
@@ -0,0 +1,27 @@
+import scala.util.continuations._
+
+class ReturnRepro {
+ def s1: Int @cpsParam[Any, Unit] = shift { k => k(5) }
+ def caller = reset { println(p(3)) }
+ def caller2 = reset { println(p2(3)) }
+
+ def p(i: Int): Int @cpsParam[Unit, Any] = {
+ val v= s1 + 3
+ return { println("enter return expr"); v }
+ }
+
+ def p2(i: Int): Int @cpsParam[Unit, Any] = {
+ val v = s1 + 3
+ if (v > 0) {
+ return { println("hi"); v }
+ } else {
+ return { println("hi"); 8 }
+ }
+ }
+}
+
+object Test extends App {
+ val repro = new ReturnRepro
+ repro.caller
+ repro.caller2
+}
diff --git a/test/files/continuations-run/t5314-with-if.check b/test/files/continuations-run/t5314-with-if.check
new file mode 100644
index 0000000000..7f8f011eb7
--- /dev/null
+++ b/test/files/continuations-run/t5314-with-if.check
@@ -0,0 +1 @@
+7
diff --git a/test/files/continuations-run/t5314-with-if.scala b/test/files/continuations-run/t5314-with-if.scala
new file mode 100644
index 0000000000..5840199a3c
--- /dev/null
+++ b/test/files/continuations-run/t5314-with-if.scala
@@ -0,0 +1,17 @@
+import scala.util.continuations._
+
+object Test extends App {
+
+ def foo(x:Int): Int @cps[Int] = 7
+
+ def bar(x:Int): Int @cps[Int] = {
+ val v = foo(x)
+ if (v > 0)
+ return v
+ else
+ return 10
+ }
+
+ println(reset { bar(10) })
+
+}
diff --git a/test/files/continuations-run/t5314.check b/test/files/continuations-run/t5314.check
new file mode 100644
index 0000000000..4b35d8e6d0
--- /dev/null
+++ b/test/files/continuations-run/t5314.check
@@ -0,0 +1,8 @@
+7
+7
+7
+8
+8
+hi
+8
+8
diff --git a/test/files/continuations-run/t5314.scala b/test/files/continuations-run/t5314.scala
new file mode 100644
index 0000000000..d611016ce4
--- /dev/null
+++ b/test/files/continuations-run/t5314.scala
@@ -0,0 +1,52 @@
+import scala.util.continuations._
+
+class ReturnRepro {
+ def s1: Int @cpsParam[Any, Unit] = shift { k => k(5) }
+ def caller = reset { println(p(3)) }
+ def caller2 = reset { println(p2(3)) }
+
+ def p(i: Int): Int @cpsParam[Unit, Any] = {
+ val v= s1 + 3
+ return v
+ }
+
+ def p2(i: Int): Int @cpsParam[Unit, Any] = {
+ val v = s1 + 3
+ if (v > 0) {
+ println("hi")
+ return v
+ } else {
+ println("hi")
+ return 8
+ }
+ }
+}
+
+object Test extends App {
+ def foo(x:Int): Int @cps[Int] = shift { k => k(x) }
+
+ def bar(x:Int): Int @cps[Int] = return foo(x)
+
+ def nocps(x: Int): Int = { return x; x }
+
+ def foo2(x:Int): Int @cps[Int] = 7
+ def bar2(x:Int): Int @cps[Int] = { foo2(x); return 7 }
+ def bar3(x:Int): Int @cps[Int] = { foo2(x); if (x == 7) return 7 else return foo2(x) }
+ def bar4(x:Int): Int @cps[Int] = { foo2(x); if (x == 7) return 7 else foo2(x) }
+ def bar5(x:Int): Int @cps[Int] = { foo2(x); if (x == 7) return 7 else 8 }
+ println(reset { bar2(10) })
+ println(reset { bar3(10) })
+ println(reset { bar4(10) })
+ println(reset { bar5(10) })
+
+ /* original test case */
+ val repro = new ReturnRepro
+ repro.caller
+ repro.caller2
+
+ reset {
+ val res = bar(8)
+ println(res)
+ res
+ }
+}
diff --git a/test/files/neg/patmat-type-check.check b/test/files/neg/patmat-type-check.check
index e045841ce1..721217c314 100644
--- a/test/files/neg/patmat-type-check.check
+++ b/test/files/neg/patmat-type-check.check
@@ -1,3 +1,12 @@
+patmat-type-check.scala:11: warning: fruitless type test: a value of type Test.Bop4[T] cannot also be a Seq[A]
+ def s3[T](x: Bop4[T]) = x match { case Seq('b', 'o', 'b') => true }
+ ^
+patmat-type-check.scala:15: warning: fruitless type test: a value of type Test.Bop5[_$1,T1,T2] cannot also be a Seq[A]
+ def s4[T1, T2](x: Bop5[_, T1, T2]) = x match { case Seq('b', 'o', 'b') => true }
+ ^
+patmat-type-check.scala:19: warning: fruitless type test: a value of type Test.Bop3[T] cannot also be a Seq[A]
+ def f4[T](x: Bop3[T]) = x match { case Seq('b', 'o', 'b') => true }
+ ^
patmat-type-check.scala:22: error: scrutinee is incompatible with pattern type;
found : Seq[A]
required: String
@@ -18,4 +27,5 @@ patmat-type-check.scala:30: error: scrutinee is incompatible with pattern type;
required: Test.Bop3[Char]
def f4[T](x: Bop3[Char]) = x match { case Seq('b', 'o', 'b') => true } // fail
^
+three warnings found
four errors found
diff --git a/test/files/neg/t1872.check b/test/files/neg/t1872.check
index ef84ef79e0..c5dc2a8080 100644
--- a/test/files/neg/t1872.check
+++ b/test/files/neg/t1872.check
@@ -1,4 +1,8 @@
+t1872.scala:3: warning: fruitless type test: a value of type Int cannot also be a scala.util.Random
+ def f(x: Int) = x.isInstanceOf[util.Random]
+ ^
t1872.scala:3: error: isInstanceOf cannot test if value types are references.
def f(x: Int) = x.isInstanceOf[util.Random]
^
+one warning found
one error found
diff --git a/test/files/neg/t4302.check b/test/files/neg/t4302.check
index 1a59b79a3b..ea48729276 100644
--- a/test/files/neg/t4302.check
+++ b/test/files/neg/t4302.check
@@ -1,4 +1,4 @@
-t4302.scala:2: warning: abstract type T in type T is unchecked since it is eliminated by erasure
+t4302.scala:2: warning: abstract type T is unchecked since it is eliminated by erasure
def hasMatch[T](x: AnyRef) = x.isInstanceOf[T]
^
error: No warnings can be incurred under -Xfatal-warnings.
diff --git a/test/files/neg/t5762.check b/test/files/neg/t5762.check
new file mode 100644
index 0000000000..2a2f12144a
--- /dev/null
+++ b/test/files/neg/t5762.check
@@ -0,0 +1,15 @@
+t5762.scala:6: warning: non-variable type argument Int in type pattern D[Int] is unchecked since it is eliminated by erasure
+ case _: D[Int] if bippy => 1
+ ^
+t5762.scala:7: warning: non-variable type argument String in type pattern D[String] is unchecked since it is eliminated by erasure
+ case _: D[String] => 2
+ ^
+t5762.scala:20: warning: non-variable type argument D[Int] in type pattern D[D[Int]] is unchecked since it is eliminated by erasure
+ case _: D[D[Int]] if bippy => 1
+ ^
+t5762.scala:21: warning: non-variable type argument D[String] in type pattern D[D[String]] is unchecked since it is eliminated by erasure
+ case _: D[D[String]] => 2
+ ^
+error: No warnings can be incurred under -Xfatal-warnings.
+four warnings found
+one error found
diff --git a/test/files/neg/t5762.flags b/test/files/neg/t5762.flags
new file mode 100644
index 0000000000..85d8eb2ba2
--- /dev/null
+++ b/test/files/neg/t5762.flags
@@ -0,0 +1 @@
+-Xfatal-warnings
diff --git a/test/files/neg/t5762.scala b/test/files/neg/t5762.scala
new file mode 100644
index 0000000000..fb73552b12
--- /dev/null
+++ b/test/files/neg/t5762.scala
@@ -0,0 +1,24 @@
+class D[-A]
+
+object Test {
+ var bippy: Boolean = true
+ def f1(x: D[Int with String]) = x match {
+ case _: D[Int] if bippy => 1
+ case _: D[String] => 2
+ }
+ // Correctly warns:
+ //
+ // a.scala:5: warning: non variable type-argument Int in type pattern D[Int] is unchecked since it is eliminated by erasure
+ // case _: D[Int] => 1
+ // ^
+ // a.scala:6: warning: non variable type-argument String in type pattern D[String] is unchecked since it is eliminated by erasure
+ // case _: D[String] => 2
+ // ^
+ // two warnings found
+
+ def f2(x: D[D[Int] with D[String]]) = x match {
+ case _: D[D[Int]] if bippy => 1
+ case _: D[D[String]] => 2
+ }
+ // No warnings!
+}
diff --git a/test/files/neg/unchecked-abstract.check b/test/files/neg/unchecked-abstract.check
new file mode 100644
index 0000000000..762859574b
--- /dev/null
+++ b/test/files/neg/unchecked-abstract.check
@@ -0,0 +1,27 @@
+unchecked-abstract.scala:16: warning: abstract type H in type Con[M.this.H] is unchecked since it is eliminated by erasure
+ /* warn */ println(x.isInstanceOf[Con[H]])
+ ^
+unchecked-abstract.scala:21: warning: abstract type H in type Con[M.this.H] is unchecked since it is eliminated by erasure
+ /* warn */ println(x.isInstanceOf[Con[H]])
+ ^
+unchecked-abstract.scala:27: warning: abstract type T in type Inv[M.this.T] is unchecked since it is eliminated by erasure
+ /* warn */ println(x.isInstanceOf[Inv[T]])
+ ^
+unchecked-abstract.scala:28: warning: abstract type L in type Inv[M.this.L] is unchecked since it is eliminated by erasure
+ /* warn */ println(x.isInstanceOf[Inv[L]])
+ ^
+unchecked-abstract.scala:31: warning: abstract type H in type Inv[M.this.H] is unchecked since it is eliminated by erasure
+ /* warn */ println(x.isInstanceOf[Inv[H]])
+ ^
+unchecked-abstract.scala:33: warning: abstract type L in type Inv[M.this.L] is unchecked since it is eliminated by erasure
+ /* warn */ println(x.isInstanceOf[Inv[L]])
+ ^
+unchecked-abstract.scala:36: warning: abstract type H in type Inv[M.this.H] is unchecked since it is eliminated by erasure
+ /* warn */ println(x.isInstanceOf[Inv[H]])
+ ^
+unchecked-abstract.scala:37: warning: abstract type T in type Inv[M.this.T] is unchecked since it is eliminated by erasure
+ /* warn */ println(x.isInstanceOf[Inv[T]])
+ ^
+error: No warnings can be incurred under -Xfatal-warnings.
+8 warnings found
+one error found
diff --git a/test/files/neg/unchecked-abstract.flags b/test/files/neg/unchecked-abstract.flags
new file mode 100644
index 0000000000..85d8eb2ba2
--- /dev/null
+++ b/test/files/neg/unchecked-abstract.flags
@@ -0,0 +1 @@
+-Xfatal-warnings
diff --git a/test/files/neg/unchecked-abstract.scala b/test/files/neg/unchecked-abstract.scala
new file mode 100644
index 0000000000..5b915755f4
--- /dev/null
+++ b/test/files/neg/unchecked-abstract.scala
@@ -0,0 +1,93 @@
+trait Con[-X]
+trait Inv[X]
+trait Cov[+X]
+
+abstract class M {
+ type H
+ type L <: H
+ type T >: L <: H
+
+ def h1(x: Con[H]) = {
+ /* nowarn */ println(x.isInstanceOf[Con[H]])
+ /* nowarn */ println(x.isInstanceOf[Con[T]])
+ /* nowarn */ println(x.isInstanceOf[Con[L]])
+ }
+ def h2(x: Con[T]) = {
+ /* warn */ println(x.isInstanceOf[Con[H]])
+ /* nowarn */ println(x.isInstanceOf[Con[T]])
+ /* nowarn */ println(x.isInstanceOf[Con[L]])
+ }
+ def h3(x: Con[L]) = {
+ /* warn */ println(x.isInstanceOf[Con[H]])
+ /* warn */ println(x.isInstanceOf[Con[T]])
+ /* nowarn */ println(x.isInstanceOf[Con[L]])
+ }
+ def h4(x: Inv[H]) = {
+ /* nowarn */ println(x.isInstanceOf[Inv[H]])
+ /* warn */ println(x.isInstanceOf[Inv[T]])
+ /* warn */ println(x.isInstanceOf[Inv[L]])
+ }
+ def h5(x: Inv[T]) = {
+ /* warn */ println(x.isInstanceOf[Inv[H]])
+ /* nowarn */ println(x.isInstanceOf[Inv[T]])
+ /* warn */ println(x.isInstanceOf[Inv[L]])
+ }
+ def h6(x: Inv[L]) = {
+ /* warn */ println(x.isInstanceOf[Inv[H]])
+ /* warn */ println(x.isInstanceOf[Inv[T]])
+ /* nowarn */ println(x.isInstanceOf[Inv[L]])
+ }
+ def h7(x: Cov[H]) = {
+ /* nowarn */ println(x.isInstanceOf[Cov[H]])
+ /* warn */ println(x.isInstanceOf[Cov[T]])
+ /* warn */ println(x.isInstanceOf[Cov[L]])
+ }
+ def h8(x: Cov[T]) = {
+ /* nowarn */ println(x.isInstanceOf[Cov[H]])
+ /* nowarn */ println(x.isInstanceOf[Cov[T]])
+ /* warn */ println(x.isInstanceOf[Cov[L]])
+ }
+ def h9(x: Cov[L]) = {
+ /* nowarn */ println(x.isInstanceOf[Cov[H]])
+ /* nowarn */ println(x.isInstanceOf[Cov[T]])
+ /* nowarn */ println(x.isInstanceOf[Cov[L]])
+ }
+}
+
+object Test extends M {
+ type H = Any
+ type T = Int
+ type L = Nothing
+
+ val conh = new Con[H] { }
+ val cont = new Con[T] { }
+ val conl = new Con[L] { }
+
+ val invh = new Inv[H] { }
+ val invt = new Inv[T] { }
+ val invl = new Inv[L] { }
+
+ val covh = new Cov[H] { }
+ val covt = new Cov[T] { }
+ val covl = new Cov[L] { }
+
+ def main(args: Array[String]): Unit = {
+ h1(conh)
+ h2(conh)
+ h2(cont)
+ h3(conh)
+ h3(cont)
+ h3(conl)
+
+ h4(invh)
+ h5(invt)
+ h6(invl)
+
+ h7(covh)
+ h7(covt)
+ h7(covl)
+ h8(covt)
+ h8(covl)
+ h9(covl)
+ }
+}
diff --git a/test/files/neg/unchecked-impossible.check b/test/files/neg/unchecked-impossible.check
new file mode 100644
index 0000000000..75fc390fa8
--- /dev/null
+++ b/test/files/neg/unchecked-impossible.check
@@ -0,0 +1,6 @@
+unchecked-impossible.scala:5: warning: fruitless type test: a value of type T2[Int,Int] cannot also be a Seq[A]
+ case Seq(x) =>
+ ^
+error: No warnings can be incurred under -Xfatal-warnings.
+one warning found
+one error found
diff --git a/test/files/neg/unchecked-impossible.flags b/test/files/neg/unchecked-impossible.flags
new file mode 100644
index 0000000000..85d8eb2ba2
--- /dev/null
+++ b/test/files/neg/unchecked-impossible.flags
@@ -0,0 +1 @@
+-Xfatal-warnings
diff --git a/test/files/neg/unchecked-impossible.scala b/test/files/neg/unchecked-impossible.scala
new file mode 100644
index 0000000000..985a2d0b08
--- /dev/null
+++ b/test/files/neg/unchecked-impossible.scala
@@ -0,0 +1,16 @@
+final case class T2[+A, +B](a: A, b: B)
+
+class A {
+ def f1 = T2(1, 2) match {
+ case Seq(x) =>
+ case _ =>
+ }
+ def f2 = T2(1, 2) match {
+ case _: T2[Int, Int] => /* nowarn */
+ case _ =>
+ }
+ def f3 = T2(1, 2) match {
+ case _: T2[_, Int] => /* nowarn */
+ case _ =>
+ }
+}
diff --git a/test/files/neg/unchecked-knowable.check b/test/files/neg/unchecked-knowable.check
new file mode 100644
index 0000000000..28e2d67920
--- /dev/null
+++ b/test/files/neg/unchecked-knowable.check
@@ -0,0 +1,6 @@
+unchecked-knowable.scala:17: warning: fruitless type test: a value of type Bippy cannot also be a A1
+ /* warn */ (new Bippy).isInstanceOf[A1]
+ ^
+error: No warnings can be incurred under -Xfatal-warnings.
+one warning found
+one error found
diff --git a/test/files/neg/unchecked-knowable.flags b/test/files/neg/unchecked-knowable.flags
new file mode 100644
index 0000000000..85d8eb2ba2
--- /dev/null
+++ b/test/files/neg/unchecked-knowable.flags
@@ -0,0 +1 @@
+-Xfatal-warnings
diff --git a/test/files/neg/unchecked-knowable.scala b/test/files/neg/unchecked-knowable.scala
new file mode 100644
index 0000000000..667b47f504
--- /dev/null
+++ b/test/files/neg/unchecked-knowable.scala
@@ -0,0 +1,20 @@
+/** Knowable - only final leaves */
+sealed abstract class A1
+sealed abstract class A2 extends A1
+final class A3 extends A1
+final class A4 extends A2
+
+/** Unknowable */
+sealed abstract class B1
+sealed abstract class B2 extends B1
+final class B3 extends B1
+trait B4 extends B2
+
+class Bippy
+trait Dingus
+
+class A {
+ /* warn */ (new Bippy).isInstanceOf[A1]
+ /* nowarn */ (new Bippy).isInstanceOf[B1]
+ /* nowarn */ ((new Bippy): Any).isInstanceOf[A1]
+}
diff --git a/test/files/neg/unchecked-refinement.check b/test/files/neg/unchecked-refinement.check
new file mode 100644
index 0000000000..e85a51f44d
--- /dev/null
+++ b/test/files/neg/unchecked-refinement.check
@@ -0,0 +1,15 @@
+unchecked-refinement.scala:17: warning: abstract type U in type pattern Foo[U,U,V] is unchecked since it is eliminated by erasure
+ /* warn */ case _: Foo[U, U, V] if b => ()
+ ^
+unchecked-refinement.scala:19: warning: non-variable type argument Any in type pattern Foo[Any,U,V] is unchecked since it is eliminated by erasure
+ /* warn */ case _: Foo[Any, U, V] if b => ()
+ ^
+unchecked-refinement.scala:23: warning: a pattern match on a refinement type is unchecked
+ /* nowarn - todo */ case x: AnyRef { def bippy: Int } if b => x.bippy // this could/should do an instance check and not warn
+ ^
+unchecked-refinement.scala:24: warning: a pattern match on a refinement type is unchecked
+ /* nowarn - todo */ case x: AnyRef { def size: Int } if b => x.size // this could/should do a static conformance test and not warn
+ ^
+error: No warnings can be incurred under -Xfatal-warnings.
+four warnings found
+one error found
diff --git a/test/files/neg/unchecked-refinement.flags b/test/files/neg/unchecked-refinement.flags
new file mode 100644
index 0000000000..85d8eb2ba2
--- /dev/null
+++ b/test/files/neg/unchecked-refinement.flags
@@ -0,0 +1 @@
+-Xfatal-warnings
diff --git a/test/files/neg/unchecked-refinement.scala b/test/files/neg/unchecked-refinement.scala
new file mode 100644
index 0000000000..79ed7f13c1
--- /dev/null
+++ b/test/files/neg/unchecked-refinement.scala
@@ -0,0 +1,27 @@
+// a.scala
+// Thu Sep 27 09:42:16 PDT 2012
+
+trait Bar[-T1, T2, +T3] { }
+trait Foo[-T1, T2, +T3] extends Bar[T1, T2, T3]
+
+class A {
+ var b = true
+
+ def f1(x: Foo[Int, Int, Int]) = x match {
+ /* nowarn */ case _: Foo[Nothing, Int, Any] => true
+ }
+ def f2[T, U, V](x: Foo[T, U, V]) = x match {
+ /* nowarn */ case _: Foo[Nothing, U, Any] => true
+ }
+ def f3[T, U, V](x: Foo[T, U, V]) = x match {
+ /* warn */ case _: Foo[U, U, V] if b => ()
+ /* nowarn */ case _: Foo[Nothing, U, V] if b => ()
+ /* warn */ case _: Foo[Any, U, V] if b => ()
+ }
+
+ def f4(xs: List[Int]) = xs match {
+ /* nowarn - todo */ case x: AnyRef { def bippy: Int } if b => x.bippy // this could/should do an instance check and not warn
+ /* nowarn - todo */ case x: AnyRef { def size: Int } if b => x.size // this could/should do a static conformance test and not warn
+ /* nowarn */ case x: ((AnyRef { def size: Int }) @unchecked) if b => x.size
+ }
+}
diff --git a/test/files/neg/unchecked.check b/test/files/neg/unchecked.check
index 19b8c908da..570f02f219 100644
--- a/test/files/neg/unchecked.check
+++ b/test/files/neg/unchecked.check
@@ -2,7 +2,7 @@ unchecked.scala:18: warning: non-variable type argument String in type pattern I
case xs: Iterable[String] => xs.head // unchecked
^
unchecked.scala:22: warning: non-variable type argument Any in type pattern Set[Any] is unchecked since it is eliminated by erasure
- case xs: Set[Any] => xs.head // unchecked
+ case xs: Set[Any] => xs.head // unchecked
^
unchecked.scala:26: warning: non-variable type argument Any in type pattern Map[Any,Any] is unchecked since it is eliminated by erasure
case xs: Map[Any, Any] => xs.head // unchecked
diff --git a/test/files/neg/unchecked.scala b/test/files/neg/unchecked.scala
index b50cdf9d7a..e491b253ba 100644
--- a/test/files/neg/unchecked.scala
+++ b/test/files/neg/unchecked.scala
@@ -19,8 +19,8 @@ object Test {
case _ => 0
}
def f3(x: Any) = x match {
- case xs: Set[Any] => xs.head // unchecked
- case _ => 0
+ case xs: Set[Any] => xs.head // unchecked
+ case _ => 0
}
def f4(x: Any) = x match {
case xs: Map[Any, Any] => xs.head // unchecked
diff --git a/test/files/neg/unchecked2.check b/test/files/neg/unchecked2.check
index 599d11c43a..a7b8391856 100644
--- a/test/files/neg/unchecked2.check
+++ b/test/files/neg/unchecked2.check
@@ -1,21 +1,45 @@
-unchecked2.scala:2: warning: non-variable type argument Int in type Option[Int] is unchecked since it is eliminated by erasure
- Some(123).isInstanceOf[Option[Int]]
- ^
-unchecked2.scala:3: warning: non-variable type argument String in type Option[String] is unchecked since it is eliminated by erasure
- Some(123).isInstanceOf[Option[String]]
- ^
-unchecked2.scala:4: warning: non-variable type argument List[String] in type Option[List[String]] is unchecked since it is eliminated by erasure
- Some(123).isInstanceOf[Option[List[String]]]
- ^
-unchecked2.scala:5: warning: non-variable type argument List[Int => String] in type Option[List[Int => String]] is unchecked since it is eliminated by erasure
- Some(123).isInstanceOf[Option[List[Int => String]]]
- ^
-unchecked2.scala:6: warning: non-variable type argument (String, Double) in type Option[(String, Double)] is unchecked since it is eliminated by erasure
- Some(123).isInstanceOf[Option[(String, Double)]]
- ^
-unchecked2.scala:7: warning: non-variable type argument String => Double in type Option[String => Double] is unchecked since it is eliminated by erasure
- Some(123).isInstanceOf[Option[String => Double]]
- ^
+unchecked2.scala:4: warning: fruitless type test: a value of type Some[List[Int]] cannot also be a Option[List[String]] (but still might match its erasure)
+ /* warn */ Some(List(1)).isInstanceOf[Option[List[String]]]
+ ^
+unchecked2.scala:5: warning: non-variable type argument Option[_] in type Option[Option[_]] is unchecked since it is eliminated by erasure
+ /* warn */ Some(123).isInstanceOf[Option[Option[_]]]
+ ^
+unchecked2.scala:6: warning: fruitless type test: a value of type Some[Int] cannot also be a Option[String] (but still might match its erasure)
+ /* warn */ Some(123).isInstanceOf[Option[String]]
+ ^
+unchecked2.scala:7: warning: fruitless type test: a value of type Some[Int] cannot also be a Option[List[String]] (but still might match its erasure)
+ /* warn */ Some(123).isInstanceOf[Option[List[String]]]
+ ^
+unchecked2.scala:8: warning: fruitless type test: a value of type Some[Int] cannot also be a Option[List[Int => String]] (but still might match its erasure)
+ /* warn */ Some(123).isInstanceOf[Option[List[Int => String]]]
+ ^
+unchecked2.scala:9: warning: fruitless type test: a value of type Some[Int] cannot also be a Option[(String, Double)] (but still might match its erasure)
+ /* warn */ Some(123).isInstanceOf[Option[(String, Double)]]
+ ^
+unchecked2.scala:10: warning: fruitless type test: a value of type Some[Int] cannot also be a Option[String => Double] (but still might match its erasure)
+ /* warn */ Some(123).isInstanceOf[Option[String => Double]]
+ ^
+unchecked2.scala:14: warning: non-variable type argument List[String] in type Option[List[String]] is unchecked since it is eliminated by erasure
+ /* warn */ (Some(List(1)): Any).isInstanceOf[Option[List[String]]]
+ ^
+unchecked2.scala:15: warning: non-variable type argument Int in type Option[Int] is unchecked since it is eliminated by erasure
+ /* warn */ (Some(123): Any).isInstanceOf[Option[Int]]
+ ^
+unchecked2.scala:16: warning: non-variable type argument String in type Option[String] is unchecked since it is eliminated by erasure
+ /* warn */ (Some(123): Any).isInstanceOf[Option[String]]
+ ^
+unchecked2.scala:17: warning: non-variable type argument List[String] in type Option[List[String]] is unchecked since it is eliminated by erasure
+ /* warn */ (Some(123): Any).isInstanceOf[Option[List[String]]]
+ ^
+unchecked2.scala:18: warning: non-variable type argument List[Int => String] in type Option[List[Int => String]] is unchecked since it is eliminated by erasure
+ /* warn */ (Some(123): Any).isInstanceOf[Option[List[Int => String]]]
+ ^
+unchecked2.scala:19: warning: non-variable type argument (String, Double) in type Option[(String, Double)] is unchecked since it is eliminated by erasure
+ /* warn */ (Some(123): Any).isInstanceOf[Option[(String, Double)]]
+ ^
+unchecked2.scala:20: warning: non-variable type argument String => Double in type Option[String => Double] is unchecked since it is eliminated by erasure
+ /* warn */ (Some(123): Any).isInstanceOf[Option[String => Double]]
+ ^
error: No warnings can be incurred under -Xfatal-warnings.
-6 warnings found
+14 warnings found
one error found
diff --git a/test/files/neg/unchecked2.scala b/test/files/neg/unchecked2.scala
index a2e757e1dc..616b05aad8 100644
--- a/test/files/neg/unchecked2.scala
+++ b/test/files/neg/unchecked2.scala
@@ -1,8 +1,33 @@
object Test {
- Some(123).isInstanceOf[Option[Int]]
- Some(123).isInstanceOf[Option[String]]
- Some(123).isInstanceOf[Option[List[String]]]
- Some(123).isInstanceOf[Option[List[Int => String]]]
- Some(123).isInstanceOf[Option[(String, Double)]]
- Some(123).isInstanceOf[Option[String => Double]]
+ // These warn because it can be statically shown they won't match.
+
+ /* warn */ Some(List(1)).isInstanceOf[Option[List[String]]]
+ /* warn */ Some(123).isInstanceOf[Option[Option[_]]]
+ /* warn */ Some(123).isInstanceOf[Option[String]]
+ /* warn */ Some(123).isInstanceOf[Option[List[String]]]
+ /* warn */ Some(123).isInstanceOf[Option[List[Int => String]]]
+ /* warn */ Some(123).isInstanceOf[Option[(String, Double)]]
+ /* warn */ Some(123).isInstanceOf[Option[String => Double]]
+
+ // These warn because you can't check at runtime.
+
+ /* warn */ (Some(List(1)): Any).isInstanceOf[Option[List[String]]]
+ /* warn */ (Some(123): Any).isInstanceOf[Option[Int]]
+ /* warn */ (Some(123): Any).isInstanceOf[Option[String]]
+ /* warn */ (Some(123): Any).isInstanceOf[Option[List[String]]]
+ /* warn */ (Some(123): Any).isInstanceOf[Option[List[Int => String]]]
+ /* warn */ (Some(123): Any).isInstanceOf[Option[(String, Double)]]
+ /* warn */ (Some(123): Any).isInstanceOf[Option[String => Double]]
+
+ // These don't warn.
+
+ /* nowarn */ Some(List(1)).isInstanceOf[Option[List[Int]]]
+ /* nowarn */ Some(123).isInstanceOf[Option[Int]]
+ /* nowarn */ Some(123).isInstanceOf[Some[Int]]
+ /* nowarn */ Some(123).isInstanceOf[AnyRef]
+
+ /* nowarn */ (Some(List(1)): Any).isInstanceOf[Option[_]]
+ /* nowarn */ (Some(123): Any).isInstanceOf[Option[_]]
+ /* nowarn */ (Some(123): Any).isInstanceOf[Some[_]]
+ /* nowarn */ (Some(123): Any).isInstanceOf[AnyRef]
}
diff --git a/test/files/neg/unchecked3.check b/test/files/neg/unchecked3.check
new file mode 100644
index 0000000000..a7582a8930
--- /dev/null
+++ b/test/files/neg/unchecked3.check
@@ -0,0 +1,42 @@
+unchecked3.scala:24: warning: non-variable type argument Double in type pattern E1[Double] is unchecked since it is eliminated by erasure
+ /* warn */ def peerTypes2(x: B1[Int]) = x match { case _: E1[Double] => true }
+ ^
+unchecked3.scala:25: warning: non-variable type argument Double in type pattern F1[Double] is unchecked since it is eliminated by erasure
+ /* warn */ def peerTypes3(x: B1[_]) = x match { case _: F1[Double] => true }
+ ^
+unchecked3.scala:28: warning: non-variable type argument Int in type pattern A2[Int] is unchecked since it is eliminated by erasure
+ /* warn */ def twotypes1[T](x: B2[T, Int]) = x match { case _: A2[Int] => true }
+ ^
+unchecked3.scala:32: warning: non-variable type argument Int in type pattern B2[_,Int] is unchecked since it is eliminated by erasure
+ /* warn */ def twotypes5[T](x: A2[T]) = x match { case _: B2[_, Int] => true }
+ ^
+unchecked3.scala:40: warning: non-variable type argument String in type pattern Array[List[String]] is unchecked since it is eliminated by erasure
+ /* warn */ case _: Array[List[String]] => ()
+ ^
+unchecked3.scala:43: warning: non-variable type argument String in type pattern Array[Array[List[String]]] is unchecked since it is eliminated by erasure
+ /* warn */ case _: Array[Array[List[String]]] => ()
+ ^
+unchecked3.scala:50: warning: non-variable type argument String in type pattern Array[List[String]] is unchecked since it is eliminated by erasure
+ /* warn */ case _: Array[List[String]] => ()
+ ^
+unchecked3.scala:53: warning: non-variable type argument String in type pattern Array[Array[List[String]]] is unchecked since it is eliminated by erasure
+ /* warn */ case _: Array[Array[List[String]]] => ()
+ ^
+unchecked3.scala:60: warning: non-variable type argument String in type pattern Array[List[String]] is unchecked since it is eliminated by erasure
+ /* warn */ case _: Array[List[String]] => ()
+ ^
+unchecked3.scala:62: warning: non-variable type argument Array[String] in type pattern Array[List[Array[String]]] is unchecked since it is eliminated by erasure
+ /* warn */ case _: Array[List[Array[String]]] => ()
+ ^
+unchecked3.scala:63: warning: non-variable type argument String in type pattern Array[Array[List[String]]] is unchecked since it is eliminated by erasure
+ /* warn */ case _: Array[Array[List[String]]] => ()
+ ^
+unchecked3.scala:75: warning: abstract type A in type pattern Set[Q.this.A] is unchecked since it is eliminated by erasure
+ /* warn */ case xs: Set[A] => xs.head
+ ^
+unchecked3.scala:62: warning: unreachable code
+ /* warn */ case _: Array[List[Array[String]]] => ()
+ ^
+error: No warnings can be incurred under -Xfatal-warnings.
+13 warnings found
+one error found
diff --git a/test/files/neg/unchecked3.flags b/test/files/neg/unchecked3.flags
new file mode 100644
index 0000000000..85d8eb2ba2
--- /dev/null
+++ b/test/files/neg/unchecked3.flags
@@ -0,0 +1 @@
+-Xfatal-warnings
diff --git a/test/files/neg/unchecked3.scala b/test/files/neg/unchecked3.scala
new file mode 100644
index 0000000000..7b8c13e8f8
--- /dev/null
+++ b/test/files/neg/unchecked3.scala
@@ -0,0 +1,83 @@
+sealed trait A2[T1]
+final class B2[T1, T2] extends A2[T1]
+
+sealed trait A[T]
+final class B[T] extends A[T]
+
+sealed trait A1[T]
+trait B1[T] extends A1[T]
+trait C1[T] extends A1[T]
+trait D1[T] extends A1[Int]
+trait E1[T] extends B1[Int]
+trait F1[T] extends B1[T]
+
+object MiscUnchecked {
+ /* nowarn */ def knownType1(x: A[Int]) = x match { case _: B[Int] if true => 1 }
+ /* nowarn */ def knownType2(x: B[Int]) = x match { case _: A[Int] if true => 1 }
+ /* nowarn */ def tparamLeakage1(x: Any) = x match { case Array() => 1 }
+ /* nowarn */ def tparamLeakage2(x: Any) = x match { case List() => 1 }
+
+ // E1[Double] implies B1[Int], but B1[Int] does not imply E1[Double], even if .isInstanceOf[E1[_]]
+ // F1[Int] implies B1[Int], and B1[Int] implies F1[Int]
+
+ /* nowarn */ def peerTypes1(x: B1[Int]) = x match { case _: C1[Int] => true }
+ /* warn */ def peerTypes2(x: B1[Int]) = x match { case _: E1[Double] => true }
+ /* warn */ def peerTypes3(x: B1[_]) = x match { case _: F1[Double] => true }
+ /* nowarn */ def peerTypes4(x: B1[Int]) = x match { case _: F1[Int] => true }
+
+ /* warn */ def twotypes1[T](x: B2[T, Int]) = x match { case _: A2[Int] => true }
+ /* nowarn */ def twotypes2[T](x: B2[Int, T]) = x match { case _: A2[Int] => true }
+ /* nowarn */ def twotypes3(x: A2[Int]) = x match { case _: B2[Int, _] => true }
+ /* nowarn */ def twotypes4[T](x: A2[T]) = x match { case _: B2[T, _] => true }
+ /* warn */ def twotypes5[T](x: A2[T]) = x match { case _: B2[_, Int] => true }
+}
+
+object Arrays {
+ def f1(x: Any) = x match {
+ /* nowarn */ case _: Array[Int] => ()
+ /* nowarn */ case _: Array[Boolean] => ()
+ /* nowarn */ case _: Array[String] => ()
+ /* warn */ case _: Array[List[String]] => ()
+ /* nowarn */ case _: Array[Array[String]] => ()
+ /* nowarn */ case _: Array[Array[Array[String]]] => ()
+ /* warn */ case _: Array[Array[List[String]]] => ()
+ }
+
+ def f2(x: Array[_]) = x match {
+ /* nowarn */ case _: Array[Int] => ()
+ /* nowarn */ case _: Array[Boolean] => ()
+ /* nowarn */ case _: Array[String] => ()
+ /* warn */ case _: Array[List[String]] => ()
+ /* nowarn */ case _: Array[Array[String]] => ()
+ /* nowarn */ case _: Array[Array[Array[String]]] => ()
+ /* warn */ case _: Array[Array[List[String]]] => ()
+ }
+
+ def f3[T](x: Array[T]) = x match {
+ /* nowarn */ case _: Array[Int] => ()
+ /* nowarn */ case _: Array[Boolean] => ()
+ /* nowarn */ case _: Array[String] => ()
+ /* warn */ case _: Array[List[String]] => ()
+ /* nowarn */ case _: Array[Array[String]] => ()
+ /* warn */ case _: Array[List[Array[String]]] => ()
+ /* warn */ case _: Array[Array[List[String]]] => ()
+ }
+}
+
+object Matching {
+ class Q {
+ type A
+ type B <: A
+
+ def f(xs: Traversable[B]) = xs match {
+ /* nowarn */ case xs: List[A] => xs.head
+ /* nowarn */ case xs: Seq[B] => xs.head
+ /* warn */ case xs: Set[A] => xs.head
+ }
+ def f2[T <: B](xs: Traversable[T]) = xs match {
+ /* nowarn */ case xs: List[B with T] => xs.head
+ /* nowarn */ case xs: Seq[A] => xs.head
+ /* nowarn */ case xs: Set[T] => xs.head
+ }
+ }
+}
diff --git a/test/files/pos/t1107/O.scala b/test/files/pos/t1107b/O.scala
index aa605a6d09..aa605a6d09 100644
--- a/test/files/pos/t1107/O.scala
+++ b/test/files/pos/t1107b/O.scala
diff --git a/test/files/pos/t1107/T.scala b/test/files/pos/t1107b/T.scala
index 1f3712d529..1f3712d529 100644
--- a/test/files/pos/t1107/T.scala
+++ b/test/files/pos/t1107b/T.scala
diff --git a/test/files/pos/t1203/J.java b/test/files/pos/t1203b/J.java
index 7fae118e04..7fae118e04 100644
--- a/test/files/pos/t1203/J.java
+++ b/test/files/pos/t1203b/J.java
diff --git a/test/files/pos/t1203/S.scala b/test/files/pos/t1203b/S.scala
index 68eac4bf6d..68eac4bf6d 100644
--- a/test/files/pos/t1203/S.scala
+++ b/test/files/pos/t1203b/S.scala
diff --git a/test/files/pos/t6275.flags b/test/files/pos/t6275.flags
new file mode 100644
index 0000000000..85d8eb2ba2
--- /dev/null
+++ b/test/files/pos/t6275.flags
@@ -0,0 +1 @@
+-Xfatal-warnings
diff --git a/test/files/pos/t6275.scala b/test/files/pos/t6275.scala
new file mode 100644
index 0000000000..6b5ec7dceb
--- /dev/null
+++ b/test/files/pos/t6275.scala
@@ -0,0 +1,11 @@
+
+sealed trait A[T]
+final class B[T] extends A[T]
+
+object ParsedAxis {
+ type BI = B[Int]
+
+ def f1(a: A[Int]) = a match { case b: B[Int] => 3 }
+ def f2(a: A[Int]) = a match { case b: BI => 3 }
+ def f3(a: A[Int]) = a match { case b: B[t] => 3 }
+}
diff --git a/test/files/run/macro-openmacros/Impls_Macros_1.scala b/test/files/run/macro-openmacros/Impls_Macros_1.scala
index 38d46c5185..b863ac048b 100644
--- a/test/files/run/macro-openmacros/Impls_Macros_1.scala
+++ b/test/files/run/macro-openmacros/Impls_Macros_1.scala
@@ -4,8 +4,7 @@ object Macros {
def impl(c: Context): c.Expr[Unit] = {
// we're macros, so we can reflect against our source path
// so we don't need any partests to clean up after us!
- val c.CompilationUnit(file, _, _) = c.enclosingUnit
- val dir = file.getCanonicalFile.getParentFile
+ val dir = c.enclosingUnit.source.file.file.getCanonicalFile.getParentFile
def normalizePaths(s: String) = {
val base = (dir.getCanonicalPath + java.io.File.separator).replace('\\', '/')
var regex = """\Q%s\E""" format base
diff --git a/test/files/run/macro-reify-nested-a/Impls_Macros_1.scala b/test/files/run/macro-reify-nested-a/Impls_Macros_1.scala
index ae2def2d3e..b4351c2c53 100644
--- a/test/files/run/macro-reify-nested-a/Impls_Macros_1.scala
+++ b/test/files/run/macro-reify-nested-a/Impls_Macros_1.scala
@@ -23,9 +23,10 @@ case class Utils[C <: Context]( c:C ) {
object QueryableMacros{
def _helper[C <: Context,S:c.WeakTypeTag]( c:C )( name:String, projection:c.Expr[_] ) = {
import c.universe._
+ import treeBuild._
val element_type = implicitly[c.WeakTypeTag[S]].tpe
val foo = c.Expr[ru.Expr[Queryable[S]]](
- c.reifyTree( c.runtimeUniverse, EmptyTree, c.typeCheck(
+ c.reifyTree( mkRuntimeUniverseRef, EmptyTree, c.typeCheck(
Utils[c.type](c).removeDoubleReify(
Apply(Select(c.prefix.tree, newTermName( name )), List( projection.tree ))
).asInstanceOf[Tree]
diff --git a/test/files/run/macro-reify-nested-b/Impls_Macros_1.scala b/test/files/run/macro-reify-nested-b/Impls_Macros_1.scala
index ae2def2d3e..b4351c2c53 100644
--- a/test/files/run/macro-reify-nested-b/Impls_Macros_1.scala
+++ b/test/files/run/macro-reify-nested-b/Impls_Macros_1.scala
@@ -23,9 +23,10 @@ case class Utils[C <: Context]( c:C ) {
object QueryableMacros{
def _helper[C <: Context,S:c.WeakTypeTag]( c:C )( name:String, projection:c.Expr[_] ) = {
import c.universe._
+ import treeBuild._
val element_type = implicitly[c.WeakTypeTag[S]].tpe
val foo = c.Expr[ru.Expr[Queryable[S]]](
- c.reifyTree( c.runtimeUniverse, EmptyTree, c.typeCheck(
+ c.reifyTree( mkRuntimeUniverseRef, EmptyTree, c.typeCheck(
Utils[c.type](c).removeDoubleReify(
Apply(Select(c.prefix.tree, newTermName( name )), List( projection.tree ))
).asInstanceOf[Tree]
diff --git a/test/files/run/macro-reify-splice-outside-reify/Impls_Macros_1.scala b/test/files/run/macro-reify-splice-outside-reify/Impls_Macros_1.scala
index b23a5c70e1..5330d0e32b 100644
--- a/test/files/run/macro-reify-splice-outside-reify/Impls_Macros_1.scala
+++ b/test/files/run/macro-reify-splice-outside-reify/Impls_Macros_1.scala
@@ -4,18 +4,7 @@ object Impls {
def foo(c: Ctx)(x: c.Expr[Int]) = {
val x1 = c.Expr[Int](c.resetAllAttrs(x.tree))
// was: c.literal(x1.splice)
- c.literal(eval(c)(x1))
- }
-
- private def eval[T](c: Ctx)(x: c.Expr[T]): T = {
- import scala.reflect.runtime.{universe => ru}
- val mirror = ru.runtimeMirror(c.libraryClassLoader)
- import scala.tools.reflect.ToolBox
- val toolBox = mirror.mkToolBox()
- val importer = ru.mkImporter(c.universe).asInstanceOf[ru.Importer { val from: c.universe.type }]
- val tree = c.resetAllAttrs(x.tree.duplicate)
- val imported = importer.importTree(tree)
- toolBox.eval(imported).asInstanceOf[T]
+ c.literal(c.eval(x1))
}
}
diff --git a/test/files/run/macro-reify-unreify/Macros_1.scala b/test/files/run/macro-reify-unreify/Macros_1.scala
index 620a929210..9f04c13014 100644
--- a/test/files/run/macro-reify-unreify/Macros_1.scala
+++ b/test/files/run/macro-reify-unreify/Macros_1.scala
@@ -6,9 +6,10 @@ object Macros {
object Impls {
def foo(c: Ctx)(s: c.Expr[String]) = {
import c.universe._
+ import treeBuild._
- val world = c.reifyTree(c.runtimeUniverse, EmptyTree, s.tree)
- val greeting = c.reifyTree(c.runtimeUniverse, EmptyTree, c.typeCheck(Apply(Select(Literal(Constant("hello ")), newTermName("$plus")), List(c.unreifyTree(world)))))
+ val world = c.reifyTree(mkRuntimeUniverseRef, EmptyTree, s.tree)
+ val greeting = c.reifyTree(mkRuntimeUniverseRef, EmptyTree, c.typeCheck(Apply(Select(Literal(Constant("hello ")), newTermName("$plus")), List(c.unreifyTree(world)))))
val typedGreeting = c.Expr[String](greeting)
c.universe.reify {
diff --git a/test/files/run/macro-sip19-revised/Impls_Macros_1.scala b/test/files/run/macro-sip19-revised/Impls_Macros_1.scala
index 0793696fd4..5f3f61ca3f 100644
--- a/test/files/run/macro-sip19-revised/Impls_Macros_1.scala
+++ b/test/files/run/macro-sip19-revised/Impls_Macros_1.scala
@@ -8,7 +8,7 @@ object Macros {
val outer = c.Expr[SourceLocation](if (!inscope.isEmpty) inscope else Literal(Constant(null)))
val Apply(fun, args) = c.enclosingImplicits(0)._2
- val fileName = fun.pos.fileInfo.getName
+ val fileName = fun.pos.source.file.file.getName
val line = fun.pos.line
val charOffset = fun.pos.point
c.universe.reify { SourceLocation1(outer.splice, c.literal(fileName).splice, c.literal(line).splice, c.literal(charOffset).splice) }
diff --git a/test/files/run/macro-sip19/Impls_Macros_1.scala b/test/files/run/macro-sip19/Impls_Macros_1.scala
index f89e51f560..535ec2ccf0 100644
--- a/test/files/run/macro-sip19/Impls_Macros_1.scala
+++ b/test/files/run/macro-sip19/Impls_Macros_1.scala
@@ -4,7 +4,7 @@ object Macros {
def impl(c: Context) = {
import c.universe._
val Apply(fun, args) = c.enclosingImplicits(0)._2
- val fileName = fun.pos.fileInfo.getName
+ val fileName = fun.pos.source.file.file.getName
val line = fun.pos.line
val charOffset = fun.pos.point
c.universe.reify { SourceLocation(c.literal(fileName).splice, c.literal(line).splice, c.literal(charOffset).splice) }
diff --git a/test/files/run/macro-typecheck-macrosdisabled.check b/test/files/run/macro-typecheck-macrosdisabled.check
index 719c6a2ef2..29a881f8b1 100644
--- a/test/files/run/macro-typecheck-macrosdisabled.check
+++ b/test/files/run/macro-typecheck-macrosdisabled.check
@@ -7,7 +7,7 @@
$treecreator1.super.<init>();
()
};
- def apply[U >: Nothing <: scala.reflect.api.Universe with Singleton]($m$untyped: scala.reflect.api.MirrorOf[U]): U#Tree = {
+ def apply[U >: Nothing <: scala.reflect.api.Universe with Singleton]($m$untyped: scala.reflect.api.Mirror[U]): U#Tree = {
val $u: U = $m$untyped.universe;
val $m: $u.Mirror = $m$untyped.asInstanceOf[$u.Mirror];
$u.Literal.apply($u.Constant.apply(2))
@@ -20,7 +20,7 @@
$typecreator2.super.<init>();
()
};
- def apply[U >: Nothing <: scala.reflect.api.Universe with Singleton]($m$untyped: scala.reflect.api.MirrorOf[U]): U#Type = {
+ def apply[U >: Nothing <: scala.reflect.api.Universe with Singleton]($m$untyped: scala.reflect.api.Mirror[U]): U#Type = {
val $u: U = $m$untyped.universe;
val $m: $u.Mirror = $m$untyped.asInstanceOf[$u.Mirror];
$u.ConstantType.apply($u.Constant.apply(2))
diff --git a/test/files/run/macro-typecheck-macrosdisabled2.check b/test/files/run/macro-typecheck-macrosdisabled2.check
index 1fd422083c..7bdd1d6a3a 100644
--- a/test/files/run/macro-typecheck-macrosdisabled2.check
+++ b/test/files/run/macro-typecheck-macrosdisabled2.check
@@ -7,7 +7,7 @@
$treecreator1.super.<init>();
()
};
- def apply[U >: Nothing <: scala.reflect.api.Universe with Singleton]($m$untyped: scala.reflect.api.MirrorOf[U]): U#Tree = {
+ def apply[U >: Nothing <: scala.reflect.api.Universe with Singleton]($m$untyped: scala.reflect.api.Mirror[U]): U#Tree = {
val $u: U = $m$untyped.universe;
val $m: $u.Mirror = $m$untyped.asInstanceOf[$u.Mirror];
$u.Apply.apply($u.Select.apply($u.Select.apply($u.build.Ident($m.staticPackage("scala")), $u.newTermName("Array")), $u.newTermName("apply")), scala.collection.immutable.List.apply[$u.Literal]($u.Literal.apply($u.Constant.apply(2))))
@@ -20,7 +20,7 @@
$typecreator2.super.<init>();
()
};
- def apply[U >: Nothing <: scala.reflect.api.Universe with Singleton]($m$untyped: scala.reflect.api.MirrorOf[U]): U#Type = {
+ def apply[U >: Nothing <: scala.reflect.api.Universe with Singleton]($m$untyped: scala.reflect.api.Mirror[U]): U#Type = {
val $u: U = $m$untyped.universe;
val $m: $u.Mirror = $m$untyped.asInstanceOf[$u.Mirror];
$u.TypeRef.apply($u.ThisType.apply($m.staticPackage("scala").asModule.moduleClass), $m.staticClass("scala.Array"), scala.collection.immutable.List.apply[$u.Type]($m.staticClass("scala.Int").asType.toTypeConstructor))
diff --git a/test/files/run/t576.scala b/test/files/run/t576.scala
index dc09d8dc98..756a241572 100644
--- a/test/files/run/t576.scala
+++ b/test/files/run/t576.scala
@@ -12,7 +12,7 @@ object Dingus {
object Test {
val x1 = new A
val x2 = new A
-
+
val x3 = new { self =>
override def equals(other : Any) = other match {
case that: self.type => true
@@ -20,7 +20,7 @@ object Test {
}
}
val x4 = new { self =>
- def f(x: Any) = x match {
+ def f(x: Any): Int = x match {
case _: x1.type => 1
case _: x2.type => 2
case _: x3.type => 3
@@ -35,11 +35,11 @@ object Test {
assert(x1 != x2)
assert(x1 != ())
assert(x2 != x1)
-
+
assert(x3 == x3)
assert(x3 != x2)
assert(x2 != x3)
-
+
List(x1, x2, x3, x4, Dingus) map x4.f foreach println
}
-} \ No newline at end of file
+}
diff --git a/test/files/run/toolbox_console_reporter.check b/test/files/run/toolbox_console_reporter.check
index e69de29bb2..1395c68740 100644
--- a/test/files/run/toolbox_console_reporter.check
+++ b/test/files/run/toolbox_console_reporter.check
@@ -0,0 +1,8 @@
+hello
+============compiler console=============
+warning: method foo in object Utils is deprecated: test
+
+=========================================
+============compiler messages============
+Info(NoPosition,method foo in object Utils is deprecated: test,WARNING)
+=========================================
diff --git a/test/files/run/toolbox_console_reporter.scala b/test/files/run/toolbox_console_reporter.scala
index a57dea38a8..d672ccb9cb 100644
--- a/test/files/run/toolbox_console_reporter.scala
+++ b/test/files/run/toolbox_console_reporter.scala
@@ -1,16 +1,29 @@
import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{universe => ru}
+import scala.reflect.runtime.{currentMirror => cm}
+import scala.tools.reflect.{ToolBox, mkConsoleFrontEnd}
object Test extends App {
- // todo. cannot test this unfortunately, because ConsoleFrontEnd grabs Console.out too early
- // todo. and isn't affected by Console.setOut employed by partest to intercept output
+ val oldErr = Console.err;
+ val baos = new java.io.ByteArrayOutputStream();
+ Console.setErr(new java.io.PrintStream(baos));
+ try {
+ val toolbox = cm.mkToolBox(frontEnd = mkConsoleFrontEnd(), options = "-deprecation")
+ toolbox.eval(reify{
+ object Utils {
+ @deprecated("test", "2.10.0")
+ def foo { println("hello") }
+ }
- //val toolbox = mkToolBox(frontEnd = mkConsoleFrontEnd(), options = "-deprecation")
- //toolbox.eval(reify{
- // object Utils {
- // @deprecated("test", "2.10.0")
- // def foo { println("hello") }
- // }
- //
- // Utils.foo
- //})
+ Utils.foo
+ }.tree)
+ println("============compiler console=============")
+ println(baos.toString);
+ println("=========================================")
+ println("============compiler messages============")
+ toolbox.frontEnd.infos.foreach(println(_))
+ println("=========================================")
+ } finally {
+ Console.setErr(oldErr);
+ }
} \ No newline at end of file
diff --git a/test/files/run/toolbox_silent_reporter.scala b/test/files/run/toolbox_silent_reporter.scala
index 15f559d605..03b1d6defa 100644
--- a/test/files/run/toolbox_silent_reporter.scala
+++ b/test/files/run/toolbox_silent_reporter.scala
@@ -1,10 +1,10 @@
import scala.reflect.runtime.universe._
import scala.reflect.runtime.{universe => ru}
import scala.reflect.runtime.{currentMirror => cm}
-import scala.tools.reflect.ToolBox
+import scala.tools.reflect.{ToolBox, mkSilentFrontEnd}
object Test extends App {
- val toolbox = cm.mkToolBox(options = "-deprecation")
+ val toolbox = cm.mkToolBox(options = "-deprecation", frontEnd = mkSilentFrontEnd())
toolbox.eval(reify{
object Utils {
@deprecated("test", "2.10.0")
diff --git a/test/files/run/toolbox_typecheck_macrosdisabled.check b/test/files/run/toolbox_typecheck_macrosdisabled.check
index 9e997dafed..688f37927c 100644
--- a/test/files/run/toolbox_typecheck_macrosdisabled.check
+++ b/test/files/run/toolbox_typecheck_macrosdisabled.check
@@ -16,7 +16,7 @@
$treecreator1.super.<init>();
()
};
- def apply[U <: scala.reflect.api.Universe with Singleton]($m$untyped: scala.reflect.api.MirrorOf[U]): U#Tree = {
+ def apply[U <: scala.reflect.api.Universe with Singleton]($m$untyped: scala.reflect.api.Mirror[U]): U#Tree = {
val $u: U = $m$untyped.universe;
val $m: $u.Mirror = $m$untyped.asInstanceOf[$u.Mirror];
$u.Literal.apply($u.Constant.apply(2))
@@ -29,7 +29,7 @@
$typecreator2.super.<init>();
()
};
- def apply[U <: scala.reflect.api.Universe with Singleton]($m$untyped: scala.reflect.api.MirrorOf[U]): U#Type = {
+ def apply[U <: scala.reflect.api.Universe with Singleton]($m$untyped: scala.reflect.api.Mirror[U]): U#Type = {
val $u: U = $m$untyped.universe;
val $m: $u.Mirror = $m$untyped.asInstanceOf[$u.Mirror];
$u.ConstantType.apply($u.Constant.apply(2))
diff --git a/test/files/run/toolbox_typecheck_macrosdisabled2.check b/test/files/run/toolbox_typecheck_macrosdisabled2.check
index 16c8d6c397..f5c9b6eeab 100644
--- a/test/files/run/toolbox_typecheck_macrosdisabled2.check
+++ b/test/files/run/toolbox_typecheck_macrosdisabled2.check
@@ -16,7 +16,7 @@
$treecreator1.super.<init>();
()
};
- def apply[U <: scala.reflect.api.Universe with Singleton]($m$untyped: scala.reflect.api.MirrorOf[U]): U#Tree = {
+ def apply[U <: scala.reflect.api.Universe with Singleton]($m$untyped: scala.reflect.api.Mirror[U]): U#Tree = {
val $u: U = $m$untyped.universe;
val $m: $u.Mirror = $m$untyped.asInstanceOf[$u.Mirror];
$u.Apply.apply($u.Select.apply($u.Select.apply($u.build.Ident($m.staticPackage("scala")), $u.newTermName("Array")), $u.newTermName("apply")), scala.collection.immutable.List.apply[$u.Literal]($u.Literal.apply($u.Constant.apply(2))))
@@ -29,7 +29,7 @@
$typecreator2.super.<init>();
()
};
- def apply[U <: scala.reflect.api.Universe with Singleton]($m$untyped: scala.reflect.api.MirrorOf[U]): U#Type = {
+ def apply[U <: scala.reflect.api.Universe with Singleton]($m$untyped: scala.reflect.api.Mirror[U]): U#Type = {
val $u: U = $m$untyped.universe;
val $m: $u.Mirror = $m$untyped.asInstanceOf[$u.Mirror];
$u.TypeRef.apply($u.ThisType.apply($m.staticPackage("scala").asModule.moduleClass), $m.staticClass("scala.Array"), scala.collection.immutable.List.apply[$u.Type]($m.staticClass("scala.Int").asType.toTypeConstructor))
diff --git a/test/pending/pos/exhaust_2.scala b/test/pending/pos/exhaust_2.scala
new file mode 100644
index 0000000000..4f4e47c43b
--- /dev/null
+++ b/test/pending/pos/exhaust_2.scala
@@ -0,0 +1,54 @@
+object ExhaustivityWarnBugReportMinimal {
+ //sealed is needed for the warning
+ sealed trait FoundNode[T]/*presence of parameters is irrelevant*/
+ // This also causes a warning:
+ // sealed abstract class FoundNode[T]/*presence of parameters is irrelevant*/
+ case class FoundFilter[T](/*presence of parameters is irrelevant*/) extends FoundNode[T]
+ case class FoundTypeCase[T](/*presence of parameters is irrelevant*/) extends FoundNode[T]
+ val f: Some[_] = ???
+ f match {
+ case x: Some[t] => //no warning
+ }
+ //With these variants, no warnings:
+ //val v: (Some[Int], FoundNode[_]) = (???, ???)
+ //val v: (Some[AnyRef], FoundNode[_]) = (???, ???)
+ //val v: (Some[String], FoundNode[_]) = (???, ???)
+
+ val v: (Some[_], FoundNode[_]) = (???, ???)
+ //Warning here:
+ v match {
+ case (x: Some[t], _: FoundNode[_]) =>
+ }
+ v match {
+ case (x: Some[t], _) =>
+ }
+
+ v match {
+ case (x: Some[_], _) =>
+ }
+ case class Foo[T]()
+
+ val vp: (Foo[_], FoundNode[_]) = (???, ???)
+ vp match {
+ case (x: Foo[_], _) =>
+ }
+
+ //No warning here:
+ v match {
+ case (Some(y), _) =>
+ }
+
+ v match {
+ case (x, _) =>
+ }
+
+ val v2: (Some[_], Int) = (???, ???)
+ v2 match {
+ case (x: Some[t], _) =>
+ }
+
+ val v3: (Option[_], FoundNode[_]) = (???, ???)
+ v match {
+ case (x: Option[_], _) =>
+ }
+}