summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala2
-rw-r--r--src/compiler/scala/reflect/internal/Types.scala4
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala22
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala18
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala19
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala274
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala19
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala7
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Unapplies.scala22
-rw-r--r--src/library/scala/concurrent/ConcurrentPackageObject.scala29
-rw-r--r--src/library/scala/concurrent/ExecutionContext.scala3
-rw-r--r--src/library/scala/concurrent/Future.scala14
-rw-r--r--src/library/scala/concurrent/impl/ExecutionContextImpl.scala6
-rw-r--r--src/library/scala/concurrent/impl/Future.scala2
-rw-r--r--src/library/scala/concurrent/impl/Promise.scala16
15 files changed, 279 insertions, 178 deletions
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index 724e5bf628..240dedc658 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -3054,7 +3054,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def originalEnclosingMethod = this
override def owner: Symbol =
- abort("no-symbol does not have an owner (this is a bug: scala " + scala.util.Properties.versionString + ")")
+ abort("no-symbol does not have an owner")
override def typeConstructor: Type =
abort("no-symbol does not have a type constructor (this may indicate scalac cannot find fundamental classes)")
}
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala
index 09e7303b90..81582db5f2 100644
--- a/src/compiler/scala/reflect/internal/Types.scala
+++ b/src/compiler/scala/reflect/internal/Types.scala
@@ -2663,6 +2663,10 @@ trait Types extends api.Types { self: SymbolTable =>
override def kind = "OverloadedType"
}
+ def overloadedType(pre: Type, alternatives: List[Symbol]): Type =
+ if (alternatives.tail.isEmpty) pre memberType alternatives.head
+ else OverloadedType(pre, alternatives)
+
/** A class remembering a type instantiation for some a set of overloaded
* polymorphic symbols.
* Not used after phase `typer`.
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
index 042e739abe..7d3249a7d3 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
@@ -1159,6 +1159,27 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
*/
def generateMirrorClass(clasz: Symbol, sourceFile: SourceFile) {
import JAccessFlags._
+ /* We need to save inner classes buffer and create a new one to make sure
+ * that we do confuse inner classes of the class we mirror with inner
+ * classes of the class we are mirroring. These two sets can be different
+ * as seen in this case:
+ *
+ * class A {
+ * class B
+ * def b: B = new B
+ * }
+ * object C extends A
+ *
+ * Here mirror class of C has a static forwarder for (inherited) method `b`
+ * therefore it refers to class `B` and needs InnerClasses entry. However,
+ * the real class for `C` (named `C$`) is empty and does not refer to `B`
+ * thus does not need InnerClasses entry it.
+ *
+ * NOTE: This logic has been refactored in GenASM and everything is
+ * implemented in a much cleaner way by having two separate buffers.
+ */
+ val savedInnerClasses = innerClassBuffer
+ innerClassBuffer = mutable.LinkedHashSet[Symbol]()
val moduleName = javaName(clasz) // + "$"
val mirrorName = moduleName.substring(0, moduleName.length() - 1)
val mirrorClass = fjbgContext.JClass(ACC_SUPER | ACC_PUBLIC | ACC_FINAL,
@@ -1172,6 +1193,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
val ssa = scalaSignatureAddingMarker(mirrorClass, clasz.companionSymbol)
addAnnotations(mirrorClass, clasz.annotations ++ ssa)
emitClass(mirrorClass, clasz)
+ innerClassBuffer = savedInnerClasses
}
var linearization: List[BasicBlock] = Nil
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 3625b19dd4..3de287e58c 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -480,16 +480,22 @@ abstract class Erasure extends AddInterfaces
// TODO: should we do this for user-defined unapplies as well?
// does the first argument list have exactly one argument -- for user-defined unapplies we can't be sure
def maybeWrap(bridgingCall: Tree): Tree = {
- val canReturnNone = ( // can't statically know which member is going to be selected, so don't let this depend on member.isSynthetic
+ val guardExtractor = ( // can't statically know which member is going to be selected, so don't let this depend on member.isSynthetic
(member.name == nme.unapply || member.name == nme.unapplySeq)
&& !afterErasure((member.tpe <:< other.tpe))) // no static guarantees (TODO: is the subtype test ever true?)
- if (canReturnNone) {
- import CODE._
+ import CODE._
+ val _false = FALSE_typed
+ val pt = member.tpe.resultType
+ lazy val zero =
+ if (_false.tpe <:< pt) _false
+ else if (NoneModule.tpe <:< pt) REF(NoneModule)
+ else EmptyTree
+
+ if (guardExtractor && (zero ne EmptyTree)) {
val typeTest = gen.mkIsInstanceOf(REF(bridge.firstParam), member.tpe.params.head.tpe)
- IF (typeTest) THEN bridgingCall ELSE REF(NoneModule)
- }
- else bridgingCall
+ IF (typeTest) THEN bridgingCall ELSE zero
+ } else bridgingCall
}
val rhs = member.tpe match {
case MethodType(Nil, ConstantType(c)) => Literal(c)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index 722440349a..793b85da18 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -1133,16 +1133,27 @@ trait Implicits {
* An EmptyTree is returned if materialization fails.
*/
private def tagOfType(pre: Type, tp: Type, tagClass: Symbol): SearchResult = {
- def success(arg: Tree) =
+ def success(arg: Tree) = {
+ def isMacroException(msg: String): Boolean =
+ // [Eugene] very unreliable, ask Hubert about a better way
+ msg contains "exception during macro expansion"
+
+ def processMacroExpansionError(pos: Position, msg: String): SearchResult = {
+ // giving up and reporting all macro exceptions regardless of their source
+ // this might lead to an avalanche of errors if one of your implicit macros misbehaves
+ if (isMacroException(msg)) context.error(pos, msg)
+ failure(arg, "failed to typecheck the materialized tag: %n%s".format(msg), pos)
+ }
+
try {
val tree1 = typed(atPos(pos.focus)(arg))
- def isErroneous = tree exists (_.isErroneous)
- if (context.hasErrors) failure(tp, "failed to typecheck the materialized typetag: %n%s".format(context.errBuffer.head.errMsg), context.errBuffer.head.errPos)
+ if (context.hasErrors) processMacroExpansionError(context.errBuffer.head.errPos, context.errBuffer.head.errMsg)
else new SearchResult(tree1, EmptyTreeTypeSubstituter)
} catch {
case ex: TypeError =>
- failure(arg, "failed to typecheck the materialized typetag: %n%s".format(ex.msg), ex.pos)
+ processMacroExpansionError(ex.pos, ex.msg)
}
+ }
val prefix = (
// ClassTags only exist for scala.reflect.mirror, so their materializer
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
index 353514c397..c10901cdce 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
@@ -641,143 +641,181 @@ trait Macros extends Traces {
*/
private type MacroRuntime = List[Any] => Any
private val macroRuntimesCache = perRunCaches.newWeakMap[Symbol, Option[MacroRuntime]]
- private def macroRuntime(macroDef: Symbol): Option[MacroRuntime] =
- macroRuntimesCache.getOrElseUpdate(macroDef, {
- val runtime = {
- macroTraceVerbose("looking for macro implementation: ")(macroDef)
- macroTraceVerbose("macroDef is annotated with: ")(macroDef.annotations)
-
- val ann = macroDef.getAnnotation(MacroImplAnnotation)
- if (ann == None) {
- macroTraceVerbose("@macroImpl annotation is missing (this means that macro definition failed to typecheck)")(macroDef)
- return None
- }
+ private lazy val fastTrack: Map[Symbol, MacroRuntime] = {
+ import scala.reflect.api.Universe
+ import scala.reflect.makro.internal._
+ Map( // challenge: how can we factor out the common code? Does not seem to be easy.
+ MacroInternal_materializeArrayTag -> (args => {
+ assert(args.length == 3, args)
+ val c = args(0).asInstanceOf[MacroContext]
+ materializeArrayTag_impl(c)(args(1).asInstanceOf[c.Expr[Universe]])(args(2).asInstanceOf[c.TypeTag[_]])
+ }),
+ MacroInternal_materializeErasureTag -> (args => {
+ assert(args.length == 3, args)
+ val c = args(0).asInstanceOf[MacroContext]
+ materializeErasureTag_impl(c)(args(1).asInstanceOf[c.Expr[Universe]])(args(2).asInstanceOf[c.TypeTag[_]])
+ }),
+ MacroInternal_materializeClassTag -> (args => {
+ assert(args.length == 3, args)
+ val c = args(0).asInstanceOf[MacroContext]
+ materializeClassTag_impl(c)(args(1).asInstanceOf[c.Expr[Universe]])(args(2).asInstanceOf[c.TypeTag[_]])
+ }),
+ MacroInternal_materializeTypeTag -> (args => {
+ assert(args.length == 3, args)
+ val c = args(0).asInstanceOf[MacroContext]
+ materializeTypeTag_impl(c)(args(1).asInstanceOf[c.Expr[Universe]])(args(2).asInstanceOf[c.TypeTag[_]])
+ }),
+ MacroInternal_materializeConcreteTypeTag -> (args => {
+ assert(args.length == 3, args)
+ val c = args(0).asInstanceOf[MacroContext]
+ materializeConcreteTypeTag_impl(c)(args(1).asInstanceOf[c.Expr[Universe]])(args(2).asInstanceOf[c.TypeTag[_]])
+ })
+ )
+ }
+ private def macroRuntime(macroDef: Symbol): Option[MacroRuntime] = {
+ macroTraceVerbose("looking for macro implementation: ")(macroDef)
+ if (fastTrack contains macroDef) {
+ macroLogVerbose("macro expansion serviced by a fast track")
+ Some(fastTrack(macroDef))
+ } else {
+ macroRuntimesCache.getOrElseUpdate(macroDef, {
+ val runtime = {
+ macroTraceVerbose("looking for macro implementation: ")(macroDef)
+ macroTraceVerbose("macroDef is annotated with: ")(macroDef.annotations)
- val macroImpl = ann.get.args(0).symbol
- if (macroImpl == NoSymbol) {
- macroTraceVerbose("@macroImpl annotation is malformed (this means that macro definition failed to typecheck)")(macroDef)
- return None
- }
+ val ann = macroDef.getAnnotation(MacroImplAnnotation)
+ if (ann == None) {
+ macroTraceVerbose("@macroImpl annotation is missing (this means that macro definition failed to typecheck)")(macroDef)
+ return None
+ }
- macroLogVerbose("resolved implementation %s at %s".format(macroImpl, macroImpl.pos))
- if (macroImpl.isErroneous) {
- macroTraceVerbose("macro implementation is erroneous (this means that either macro body or macro implementation signature failed to typecheck)")(macroDef)
- return None
- }
+ val macroImpl = ann.get.args(0).symbol
+ if (macroImpl == NoSymbol) {
+ macroTraceVerbose("@macroImpl annotation is malformed (this means that macro definition failed to typecheck)")(macroDef)
+ return None
+ }
- def loadMacroImpl(macroMirror: Mirror): Option[(Object, macroMirror.Symbol)] = {
- try {
- // this logic relies on the assumptions that were valid for the old macro prototype
- // namely that macro implementations can only be defined in top-level classes and modules
- // with the new prototype that materialized in a SIP, macros need to be statically accessible, which is different
- // for example, a macro def could be defined in a trait that is implemented by an object
- // there are some more clever cases when seemingly non-static method ends up being statically accessible
- // however, the code below doesn't account for these guys, because it'd take a look of time to get it right
- // for now I leave it as a todo and move along to more the important stuff
-
- macroTraceVerbose("loading implementation class from %s: ".format(macroMirror))(macroImpl.owner.fullName)
- macroTraceVerbose("classloader is: ")("%s of type %s".format(macroMirror.classLoader, if (macroMirror.classLoader != null) macroMirror.classLoader.getClass.toString else "primordial classloader"))
- def inferClasspath(cl: ClassLoader) = cl match {
- case cl: java.net.URLClassLoader => "[" + (cl.getURLs mkString ",") + "]"
- case null => "[" + scala.tools.util.PathResolver.Environment.javaBootClassPath + "]"
- case _ => "<unknown>"
- }
- macroTraceVerbose("classpath is: ")(inferClasspath(macroMirror.classLoader))
-
- // [Eugene] relies on the fact that macro implementations can only be defined in static classes
- // [Martin to Eugene] There's similar logic buried in Symbol#flatname. Maybe we can refactor?
- def classfile(sym: Symbol): String = {
- def recur(sym: Symbol): String = sym match {
- case sym if sym.owner.isPackageClass =>
- val suffix = if (sym.isModuleClass) "$" else ""
- sym.fullName + suffix
- case sym =>
- val separator = if (sym.owner.isModuleClass) "" else "$"
- recur(sym.owner) + separator + sym.javaSimpleName.toString
+ macroLogVerbose("resolved implementation %s at %s".format(macroImpl, macroImpl.pos))
+ if (macroImpl.isErroneous) {
+ macroTraceVerbose("macro implementation is erroneous (this means that either macro body or macro implementation signature failed to typecheck)")(macroDef)
+ return None
+ }
+
+ def loadMacroImpl(macroMirror: Mirror): Option[(Object, macroMirror.Symbol)] = {
+ try {
+ // this logic relies on the assumptions that were valid for the old macro prototype
+ // namely that macro implementations can only be defined in top-level classes and modules
+ // with the new prototype that materialized in a SIP, macros need to be statically accessible, which is different
+ // for example, a macro def could be defined in a trait that is implemented by an object
+ // there are some more clever cases when seemingly non-static method ends up being statically accessible
+ // however, the code below doesn't account for these guys, because it'd take a look of time to get it right
+ // for now I leave it as a todo and move along to more the important stuff
+
+ macroTraceVerbose("loading implementation class from %s: ".format(macroMirror))(macroImpl.owner.fullName)
+ macroTraceVerbose("classloader is: ")("%s of type %s".format(macroMirror.classLoader, if (macroMirror.classLoader != null) macroMirror.classLoader.getClass.toString else "primordial classloader"))
+ def inferClasspath(cl: ClassLoader) = cl match {
+ case cl: java.net.URLClassLoader => "[" + (cl.getURLs mkString ",") + "]"
+ case null => "[" + scala.tools.util.PathResolver.Environment.javaBootClassPath + "]"
+ case _ => "<unknown>"
}
+ macroTraceVerbose("classpath is: ")(inferClasspath(macroMirror.classLoader))
+
+ // [Eugene] relies on the fact that macro implementations can only be defined in static classes
+ // [Martin to Eugene] There's similar logic buried in Symbol#flatname. Maybe we can refactor?
+ def classfile(sym: Symbol): String = {
+ def recur(sym: Symbol): String = sym match {
+ case sym if sym.owner.isPackageClass =>
+ val suffix = if (sym.isModuleClass) "$" else ""
+ sym.fullName + suffix
+ case sym =>
+ val separator = if (sym.owner.isModuleClass) "" else "$"
+ recur(sym.owner) + separator + sym.javaSimpleName.toString
+ }
- if (sym.isClass || sym.isModule) recur(sym)
- else recur(sym.enclClass)
- }
+ if (sym.isClass || sym.isModule) recur(sym)
+ else recur(sym.enclClass)
+ }
- // [Eugene] this doesn't work for inner classes
- // neither does macroImpl.owner.javaClassName, so I had to roll my own implementation
- //val receiverName = macroImpl.owner.fullName
- val implClassName = classfile(macroImpl.owner)
- val implClassSymbol: macroMirror.Symbol = macroMirror.symbolForName(implClassName)
+ // [Eugene] this doesn't work for inner classes
+ // neither does macroImpl.owner.javaClassName, so I had to roll my own implementation
+ //val receiverName = macroImpl.owner.fullName
+ val implClassName = classfile(macroImpl.owner)
+ val implClassSymbol: macroMirror.Symbol = macroMirror.symbolForName(implClassName)
- if (macroDebugVerbose) {
- println("implClassSymbol is: " + implClassSymbol.fullNameString)
+ if (macroDebugVerbose) {
+ println("implClassSymbol is: " + implClassSymbol.fullNameString)
- if (implClassSymbol != macroMirror.NoSymbol) {
- val implClass = macroMirror.classToJava(implClassSymbol)
- val implSource = implClass.getProtectionDomain.getCodeSource
- println("implClass is %s from %s".format(implClass, implSource))
- println("implClassLoader is %s with classpath %s".format(implClass.getClassLoader, inferClasspath(implClass.getClassLoader)))
+ if (implClassSymbol != macroMirror.NoSymbol) {
+ val implClass = macroMirror.classToJava(implClassSymbol)
+ val implSource = implClass.getProtectionDomain.getCodeSource
+ println("implClass is %s from %s".format(implClass, implSource))
+ println("implClassLoader is %s with classpath %s".format(implClass.getClassLoader, inferClasspath(implClass.getClassLoader)))
+ }
}
- }
- val implObjSymbol = implClassSymbol.companionModule
- macroTraceVerbose("implObjSymbol is: ")(implObjSymbol.fullNameString)
+ val implObjSymbol = implClassSymbol.companionModule
+ macroTraceVerbose("implObjSymbol is: ")(implObjSymbol.fullNameString)
- if (implObjSymbol == macroMirror.NoSymbol) None
- else {
- // yet another reflection method that doesn't work for inner classes
- //val receiver = macroMirror.companionInstance(receiverClass)
- val implObj = try {
- val implObjClass = java.lang.Class.forName(implClassName, true, macroMirror.classLoader)
- implObjClass getField "MODULE$" get null
- } catch {
- case ex: NoSuchFieldException => macroTraceVerbose("exception when loading implObj: ")(ex); null
- case ex: NoClassDefFoundError => macroTraceVerbose("exception when loading implObj: ")(ex); null
- case ex: ClassNotFoundException => macroTraceVerbose("exception when loading implObj: ")(ex); null
- }
-
- if (implObj == null) None
+ if (implObjSymbol == macroMirror.NoSymbol) None
else {
- val implMethSymbol = implObjSymbol.info.member(macroMirror.newTermName(macroImpl.name.toString))
- macroLogVerbose("implMethSymbol is: " + implMethSymbol.fullNameString)
- macroLogVerbose("jimplMethSymbol is: " + macroMirror.methodToJava(implMethSymbol))
+ // yet another reflection method that doesn't work for inner classes
+ //val receiver = macroMirror.companionInstance(receiverClass)
+ val implObj = try {
+ val implObjClass = java.lang.Class.forName(implClassName, true, macroMirror.classLoader)
+ implObjClass getField "MODULE$" get null
+ } catch {
+ case ex: NoSuchFieldException => macroTraceVerbose("exception when loading implObj: ")(ex); null
+ case ex: NoClassDefFoundError => macroTraceVerbose("exception when loading implObj: ")(ex); null
+ case ex: ClassNotFoundException => macroTraceVerbose("exception when loading implObj: ")(ex); null
+ }
- if (implMethSymbol == macroMirror.NoSymbol) None
+ if (implObj == null) None
else {
- macroLogVerbose("successfully loaded macro impl as (%s, %s)".format(implObj, implMethSymbol))
- Some((implObj, implMethSymbol))
+ val implMethSymbol = implObjSymbol.info.member(macroMirror.newTermName(macroImpl.name.toString))
+ macroLogVerbose("implMethSymbol is: " + implMethSymbol.fullNameString)
+ macroLogVerbose("jimplMethSymbol is: " + macroMirror.methodToJava(implMethSymbol))
+
+ if (implMethSymbol == macroMirror.NoSymbol) None
+ else {
+ macroLogVerbose("successfully loaded macro impl as (%s, %s)".format(implObj, implMethSymbol))
+ Some((implObj, implMethSymbol))
+ }
}
}
+ } catch {
+ case ex: ClassNotFoundException =>
+ macroTraceVerbose("implementation class failed to load: ")(ex.toString)
+ None
}
- } catch {
- case ex: ClassNotFoundException =>
- macroTraceVerbose("implementation class failed to load: ")(ex.toString)
- None
}
- }
- val primary = loadMacroImpl(primaryMirror)
- primary match {
- case Some((implObj, implMethSymbol)) =>
- def runtime(args: List[Any]) = primaryMirror.invoke(implObj, implMethSymbol)(args: _*).asInstanceOf[Any]
- Some(runtime _)
- case None =>
- if (settings.XmacroFallbackClasspath.value != "") {
- macroLogVerbose("trying to load macro implementation from the fallback mirror: %s".format(settings.XmacroFallbackClasspath.value))
- val fallback = loadMacroImpl(fallbackMirror)
- fallback match {
- case Some((implObj, implMethSymbol)) =>
- def runtime(args: List[Any]) = fallbackMirror.invoke(implObj, implMethSymbol)(args: _*).asInstanceOf[Any]
- Some(runtime _)
- case None =>
- None
+ val primary = loadMacroImpl(primaryMirror)
+ primary match {
+ case Some((implObj, implMethSymbol)) =>
+ def runtime(args: List[Any]) = primaryMirror.invoke(implObj, implMethSymbol)(args: _*).asInstanceOf[Any]
+ Some(runtime _)
+ case None =>
+ if (settings.XmacroFallbackClasspath.value != "") {
+ macroLogVerbose("trying to load macro implementation from the fallback mirror: %s".format(settings.XmacroFallbackClasspath.value))
+ val fallback = loadMacroImpl(fallbackMirror)
+ fallback match {
+ case Some((implObj, implMethSymbol)) =>
+ def runtime(args: List[Any]) = fallbackMirror.invoke(implObj, implMethSymbol)(args: _*).asInstanceOf[Any]
+ Some(runtime _)
+ case None =>
+ None
+ }
+ } else {
+ None
}
- } else {
- None
- }
+ }
}
- }
- if (runtime == None) macroDef setFlag IS_ERROR
- runtime
- })
+ if (runtime == None) macroDef setFlag IS_ERROR
+ runtime
+ })
+ }
+ }
/** Should become private again once we're done with migrating typetag generation from implicits */
def macroContext(typer: Typer, prefixTree: Tree, expandeeTree: Tree): MacroContext { val mirror: global.type } =
@@ -1203,8 +1241,10 @@ trait Macros extends Traces {
if (relevancyThreshold == -1) None
else {
var relevantElements = realex.getStackTrace().take(relevancyThreshold + 1)
- var framesTillReflectiveInvocationOfMacroImpl = relevantElements.reverse.indexWhere(_.isNativeMethod) + 1
- relevantElements = relevantElements dropRight framesTillReflectiveInvocationOfMacroImpl
+ def isMacroInvoker(este: StackTraceElement) = este.isNativeMethod || (este.getClassName != null && (este.getClassName contains "fastTrack"))
+ var threshold = relevantElements.reverse.indexWhere(isMacroInvoker) + 1
+ while (threshold != relevantElements.length && isMacroInvoker(relevantElements(relevantElements.length - threshold - 1))) threshold += 1
+ relevantElements = relevantElements dropRight threshold
realex.setStackTrace(relevantElements)
val message = new java.io.StringWriter()
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index b878ce3a53..4e578e3f0d 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -1488,8 +1488,23 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
private def transformCaseApply(tree: Tree, ifNot: => Unit) = {
val sym = tree.symbol
-
- if (sym.isSourceMethod && sym.isCase && sym.name == nme.apply)
+
+ def isClassTypeAccessible(tree: Tree): Boolean = tree match {
+ case TypeApply(fun, targs) =>
+ isClassTypeAccessible(fun)
+ case Select(module, apply) =>
+ // Fixes SI-5626. Classes in refinement types cannot be constructed with `new`. In this case,
+ // the companion class is actually not a ClassSymbol, but a reference to an abstract type.
+ module.symbol.companionClass.isClass
+ }
+
+ val doTransform =
+ sym.isSourceMethod &&
+ sym.isCase &&
+ sym.name == nme.apply &&
+ isClassTypeAccessible(tree)
+
+ if (doTransform)
toConstructor(tree.pos, tree.tpe)
else {
ifNot
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 34e1aaedfd..b5e58efaff 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -958,9 +958,14 @@ trait Typers extends Modes with Adaptations with Taggings {
* see test/files/../t5189*.scala
*/
def adaptConstrPattern(): Tree = { // (5)
- val extractor = tree.symbol.filter(sym => reallyExists(unapplyMember(sym.tpe)))
+ def isExtractor(sym: Symbol) = reallyExists(unapplyMember(sym.tpe))
+ val extractor = tree.symbol filter isExtractor
if (extractor != NoSymbol) {
tree setSymbol extractor
+ tree.tpe match {
+ case OverloadedType(pre, alts) => tree.tpe = overloadedType(pre, alts filter isExtractor)
+ case _ =>
+ }
val unapply = unapplyMember(extractor.tpe)
val clazz = unapplyParameterType(unapply)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
index 1ebcea4a07..3d9453d8cd 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
@@ -210,13 +210,25 @@ trait Unapplies extends ast.TreeDSL
// and re-added in ``finishWith'' in the namer.
def paramWithDefault(vd: ValDef) =
treeCopy.ValDef(vd, vd.mods | DEFAULTPARAM, vd.name, atPos(vd.pos.focus)(TypeTree() setOriginal vd.tpt), toIdent(vd))
-
- val paramss = mmap(cparamss)(paramWithDefault)
- val classTpe = classType(cdef, tparams)
+
+ val (copyParamss, funParamss) = cparamss match {
+ case Nil => (Nil, Nil)
+ case ps :: pss =>
+ (List(ps.map(paramWithDefault)), mmap(pss)(p => copyUntyped[ValDef](p).copy(rhs = EmptyTree)))
+ }
+
+ val classTpe = classType(cdef, tparams)
+ val bodyTpe = funParamss.foldRight(classTpe)((params, restp) => gen.scalaFunctionConstr(params.map(_.tpt), restp))
+
+ val argss = copyParamss match {
+ case Nil => Nil
+ case ps :: Nil => mmap(ps :: funParamss)(toIdent)
+ }
+ val body = funParamss.foldRight(New(classTpe, argss): Tree)(Function)
Some(atPos(cdef.pos.focus)(
- DefDef(Modifiers(SYNTHETIC), nme.copy, tparams, paramss, classTpe,
- New(classTpe, mmap(paramss)(toIdent)))
+ DefDef(Modifiers(SYNTHETIC), nme.copy, tparams, copyParamss, bodyTpe,
+ body)
))
}
}
diff --git a/src/library/scala/concurrent/ConcurrentPackageObject.scala b/src/library/scala/concurrent/ConcurrentPackageObject.scala
index a3d985733e..c3c329121c 100644
--- a/src/library/scala/concurrent/ConcurrentPackageObject.scala
+++ b/src/library/scala/concurrent/ConcurrentPackageObject.scala
@@ -11,7 +11,6 @@ package scala.concurrent
import java.util.concurrent.{ Executors, ExecutorService, ThreadFactory }
import scala.concurrent.forkjoin.{ ForkJoinPool, ForkJoinWorkerThread }
import scala.concurrent.util.Duration
-import ConcurrentPackageObject._
import language.implicitConversions
@@ -36,19 +35,6 @@ abstract class ConcurrentPackageObject {
case _ => true
}
- private[concurrent] def resolveEither[T](source: Either[Throwable, T]): Either[Throwable, T] = source match {
- case Left(t) => resolver(t)
- case _ => source
- }
-
- private[concurrent] def resolver[T](throwable: Throwable): Either[Throwable, T] = throwable match {
- case t: scala.runtime.NonLocalReturnControl[_] => Right(t.value.asInstanceOf[T])
- case t: scala.util.control.ControlThrowable => Left(new ExecutionException("Boxed ControlThrowable", t))
- case t: InterruptedException => Left(new ExecutionException("Boxed InterruptedException", t))
- case e: Error => Left(new ExecutionException("Boxed Error", e))
- case t => Left(t)
- }
-
/* concurrency constructs */
/** Starts an asynchronous computation and returns a `Future` object with the result of that computation.
@@ -102,18 +88,3 @@ abstract class ConcurrentPackageObject {
@inline implicit final def int2durationops(x: Int): DurationOps = new DurationOps(x)
}
-
-private[concurrent] object ConcurrentPackageObject {
- // TODO, docs, return type
- // Note that having this in the package object led to failures when
- // compiling a subset of sources; it seems that the wildcard is not
- // properly handled, and you get messages like "type _$1 defined twice".
- // This is consistent with other package object breakdowns.
- // private val resolverFunction: PartialFunction[Throwable, Either[Throwable, _]] = {
- // case t: scala.runtime.NonLocalReturnControl[_] => Right(t.value)
- // case t: scala.util.control.ControlThrowable => Left(new ExecutionException("Boxed ControlThrowable", t))
- // case t: InterruptedException => Left(new ExecutionException("Boxed InterruptedException", t))
- // case e: Error => Left(new ExecutionException("Boxed Error", e))
- // case t => Left(t)
- // }
-}
diff --git a/src/library/scala/concurrent/ExecutionContext.scala b/src/library/scala/concurrent/ExecutionContext.scala
index 4666674b5b..d2a2d5e8a8 100644
--- a/src/library/scala/concurrent/ExecutionContext.scala
+++ b/src/library/scala/concurrent/ExecutionContext.scala
@@ -54,8 +54,7 @@ object ExecutionContext {
def fromExecutor(e: Executor, reporter: Throwable => Unit = defaultReporter): ExecutionContext with Executor = new impl.ExecutionContextImpl(e, reporter)
def defaultReporter: Throwable => Unit = {
- // `Error`s are currently wrapped by `resolver`.
- // Also, re-throwing `Error`s here causes an exception handling test to fail.
+ // re-throwing `Error`s here causes an exception handling test to fail.
//case e: Error => throw e
case t => t.printStackTrace()
}
diff --git a/src/library/scala/concurrent/Future.scala b/src/library/scala/concurrent/Future.scala
index 70b3c3dbbb..496e4698d4 100644
--- a/src/library/scala/concurrent/Future.scala
+++ b/src/library/scala/concurrent/Future.scala
@@ -201,7 +201,7 @@ trait Future[+T] extends Awaitable[T] {
case Right(v) =>
try p success f(v)
catch {
- case NonFatal(t) => p complete resolver(t)
+ case NonFatal(t) => p failure t
}
}
@@ -227,7 +227,7 @@ trait Future[+T] extends Awaitable[T] {
case Right(v) => p success v
}
} catch {
- case NonFatal(t) => p complete resolver(t)
+ case NonFatal(t) => p failure t
}
}
@@ -260,7 +260,7 @@ trait Future[+T] extends Awaitable[T] {
if (pred(v)) p success v
else p failure new NoSuchElementException("Future.filter predicate is not satisfied by: " + v)
} catch {
- case NonFatal(t) => p complete resolver(t)
+ case NonFatal(t) => p failure t
}
}
@@ -309,7 +309,7 @@ trait Future[+T] extends Awaitable[T] {
if (pf.isDefinedAt(v)) p success pf(v)
else p failure new NoSuchElementException("Future.collect partial function is not defined at: " + v)
} catch {
- case NonFatal(t) => p complete resolver(t)
+ case NonFatal(t) => p failure t
}
}
@@ -334,7 +334,9 @@ trait Future[+T] extends Awaitable[T] {
onComplete {
case Left(t) if pf isDefinedAt t =>
try { p success pf(t) }
- catch { case NonFatal(t) => p complete resolver(t) }
+ catch {
+ case NonFatal(t) => p failure t
+ }
case otherwise => p complete otherwise
}
@@ -362,7 +364,7 @@ trait Future[+T] extends Awaitable[T] {
try {
p completeWith pf(t)
} catch {
- case NonFatal(t) => p complete resolver(t)
+ case NonFatal(t) => p failure t
}
case otherwise => p complete otherwise
}
diff --git a/src/library/scala/concurrent/impl/ExecutionContextImpl.scala b/src/library/scala/concurrent/impl/ExecutionContextImpl.scala
index 7dc3ed2988..3ed960c7ab 100644
--- a/src/library/scala/concurrent/impl/ExecutionContextImpl.scala
+++ b/src/library/scala/concurrent/impl/ExecutionContextImpl.scala
@@ -10,10 +10,10 @@ package scala.concurrent.impl
-import java.util.concurrent.{Callable, Executor, ExecutorService, Executors, ThreadFactory}
+import java.util.concurrent.{ Callable, Executor, ExecutorService, Executors, ThreadFactory }
import scala.concurrent.forkjoin._
-import scala.concurrent.{ExecutionContext, resolver, Awaitable}
-import scala.concurrent.util.{ Duration }
+import scala.concurrent.{ ExecutionContext, Awaitable }
+import scala.concurrent.util.Duration
diff --git a/src/library/scala/concurrent/impl/Future.scala b/src/library/scala/concurrent/impl/Future.scala
index 20d4122e8f..bf136b6195 100644
--- a/src/library/scala/concurrent/impl/Future.scala
+++ b/src/library/scala/concurrent/impl/Future.scala
@@ -57,7 +57,7 @@ private[concurrent] object Future {
case NonFatal(e) =>
// Commenting out reporting for now, since it produces too much output in the tests
//executor.reportFailure(e)
- scala.concurrent.resolver(e)
+ Left(e)
}
}
})
diff --git a/src/library/scala/concurrent/impl/Promise.scala b/src/library/scala/concurrent/impl/Promise.scala
index da70b3dea5..5a5b893f16 100644
--- a/src/library/scala/concurrent/impl/Promise.scala
+++ b/src/library/scala/concurrent/impl/Promise.scala
@@ -11,7 +11,7 @@ package scala.concurrent.impl
import java.util.concurrent.TimeUnit.{ NANOSECONDS, MILLISECONDS }
-import scala.concurrent.{Awaitable, ExecutionContext, resolveEither, resolver, blocking, CanAwait, TimeoutException}
+import scala.concurrent.{ Awaitable, ExecutionContext, blocking, CanAwait, TimeoutException, ExecutionException }
//import scala.util.continuations._
import scala.concurrent.util.Duration
import scala.util
@@ -26,6 +26,20 @@ private[concurrent] trait Promise[T] extends scala.concurrent.Promise[T] with Fu
object Promise {
+
+ private def resolveEither[T](source: Either[Throwable, T]): Either[Throwable, T] = source match {
+ case Left(t) => resolver(t)
+ case _ => source
+ }
+
+ private def resolver[T](throwable: Throwable): Either[Throwable, T] = throwable match {
+ case t: scala.runtime.NonLocalReturnControl[_] => Right(t.value.asInstanceOf[T])
+ case t: scala.util.control.ControlThrowable => Left(new ExecutionException("Boxed ControlThrowable", t))
+ case t: InterruptedException => Left(new ExecutionException("Boxed InterruptedException", t))
+ case e: Error => Left(new ExecutionException("Boxed Error", e))
+ case t => Left(t)
+ }
+
/** Default promise implementation.
*/
class DefaultPromise[T](implicit val executor: ExecutionContext) extends AbstractPromise with Promise[T] { self =>