From add30e2f48f0120728a931377cc8a00748f5c9b9 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Tue, 17 Apr 2012 17:13:53 +0100 Subject: Try to fix sbt. It depended on the signature of uncheckedWarnings. --- src/compiler/scala/tools/nsc/CompilationUnits.scala | 2 +- src/compiler/scala/tools/nsc/Global.scala | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/compiler/scala/tools/nsc/CompilationUnits.scala b/src/compiler/scala/tools/nsc/CompilationUnits.scala index 767df0791e..f89f278338 100644 --- a/src/compiler/scala/tools/nsc/CompilationUnits.scala +++ b/src/compiler/scala/tools/nsc/CompilationUnits.scala @@ -91,7 +91,7 @@ trait CompilationUnits { self: Global => currentRun.deprecationWarnings.warn(pos, msg) def uncheckedWarning(pos: Position, msg: String) = - currentRun.uncheckedWarnings.warn(pos, msg) + currentRun.uncheckedWarnings0.warn(pos, msg) def inlinerWarning(pos: Position, msg: String) = currentRun.inlinerWarnings.warn(pos, msg) diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index bbeee3220b..73c68f44d4 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -967,10 +967,15 @@ class Global(var currentSettings: Settings, var reporter: NscReporter) extends S var currentUnit: CompilationUnit = NoCompilationUnit val deprecationWarnings = new ConditionalWarning("deprecation", settings.deprecation) - val uncheckedWarnings = new ConditionalWarning("unchecked", settings.unchecked) + // This change broke sbt; I gave it the thrilling name of uncheckedWarnings0 so + // as to recover uncheckedWarnings for its ever-fragile compiler interface. + val uncheckedWarnings0 = new ConditionalWarning("unchecked", settings.unchecked) val featureWarnings = new ConditionalWarning("feature", settings.feature) val inlinerWarnings = new ConditionalWarning("inliner", settings.YinlinerWarnings) - val allConditionalWarnings = List(deprecationWarnings, uncheckedWarnings, featureWarnings, inlinerWarnings) + val allConditionalWarnings = List(deprecationWarnings, uncheckedWarnings0, featureWarnings, inlinerWarnings) + + // for sbt's benefit + def uncheckedWarnings: List[(Position, String)] = uncheckedWarnings0.warnings.toList var reportedFeature = Set[Symbol]() -- cgit v1.2.3 From 17fa0b13480c7dd9796885e32ec562e162253350 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Mon, 16 Apr 2012 12:55:26 +0200 Subject: big fat error message, reloaded --- src/library/scala/reflect/package.scala | 48 +++------------------------------ 1 file changed, 3 insertions(+), 45 deletions(-) diff --git a/src/library/scala/reflect/package.scala b/src/library/scala/reflect/package.scala index 6f40a3ac3e..6d50a96dfd 100644 --- a/src/library/scala/reflect/package.scala +++ b/src/library/scala/reflect/package.scala @@ -21,52 +21,10 @@ package object reflect { | | In Scala 2.10.0 M3, scala-compiler.jar is required to be on the classpath | for manifests and type tags to function. This will change in the final release, - | but for now you need to adjust your scripts or build system to proceed. - | Here are the instructions for some of the situations that might be relevant. + | but for now you need to adjust your scripts or the build system to proceed. | - | If you compile your application directly from the command line - | or a hand-rolled script, this is a bug. Please, report it. - | - | If you compile your application with Maven using the maven-scala plugin, - | set its "fork" configuration entry to "false: - | - | - | org.scala-tools - | maven-scala-plugin - | 2.15.0 - | - | - | - | ... - | - | - | false - | ... - | - | - | - | - | - | If you compile your application with SBT, - | - | - | If you compile your application in Scala IDE, - | . - | - | If you launch your application directly from the command line - | or a hand-rolled script, add `scala-compiler.jar` to the classpath: - | - | scalac HelloWorld.scala - | scala HelloWorld -cp path/to/scala-compiler.jar - | - | If you launch your application with Maven using the maven-scala plugin, - | set its "fork" configuration entry to "false as shown above. - | - | If you launch your application with SBT, make sure that you use - | - | - | If you launch your application in Scala IDE, make sure that both scala-library.jar and scala-compiler.jar - | are in bootstrap entries on the classpath of your launch configuration. + | For the instructions for some of the situations that might be relevant + | visit our knowledge base at https://gist.github.com/2391081. """.stripMargin('|').format(show(cl)) def mkMirror(classLoader: ClassLoader): api.Mirror = { -- cgit v1.2.3 From e408aa9ccaba736d0f85b7afecd288c3873d05bb Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Mon, 16 Apr 2012 11:52:25 +0200 Subject: adds erasures to concrete type tags --- .../scala/reflect/internal/Importers.scala | 4 +- src/compiler/scala/reflect/internal/StdNames.scala | 8 +- src/compiler/scala/reflect/internal/Symbols.scala | 8 +- .../scala/reflect/internal/TreeBuildUtil.scala | 8 +- src/compiler/scala/reflect/internal/TreeInfo.scala | 31 +- src/compiler/scala/reflect/internal/Types.scala | 2 +- .../scala/reflect/makro/runtime/Reifiers.scala | 41 +- .../scala/reflect/makro/runtime/Typers.scala | 8 +- src/compiler/scala/reflect/reify/Reifier.scala | 26 +- .../scala/reflect/reify/codegen/Symbols.scala | 10 +- .../scala/reflect/reify/codegen/Trees.scala | 35 +- .../scala/reflect/reify/codegen/Types.scala | 27 +- .../scala/reflect/reify/codegen/Util.scala | 2 + .../scala/reflect/reify/phases/Metalevels.scala | 4 +- .../scala/reflect/reify/phases/Reify.scala | 47 +- .../scala/reflect/reify/phases/Reshape.scala | 6 - .../reflect/runtime/SynchronizedSymbols.scala | 8 +- src/compiler/scala/tools/nsc/ast/FreeVars.scala | 4 +- .../scala/tools/nsc/typechecker/Implicits.scala | 3 +- src/library/scala/reflect/ClassTag.scala | 4 + src/library/scala/reflect/DynamicProxy.scala | 20 +- src/library/scala/reflect/TagMaterialization.scala | 49 +- src/library/scala/reflect/api/Symbols.scala | 10 + src/library/scala/reflect/api/TreeBuildUtil.scala | 20 +- src/library/scala/reflect/api/TypeTags.scala | 43 +- src/library/scala/reflect/api/Types.scala | 14 +- src/library/scala/reflect/makro/Reifiers.scala | 4 + .../scala/reflect/makro/internal/Utils.scala | 45 +- src/library/scala/reflect/package.scala | 2 +- test/files/jvm/interpreter.check | 743 +++++++++++---------- test/files/run/existentials3.check | 4 +- .../macro-reify-typetag-typeparams-notags.check | 4 +- .../run/macro-reify-typetag-typeparams-tags.check | 2 +- .../run/macro-reify-typetag-usegroundtypetag.check | 2 +- .../files/run/macro-typecheck-macrosdisabled.check | 2 +- .../Impls_Macros_1.scala | 4 +- test/files/run/reify_newimpl_26.check | 2 +- test/files/run/t3507.check | 2 +- .../run/toolbox_typecheck_macrosdisabled.check | 2 +- .../run/toolbox_typecheck_macrosdisabled.scala | 2 +- 40 files changed, 669 insertions(+), 593 deletions(-) diff --git a/src/compiler/scala/reflect/internal/Importers.scala b/src/compiler/scala/reflect/internal/Importers.scala index ab5e19fca9..596d400628 100644 --- a/src/compiler/scala/reflect/internal/Importers.scala +++ b/src/compiler/scala/reflect/internal/Importers.scala @@ -71,9 +71,9 @@ trait Importers { self: SymbolTable => case x: from.ModuleSymbol => linkReferenced(myowner.newModuleSymbol(myname, mypos, myflags), x, importSymbol) case x: from.FreeTerm => - newFreeTerm(importName(x.name).toTermName, importType(x.info), x.value, x.origin, myflags) + newFreeTermSymbol(importName(x.name).toTermName, importType(x.info), x.value, x.flags, x.origin) case x: from.FreeType => - newFreeType(importName(x.name).toTypeName, importType(x.info), x.value, x.origin, myflags) + newFreeTypeSymbol(importName(x.name).toTypeName, importType(x.info), x.value, x.flags, x.origin) case x: from.TermSymbol => linkReferenced(myowner.newValue(myname, mypos, myflags), x, importSymbol) case x: from.TypeSkolem => diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala index bf468affe6..c5fe1ecb45 100644 --- a/src/compiler/scala/reflect/internal/StdNames.scala +++ b/src/compiler/scala/reflect/internal/StdNames.scala @@ -291,11 +291,14 @@ trait StdNames extends NameManglers { self: SymbolTable => val AnnotationInfo: NameType = "AnnotationInfo" val Any: NameType = "Any" val AnyVal: NameType = "AnyVal" + val AppliedTypeTree: NameType = "AppliedTypeTree" val Apply: NameType = "Apply" val ArrayAnnotArg: NameType = "ArrayAnnotArg" + val Constant: NameType = "Constant" val ConstantType: NameType = "ConstantType" val EmptyPackage: NameType = "EmptyPackage" val EmptyPackageClass: NameType = "EmptyPackageClass" + val ExistentialTypeTree: NameType = "ExistentialTypeTree" val Expr: NameType = "Expr" val Ident: NameType = "Ident" val Import: NameType = "Import" @@ -404,13 +407,15 @@ trait StdNames extends NameManglers { self: SymbolTable => val name: NameType = "name" val ne: NameType = "ne" val newArray: NameType = "newArray" + val newFreeExistential: NameType = "newFreeExistential" val newFreeTerm: NameType = "newFreeTerm" val newFreeType: NameType = "newFreeType" val newNestedSymbol: NameType = "newNestedSymbol" val newScopeWith: NameType = "newScopeWith" + val next: NameType = "next" val nmeNewTermName: NameType = "newTermName" val nmeNewTypeName: NameType = "newTypeName" - val next: NameType = "next" + val normalize: NameType = "normalize" val notifyAll_ : NameType = "notifyAll" val notify_ : NameType = "notify" val null_ : NameType = "null" @@ -465,6 +470,7 @@ trait StdNames extends NameManglers { self: SymbolTable => val view_ : NameType = "view" val wait_ : NameType = "wait" val withFilter: NameType = "withFilter" + val wrap: NameType = "wrap" val zip: NameType = "zip" val synthSwitch: NameType = "$synthSwitch" diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala index 6eaae7f1ee..74e924add4 100644 --- a/src/compiler/scala/reflect/internal/Symbols.scala +++ b/src/compiler/scala/reflect/internal/Symbols.scala @@ -47,13 +47,13 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** Create a new free term. Its owner is NoSymbol. */ - def newFreeTerm(name: TermName, info: Type, value: => Any, origin: String, newFlags: Long = 0L): FreeTerm = - new FreeTerm(name, value, origin) initFlags newFlags setInfo info + def newFreeTermSymbol(name: TermName, info: Type, value: => Any, flags: Long = 0L, origin: String): FreeTerm = + new FreeTerm(name, value, origin) initFlags flags setInfo info /** Create a new free type. Its owner is NoSymbol. */ - def newFreeType(name: TypeName, info: Type, value: => Any, origin: String, newFlags: Long = 0L): FreeType = - new FreeType(name, value, origin) initFlags newFlags setInfo info + def newFreeTypeSymbol(name: TypeName, info: Type, value: => Any, flags: Long = 0L, origin: String): FreeType = + new FreeType(name, value, origin) initFlags flags setInfo info /** The original owner of a class. Used by the backend to generate * EnclosingMethod attributes. diff --git a/src/compiler/scala/reflect/internal/TreeBuildUtil.scala b/src/compiler/scala/reflect/internal/TreeBuildUtil.scala index fbcd5043bc..d4d4652e91 100644 --- a/src/compiler/scala/reflect/internal/TreeBuildUtil.scala +++ b/src/compiler/scala/reflect/internal/TreeBuildUtil.scala @@ -1,6 +1,8 @@ package scala.reflect package internal +import Flags._ + trait TreeBuildUtil extends api.TreeBuildUtil { self: SymbolTable => // ``staticClass'' and ``staticModule'' rely on ClassLoaders @@ -51,9 +53,11 @@ trait TreeBuildUtil extends api.TreeBuildUtil { self: SymbolTable => try selectOverloadedMethod(owner, name, index) catch { case _: MissingRequirementError => NoSymbol } - def newFreeTerm(name: String, info: Type, value: => Any, origin: String) = newFreeTerm(newTermName(name), info, value, origin) + def newFreeTerm(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null) = newFreeTermSymbol(newTermName(name), info, value, flags, origin) + + def newFreeType(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null) = newFreeTypeSymbol(newTypeName(name), info, value, (if (flags == 0L) PARAM else flags) | DEFERRED, origin) - def newFreeType(name: String, info: Type, value: => Any, origin: String) = newFreeType(newTypeName(name), info, value, origin) + def newFreeExistential(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null) = newFreeTypeSymbol(newTypeName(name), info, value, (if (flags == 0L) EXISTENTIAL else flags) | DEFERRED, origin) def modifiersFromInternalFlags(flags: Long, privateWithin: Name, annotations: List[Tree]): Modifiers = Modifiers(flags, privateWithin, annotations) diff --git a/src/compiler/scala/reflect/internal/TreeInfo.scala b/src/compiler/scala/reflect/internal/TreeInfo.scala index 039c8e557a..937b3ea5d6 100644 --- a/src/compiler/scala/reflect/internal/TreeInfo.scala +++ b/src/compiler/scala/reflect/internal/TreeInfo.scala @@ -629,7 +629,7 @@ abstract class TreeInfo { object ReifiedType { def unapply(tree: Tree): Option[(Tree, List[Tree], Tree)] = tree match { - case reifee @ Block((mrDef @ ValDef(_, _, _, _)) :: symbolTable, Apply(_, List(tpe))) if mrDef.name == nme.MIRROR_SHORT => + case reifee @ Block((mrDef @ ValDef(_, _, _, _)) :: symbolTable, Apply(_, tpe :: _)) if mrDef.name == nme.MIRROR_SHORT => Some(reifee, symbolTable, tpe) case _ => None @@ -646,11 +646,11 @@ abstract class TreeInfo { } object FreeDef { - def unapply(tree: Tree): Option[(Tree, TermName, Tree, String)] = tree match { - case FreeTermDef(mrRef, name, binding, origin) => - Some(mrRef, name, binding, origin) - case FreeTypeDef(mrRef, name, binding, origin) => - Some(mrRef, name, binding, origin) + def unapply(tree: Tree): Option[(Tree, TermName, Tree, Long, String)] = tree match { + case FreeTermDef(mrRef, name, binding, flags, origin) => + Some(mrRef, name, binding, flags, origin) + case FreeTypeDef(mrRef, name, binding, flags, origin) => + Some(mrRef, name, binding, flags, origin) case _ => None } @@ -659,28 +659,29 @@ abstract class TreeInfo { object FreeTermDef { lazy val newFreeTermMethod = getMember(getRequiredClass("scala.reflect.api.TreeBuildUtil"), nme.newFreeTerm) - def unapply(tree: Tree): Option[(Tree, TermName, Tree, String)] = tree match { - case ValDef(_, name, _, Apply(Select(mrRef @ Ident(_), newFreeTerm), List(_, _, binding, Literal(Constant(origin: String))))) + def unapply(tree: Tree): Option[(Tree, TermName, Tree, Long, String)] = tree match { + case ValDef(_, name, _, Apply(Select(mrRef @ Ident(_), newFreeTerm), List(_, _, binding, Literal(Constant(flags: Long)), Literal(Constant(origin: String))))) if mrRef.name == nme.MIRROR_SHORT && newFreeTerm == newFreeTermMethod.name => - Some(mrRef, name, binding, origin) + Some(mrRef, name, binding, flags, origin) case _ => None } } object FreeTypeDef { - lazy val newFreeTypeMethod = getMember(getRequiredClass("scala.reflect.api.TreeBuildUtil"), nme.newFreeType) + lazy val newFreeExistentialMethod = getMember(getRequiredClass("scala.reflect.api.TreeBuildUtil"), nme.newFreeType) + lazy val newFreeTypeMethod = getMember(getRequiredClass("scala.reflect.api.TreeBuildUtil"), nme.newFreeExistential) - def unapply(tree: Tree): Option[(Tree, TermName, Tree, String)] = tree match { - case ValDef(_, name, _, Apply(Select(mrRef1 @ Ident(_), newFreeType), List(_, _, value, Literal(Constant(origin: String))))) - if mrRef1.name == nme.MIRROR_SHORT && newFreeType == newFreeTypeMethod.name => + def unapply(tree: Tree): Option[(Tree, TermName, Tree, Long, String)] = tree match { + case ValDef(_, name, _, Apply(Select(mrRef1 @ Ident(_), newFreeType), List(_, _, value, Literal(Constant(flags: Long)), Literal(Constant(origin: String))))) + if mrRef1.name == nme.MIRROR_SHORT && (newFreeType == newFreeTypeMethod.name || newFreeType == newFreeExistentialMethod.name) => value match { case Apply(TypeApply(Select(Select(mrRef2 @ Ident(_), typeTag), apply), List(binding)), List(Literal(Constant(null)))) if mrRef2.name == nme.MIRROR_SHORT && typeTag == nme.TypeTag && apply == nme.apply => - Some(mrRef1, name, binding, origin) + Some(mrRef1, name, binding, flags, origin) case Apply(TypeApply(Select(mrRef2 @ Ident(_), typeTag), List(binding)), List(Literal(Constant(null)))) if mrRef2.name == nme.MIRROR_SHORT && typeTag == nme.TypeTag => - Some(mrRef1, name, binding, origin) + Some(mrRef1, name, binding, flags, origin) case _ => throw new Error("unsupported free type def: " + showRaw(tree)) } diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index fc57a130d1..7115cafc33 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -277,7 +277,7 @@ trait Types extends api.Types { self: SymbolTable => case SuperType(_, _) => false case SingleType(pre, sym) => notConcreteSym(sym) case ConstantType(_) => false - case TypeRef(_, sym, _) => notConcreteSym(sym) + case TypeRef(_, sym, args) => notConcreteSym(sym) || (args exists (arg => notConcreteTpe(arg))) case RefinedType(_, _) => false case ExistentialType(_, _) => false case AnnotatedType(_, tp, _) => notConcreteTpe(tp) diff --git a/src/compiler/scala/reflect/makro/runtime/Reifiers.scala b/src/compiler/scala/reflect/makro/runtime/Reifiers.scala index 2488b06d6c..3586adc590 100644 --- a/src/compiler/scala/reflect/makro/runtime/Reifiers.scala +++ b/src/compiler/scala/reflect/makro/runtime/Reifiers.scala @@ -10,6 +10,7 @@ trait Reifiers { self: Context => import mirror._ + import definitions._ lazy val reflectMirrorPrefix: Tree = { // [Eugene] how do I typecheck this without undergoing this tiresome (and, in general, incorrect) procedure? @@ -24,6 +25,44 @@ trait Reifiers { def reifyType(prefix: Tree, tpe: Type, dontSpliceAtTopLevel: Boolean = false, requireConcreteTypeTag: Boolean = false): Tree = reifyTopLevel(prefix, tpe, dontSpliceAtTopLevel, requireConcreteTypeTag) + def reifyErasure(tpe: Type): Tree = { + val positionBearer = enclosingMacros.find(c => c.macroApplication.pos != NoPosition).map(_.macroApplication).getOrElse(EmptyTree).asInstanceOf[Tree] + val typetagInScope = callsiteTyper.context.withMacrosDisabled(callsiteTyper.resolveTypeTag(positionBearer, gen.mkAttributedRef(Reflect_mirror).tpe, tpe, full = true)) + def typetagIsSynthetic(tree: Tree) = tree.isInstanceOf[Block] || (tree exists (sub => sub.symbol == TypeTagModule || sub.symbol == ConcreteTypeTagModule)) + typetagInScope match { + case success if !success.isEmpty && !typetagIsSynthetic(success) => + val factory = TypeApply(Select(Ident(ClassTagModule), nme.apply), List(TypeTree(tpe))) + Apply(factory, List(typetagInScope)) + case _ => + if (tpe.typeSymbol == ArrayClass) { + val componentTpe = tpe.typeArguments(0) + val componentTag = callsiteTyper.resolveClassTag(positionBearer, componentTpe) + Select(componentTag, nme.wrap) + } else { + // [Eugene] what's the intended behavior? there's no spec on ClassManifests + // for example, should we ban Array[T] or should we tag them with Array[AnyRef]? + // if its the latter, what should be the result of tagging Array[T] where T <: Int? + if (tpe.isSpliceable) throw new ReificationError(enclosingPosition, "tpe %s is an unresolved spliceable type".format(tpe)) + // [Eugene] imho this logic should be moved into `erasure` + var erasure = tpe match { + case tpe if tpe.typeSymbol.isDerivedValueClass => tpe // [Eugene to Martin] is this correct? + case ConstantType(value) => tpe.widen.erasure + case _ => { + // [Eugene] magikz. needs review + var result = tpe.erasure.normalize // necessary to deal with erasures of HK types, typeConstructor won't work + result = result match { + case PolyType(undets, underlying) => existentialAbstraction(undets, underlying) // we don't want undets in the result + case _ => result + } + result + } + } + val factory = TypeApply(Select(Ident(ClassTagModule), nme.apply), List(TypeTree(tpe))) + Apply(factory, List(TypeApply(Select(Ident(PredefModule), nme.classOf), List(TypeTree(erasure))))) + } + } + } + def unreifyTree(tree: Tree): Tree = Select(tree, definitions.ExprEval) @@ -34,7 +73,7 @@ trait Reifiers { try { val result = reifier.reified - logFreeVars(expandee.pos, result) + logFreeVars(enclosingPosition, result) result } catch { case ex: reifier.ReificationError => diff --git a/src/compiler/scala/reflect/makro/runtime/Typers.scala b/src/compiler/scala/reflect/makro/runtime/Typers.scala index 38e819746d..b32d4fb7b1 100644 --- a/src/compiler/scala/reflect/makro/runtime/Typers.scala +++ b/src/compiler/scala/reflect/makro/runtime/Typers.scala @@ -34,9 +34,9 @@ trait Typers { def trace(msg: Any) = if (mirror.settings.Ymacrodebug.value) println(msg) trace("inferring implicit value of type %s, macros = %s".format(pt, !withMacrosDisabled)) import mirror.analyzer.SearchResult - val wrapper1 = if (!withMacrosDisabled) (callsiteTyper.context.withMacrosEnabled[SearchResult] _) else (callsiteTyper.context.withMacrosDisabled[SearchResult] _) - def wrapper (inference: => SearchResult) = wrapper1(inference) val context = callsiteTyper.context.makeImplicit(true) + val wrapper1 = if (!withMacrosDisabled) (context.withMacrosEnabled[SearchResult] _) else (context.withMacrosDisabled[SearchResult] _) + def wrapper (inference: => SearchResult) = wrapper1(inference) wrapper(mirror.analyzer.inferImplicit(mirror.EmptyTree, pt, true, false, context, !silent, pos)) match { case failure if failure.tree.isEmpty => trace("implicit search has failed. to find out the reason, turn on -Xlog-implicits") @@ -51,11 +51,11 @@ trait Typers { def trace(msg: Any) = if (mirror.settings.Ymacrodebug.value) println(msg) trace("inferring implicit view from %s to %s for %s, macros = %s, reportAmbiguous = %s".format(from, to, tree, !withMacrosDisabled, reportAmbiguous)) import mirror.analyzer.SearchResult - val wrapper1 = if (!withMacrosDisabled) (callsiteTyper.context.withMacrosEnabled[SearchResult] _) else (callsiteTyper.context.withMacrosDisabled[SearchResult] _) + val context = callsiteTyper.context.makeImplicit(reportAmbiguous) + val wrapper1 = if (!withMacrosDisabled) (context.withMacrosEnabled[SearchResult] _) else (context.withMacrosDisabled[SearchResult] _) def wrapper (inference: => SearchResult) = wrapper1(inference) val fun1 = mirror.definitions.FunctionClass(1) val viewTpe = mirror.TypeRef(fun1.typeConstructor.prefix, fun1, List(from, to)) - val context = callsiteTyper.context.makeImplicit(reportAmbiguous) wrapper(mirror.analyzer.inferImplicit(mirror.EmptyTree, viewTpe, reportAmbiguous, true, context, !silent, pos)) match { case failure if failure.tree.isEmpty => trace("implicit search has failed. to find out the reason, turn on -Xlog-implicits") diff --git a/src/compiler/scala/reflect/reify/Reifier.scala b/src/compiler/scala/reflect/reify/Reifier.scala index 16c26734b2..c89ebf0d39 100644 --- a/src/compiler/scala/reflect/reify/Reifier.scala +++ b/src/compiler/scala/reflect/reify/Reifier.scala @@ -47,6 +47,15 @@ abstract class Reifier extends Phases if (prefix exists (_.isErroneous)) CannotReifyErroneousPrefix(prefix) if (prefix.tpe == null) CannotReifyUntypedPrefix(prefix) + def reifyErasure(tpe: Type): Tree = { + val result = typer.resolveClassTag(positionBearer, tpe) + if (result == EmptyTree) throw new Error("cannot reify erasure for %s: ".format(tpe)) + result match { + case Apply(TypeApply(Select(_, _), _), List(clazz)) => clazz + case _ => Select(result, nme.erasure) + } + } + val rtree = reifee match { case tree: Tree => reifyTrace("reifying = ")(if (opt.showTrees) "\n" + nodePrinters.nodeToString(tree).trim else tree.toString) @@ -73,11 +82,11 @@ abstract class Reifier extends Phases CannotReifyReifeeThatHasTypeLocalToReifee(tree) val manifestedType = typer.packedType(tree, NoSymbol) - val manifestedRtype = reifyType(manifestedType) val tagModule = if (definitelyConcrete) ConcreteTypeTagModule else TypeTagModule - var typeTagCtor = TypeApply(Select(Ident(nme.MIRROR_SHORT), tagModule.name), List(TypeTree(manifestedType))) - var exprCtor = TypeApply(Select(Ident(nme.MIRROR_SHORT), ExprModule.name), List(TypeTree(manifestedType))) - Apply(Apply(exprCtor, List(rtree)), List(Apply(typeTagCtor, List(manifestedRtype)))) + val tagCtor = TypeApply(Select(Ident(nme.MIRROR_SHORT), tagModule.name), List(TypeTree(manifestedType))) + val exprCtor = TypeApply(Select(Ident(nme.MIRROR_SHORT), ExprModule.name), List(TypeTree(manifestedType))) + val tagArgs = if (definitelyConcrete) List(reify(manifestedType), reifyErasure(manifestedType)) else List(reify(manifestedType)) + Apply(Apply(exprCtor, List(rtree)), List(Apply(tagCtor, tagArgs))) case tpe: Type => reifyTrace("reifying = ")(tpe.toString) @@ -85,9 +94,10 @@ abstract class Reifier extends Phases val rtree = reify(tpe) val manifestedType = tpe - var tagModule = if (definitelyConcrete) ConcreteTypeTagModule else TypeTagModule - var ctor = TypeApply(Select(Ident(nme.MIRROR_SHORT), tagModule.name), List(TypeTree(manifestedType))) - Apply(ctor, List(rtree)) + val tagModule = if (definitelyConcrete) ConcreteTypeTagModule else TypeTagModule + val ctor = TypeApply(Select(Ident(nme.MIRROR_SHORT), tagModule.name), List(TypeTree(manifestedType))) + val args = if (definitelyConcrete) List(rtree, reifyErasure(manifestedType)) else List(rtree) + Apply(ctor, args) case _ => throw new Error("reifee %s of type %s is not supported".format(reifee, if (reifee == null) "null" else reifee.getClass.toString)) @@ -126,7 +136,7 @@ abstract class Reifier extends Phases // 3) local freeterm inlining in Metalevels // 4) trivial tree splice inlining in Reify (Trees.scala) // 5) trivial type splice inlining in Reify (Types.scala) - val freevarBindings = symbolTable collect { case freedef @ FreeDef(_, _, binding, _) => binding.symbol } toSet + val freevarBindings = symbolTable collect { case entry @ FreeDef(_, _, binding, _, _) => binding.symbol } toSet val untyped = resetAllAttrs(wrapped, leaveAlone = { case ValDef(_, mr, _, _) if mr == nme.MIRROR_SHORT => true case tree if freevarBindings contains tree.symbol => true diff --git a/src/compiler/scala/reflect/reify/codegen/Symbols.scala b/src/compiler/scala/reflect/reify/codegen/Symbols.scala index 2fc0002838..0513f99366 100644 --- a/src/compiler/scala/reflect/reify/codegen/Symbols.scala +++ b/src/compiler/scala/reflect/reify/codegen/Symbols.scala @@ -63,9 +63,9 @@ trait Symbols { assert(value.isInstanceOf[Ident], showRaw(value)) val capturedTpe = capturedVariableType(sym) val capturedValue = referenceCapturedVariable(sym) - locallyReify(sym, name, mirrorCall(nme.newFreeTerm, reify(sym.name.toString), reify(capturedTpe), capturedValue, reify(origin(sym)))) + locallyReify(sym, name, mirrorCall(nme.newFreeTerm, reify(sym.name.toString), reify(capturedTpe), capturedValue, reify(sym.flags), reify(origin(sym)))) } else { - locallyReify(sym, name, mirrorCall(nme.newFreeTerm, reify(sym.name.toString), reify(sym.tpe), value, reify(origin(sym)))) + locallyReify(sym, name, mirrorCall(nme.newFreeTerm, reify(sym.name.toString), reify(sym.tpe), value, reify(sym.flags), reify(origin(sym)))) } } @@ -77,8 +77,8 @@ trait Symbols { if (reifyDebug) println("Free type: %s (%s)".format(sym, sym.accurateKindString)) var name = newTermName(nme.MIRROR_FREE_PREFIX + sym.name) val phantomTypeTag = Apply(TypeApply(Select(Ident(nme.MIRROR_SHORT), nme.TypeTag), List(value)), List(Literal(Constant(null)))) - // todo. implement info reification for free types: type bounds, HK-arity, whatever else that can be useful - locallyReify(sym, name, mirrorCall(nme.newFreeType, reify(sym.name.toString), reify(sym.info), phantomTypeTag, reify(origin(sym)))) + val flavor = if (sym.isExistential) nme.newFreeExistential else nme.newFreeType + locallyReify(sym, name, mirrorCall(flavor, reify(sym.name.toString), reify(sym.info), phantomTypeTag, reify(sym.flags), reify(origin(sym)))) } def reifySymDef(sym: Symbol): Tree = @@ -169,7 +169,7 @@ trait Symbols { if (sym.annotations.isEmpty) EmptyTree else Apply(Select(locallyReified(sym), nme.setAnnotations), List(reify(sym.annotations))) } else { - val rset = Apply(Select(locallyReified(sym), nme.setTypeSignature), List(reifyType(sym.info))) + val rset = Apply(Select(locallyReified(sym), nme.setTypeSignature), List(reify(sym.info))) if (sym.annotations.isEmpty) rset else Apply(Select(rset, nme.setAnnotations), List(reify(sym.annotations))) } diff --git a/src/compiler/scala/reflect/reify/codegen/Trees.scala b/src/compiler/scala/reflect/reify/codegen/Trees.scala index 5ad53c0009..c9f5fc5b8d 100644 --- a/src/compiler/scala/reflect/reify/codegen/Trees.scala +++ b/src/compiler/scala/reflect/reify/codegen/Trees.scala @@ -7,6 +7,7 @@ trait Trees { import mirror._ import definitions._ import treeInfo._ + import scala.reflect.api.Modifier // unfortunately, these are necessary to reify AnnotatedTypes // I'd gladly got rid of them, but I don't fancy making a metaprogramming API that doesn't work with annotated types @@ -46,7 +47,7 @@ trait Trees { reifyMirrorObject(EmptyTree) case mirror.emptyValDef => mirrorSelect(nme.emptyValDef) - case FreeDef(_, _, _, _) => + case FreeDef(_, _, _, _, _) => reifyNestedFreeDef(tree) case FreeRef(_, _) => reifyNestedFreeRef(tree) @@ -57,6 +58,28 @@ trait Trees { case NestedExpr(_, _, _) => reifyNestedExpr(tree) case Literal(const @ Constant(_)) => + // [Eugene] was necessary when we reified erasures as normalized tycons + // now, when we do existentialAbstraction on normalizations, everything works great + // todo. find an explanation +// if (const.tag == ClazzTag) { +//// def preprocess(tpe: Type): Type = tpe.typeSymbol match { +//// case ArrayClass => appliedType(ArrayClass, preprocess(tpe.typeArgs.head)) +//// case _ => tpe.typeConstructor +//// } +//// val tpe = preprocess(const.typeValue) +// val tpe = const.typeValue +// var reified = reify(tpe) +// reified = mirrorCall(nme.Literal, mirrorCall(nme.Constant, reified)) +//// val skolems = ClassClass.typeParams map (_ => newTypeName(typer.context.unit.fresh.newName("_$"))) +//// var existential = mirrorCall(nme.AppliedTypeTree, mirrorCall(nme.TypeTree, reify(ClassClass.typeConstructor)), mkList(skolems map (skolem => mirrorCall(nme.Ident, reify(skolem))))) +//// existential = mirrorCall(nme.ExistentialTypeTree, existential, reify(skolems map (skolem => TypeDef(Modifiers(Set(Modifier.deferred: Modifier)), skolem, Nil, TypeBoundsTree(Ident(NothingClass) setType NothingClass.tpe, Ident(AnyClass) setType AnyClass.tpe))))) +//// reified = mirrorCall(nme.TypeApply, mirrorCall(nme.Select, reified, reify(nme.asInstanceOf_)), mkList(List(existential))) +// // why is this required?? +//// reified = mirrorCall(nme.TypeApply, mirrorCall(nme.Select, reified, reify(nme.asInstanceOf_)), mkList(List(mirrorCall(nme.TypeTree, reify(appliedType(ClassClass.tpe, List(AnyClass.tpe))))))) +// reified +// } else { +// mirrorCall(nme.Literal, reifyProduct(const)) +// } mirrorCall(nme.Literal, reifyProduct(const)) case Import(expr, selectors) => mirrorCall(nme.Import, reify(expr), mkList(selectors map reifyProduct)) @@ -68,11 +91,11 @@ trait Trees { // however, reification of AnnotatedTypes is special. see ``reifyType'' to find out why. if (reifyTreeSymbols && tree.hasSymbol) { if (reifyDebug) println("reifying symbol %s for tree %s".format(tree.symbol, tree)) - rtree = Apply(Select(rtree, nme.setSymbol), List(reifySymRef(tree.symbol))) + rtree = Apply(Select(rtree, nme.setSymbol), List(reify(tree.symbol))) } if (reifyTreeTypes && tree.tpe != null) { if (reifyDebug) println("reifying type %s for tree %s".format(tree.tpe, tree)) - rtree = Apply(Select(rtree, nme.setType), List(reifyType(tree.tpe))) + rtree = Apply(Select(rtree, nme.setType), List(reify(tree.tpe))) } rtree @@ -98,7 +121,7 @@ trait Trees { case InlinedTreeSplice(_, inlinedSymbolTable, tree, _) => if (reifyDebug) println("inlining the splicee") // all free vars local to the enclosing reifee should've already been inlined by ``Metalevels'' - inlinedSymbolTable collect { case freedef @ FreeDef(_, _, binding, _) if binding.symbol.isLocalToReifee => assert(false, freedef) } + inlinedSymbolTable collect { case freedef @ FreeDef(_, _, binding, _, _) if binding.symbol.isLocalToReifee => assert(false, freedef) } symbolTable ++= inlinedSymbolTable tree case tree => @@ -172,7 +195,7 @@ trait Trees { val spliced = spliceType(tpe) if (spliced == EmptyTree) { if (reifyDebug) println("splicing failed: reify as is") - mirrorCall(nme.TypeTree, reifyType(tpe)) + mirrorCall(nme.TypeTree, reify(tpe)) } else { spliced match { case TypeRefToFreeType(freeType) => @@ -189,7 +212,7 @@ trait Trees { mirrorCall(nme.Ident, reify(sym)) } else { if (reifyDebug) println("tpe is an alias, but not a locatable: reify as TypeTree(%s)".format(tpe)) - mirrorCall(nme.TypeTree, reifyType(tpe)) + mirrorCall(nme.TypeTree, reify(tpe)) } } } diff --git a/src/compiler/scala/reflect/reify/codegen/Types.scala b/src/compiler/scala/reflect/reify/codegen/Types.scala index 948728088e..e2a2a69828 100644 --- a/src/compiler/scala/reflect/reify/codegen/Types.scala +++ b/src/compiler/scala/reflect/reify/codegen/Types.scala @@ -65,8 +65,16 @@ trait Types { private var spliceTypesEnabled = !dontSpliceAtTopLevel /** Keeps track of whether this reification contains abstract type parameters */ - var maybeConcrete = true - var definitelyConcrete = true + private var _definitelyConcrete = true + def definitelyConcrete = _definitelyConcrete + def definitelyConcrete_=(value: Boolean) { + _definitelyConcrete = value + if (!value && requireConcreteTypeTag) { + assert(current.isInstanceOf[Type], current) + val offender = current.asInstanceOf[Type] + CannotReifyConcreteTypeTagHavingUnresolvedTypeParameters(offender) + } + } private type SpliceCacheKey = (Symbol, Symbol) private lazy val spliceCache: collection.mutable.Map[SpliceCacheKey, Tree] = { @@ -75,7 +83,9 @@ trait Types { } def spliceType(tpe: Type): Tree = { - if (tpe.isSpliceable) { + // [Eugene] it seems that depending on the context the very same symbol can be either a spliceable tparam or a quantified existential. very weird! + val quantified = currents collect { case ExistentialType(quantified, _) => quantified } flatMap identity + if (tpe.isSpliceable && !(quantified contains tpe.typeSymbol)) { if (reifyDebug) println("splicing " + tpe) if (spliceTypesEnabled) { @@ -89,22 +99,18 @@ trait Types { // if this fails, it might produce the dreaded "erroneous or inaccessible type" error // to find out the whereabouts of the error run scalac with -Ydebug if (reifyDebug) println("launching implicit search for %s.%s[%s]".format(prefix, tagClass.name, tpe)) - val positionBearer = mirror.analyzer.openMacros.find(c => c.macroApplication.pos != NoPosition).map(_.macroApplication).getOrElse(EmptyTree).asInstanceOf[Tree] typer.resolveTypeTag(positionBearer, prefix.tpe, tpe, requireConcreteTypeTag) match { case failure if failure.isEmpty => if (reifyDebug) println("implicit search was fruitless") - definitelyConcrete &= false - maybeConcrete &= false EmptyTree case success => if (reifyDebug) println("implicit search has produced a result: " + success) - definitelyConcrete |= requireConcreteTypeTag - maybeConcrete |= true + definitelyConcrete &= requireConcreteTypeTag var splice = Select(success, nme.tpe) splice match { case InlinedTypeSplice(_, inlinedSymbolTable, tpe) => // all free vars local to the enclosing reifee should've already been inlined by ``Metalevels'' - inlinedSymbolTable collect { case freedef @ FreeDef(_, _, binding, _) if binding.symbol.isLocalToReifee => assert(false, freedef) } + inlinedSymbolTable collect { case freedef @ FreeDef(_, _, binding, _, _) if binding.symbol.isLocalToReifee => assert(false, freedef) } symbolTable ++= inlinedSymbolTable reifyTrace("inlined the splicee: ")(tpe) case tpe => @@ -117,8 +123,7 @@ trait Types { if (reifyDebug) println("splicing has been cancelled: spliceTypesEnabled = false") } - if (requireConcreteTypeTag) - CannotReifyConcreteTypeTagHavingUnresolvedTypeParameters(tpe) + definitelyConcrete = false } spliceTypesEnabled = true diff --git a/src/compiler/scala/reflect/reify/codegen/Util.scala b/src/compiler/scala/reflect/reify/codegen/Util.scala index bb369a1adb..8d7cf39ff7 100644 --- a/src/compiler/scala/reflect/reify/codegen/Util.scala +++ b/src/compiler/scala/reflect/reify/codegen/Util.scala @@ -14,6 +14,8 @@ trait Util { object reifiedNodePrinters extends { val global: mirror.type = mirror } with tools.nsc.ast.NodePrinters with NodePrinters val reifiedNodeToString = reifiedNodePrinters.reifiedNodeToString + val positionBearer = mirror.analyzer.openMacros.find(c => c.macroApplication.pos != NoPosition).map(_.macroApplication).getOrElse(EmptyTree).asInstanceOf[Tree] + def reifyList(xs: List[Any]): Tree = mkList(xs map reify) diff --git a/src/compiler/scala/reflect/reify/phases/Metalevels.scala b/src/compiler/scala/reflect/reify/phases/Metalevels.scala index bb0b8ac138..206f3b1118 100644 --- a/src/compiler/scala/reflect/reify/phases/Metalevels.scala +++ b/src/compiler/scala/reflect/reify/phases/Metalevels.scala @@ -115,7 +115,7 @@ trait Metalevels { if (reifyDebug) println("entering inlineable splice: " + splicee) val Block(mrDef :: symbolTable, expr) = splicee // [Eugene] how to express the fact that a scrutinee is both of some type and matches an extractor? - val freedefsToInline = symbolTable collect { case freedef @ FreeTermDef(_, _, binding, _) if binding.symbol.isLocalToReifee => freedef.asInstanceOf[ValDef] } + val freedefsToInline = symbolTable collect { case freedef @ FreeTermDef(_, _, binding, _, _) if binding.symbol.isLocalToReifee => freedef.asInstanceOf[ValDef] } freedefsToInline foreach (vdef => this.freedefsToInline(vdef.name) = vdef) val symbolTable1 = symbolTable diff freedefsToInline val tree1 = Select(Block(mrDef :: symbolTable1, expr), flavor) @@ -138,7 +138,7 @@ trait Metalevels { // some of them need to be rebuilt, some of them need to be removed, because they're no longer necessary case FreeRef(mr, name) if freedefsToInline contains name => if (reifyDebug) println("inlineable free ref: %s in %s".format(name, showRaw(tree))) - val freedef @ FreeDef(_, _, binding, _) = freedefsToInline(name) + val freedef @ FreeDef(_, _, binding, _, _) = freedefsToInline(name) if (reifyDebug) println("related definition: %s".format(showRaw(freedef))) val inlined = reify(binding) if (reifyDebug) println("verdict: inlined as %s".format(showRaw(inlined))) diff --git a/src/compiler/scala/reflect/reify/phases/Reify.scala b/src/compiler/scala/reflect/reify/phases/Reify.scala index 02a96987ed..a1ff486ed7 100644 --- a/src/compiler/scala/reflect/reify/phases/Reify.scala +++ b/src/compiler/scala/reflect/reify/phases/Reify.scala @@ -23,24 +23,33 @@ trait Reify extends Symbols * Reifies any supported value. * For internal use only, use ``reified'' instead. */ - def reify(reifee: Any): Tree = reifee match { - // before adding some case here, in global scope, please, consider - // whether it can be localized like reifyAnnotationInfo or reifyScope - // this will help reification stay as sane as possible - case sym: Symbol => reifySymRef(sym) - case tpe: Type => reifyType(tpe) - case name: Name => reifyName(name) - case tree: Tree => reifyTree(tree) - // disabled because this is a very special case that I plan to remove later - // why do I dislike annotations? see comments to `reifyAnnotationInfo` -// case ann: AnnotationInfo => reifyAnnotationInfo(ann) - case pos: Position => reifyPosition(pos) - case mods: mirror.Modifiers => reifyModifiers(mods) - case xs: List[_] => reifyList(xs) - case s: String => Literal(Constant(s)) - case v if isAnyVal(v) => Literal(Constant(v)) - case null => Literal(Constant(null)) - case _ => - throw new Error("reifee %s of type %s is not supported".format(reifee, reifee.getClass)) + var currents: List[Any] = reifee :: Nil + def current = currents.head + def reify(reifee: Any): Tree = { + currents = reifee :: currents + try { + reifee match { + // before adding some case here, in global scope, please, consider + // whether it can be localized like reifyAnnotationInfo or reifyScope + // this will help reification stay as sane as possible + case sym: Symbol => reifySymRef(sym) + case tpe: Type => reifyType(tpe) + case name: Name => reifyName(name) + case tree: Tree => reifyTree(tree) + // disabled because this is a very special case that I plan to remove later + // why do I dislike annotations? see comments to `reifyAnnotationInfo` +// case ann: AnnotationInfo => reifyAnnotationInfo(ann) + case pos: Position => reifyPosition(pos) + case mods: mirror.Modifiers => reifyModifiers(mods) + case xs: List[_] => reifyList(xs) + case s: String => Literal(Constant(s)) + case v if isAnyVal(v) => Literal(Constant(v)) + case null => Literal(Constant(null)) + case _ => + throw new Error("reifee %s of type %s is not supported".format(reifee, reifee.getClass)) + } + } finally { + currents = currents.tail + } } } \ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/phases/Reshape.scala b/src/compiler/scala/reflect/reify/phases/Reshape.scala index e700604612..4ab306a13f 100644 --- a/src/compiler/scala/reflect/reify/phases/Reshape.scala +++ b/src/compiler/scala/reflect/reify/phases/Reshape.scala @@ -78,12 +78,6 @@ trait Reshape { if (reifyDebug) println("unapplying unapply: " + tree) val fun1 = extractExtractor(fun) Apply(fun1, args).copyAttrs(unapply) - case Literal(const @ Constant(tpe: Type)) => - // todo. implement this - ??? - case Literal(const @ Constant(sym: Symbol)) => - // todo. implement this - ??? case _ => tree } diff --git a/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala b/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala index 6fc5f7ed8a..4048e94d0f 100644 --- a/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala +++ b/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala @@ -14,11 +14,11 @@ trait SynchronizedSymbols extends internal.Symbols { self: SymbolTable => override def connectModuleToClass(m: ModuleSymbol, moduleClass: ClassSymbol): ModuleSymbol = synchronized { super.connectModuleToClass(m, moduleClass) } - override def newFreeTerm(name: TermName, info: Type, value: => Any, origin: String = null, newFlags: Long = 0L): FreeTerm = - new FreeTerm(name, value, origin) with SynchronizedTermSymbol initFlags newFlags setInfo info + override def newFreeTermSymbol(name: TermName, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeTerm = + new FreeTerm(name, value, origin) with SynchronizedTermSymbol initFlags flags setInfo info - override def newFreeType(name: TypeName, info: Type, value: => Any, origin: String = null, newFlags: Long = 0L): FreeType = - new FreeType(name, value, origin) with SynchronizedTypeSymbol initFlags newFlags setInfo info + override def newFreeTypeSymbol(name: TypeName, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeType = + new FreeType(name, value, origin) with SynchronizedTypeSymbol initFlags flags setInfo info override protected def makeNoSymbol: NoSymbol = new NoSymbol with SynchronizedSymbol diff --git a/src/compiler/scala/tools/nsc/ast/FreeVars.scala b/src/compiler/scala/tools/nsc/ast/FreeVars.scala index 1bf36e8bf2..a1983d1834 100644 --- a/src/compiler/scala/tools/nsc/ast/FreeVars.scala +++ b/src/compiler/scala/tools/nsc/ast/FreeVars.scala @@ -13,9 +13,9 @@ trait FreeVars extends reflect.internal.FreeVars { self: Global => case Reified(_, symbolTable, _) => // logging free vars only when they are untyped prevents avalanches of duplicate messages symbolTable foreach { - case FreeTermDef(_, _, binding, origin) if settings.logFreeTerms.value && binding.tpe == null => + case FreeTermDef(_, _, binding, _, origin) if settings.logFreeTerms.value && binding.tpe == null => reporter.echo(position, "free term: %s %s".format(showRaw(binding), origin)) - case FreeTypeDef(_, _, binding, origin) if settings.logFreeTypes.value && binding.tpe == null => + case FreeTypeDef(_, _, binding, _, origin) if settings.logFreeTypes.value && binding.tpe == null => reporter.echo(position, "free type: %s %s".format(showRaw(binding), origin)) case _ => // do nothing diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index 4fb9362ccc..30a79917c9 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -1161,7 +1161,8 @@ trait Implicits { // todo. migrate hardcoded materialization in Implicits to corresponding implicit macros var materializer = atPos(pos.focus)(Apply(TypeApply(Ident(TagMaterializers(tagClass)), List(TypeTree(tp))), List(prefix))) if (settings.XlogImplicits.value) println("materializing requested %s.%s[%s] using %s".format(pre, tagClass.name, tp, materializer)) - success(materializer) + if (context.macrosEnabled) success(materializer) + else failure(materializer, "macros are disabled") } /** The manifest corresponding to type `pt`, provided `pt` is an instance of Manifest. diff --git a/src/library/scala/reflect/ClassTag.scala b/src/library/scala/reflect/ClassTag.scala index 7138837f0d..fe8a16a484 100644 --- a/src/library/scala/reflect/ClassTag.scala +++ b/src/library/scala/reflect/ClassTag.scala @@ -117,6 +117,10 @@ object ClassTag { case _ => apply[T](rm.typeToClass(tpe.erasure)) } + def apply[T](ttag: rm.ConcreteTypeTag[T]): ClassTag[T] = + if (ttag.erasure != null) ClassTag[T](ttag.erasure) + else ClassTag[T](ttag.tpe) + implicit def toDeprecatedClassManifestApis[T](ctag: ClassTag[T]): DeprecatedClassManifestApis[T] = new DeprecatedClassManifestApis[T](ctag) } diff --git a/src/library/scala/reflect/DynamicProxy.scala b/src/library/scala/reflect/DynamicProxy.scala index ffd1e7a39f..02872977f5 100644 --- a/src/library/scala/reflect/DynamicProxy.scala +++ b/src/library/scala/reflect/DynamicProxy.scala @@ -2,13 +2,13 @@ package scala.reflect /** * A dynamic proxy which redirects method calls and attribute access to a given * target object at runtime using reflection. - * + * * Usage example: - * + * * object x{ def hello = "hello world" } * val d = new DynamicProxy{ val dynamicProxyTarget = x } * assert( d.hello == "hello world" ) - * + * * Not supported (yet): * - implicit conversions and parameters * - multiple arguments lists @@ -26,7 +26,7 @@ trait DynamicProxy extends Dynamic{ object DynamicReflectBoxed{ implicit def box[@specialized T]( v:T ) = DynamicReflectBoxed( v.getClass, v ) } - + def selectDynamic( method:String ) = { val symbol = classToType( dynamicProxyTarget.getClass ).member( newTermName(method).encodedName ) invoke( dynamicProxyTarget, symbol )() @@ -38,7 +38,7 @@ trait DynamicProxy extends Dynamic{ } def applyDynamic( method:String )( args:DynamicReflectBoxed* ) : Any - = applyDynamicNamed( method )( args.map( value => ("",value) ) :_* ) + = applyDynamicNamed( method )( args.map( value => ("",value) ) :_* ) def applyDynamicNamed( method:String )( args:(String,DynamicReflectBoxed)* ) : Any = { val class_ = dynamicProxyTarget.getClass @@ -48,27 +48,27 @@ trait DynamicProxy extends Dynamic{ if(args.size == 0){ invoke( dynamicProxyTarget, symbol )() } else { - val call = + val call = Apply( Select( TypeApply( Select( Select( - Ident(newFreeTerm("__this", symbolForName("scala.reflect.DynamicProxy").asType, this, null)) + Ident(newFreeTerm("__this", symbolForName("scala.reflect.DynamicProxy").asType, this)) , newTermName("dynamicProxyTarget") - ), + ), newTermName("asInstanceOf") ) , List(TypeTree().setType(classToType(class_))) ) ,newTermName(method).encodedName ) ,args.map{ case(name,box) => - val value = Ident(newFreeTerm("__arg"+({i+=1;i}.toString), classToType(box.class_), box.value, null)) + val value = Ident(newFreeTerm("__arg"+({i+=1;i}.toString), classToType(box.class_), box.value)) if( name == "" ) value else AssignOrNamedArg( Ident(name), value ) }.toList ) toolbox.runExpr( call ) - } + } } } diff --git a/src/library/scala/reflect/TagMaterialization.scala b/src/library/scala/reflect/TagMaterialization.scala index aede00020f..a7237223f1 100644 --- a/src/library/scala/reflect/TagMaterialization.scala +++ b/src/library/scala/reflect/TagMaterialization.scala @@ -65,59 +65,22 @@ object TagMaterialization { val ConcreteTypeTagClass = selectType(TypeTagsClass, "ConcreteTypeTag") val ConcreteTypeTagModule = selectTerm(TypeTagsClass, "ConcreteTypeTag") - def materializeClassTag(tpe: Type): Tree = { - val prefix = gen.mkAttributedRef(Reflect_mirror) setType singleType(Reflect_mirror.owner.thisPrefix, Reflect_mirror) - materializeClassTag(prefix, tpe) - } - - def materializeClassTag(prefix: Tree, tpe: Type): Tree = { - val typetagInScope = c.inferImplicitValue(appliedType(typeRef(prefix.tpe, ConcreteTypeTagClass, Nil), List(tpe))) - def typetagIsSynthetic(tree: Tree) = tree.isInstanceOf[Block] || (tree exists (sub => sub.symbol == TypeTagModule || sub.symbol == ConcreteTypeTagModule)) - typetagInScope match { - case success if !success.isEmpty && !typetagIsSynthetic(success) => - val factory = TypeApply(Select(Ident(ClassTagModule), newTermName("apply")), List(TypeTree(tpe))) - Apply(factory, List(Select(typetagInScope, newTermName("tpe")))) - case _ => - val result = - tpe match { - case coreTpe if coreTags contains coreTpe => - Select(Ident(ClassTagModule), coreTags(coreTpe)) - case _ => - if (tpe.typeSymbol == ArrayClass) { - val componentTpe = tpe.typeArguments(0) - val classtagInScope = c.inferImplicitValue(appliedType(typeRef(NoPrefix, ClassTagClass, Nil), List(componentTpe))) - val componentTag = classtagInScope orElse materializeClassTag(prefix, componentTpe) - Select(componentTag, newTermName("wrap")) - } else { - // [Eugene] what's the intended behavior? there's no spec on ClassManifests - // for example, should we ban Array[T] or should we tag them with Array[AnyRef]? - // if its the latter, what should be the result of tagging Array[T] where T <: Int? - if (tpe.typeSymbol.isAbstractType) fail("tpe is an abstract type") - val erasure = - if (tpe.typeSymbol.isDerivedValueClass) tpe // [Eugene to Martin] is this correct? - else tpe.erasure.normalize // necessary to deal with erasures of HK types - val factory = TypeApply(Select(Ident(ClassTagModule), newTermName("apply")), List(TypeTree(tpe))) - Apply(factory, List(TypeApply(Ident(newTermName("classOf")), List(TypeTree(erasure))))) - } - } - try c.typeCheck(result) - catch { case terr @ c.TypeError(pos, msg) => fail(terr) } - } - } + def materializeClassTag(tpe: Type): Tree = + materializeTag(c.reflectMirrorPrefix, tpe, ClassTagModule, c.reifyErasure(tpe)) def materializeTypeTag(tpe: Type, requireConcreteTypeTag: Boolean): Tree = { def prefix: Tree = ??? // todo. needs to be synthesized from c.prefix - materializeTypeTag(prefix, tpe, requireConcreteTypeTag) + val tagModule = if (requireConcreteTypeTag) ConcreteTypeTagModule else TypeTagModule + materializeTag(prefix, tpe, tagModule, c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, requireConcreteTypeTag = requireConcreteTypeTag)) } - def materializeTypeTag(prefix: Tree, tpe: Type, requireConcreteTypeTag: Boolean): Tree = { - val tagModule = if (requireConcreteTypeTag) ConcreteTypeTagModule else TypeTagModule + private def materializeTag(prefix: Tree, tpe: Type, tagModule: Symbol, materializer: => Tree): Tree = { val result = tpe match { case coreTpe if coreTags contains coreTpe => Select(Select(prefix, tagModule.name), coreTags(coreTpe)) case _ => - try c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, requireConcreteTypeTag = requireConcreteTypeTag) + try materializer catch { case ex: Throwable => // [Eugene] cannot pattern match on an abstract type, so had to do this diff --git a/src/library/scala/reflect/api/Symbols.scala b/src/library/scala/reflect/api/Symbols.scala index e47bc7216e..d9293888d9 100755 --- a/src/library/scala/reflect/api/Symbols.scala +++ b/src/library/scala/reflect/api/Symbols.scala @@ -120,6 +120,11 @@ trait Symbols { self: Universe => */ def isTerm : Boolean + /** Does this symbol represent a package? + * If yes, `isTerm` is also guaranteed to be true. + */ + def isPackage : Boolean + /** Does this symbol represent the definition of method? * If yes, `isTerm` is also guaranteed to be true. */ @@ -146,6 +151,11 @@ trait Symbols { self: Universe => */ def isClass : Boolean + /** Does this symbol represent a package class? + * If yes, `isClass` is also guaranteed to be true. + */ + def isPackageClass : Boolean + /** Does this symbol represent the definition of a primitive class? * Namely, is it one of [[scala.Double]], [[scala.Float]], [[scala.Long]], [[scala.Int]], [[scala.Char]], * [[scala.Short]], [[scala.Byte]], [[scala.Unit]] or [[scala.Boolean]]? diff --git a/src/library/scala/reflect/api/TreeBuildUtil.scala b/src/library/scala/reflect/api/TreeBuildUtil.scala index 32d7eefa5b..4f510337c2 100644 --- a/src/library/scala/reflect/api/TreeBuildUtil.scala +++ b/src/library/scala/reflect/api/TreeBuildUtil.scala @@ -62,20 +62,34 @@ trait TreeBuildUtil { self: Universe => * @param name the name of the free variable * @param info the type signature of the free variable * @param value the value of the free variable at runtime + * @param flags (optional) flags of the free variable * @param origin debug information that tells where this symbol comes from */ - def newFreeTerm(name: String, info: Type, value: => Any, origin: String): Symbol + def newFreeTerm(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): Symbol - /** Create a fresh free type symbol. + /** Create a fresh free non-existential type symbol. * @param name the name of the free variable * @param info the type signature of the free variable * @param value a type tag that captures the value of the free variable * is completely phantom, since the captured type cannot be propagated to the runtime * if it could be, we wouldn't be creating a free type to begin with * the only usage for it is preserving the captured symbol for compile-time analysis + * @param flags (optional) flags of the free variable * @param origin debug information that tells where this symbol comes from */ - def newFreeType(name: String, info: Type, value: => Any, origin: String): Symbol + def newFreeType(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): Symbol + + /** Create a fresh free existential type symbol. + * @param name the name of the free variable + * @param info the type signature of the free variable + * @param value a type tag that captures the value of the free variable + * is completely phantom, since the captured type cannot be propagated to the runtime + * if it could be, we wouldn't be creating a free type to begin with + * the only usage for it is preserving the captured symbol for compile-time analysis + * @param flags (optional) flags of the free variable + * @param origin (optional) debug information that tells where this symbol comes from + */ + def newFreeExistential(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): Symbol /** Create a Modiiers structure given internal flags, qualifier, annotations */ def modifiersFromInternalFlags(flags: Long, privateWithin: Name, annotations: List[Tree]): Modifiers diff --git a/src/library/scala/reflect/api/TypeTags.scala b/src/library/scala/reflect/api/TypeTags.scala index 59a7c87f44..85755cd2f2 100644 --- a/src/library/scala/reflect/api/TypeTags.scala +++ b/src/library/scala/reflect/api/TypeTags.scala @@ -7,6 +7,7 @@ package scala.reflect package api import scala.reflect.{ mirror => rm } +import java.lang.{ Class => jClass } import language.implicitConversions /** @@ -119,7 +120,7 @@ trait TypeTags { self: Universe => * @see [[scala.reflect.api.TypeTags]] */ @annotation.implicitNotFound(msg = "No ConcreteTypeTag available for ${T}") - class ConcreteTypeTag[T](tpe: Type) extends TypeTag[T](tpe) { + abstract class ConcreteTypeTag[T](tpe: Type, val erasure: jClass[_]) extends TypeTag[T](tpe) { // it's unsafe to use assert here, because we might run into deadlocks with Predef // also see comments in ClassTags.scala //assert(isConcrete, tpe) @@ -128,24 +129,24 @@ trait TypeTags { self: Universe => } object ConcreteTypeTag { - val Byte : ConcreteTypeTag[scala.Byte] = new ConcreteTypeTag[scala.Byte](ByteTpe) { private def readResolve() = ConcreteTypeTag.Byte } - val Short : ConcreteTypeTag[scala.Short] = new ConcreteTypeTag[scala.Short](ShortTpe) { private def readResolve() = ConcreteTypeTag.Short } - val Char : ConcreteTypeTag[scala.Char] = new ConcreteTypeTag[scala.Char](CharTpe) { private def readResolve() = ConcreteTypeTag.Char } - val Int : ConcreteTypeTag[scala.Int] = new ConcreteTypeTag[scala.Int](IntTpe) { private def readResolve() = ConcreteTypeTag.Int } - val Long : ConcreteTypeTag[scala.Long] = new ConcreteTypeTag[scala.Long](LongTpe) { private def readResolve() = ConcreteTypeTag.Long } - val Float : ConcreteTypeTag[scala.Float] = new ConcreteTypeTag[scala.Float](FloatTpe) { private def readResolve() = ConcreteTypeTag.Float } - val Double : ConcreteTypeTag[scala.Double] = new ConcreteTypeTag[scala.Double](DoubleTpe) { private def readResolve() = ConcreteTypeTag.Double } - val Boolean : ConcreteTypeTag[scala.Boolean] = new ConcreteTypeTag[scala.Boolean](BooleanTpe) { private def readResolve() = ConcreteTypeTag.Boolean } - val Unit : ConcreteTypeTag[scala.Unit] = new ConcreteTypeTag[scala.Unit](UnitTpe) { private def readResolve() = ConcreteTypeTag.Unit } - val Any : ConcreteTypeTag[scala.Any] = new ConcreteTypeTag[scala.Any](AnyTpe) { private def readResolve() = ConcreteTypeTag.Any } - val Object : ConcreteTypeTag[java.lang.Object] = new ConcreteTypeTag[java.lang.Object](ObjectTpe) { private def readResolve() = ConcreteTypeTag.Object } - val AnyVal : ConcreteTypeTag[scala.AnyVal] = new ConcreteTypeTag[scala.AnyVal](AnyValTpe) { private def readResolve() = ConcreteTypeTag.AnyVal } - val AnyRef : ConcreteTypeTag[scala.AnyRef] = new ConcreteTypeTag[scala.AnyRef](AnyRefTpe) { private def readResolve() = ConcreteTypeTag.AnyRef } - val Nothing : ConcreteTypeTag[scala.Nothing] = new ConcreteTypeTag[scala.Nothing](NothingTpe) { private def readResolve() = ConcreteTypeTag.Nothing } - val Null : ConcreteTypeTag[scala.Null] = new ConcreteTypeTag[scala.Null](NullTpe) { private def readResolve() = ConcreteTypeTag.Null } - val String : ConcreteTypeTag[java.lang.String] = new ConcreteTypeTag[java.lang.String](StringTpe) { private def readResolve() = ConcreteTypeTag.String } - - def apply[T](tpe: Type): ConcreteTypeTag[T] = + val Byte : ConcreteTypeTag[scala.Byte] = new ConcreteTypeTag[scala.Byte](ByteTpe, ClassTag.Byte.erasure) { private def readResolve() = ConcreteTypeTag.Byte } + val Short : ConcreteTypeTag[scala.Short] = new ConcreteTypeTag[scala.Short](ShortTpe, ClassTag.Short.erasure) { private def readResolve() = ConcreteTypeTag.Short } + val Char : ConcreteTypeTag[scala.Char] = new ConcreteTypeTag[scala.Char](CharTpe, ClassTag.Char.erasure) { private def readResolve() = ConcreteTypeTag.Char } + val Int : ConcreteTypeTag[scala.Int] = new ConcreteTypeTag[scala.Int](IntTpe, ClassTag.Int.erasure) { private def readResolve() = ConcreteTypeTag.Int } + val Long : ConcreteTypeTag[scala.Long] = new ConcreteTypeTag[scala.Long](LongTpe, ClassTag.Long.erasure) { private def readResolve() = ConcreteTypeTag.Long } + val Float : ConcreteTypeTag[scala.Float] = new ConcreteTypeTag[scala.Float](FloatTpe, ClassTag.Float.erasure) { private def readResolve() = ConcreteTypeTag.Float } + val Double : ConcreteTypeTag[scala.Double] = new ConcreteTypeTag[scala.Double](DoubleTpe, ClassTag.Double.erasure) { private def readResolve() = ConcreteTypeTag.Double } + val Boolean : ConcreteTypeTag[scala.Boolean] = new ConcreteTypeTag[scala.Boolean](BooleanTpe, ClassTag.Boolean.erasure) { private def readResolve() = ConcreteTypeTag.Boolean } + val Unit : ConcreteTypeTag[scala.Unit] = new ConcreteTypeTag[scala.Unit](UnitTpe, ClassTag.Unit.erasure) { private def readResolve() = ConcreteTypeTag.Unit } + val Any : ConcreteTypeTag[scala.Any] = new ConcreteTypeTag[scala.Any](AnyTpe, ClassTag.Any.erasure) { private def readResolve() = ConcreteTypeTag.Any } + val Object : ConcreteTypeTag[java.lang.Object] = new ConcreteTypeTag[java.lang.Object](ObjectTpe, ClassTag.Object.erasure) { private def readResolve() = ConcreteTypeTag.Object } + val AnyVal : ConcreteTypeTag[scala.AnyVal] = new ConcreteTypeTag[scala.AnyVal](AnyValTpe, ClassTag.AnyVal.erasure) { private def readResolve() = ConcreteTypeTag.AnyVal } + val AnyRef : ConcreteTypeTag[scala.AnyRef] = new ConcreteTypeTag[scala.AnyRef](AnyRefTpe, ClassTag.AnyRef.erasure) { private def readResolve() = ConcreteTypeTag.AnyRef } + val Nothing : ConcreteTypeTag[scala.Nothing] = new ConcreteTypeTag[scala.Nothing](NothingTpe, ClassTag.Nothing.erasure) { private def readResolve() = ConcreteTypeTag.Nothing } + val Null : ConcreteTypeTag[scala.Null] = new ConcreteTypeTag[scala.Null](NullTpe, ClassTag.Null.erasure) { private def readResolve() = ConcreteTypeTag.Null } + val String : ConcreteTypeTag[java.lang.String] = new ConcreteTypeTag[java.lang.String](StringTpe, ClassTag.String.erasure) { private def readResolve() = ConcreteTypeTag.String } + + def apply[T](tpe: Type, erasure: jClass[_] = null): ConcreteTypeTag[T] = tpe match { case ByteTpe => ConcreteTypeTag.Byte.asInstanceOf[ConcreteTypeTag[T]] case ShortTpe => ConcreteTypeTag.Short.asInstanceOf[ConcreteTypeTag[T]] @@ -163,12 +164,12 @@ trait TypeTags { self: Universe => case NothingTpe => ConcreteTypeTag.Nothing.asInstanceOf[ConcreteTypeTag[T]] case NullTpe => ConcreteTypeTag.Null.asInstanceOf[ConcreteTypeTag[T]] case StringTpe => ConcreteTypeTag.String.asInstanceOf[ConcreteTypeTag[T]] - case _ => new ConcreteTypeTag[T](tpe) {} + case _ => new ConcreteTypeTag[T](tpe, erasure) {} } def unapply[T](ttag: TypeTag[T]): Option[Type] = if (ttag.isConcrete) Some(ttag.tpe) else None - implicit def toClassTag[T](ttag: rm.ConcreteTypeTag[T]): ClassTag[T] = ClassTag[T](rm.typeToClass(ttag.tpe.erasure)) + implicit def toClassTag[T](ttag: rm.ConcreteTypeTag[T]): ClassTag[T] = ClassTag[T](ttag) implicit def toDeprecatedManifestApis[T](ttag: rm.ConcreteTypeTag[T]): DeprecatedManifestApis[T] = new DeprecatedManifestApis[T](ttag) diff --git a/src/library/scala/reflect/api/Types.scala b/src/library/scala/reflect/api/Types.scala index 5e1c1af2fe..4cb5609166 100755 --- a/src/library/scala/reflect/api/Types.scala +++ b/src/library/scala/reflect/api/Types.scala @@ -53,14 +53,26 @@ trait Types { self: Universe => */ def typeArguments: List[Type] + /** For a (potentially wrapped) poly type, its type parameters, + * the empty list for all other types */ + def typeParams: List[Symbol] + /** Is this type a type constructor that is missing its type arguments? */ def isHigherKinded: Boolean // !!! This should be called "isTypeConstructor", no? - /** Does this type refer to abstract types or is an abstract type? + /** Returns the corresponding type constructor (e.g. List for List[T] or List[String]) + */ + def typeConstructor: Type + + /** Does this type refer to spliceable types or is a spliceable type? */ def isConcrete: Boolean + /** Is this type an abstract type that needs to be resolved? + */ + def isSpliceable: Boolean + /** * Expands type aliases and converts higher-kinded TypeRefs to PolyTypes. * Functions on types are also implemented as PolyTypes. diff --git a/src/library/scala/reflect/makro/Reifiers.scala b/src/library/scala/reflect/makro/Reifiers.scala index d690df6aee..b9e82e0387 100644 --- a/src/library/scala/reflect/makro/Reifiers.scala +++ b/src/library/scala/reflect/makro/Reifiers.scala @@ -48,6 +48,10 @@ trait Reifiers { */ def reifyType(prefix: Tree, tpe: Type, dontSpliceAtTopLevel: Boolean = false, requireConcreteTypeTag: Boolean = false): Tree + /** Given a type, generate a tree that when compiled and executed produces the erasure of the original type. + */ + def reifyErasure(tpe: Type): Tree + /** Undoes reification of a tree. * * This reversion doesn't simply restore the original tree (that would lose the context of reification), diff --git a/src/library/scala/reflect/makro/internal/Utils.scala b/src/library/scala/reflect/makro/internal/Utils.scala index db658fd637..604bba10b6 100644 --- a/src/library/scala/reflect/makro/internal/Utils.scala +++ b/src/library/scala/reflect/makro/internal/Utils.scala @@ -55,49 +55,22 @@ package internal { NothingClass.asType -> newTermName("Nothing"), NullClass.asType -> newTermName("Null")) - def materializeClassTag(prefix: Tree, tpe: Type): Tree = { - val typetagInScope = c.inferImplicitValue(appliedType(typeRef(prefix.tpe, ConcreteTypeTagClass, Nil), List(tpe))) - def typetagIsSynthetic(tree: Tree) = tree.isInstanceOf[Block] || (tree exists (sub => sub.symbol == TypeTagModule || sub.symbol == ConcreteTypeTagModule)) - typetagInScope match { - case success if !success.isEmpty && !typetagIsSynthetic(success) => - val factory = TypeApply(Select(Ident(ClassTagModule), newTermName("apply")), List(TypeTree(tpe))) - Apply(factory, List(Select(typetagInScope, newTermName("tpe")))) - case _ => - val result = - tpe match { - case coreTpe if coreTags contains coreTpe => - Select(Ident(ClassTagModule), coreTags(coreTpe)) - case _ => - if (tpe.typeSymbol == ArrayClass) { - val componentTpe = tpe.typeArguments(0) - val classtagInScope = c.inferImplicitValue(appliedType(typeRef(NoPrefix, ClassTagClass, Nil), List(componentTpe))) - val componentTag = classtagInScope orElse materializeClassTag(prefix, componentTpe) - Select(componentTag, newTermName("wrap")) - } else { - // [Eugene] what's the intended behavior? there's no spec on ClassManifests - // for example, should we ban Array[T] or should we tag them with Array[AnyRef]? - // if its the latter, what should be the result of tagging Array[T] where T <: Int? - if (tpe.typeSymbol.isAbstractType) fail("tpe is an abstract type") - val erasure = - if (tpe.typeSymbol.isDerivedValueClass) tpe // [Eugene to Martin] is this correct? - else tpe.erasure.normalize // necessary to deal with erasures of HK types - val factory = TypeApply(Select(Ident(ClassTagModule), newTermName("apply")), List(TypeTree(tpe))) - Apply(factory, List(TypeApply(Ident(newTermName("classOf")), List(TypeTree(erasure))))) - } - } - try c.typeCheck(result) - catch { case terr @ c.TypeError(pos, msg) => fail(terr) } - } - } + def materializeClassTag(prefix: Tree, tpe: Type): Tree = + materializeTag(prefix, tpe, ClassTagModule, c.reifyErasure(tpe)) def materializeTypeTag(prefix: Tree, tpe: Type, requireConcreteTypeTag: Boolean): Tree = { val tagModule = if (requireConcreteTypeTag) ConcreteTypeTagModule else TypeTagModule + materializeTag(prefix, tpe, tagModule, c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, requireConcreteTypeTag = requireConcreteTypeTag)) + } + + private def materializeTag(prefix: Tree, tpe: Type, tagModule: Symbol, materializer: => Tree): Tree = { val result = tpe match { case coreTpe if coreTags contains coreTpe => - Select(Select(prefix, tagModule.name), coreTags(coreTpe)) + val ref = if (tagModule.owner.isPackageClass) Ident(tagModule) else Select(prefix, tagModule.name) + Select(ref, coreTags(coreTpe)) case _ => - try c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, requireConcreteTypeTag = requireConcreteTypeTag) + try materializer catch { case ex: Throwable => // [Eugene] cannot pattern match on an abstract type, so had to do this diff --git a/src/library/scala/reflect/package.scala b/src/library/scala/reflect/package.scala index 6d50a96dfd..93fd0bb711 100644 --- a/src/library/scala/reflect/package.scala +++ b/src/library/scala/reflect/package.scala @@ -64,7 +64,7 @@ package object reflect { @deprecated("Use `@scala.reflect.ConcreteTypeTag` instead", "2.10.0") lazy val Manifest = ConcreteTypeTag @deprecated("NoManifest is no longer supported, and using it may lead to incorrect results, Use `@scala.reflect.TypeTag` instead", "2.10.0") - object NoManifest extends OptManifest[Nothing](scala.reflect.mirror.definitions.NothingClass.asType) with Serializable + object NoManifest extends OptManifest[Nothing](scala.reflect.mirror.TypeTag.Nothing.tpe) // ClassTag class is defined separately from the mirror type TypeTag[T] = scala.reflect.mirror.TypeTag[T] diff --git a/test/files/jvm/interpreter.check b/test/files/jvm/interpreter.check index 292d2fc4cb..85ec46c5f5 100644 --- a/test/files/jvm/interpreter.check +++ b/test/files/jvm/interpreter.check @@ -1,374 +1,375 @@ -Type in expressions to have them evaluated. -Type :help for more information. - -scala> - -scala> // basics - -scala> 3+4 -res0: Int = 7 - -scala> def gcd(x: Int, y: Int): Int = { - if (x == 0) y - else if (y == 0) x - else gcd(y%x, x) -} -gcd: (x: Int, y: Int)Int - -scala> val five = gcd(15,35) -five: Int = 5 - -scala> var x = 1 -x: Int = 1 - -scala> x = 2 -x: Int = 2 - -scala> val three = x+1 -three: Int = 3 - -scala> type anotherint = Int -defined type alias anotherint - -scala> val four: anotherint = 4 -four: anotherint = 4 - -scala> val bogus: anotherint = "hello" -:8: error: type mismatch; - found : String("hello") - required: anotherint - (which expands to) Int - val bogus: anotherint = "hello" - ^ - -scala> trait PointlessTrait -defined trait PointlessTrait - -scala> val (x,y) = (2,3) -x: Int = 2 -y: Int = 3 - -scala> println("hello") -hello - -scala> - -scala> // ticket #1513 - -scala> val t1513 = Array(null) -t1513: Array[Null] = Array(null) - -scala> // ambiguous toString problem from #547 - -scala> val atom = new scala.xml.Atom() -atom: scala.xml.Atom[Unit] = () - -scala> // overriding toString problem from #1404 - -scala> class S(override val toString : String) -defined class S - -scala> val fish = new S("fish") -fish: S = fish - -scala> // Test that arrays pretty print nicely. - -scala> val arr = Array("What's", "up", "doc?") -arr: Array[String] = Array(What's, up, doc?) - -scala> // Test that arrays pretty print nicely, even when we give them type Any - -scala> val arrInt : Any = Array(1,2,3) -arrInt: Any = Array(1, 2, 3) - -scala> // Test that nested arrays are pretty-printed correctly - -scala> val arrArrInt : Any = Array(Array(1, 2), Array(3, 4)) -arrArrInt: Any = Array(Array(1, 2), Array(3, 4)) - -scala> - -scala> // implicit conversions - -scala> case class Foo(n: Int) -defined class Foo - -scala> case class Bar(n: Int) -defined class Bar - -scala> implicit def foo2bar(foo: Foo) = Bar(foo.n) -warning: there were 1 feature warnings; re-run with -feature for details -foo2bar: (foo: Foo)Bar - -scala> val bar: Bar = Foo(3) -bar: Bar = Bar(3) - -scala> - -scala> // importing from a previous result - -scala> import bar._ -import bar._ - -scala> val m = n -m: Int = 3 - -scala> - -scala> // stressing the imports mechanism - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> - -scala> - -scala> val x1 = 1 -x1: Int = 1 - -scala> val x2 = 1 -x2: Int = 1 - -scala> val x3 = 1 -x3: Int = 1 - -scala> val x4 = 1 -x4: Int = 1 - -scala> val x5 = 1 -x5: Int = 1 - -scala> val x6 = 1 -x6: Int = 1 - -scala> val x7 = 1 -x7: Int = 1 - -scala> val x8 = 1 -x8: Int = 1 - -scala> val x9 = 1 -x9: Int = 1 - -scala> val x10 = 1 -x10: Int = 1 - -scala> val x11 = 1 -x11: Int = 1 - -scala> val x12 = 1 -x12: Int = 1 - -scala> val x13 = 1 -x13: Int = 1 - -scala> val x14 = 1 -x14: Int = 1 - -scala> val x15 = 1 -x15: Int = 1 - -scala> val x16 = 1 -x16: Int = 1 - -scala> val x17 = 1 -x17: Int = 1 - -scala> val x18 = 1 -x18: Int = 1 - -scala> val x19 = 1 -x19: Int = 1 - -scala> val x20 = 1 -x20: Int = 1 - -scala> - -scala> val two = one + x5 -two: Int = 2 - -scala> - -scala> // handling generic wildcard arrays (#2386) - -scala> // It's put here because type feedback is an important part of it. - -scala> val xs: Array[_] = Array(1, 2) -xs: Array[_] = Array(1, 2) - -scala> xs.size -res2: Int = 2 - -scala> xs.head -res3: Any = 1 - -scala> xs filter (_ == 2) -res4: Array[_] = Array(2) - -scala> xs map (_ => "abc") -res5: Array[String] = Array(abc, abc) - -scala> xs map (x => x) -res6: scala.collection.mutable.ArraySeq[_] = ArraySeq(1, 2) - -scala> xs map (x => (x, x)) -warning: there were 1 feature warnings; re-run with -feature for details -warning: there were 1 feature warnings; re-run with -feature for details -res7: Array[(_$1, _$1)] forSome { type _$1 } = Array((1,1), (2,2)) - -scala> - -scala> // interior syntax errors should *not* go into multi-line input mode. - -scala> // both of the following should abort immediately: - -scala> def x => y => z -:1: error: '=' expected but '=>' found. - def x => y => z - ^ - -scala> [1,2,3] -:1: error: illegal start of definition - [1,2,3] - ^ - -scala> - -scala> - -scala> // multi-line XML - -scala> - -res8: scala.xml.Elem = - - - -scala> - -scala> - -scala> /* - /* - multi-line comment - */ -*/ - - -You typed two blank lines. Starting a new command. - -scala> // multi-line string - -scala> """ -hello -there -""" -res12: String = -" -hello -there -" - -scala> - -scala> (1 + // give up early by typing two blank lines - - -You typed two blank lines. Starting a new command. - -scala> // defining and using quoted names should work (ticket #323) - -scala> def `match` = 1 -match: Int - -scala> val x = `match` -x: Int = 1 - -scala> - -scala> // multiple classes defined on one line - -scala> sealed class Exp; class Fact extends Exp; class Term extends Exp -defined class Exp -defined class Fact -defined class Term - -scala> def f(e: Exp) = e match { // non-exhaustive warning here - case _:Fact => 3 -} -:18: warning: match is not exhaustive! -missing combination Exp -missing combination Term - - def f(e: Exp) = e match { // non-exhaustive warning here - ^ -f: (e: Exp)Int - -scala> - -scala> +Type in expressions to have them evaluated. +Type :help for more information. + +scala> + +scala> // basics + +scala> 3+4 +res0: Int = 7 + +scala> def gcd(x: Int, y: Int): Int = { + if (x == 0) y + else if (y == 0) x + else gcd(y%x, x) +} +gcd: (x: Int, y: Int)Int + +scala> val five = gcd(15,35) +five: Int = 5 + +scala> var x = 1 +x: Int = 1 + +scala> x = 2 +x: Int = 2 + +scala> val three = x+1 +three: Int = 3 + +scala> type anotherint = Int +defined type alias anotherint + +scala> val four: anotherint = 4 +four: anotherint = 4 + +scala> val bogus: anotherint = "hello" +:8: error: type mismatch; + found : String("hello") + required: anotherint + (which expands to) Int + val bogus: anotherint = "hello" + ^ + +scala> trait PointlessTrait +defined trait PointlessTrait + +scala> val (x,y) = (2,3) +x: Int = 2 +y: Int = 3 + +scala> println("hello") +hello + +scala> + +scala> // ticket #1513 + +scala> val t1513 = Array(null) +t1513: Array[Null] = Array(null) + +scala> // ambiguous toString problem from #547 + +scala> val atom = new scala.xml.Atom() +atom: scala.xml.Atom[Unit] = () + +scala> // overriding toString problem from #1404 + +scala> class S(override val toString : String) +defined class S + +scala> val fish = new S("fish") +fish: S = fish + +scala> // Test that arrays pretty print nicely. + +scala> val arr = Array("What's", "up", "doc?") +arr: Array[String] = Array(What's, up, doc?) + +scala> // Test that arrays pretty print nicely, even when we give them type Any + +scala> val arrInt : Any = Array(1,2,3) +arrInt: Any = Array(1, 2, 3) + +scala> // Test that nested arrays are pretty-printed correctly + +scala> val arrArrInt : Any = Array(Array(1, 2), Array(3, 4)) +arrArrInt: Any = Array(Array(1, 2), Array(3, 4)) + +scala> + +scala> // implicit conversions + +scala> case class Foo(n: Int) +defined class Foo + +scala> case class Bar(n: Int) +defined class Bar + +scala> implicit def foo2bar(foo: Foo) = Bar(foo.n) +warning: there were 1 feature warnings; re-run with -feature for details +foo2bar: (foo: Foo)Bar + +scala> val bar: Bar = Foo(3) +bar: Bar = Bar(3) + +scala> + +scala> // importing from a previous result + +scala> import bar._ +import bar._ + +scala> val m = n +m: Int = 3 + +scala> + +scala> // stressing the imports mechanism + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> + +scala> + +scala> val x1 = 1 +x1: Int = 1 + +scala> val x2 = 1 +x2: Int = 1 + +scala> val x3 = 1 +x3: Int = 1 + +scala> val x4 = 1 +x4: Int = 1 + +scala> val x5 = 1 +x5: Int = 1 + +scala> val x6 = 1 +x6: Int = 1 + +scala> val x7 = 1 +x7: Int = 1 + +scala> val x8 = 1 +x8: Int = 1 + +scala> val x9 = 1 +x9: Int = 1 + +scala> val x10 = 1 +x10: Int = 1 + +scala> val x11 = 1 +x11: Int = 1 + +scala> val x12 = 1 +x12: Int = 1 + +scala> val x13 = 1 +x13: Int = 1 + +scala> val x14 = 1 +x14: Int = 1 + +scala> val x15 = 1 +x15: Int = 1 + +scala> val x16 = 1 +x16: Int = 1 + +scala> val x17 = 1 +x17: Int = 1 + +scala> val x18 = 1 +x18: Int = 1 + +scala> val x19 = 1 +x19: Int = 1 + +scala> val x20 = 1 +x20: Int = 1 + +scala> + +scala> val two = one + x5 +two: Int = 2 + +scala> + +scala> // handling generic wildcard arrays (#2386) + +scala> // It's put here because type feedback is an important part of it. + +scala> val xs: Array[_] = Array(1, 2) +xs: Array[_] = Array(1, 2) + +scala> xs.size +res2: Int = 2 + +scala> xs.head +res3: Any = 1 + +scala> xs filter (_ == 2) +res4: Array[_] = Array(2) + +scala> xs map (_ => "abc") +res5: Array[String] = Array(abc, abc) + +scala> xs map (x => x) +res6: Array[_] = Array(1, 2) + +scala> xs map (x => (x, x)) +warning: there were 1 feature warnings; re-run with -feature for details +warning: there were 1 feature warnings; re-run with -feature for details +res7: Array[(_$1, _$1)] forSome { type _$1 } = Array((1,1), (2,2)) + +scala> + +scala> // interior syntax errors should *not* go into multi-line input mode. + +scala> // both of the following should abort immediately: + +scala> def x => y => z +:1: error: '=' expected but '=>' found. + def x => y => z + ^ + +scala> [1,2,3] +:1: error: illegal start of definition + [1,2,3] + ^ + +scala> + +scala> + +scala> // multi-line XML + +scala> + +res8: scala.xml.Elem = + + + +scala> + +scala> + +scala> /* + /* + multi-line comment + */ +*/ + +scala> + +scala> + +scala> // multi-line string + +scala> """ +hello +there +""" +res9: String = +" +hello +there +" + +scala> + +scala> (1 + // give up early by typing two blank lines + + +You typed two blank lines. Starting a new command. + +scala> // defining and using quoted names should work (ticket #323) + +scala> def `match` = 1 +match: Int + +scala> val x = `match` +x: Int = 1 + +scala> + +scala> // multiple classes defined on one line + +scala> sealed class Exp; class Fact extends Exp; class Term extends Exp +defined class Exp +defined class Fact +defined class Term + +scala> def f(e: Exp) = e match { // non-exhaustive warning here + case _:Fact => 3 +} +:18: warning: match is not exhaustive! +missing combination Exp +missing combination Term + + def f(e: Exp) = e match { // non-exhaustive warning here + ^ +f: (e: Exp)Int + +scala> + +scala> plusOne: (x: Int)Int res0: Int = 6 res0: String = after reset diff --git a/test/files/run/existentials3.check b/test/files/run/existentials3.check index 8227d77909..85bc430a21 100644 --- a/test/files/run/existentials3.check +++ b/test/files/run/existentials3.check @@ -7,7 +7,7 @@ ConcreteTypeTag[() => Test.ToS], t=TypeRef, s=class Function0 ConcreteTypeTag[() => Test.ToS], t=TypeRef, s=class Function0 ConcreteTypeTag[$anon], t=TypeRef, s= <: B with Test.ToS ConcreteTypeTag[$anon], t=TypeRef, s= <: B with A with Test.ToS -ConcreteTypeTag[List[Object{type T1}#T1]], t=TypeRef, s=class List +TypeTag[List[Object{type T1}#T1]], t=TypeRef, s=class List ConcreteTypeTag[List[Seq[Int]]], t=TypeRef, s=class List ConcreteTypeTag[List[Seq[U forSome { type U <: Int }]]], t=TypeRef, s=class List ConcreteTypeTag[Bar.type], t=TypeRef, s= <: scala.runtime.AbstractFunction0[Bar] with Serializable{case def unapply(x$0: Bar): Boolean} with Singleton @@ -19,6 +19,6 @@ ConcreteTypeTag[() => Test.ToS], t=TypeRef, s=class Function0 ConcreteTypeTag[() => Test.ToS], t=TypeRef, s=class Function0 ConcreteTypeTag[$anon], t=TypeRef, s= <: B with Test.ToS ConcreteTypeTag[$anon], t=TypeRef, s= <: B with A with Test.ToS -ConcreteTypeTag[List[Object{type T1}#T1]], t=TypeRef, s=class List +TypeTag[List[Object{type T1}#T1]], t=TypeRef, s=class List ConcreteTypeTag[List[Seq[Int]]], t=TypeRef, s=class List ConcreteTypeTag[List[Seq[U forSome { type U <: Int }]]], t=TypeRef, s=class List diff --git a/test/files/run/macro-reify-typetag-typeparams-notags.check b/test/files/run/macro-reify-typetag-typeparams-notags.check index af4877e205..11d78ece41 100644 --- a/test/files/run/macro-reify-typetag-typeparams-notags.check +++ b/test/files/run/macro-reify-typetag-typeparams-notags.check @@ -1,2 +1,2 @@ -ConcreteTypeTag[T] -ConcreteTypeTag[List[T]] +TypeTag[T] +TypeTag[List[T]] diff --git a/test/files/run/macro-reify-typetag-typeparams-tags.check b/test/files/run/macro-reify-typetag-typeparams-tags.check index d75b3c72b2..458593c449 100644 --- a/test/files/run/macro-reify-typetag-typeparams-tags.check +++ b/test/files/run/macro-reify-typetag-typeparams-tags.check @@ -1,2 +1,2 @@ ConcreteTypeTag[Int] -ConcreteTypeTag[List[Int]] +*ConcreteTypeTag[List[Int]] diff --git a/test/files/run/macro-reify-typetag-usegroundtypetag.check b/test/files/run/macro-reify-typetag-usegroundtypetag.check index d75b3c72b2..458593c449 100644 --- a/test/files/run/macro-reify-typetag-usegroundtypetag.check +++ b/test/files/run/macro-reify-typetag-usegroundtypetag.check @@ -1,2 +1,2 @@ ConcreteTypeTag[Int] -ConcreteTypeTag[List[Int]] +*ConcreteTypeTag[List[Int]] diff --git a/test/files/run/macro-typecheck-macrosdisabled.check b/test/files/run/macro-typecheck-macrosdisabled.check index b432a539fc..3e1057520b 100644 --- a/test/files/run/macro-typecheck-macrosdisabled.check +++ b/test/files/run/macro-typecheck-macrosdisabled.check @@ -1,5 +1,5 @@ { val $mr: reflect.mirror.type = scala.reflect.`package`.mirror; - $mr.Expr.apply[Int(2)]($mr.Literal.apply($mr.Constant.apply(2)))($mr.ConcreteTypeTag.apply[Int(2)]($mr.ConstantType.apply($mr.Constant.apply(2)))) + $mr.Expr.apply[Int(2)]($mr.Literal.apply($mr.Constant.apply(2)))($mr.ConcreteTypeTag.apply[Int(2)]($mr.ConstantType.apply($mr.Constant.apply(2)), classOf[scala.Int])) } mr.reify[Int](2) diff --git a/test/files/run/macro-typecheck-macrosdisabled/Impls_Macros_1.scala b/test/files/run/macro-typecheck-macrosdisabled/Impls_Macros_1.scala index c253f0b1fb..a1f124f790 100644 --- a/test/files/run/macro-typecheck-macrosdisabled/Impls_Macros_1.scala +++ b/test/files/run/macro-typecheck-macrosdisabled/Impls_Macros_1.scala @@ -8,7 +8,7 @@ object Macros { //val mrPkg = staticModule("scala.reflect.package") //val mrSym = selectTerm(mrPkg, "mirror") //val NullaryMethodType(mrTpe) = mrSym.typeSignature - //val mr = newFreeTerm("mr", mrTpe, scala.reflect.mirror, null) + //val mr = newFreeTerm("mr", mrTpe, scala.reflect.mirror) //val tree1 = Apply(Select(Ident(mr), newTermName("reify")), List(Literal(Constant(2)))) val mr = Select(Select(Select(Ident(newTermName("scala")), newTermName("reflect")), newTermName("package")), newTermName("mirror")) @@ -25,7 +25,7 @@ object Macros { val mrPkg = staticModule("scala.reflect.package") val mrSym = selectTerm(mrPkg, "mirror") val NullaryMethodType(mrTpe) = mrSym.typeSignature - val mr = newFreeTerm("mr", mrTpe, scala.reflect.mirror, null) + val mr = newFreeTerm("mr", mrTpe, scala.reflect.mirror) val tree2 = Apply(Select(Ident(mr), newTermName("reify")), List(Literal(Constant(2)))) val ttree2 = c.typeCheck(tree2, withMacrosDisabled = true) diff --git a/test/files/run/reify_newimpl_26.check b/test/files/run/reify_newimpl_26.check index bfbf1d653d..d92b3bd817 100644 --- a/test/files/run/reify_newimpl_26.check +++ b/test/files/run/reify_newimpl_26.check @@ -16,7 +16,7 @@ scala> def foo[T]{ foo: [T]=> Unit scala> foo[Int] -ConcreteTypeTag[List[T]] +TypeTag[List[T]] scala> diff --git a/test/files/run/t3507.check b/test/files/run/t3507.check index 50ab029592..6e4fa4170e 100644 --- a/test/files/run/t3507.check +++ b/test/files/run/t3507.check @@ -1 +1 @@ -ConcreteTypeTag[_1.type#b.c.type] +ConcreteTypeTag[_1.b.c.type] diff --git a/test/files/run/toolbox_typecheck_macrosdisabled.check b/test/files/run/toolbox_typecheck_macrosdisabled.check index cf2420bc17..c4af175812 100644 --- a/test/files/run/toolbox_typecheck_macrosdisabled.check +++ b/test/files/run/toolbox_typecheck_macrosdisabled.check @@ -1,5 +1,5 @@ { val $mr: mr.type = mr; - $mr.Expr.apply[Int(2)]($mr.Literal.apply($mr.Constant.apply(2)))($mr.ConcreteTypeTag.apply[Int(2)]($mr.ConstantType.apply($mr.Constant.apply(2)))) + $mr.Expr.apply[Int(2)]($mr.Literal.apply($mr.Constant.apply(2)))($mr.ConcreteTypeTag.apply[Int(2)]($mr.ConstantType.apply($mr.Constant.apply(2)), classOf[scala.Int])) } mr.reify[Int](2) diff --git a/test/files/run/toolbox_typecheck_macrosdisabled.scala b/test/files/run/toolbox_typecheck_macrosdisabled.scala index 7d2707d5e1..afbbce1736 100644 --- a/test/files/run/toolbox_typecheck_macrosdisabled.scala +++ b/test/files/run/toolbox_typecheck_macrosdisabled.scala @@ -5,7 +5,7 @@ object Test extends App { val mrPkg = staticModule("scala.reflect.package") val mrSym = selectTerm(mrPkg, "mirror") val NullaryMethodType(mrTpe) = mrSym.typeSignature - val mr = newFreeTerm("mr", mrTpe, scala.reflect.mirror, null) + val mr = newFreeTerm("mr", mrTpe, scala.reflect.mirror) val tree1 = Apply(Select(Ident(mr), newTermName("reify")), List(Literal(Constant(2)))) val ttree1 = toolbox.typeCheck(tree1, withMacrosDisabled = false) -- cgit v1.2.3 From b37350b4126a1030d1060fd982d2ade6e2e5bd8e Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Tue, 17 Apr 2012 02:50:33 +0200 Subject: adds a dummy mirror --- src/library/scala/reflect/DummyMirror.scala | 740 +++++++++++++++++++++++++++ src/library/scala/reflect/api/TypeTags.scala | 20 +- src/library/scala/reflect/package.scala | 13 +- 3 files changed, 760 insertions(+), 13 deletions(-) create mode 100644 src/library/scala/reflect/DummyMirror.scala diff --git a/src/library/scala/reflect/DummyMirror.scala b/src/library/scala/reflect/DummyMirror.scala new file mode 100644 index 0000000000..1fbf36be9d --- /dev/null +++ b/src/library/scala/reflect/DummyMirror.scala @@ -0,0 +1,740 @@ +package scala.reflect + +import scala.reflect.api.AbsTreeGen +import scala.reflect.api.Attachment +import scala.reflect.api.Modifier +import scala.reflect.api.Universe + +class DummyMirror(cl: ClassLoader) extends api.Mirror { + // Members declared in scala.reflect.api.AnnotationInfos + implicit def classfileAnnotArgManifest: scala.reflect.ClassManifest[ClassfileAnnotArg] = notSupported() + type AnnotationInfo = DummyAnnotationInfo.type + object DummyAnnotationInfo + val AnnotationInfo: AnnotationInfoExtractor = DummyAnnotationInfoExtractor + object DummyAnnotationInfoExtractor extends AnnotationInfoExtractor { + def apply(atp: Type, args: List[Tree], assocs: List[(Name, ClassfileAnnotArg)]): AnnotationInfo = DummyAnnotationInfo + def unapply(info: AnnotationInfo): Option[(Type, List[Tree], List[(Name, ClassfileAnnotArg)])] = notSupported() + } + type ClassfileAnnotArg = AnyRef + type LiteralAnnotArg = DummyLiteralAnnotArg.type + object DummyLiteralAnnotArg + val LiteralAnnotArg: LiteralAnnotArgExtractor = DummyLiteralAnnotArgExtractor + type ArrayAnnotArg = DummyArrayAnnotArg.type + object DummyArrayAnnotArg + val ArrayAnnotArg: ArrayAnnotArgExtractor = DummyArrayAnnotArgExtractor + type NestedAnnotArg = DummyNestedAnnotArg.type + object DummyNestedAnnotArg + val NestedAnnotArg: NestedAnnotArgExtractor = DummyNestedAnnotArgExtractor + object DummyLiteralAnnotArgExtractor extends LiteralAnnotArgExtractor { + def apply(const: Constant): LiteralAnnotArg = DummyLiteralAnnotArg + def unapply(arg: LiteralAnnotArg): Option[Constant] = notSupported() + } + object DummyArrayAnnotArgExtractor extends ArrayAnnotArgExtractor { + def apply(const: Array[ClassfileAnnotArg]): ArrayAnnotArg = DummyArrayAnnotArg + def unapply(arg: ArrayAnnotArg): Option[Array[ClassfileAnnotArg]] = notSupported() + } + object DummyNestedAnnotArgExtractor extends NestedAnnotArgExtractor { + def apply(anninfo: AnnotationInfo): NestedAnnotArg = DummyNestedAnnotArg + def unapply(arg: NestedAnnotArg): Option[AnnotationInfo] = notSupported() + } + + // Members declared in scala.reflect.api.Constants + type Constant = DummyConstant.type + object DummyConstant extends AbsConstant { + val value: Any = notSupported() + def tpe: Type = notSupported() + def isNaN: Boolean = notSupported() + def booleanValue: Boolean = notSupported() + def byteValue: Byte = notSupported() + def shortValue: Short = notSupported() + def charValue: Char = notSupported() + def intValue: Int = notSupported() + def longValue: Long = notSupported() + def floatValue: Float = notSupported() + def doubleValue: Double = notSupported() + def stringValue: String = notSupported() + def typeValue: Type = notSupported() + def symbolValue: Symbol = notSupported() + def convertTo(pt: Type): Constant = notSupported() + } + val Constant: ConstantExtractor = DummyConstantExtractor + object DummyConstantExtractor extends ConstantExtractor { + def apply(const: Any): Constant = DummyConstant + def unapply(arg: Constant): Option[Any] = notSupported() + } + + // Members declared in scala.reflect.api.FreeVars + type FreeTerm = DummyFreeTerm.type + val DummyFreeTerm = DummySymbol + val FreeTerm: FreeTermExtractor = DummyFreeTermExtractor + object DummyFreeTermExtractor extends FreeTermExtractor { + def unapply(freeTerm: FreeTerm): Option[(TermName, Type, Any, String)] = notSupported() + } + type FreeType = DummyFreeType.type + val DummyFreeType = DummySymbol + val FreeType: FreeTypeExtractor = DummyFreeTypeExtractor + object DummyFreeTypeExtractor extends FreeTypeExtractor { + def unapply(freeType: FreeType): Option[(TypeName, Type, String)] = notSupported() + } + def freeTerms(tree: Tree): List[FreeTerm] = notSupported() + def freeTypes(tree: Tree): List[FreeType] = notSupported() + def substituteFreeTypes(tpe: Type,subs: Map[FreeType,Type]): Type = notSupported() + def substituteFreeTypes(tree: Tree,subs: Map[FreeType,Type]): Tree = notSupported() + + // Members declared in scala.reflect.api.Importers + def mkImporter(from0: scala.reflect.api.Universe): Importer{val from: from0.type} = notSupported() + + // Members declared in scala.reflect.api.Mirror + def classLoader: ClassLoader = cl + def classLoader_=(x$1: ClassLoader): Unit = notSupported() + def classToSymbol(clazz: Class[_]): Symbol = notSupported() + def classToType(clazz: Class[_]): Type = notSupported() + def companionInstance(clazz: Symbol): AnyRef = notSupported() + def getValueOfField(receiver: AnyRef,field: Symbol): Any = notSupported() + def invoke(receiver: AnyRef,meth: Symbol)(args: Any*): Any = notSupported() + def setValueOfField(receiver: AnyRef,field: Symbol,value: Any): Unit = notSupported() + def symbolForName(name: String): Symbol = notSupported() + def symbolOfInstance(instance: Any): Symbol = notSupported() + def symbolToClass(sym: Symbol): Class[_] = notSupported() + def typeOfInstance(instance: Any): Type = notSupported() + def typeToClass(tpe: Type): Class[_] = notSupported() + + // Members declared in scala.reflect.api.Names + type Name = DummyName.type + type TypeName = DummyName.type + type TermName = DummyName.type + object DummyName extends AbsName { + def isTermName: Boolean = notSupported() + def isTypeName: Boolean = notSupported() + def toTermName: TermName = notSupported() + def toTypeName: TypeName = notSupported() + def decoded: String = notSupported() + def encoded: String = notSupported() + def decodedName: Name = notSupported() + def encodedName: Name = notSupported() + } + def newTermName(s: String): TermName = notSupported() + def newTypeName(s: String): TypeName = notSupported() + + // Members declared in scala.reflect.api.Positions + type Position = DummyPosition.type + object DummyPosition extends api.Position { + def pos: Position = notSupported() + def withPos(newPos: scala.reflect.api.Position): Attachment = notSupported() + def payload: Any = notSupported() + def withPayload(newPayload: Any): Attachment = notSupported() + def fileInfo: java.io.File = notSupported() + def fileContent: Array[Char] = notSupported() + def isDefined: Boolean = notSupported() + def isTransparent: Boolean = notSupported() + def isRange: Boolean = notSupported() + def isOpaqueRange: Boolean = notSupported() + def makeTransparent: Position = notSupported() + def start: Int = notSupported() + def startOrPoint: Int = notSupported() + def point: Int = notSupported() + def pointOrElse(default: Int): Int = notSupported() + def end: Int = notSupported() + def endOrPoint: Int = notSupported() + def withStart(off: Int): Position = notSupported() + def withEnd(off: Int): Position = notSupported() + def withPoint(off: Int): Position = notSupported() + def union(pos: scala.reflect.api.Position): Position = notSupported() + def focusStart: Position = notSupported() + def focus: Position = notSupported() + def focusEnd: Position = notSupported() + def includes(pos: scala.reflect.api.Position): Boolean = notSupported() + def properlyIncludes(pos: scala.reflect.api.Position): Boolean = notSupported() + def precedes(pos: scala.reflect.api.Position): Boolean = notSupported() + def properlyPrecedes(pos: scala.reflect.api.Position): Boolean = notSupported() + def overlaps(pos: scala.reflect.api.Position): Boolean = notSupported() + def sameRange(pos: scala.reflect.api.Position): Boolean = notSupported() + def line: Int = notSupported() + def column: Int = notSupported() + def toSingleLine: Position = notSupported() + def lineContent: String = notSupported() + def show: String = notSupported() + } + val NoPosition: Position = DummyPosition + def atPos[T <: Tree](pos: Position)(tree: T): T = tree + def ensureNonOverlapping(tree: Tree,others: List[Tree]): Unit = notSupported() + def wrappingPos(trees: List[Tree]): Position = notSupported() + def wrappingPos(default: Position,trees: List[Tree]): Position = notSupported() + + // Members declared in scala.reflect.api.Reporters + def mkConsoleReporter(minSeverity: Int): Reporter = notSupported() + + // Members declared in scala.reflect.api.Scopes + type Scope = DummyScope.type + object DummyScope extends Iterable[Symbol] { + def iterator: Iterator[Symbol] = notSupported() + } + def newScope: Scope = DummyScope + def newScopeWith(elems: Symbol*): Scope = DummyScope + def newNestedScope(outer: Scope): Scope = DummyScope + + // Members declared in scala.reflect.api.StandardDefinitions + val AnyRefTpe: Type = DummyType + val AnyTpe: Type = DummyType + val AnyValTpe: Type = DummyType + val BooleanTpe: Type = DummyType + val ByteTpe: Type = DummyType + val CharTpe: Type = DummyType + val DoubleTpe: Type = DummyType + val FloatTpe: Type = DummyType + val IntTpe: Type = DummyType + val LongTpe: Type = DummyType + val NothingTpe: Type = DummyType + val NullTpe: Type = DummyType + val ObjectTpe: Type = DummyType + val ShortTpe: Type = DummyType + val StringTpe: Type = DummyType + val UnitTpe: Type = DummyType + val definitions: AbsDefinitions = DummyDefinitions + object DummyDefinitions extends AbsDefinitions { + def AnyClass: Symbol = DummySymbol + def AnyRefClass: Symbol = DummySymbol + def AnyValClass: Symbol = DummySymbol + def ArrayClass: Symbol = DummySymbol + def ArrayModule: Symbol = DummySymbol + def ArrayModule_overloadedApply: Symbol = DummySymbol + def Array_apply: Symbol = DummySymbol + def Array_clone: Symbol = DummySymbol + def Array_length: Symbol = DummySymbol + def Array_update: Symbol = DummySymbol + def BooleanClass: Symbol = DummySymbol + def ByNameParamClass: Symbol = DummySymbol + def ByteClass: Symbol = DummySymbol + def CharClass: Symbol = DummySymbol + def ClassClass: Symbol = DummySymbol + def ClassTagClass: Symbol = DummySymbol + def ClassTagModule: Symbol = DummySymbol + def ConcreteTypeTagClass: Symbol = DummySymbol + def ConcreteTypeTagModule: Symbol = DummySymbol + def ConsClass: Symbol = DummySymbol + def DoubleClass: Symbol = DummySymbol + def EmptyPackage: Symbol = DummySymbol + def EmptyPackageClass: Symbol = DummySymbol + def FloatClass: Symbol = DummySymbol + def FunctionClass: Array[Symbol] = Array() + def IntClass: Symbol = DummySymbol + def IterableClass: Symbol = DummySymbol + def IteratorClass: Symbol = DummySymbol + def IteratorModule: Symbol = DummySymbol + def Iterator_apply: Symbol = DummySymbol + def JavaLangPackage: Symbol = DummySymbol + def JavaLangPackageClass: Symbol = DummySymbol + def JavaRepeatedParamClass: Symbol = DummySymbol + def ListClass: Symbol = DummySymbol + def ListModule: Symbol = DummySymbol + def List_apply: Symbol = DummySymbol + def LongClass: Symbol = DummySymbol + def NilModule: Symbol = DummySymbol + def NoneModule: Symbol = DummySymbol + def NothingClass: Symbol = DummySymbol + def NullClass: Symbol = DummySymbol + def ObjectClass: Symbol = DummySymbol + def OptionClass: Symbol = DummySymbol + def PredefModule: Symbol = DummySymbol + def ProductClass: Array[Symbol] = Array() + def RepeatedParamClass: Symbol = DummySymbol + def RootClass: Symbol = DummySymbol + def RootPackage: Symbol = DummySymbol + def ScalaPackage: Symbol = DummySymbol + def ScalaPackageClass: Symbol = DummySymbol + def ScalaPrimitiveValueClasses: List[Symbol] = List() + def SeqClass: Symbol = DummySymbol + def SeqModule: Symbol = DummySymbol + def ShortClass: Symbol = DummySymbol + def SomeClass: Symbol = DummySymbol + def SomeModule: Symbol = DummySymbol + def StringBuilderClass: Symbol = DummySymbol + def StringClass: Symbol = DummySymbol + def SymbolClass: Symbol = DummySymbol + def TraversableClass: Symbol = DummySymbol + def TupleClass: Array[Symbol] = Array() + def TypeTagClass: Symbol = DummySymbol + def TypeTagModule: Symbol = DummySymbol + def UnitClass: Symbol = DummySymbol + def isNumericValueClass(sym: Symbol): Boolean = notSupported() + def isPrimitiveValueClass(sym: Symbol): Boolean = notSupported() + def vmClassType(arg: Type): Type = DummyType + def vmSignature(sym: Symbol,info: Type): String = notSupported() + } + + // Members declared in scala.reflect.api.StandardNames + val nme: AbsTermNames = DummyAbsTermNames + val tpnme: AbsTypeNames = DummyAbsTypeNames + object DummyAbsTermNames extends AbsTermNames { + type NameType = TermName + val EMPTY: NameType = DummyName + val ANON_FUN_NAME: NameType = DummyName + val ANON_CLASS_NAME: NameType = DummyName + val EMPTY_PACKAGE_NAME: NameType = DummyName + val IMPORT: NameType = DummyName + val MODULE_VAR_SUFFIX: NameType = DummyName + val ROOT: NameType = DummyName + val PACKAGE: NameType = DummyName + val SPECIALIZED_SUFFIX: NameType = DummyName + val ERROR: NameType = DummyName + val NO_NAME: NameType = DummyName + val WILDCARD: NameType = DummyName + def flattenedName(segments: Name*): NameType = notSupported() + val EXPAND_SEPARATOR_STRING: String = "" + val ANYNAME: TermName = DummyName + val CONSTRUCTOR: TermName = DummyName + val FAKE_LOCAL_THIS: TermName = DummyName + val INITIALIZER: TermName = DummyName + val LAZY_LOCAL: TermName = DummyName + val LOCAL_SUFFIX_STRING: String = "" + val MIRROR_PREFIX: TermName = DummyName + val MIRROR_SHORT: TermName = DummyName + val MIRROR_FREE_PREFIX: TermName = DummyName + val MIRROR_FREE_THIS_SUFFIX: TermName = DummyName + val MIRROR_FREE_VALUE_SUFFIX: TermName = DummyName + val MIRROR_SYMDEF_PREFIX: TermName = DummyName + val MIXIN_CONSTRUCTOR: TermName = DummyName + val MODULE_INSTANCE_FIELD: TermName = DummyName + val OUTER: TermName = DummyName + val OUTER_LOCAL: TermName = DummyName + val OUTER_SYNTH: TermName = DummyName + val SELECTOR_DUMMY: TermName = DummyName + val SELF: TermName = DummyName + val SPECIALIZED_INSTANCE: TermName = DummyName + val STAR: TermName = DummyName + val THIS: TermName = DummyName + val BITMAP_NORMAL: TermName = DummyName + val BITMAP_TRANSIENT: TermName = DummyName + val BITMAP_PRIVATE: TermName = DummyName + val BITMAP_CHECKINIT: TermName = DummyName + val BITMAP_CHECKINIT_TRANSIENT: TermName = DummyName + val INTERPRETER_IMPORT_WRAPPER: String = "" + val INTERPRETER_LINE_PREFIX: String = "" + val INTERPRETER_VAR_PREFIX: String = "" + val INTERPRETER_WRAPPER_SUFFIX: String = "" + val ROOTPKG: TermName = DummyName + val ADD: TermName = DummyName + val AND: TermName = DummyName + val ASR: TermName = DummyName + val DIV: TermName = DummyName + val EQ: TermName = DummyName + val EQL: TermName = DummyName + val GE: TermName = DummyName + val GT: TermName = DummyName + val HASHHASH: TermName = DummyName + val LE: TermName = DummyName + val LSL: TermName = DummyName + val LSR: TermName = DummyName + val LT: TermName = DummyName + val MINUS: TermName = DummyName + val MOD: TermName = DummyName + val MUL: TermName = DummyName + val NE: TermName = DummyName + val OR: TermName = DummyName + val PLUS : TermName = DummyName + val SUB: TermName = DummyName + val XOR: TermName = DummyName + val ZAND: TermName = DummyName + val ZOR: TermName = DummyName + val UNARY_~ : TermName = DummyName + val UNARY_+ : TermName = DummyName + val UNARY_- : TermName = DummyName + val UNARY_! : TermName = DummyName + val ??? : TermName = DummyName + val MODULE_SUFFIX_NAME: TermName = DummyName + val NAME_JOIN_NAME: TermName = DummyName + val IMPL_CLASS_SUFFIX: String = "" + val LOCALDUMMY_PREFIX: String = "" + val PROTECTED_PREFIX: String = "" + val PROTECTED_SET_PREFIX: String = "" + val SINGLETON_SUFFIX: String = "" + val SUPER_PREFIX_STRING: String = "" + val TRAIT_SETTER_SEPARATOR_STRING: String = "" + val SETTER_SUFFIX: TermName = DummyName + def isConstructorName(name: Name): Boolean = notSupported() + def isExceptionResultName(name: Name): Boolean = notSupported() + def isImplClassName(name: Name): Boolean = notSupported() + def isLocalDummyName(name: Name): Boolean = notSupported() + def isLocalName(name: Name): Boolean = notSupported() + def isLoopHeaderLabel(name: Name): Boolean = notSupported() + def isProtectedAccessorName(name: Name): Boolean = notSupported() + def isSuperAccessorName(name: Name): Boolean = notSupported() + def isReplWrapperName(name: Name): Boolean = notSupported() + def isSetterName(name: Name): Boolean = notSupported() + def isTraitSetterName(name: Name): Boolean = notSupported() + def isSingletonName(name: Name): Boolean = notSupported() + def isModuleName(name: Name): Boolean = notSupported() + def isOpAssignmentName(name: Name): Boolean = notSupported() + def segments(name: String, assumeTerm: Boolean): List[Name] = notSupported() + def originalName(name: Name): Name = notSupported() + def stripModuleSuffix(name: Name): Name = notSupported() + def unspecializedName(name: Name): Name = notSupported() + def splitSpecializedName(name: Name): (Name, String, String) = notSupported() + def dropLocalSuffix(name: Name): Name = notSupported() + def expandedName(name: TermName, base: Symbol, separator: String = EXPAND_SEPARATOR_STRING): TermName = notSupported() + def expandedSetterName(name: TermName, base: Symbol): TermName = notSupported() + def protName(name: Name): TermName = notSupported() + def protSetterName(name: Name): TermName = notSupported() + def getterName(name: TermName): TermName = notSupported() + def getterToLocal(name: TermName): TermName = notSupported() + def getterToSetter(name: TermName): TermName = notSupported() + def localToGetter(name: TermName): TermName = notSupported() + def setterToGetter(name: TermName): TermName = notSupported() + def defaultGetterName(name: Name, pos: Int): TermName = notSupported() + def defaultGetterToMethod(name: Name): TermName = notSupported() + def dropSingletonName(name: Name): TypeName = notSupported() + def singletonName(name: Name): TypeName = notSupported() + def implClassName(name: Name): TypeName = notSupported() + def interfaceName(implname: Name): TypeName = notSupported() + def localDummyName(clazz: Symbol): TermName = notSupported() + def superName(name: Name): TermName = notSupported() + } + object DummyAbsTypeNames extends AbsTypeNames { + type NameType = TypeName + val EMPTY: NameType = DummyName + val ANON_FUN_NAME: NameType = DummyName + val ANON_CLASS_NAME: NameType = DummyName + val EMPTY_PACKAGE_NAME: NameType = DummyName + val IMPORT: NameType = DummyName + val MODULE_VAR_SUFFIX: NameType = DummyName + val ROOT: NameType = DummyName + val PACKAGE: NameType = DummyName + val SPECIALIZED_SUFFIX: NameType = DummyName + val ERROR: NameType = DummyName + val NO_NAME: NameType = DummyName + val WILDCARD: NameType = DummyName + def flattenedName(segments: Name*): NameType = notSupported() + val REFINE_CLASS_NAME: TypeName = DummyName + val BYNAME_PARAM_CLASS_NAME: TypeName = DummyName + val EQUALS_PATTERN_NAME: TypeName = DummyName + val JAVA_REPEATED_PARAM_CLASS_NAME: TypeName = DummyName + val LOCAL_CHILD: TypeName = DummyName + val REPEATED_PARAM_CLASS_NAME: TypeName = DummyName + val WILDCARD_STAR: TypeName = DummyName + } + + // Members declared in scala.reflect.api.Symbols + type Symbol = DummySymbol.type + val NoSymbol: Symbol = DummySymbol + object DummySymbol extends AbsSymbol { + this: Symbol => + + def pos: Position = notSupported() + def modifiers: Set[Modifier] = notSupported() + def hasModifier(mod: Modifier): Boolean = notSupported() + def annotations: List[AnnotationInfo] = notSupported() + def hasAnnotation(sym: Symbol): Boolean = notSupported() + def owner: Symbol = notSupported() + def name: Name = notSupported() + def fullName: String = notSupported() + def id: Int = notSupported() + def orElse[T](alt: => Symbol): Symbol = notSupported() + def privateWithin: Symbol = notSupported() + def companionSymbol: Symbol = notSupported() + def moduleClass: Symbol = notSupported() + def enclosingTopLevelClass: Symbol = notSupported() + def enclosingClass: Symbol = notSupported() + def enclosingMethod: Symbol = notSupported() + def enclosingPackageClass: Symbol = notSupported() + def isTerm : Boolean = notSupported() + def isPackage : Boolean = notSupported() + def isMethod : Boolean = notSupported() + def isOverloaded : Boolean = notSupported() + def isFreeTerm : Boolean = notSupported() + def isType : Boolean = notSupported() + def isClass : Boolean = notSupported() + def isPackageClass : Boolean = notSupported() + def isPrimitiveValueClass: Boolean = notSupported() + def isDerivedValueClass: Boolean = notSupported() + def isAliasType : Boolean = notSupported() + def isAbstractType : Boolean = notSupported() + def isSkolem : Boolean = notSupported() + def isExistential : Boolean = notSupported() + def isFreeType : Boolean = notSupported() + def isContravariant : Boolean = notSupported() + def isCovariant : Boolean = notSupported() + def isErroneous : Boolean = notSupported() + def typeSignature: Type = notSupported() + def typeSignatureIn(site: Type): Type = notSupported() + def asType: Type = notSupported() + def asTypeIn(site: Type): Type = notSupported() + def asTypeConstructor: Type = notSupported() + def thisPrefix: Type = notSupported() + def selfType: Type = notSupported() + def alternatives: List[Symbol] = notSupported() + def resolveOverloaded(pre: Type = NoPrefix, targs: Seq[Type] = List(), actuals: Seq[Type]): Symbol = notSupported() + def newNestedSymbol(name: Name, pos: Position, flags: Long, isClass: Boolean): Symbol = notSupported() + def setInternalFlags(flags: Long): this.type = notSupported() + def setTypeSignature(tpe: Type): this.type = notSupported() + def setAnnotations(annots: AnnotationInfo*): this.type = notSupported() + def kind: String = notSupported() + } + + // Members declared in scala.reflect.api.ToolBoxes + def mkToolBox(reporter: Reporter,options: String): AbsToolBox = notSupported() + + // Members declared in scala.reflect.api.TreeBuildUtil + // type TreeGen = DummyTreeGen.type // [Eugene] cannot compile if uncomment this + val gen: TreeGen{val global: DummyMirror.this.type} = DummyTreeGen.asInstanceOf[TreeGen{val global: DummyMirror.this.type}] + def modifiersFromInternalFlags(flags: Long,privateWithin: Name,annotations: List[Tree]): Modifiers = DummyModifiers + def newFreeExistential(name: String,info: Type,value: => Any,flags: Long,origin: String): Symbol = DummySymbol + def newFreeTerm(name: String,info: Type,value: => Any,flags: Long,origin: String): Symbol = DummySymbol + def newFreeType(name: String,info: Type,value: => Any,flags: Long,origin: String): Symbol = DummySymbol + def selectOverloadedMethod(owner: Symbol,name: String,index: Int): Symbol = DummySymbol + def selectOverloadedMethodIfDefined(owner: Symbol,name: String,index: Int): Symbol = DummySymbol + def selectTerm(owner: Symbol,name: String): Symbol = DummySymbol + def selectTermIfDefined(owner: Symbol,name: String): Symbol = DummySymbol + def selectType(owner: Symbol,name: String): Symbol = DummySymbol + def selectTypeIfDefined(owner: Symbol,name: String): Symbol = DummySymbol + def staticClass(fullName: String): Symbol = DummySymbol + def staticClassIfDefined(fullName: String): Symbol = DummySymbol + def staticModule(fullName: String): Symbol = DummySymbol + def staticModuleIfDefined(fullName: String): Symbol = DummySymbol + def thisModuleType(fullName: String): Type = DummyType + object DummyTreeGen extends AbsTreeGen { + val global: Universe = DummyMirror.this + type TreeGenTree = global.Tree + type TreeGenType = global.Type + type TreeGenSymbol = global.Symbol + def mkAttributedQualifier(tpe: TreeGenType): TreeGenTree = notSupported() + def mkAttributedQualifier(tpe: TreeGenType, termSym: TreeGenSymbol): TreeGenTree = notSupported() + def mkAttributedRef(pre: TreeGenType, sym: TreeGenSymbol): TreeGenTree = notSupported() + def mkAttributedRef(sym: TreeGenSymbol): TreeGenTree = notSupported() + def mkAttributedThis(sym: TreeGenSymbol): TreeGenTree = notSupported() + def mkAttributedIdent(sym: TreeGenSymbol): TreeGenTree = notSupported() + def mkAttributedSelect(qual: TreeGenTree, sym: TreeGenSymbol): TreeGenTree = notSupported() + } + + // Members declared in scala.reflect.api.TreePrinters + def newTreePrinter(out: java.io.PrintWriter): TreePrinter = notSupported() + + // Members declared in scala.reflect.api.Trees + def Apply(sym: Symbol,args: Tree*): Tree = Apply(EmptyTree, Nil) + def Bind(sym: Symbol,body: Tree): Bind = Bind(DummyName, EmptyTree) + def Block(stats: Tree*): Block = Block() + def CaseDef(pat: Tree,body: Tree): CaseDef = CaseDef(EmptyTree, EmptyTree, EmptyTree) + def ClassDef(sym: Symbol,impl: Template): ClassDef = ClassDef(DummyModifiers, DummyName, Nil, Template(Nil, emptyValDef, Nil)) + def DefDef(sym: Symbol,rhs: List[List[Symbol]] => Tree): DefDef = DefDef(DummyModifiers, DummyName, Nil, Nil, EmptyTree, EmptyTree) + def DefDef(sym: Symbol,rhs: Tree): DefDef = DefDef(DummyModifiers, DummyName, Nil, Nil, EmptyTree, EmptyTree) + def DefDef(sym: Symbol,mods: Modifiers,rhs: Tree): DefDef = DefDef(DummyModifiers, DummyName, Nil, Nil, EmptyTree, EmptyTree) + def DefDef(sym: Symbol,vparamss: List[List[ValDef]],rhs: Tree): DefDef = DefDef(DummyModifiers, DummyName, Nil, Nil, EmptyTree, EmptyTree) + def DefDef(sym: Symbol,mods: Modifiers,vparamss: List[List[ValDef]],rhs: Tree): DefDef = DefDef(DummyModifiers, DummyName, Nil, Nil, EmptyTree, EmptyTree) + def Ident(sym: Symbol): Ident = Ident(DummyName) + def Ident(name: String): Ident = Ident(DummyName) + def LabelDef(sym: Symbol,params: List[Symbol],rhs: Tree): LabelDef = LabelDef(DummyName, Nil, EmptyTree) + type Modifiers = DummyModifiers.type + val NoMods: Modifiers = DummyModifiers + object DummyModifiers extends AbsModifiers { + def modifiers: Set[Modifier] = notSupported() + def hasModifier(mod: Modifier): Boolean = notSupported() + def privateWithin: Name = notSupported() + def annotations: List[Tree] = notSupported() + def mapAnnotations(f: List[Tree] => List[Tree]): Modifiers = notSupported() + } + def Modifiers(mods: Set[scala.reflect.api.Modifier],privateWithin: Name,annotations: List[Tree]): Modifiers = DummyModifiers + def ModuleDef(sym: Symbol,impl: Template): ModuleDef = ModuleDef(DummyModifiers, DummyName, Template(Nil, emptyValDef, Nil)) + def New(sym: Symbol,args: Tree*): Tree = New(EmptyTree) + def New(tpe: Type,args: Tree*): Tree = New(EmptyTree) + def New(tpt: Tree,argss: List[List[Tree]]): Tree = New(EmptyTree) + def Select(qualifier: Tree,sym: Symbol): Select = Select(EmptyTree, DummyName) + def Select(qualifier: Tree,name: String): Select = Select(EmptyTree, DummyName) + def Super(sym: Symbol,mix: TypeName): Tree = Super(EmptyTree, DummyName) + def This(sym: Symbol): Tree = This(DummyName) + def Throw(tpe: Type,args: Tree*): Throw = Throw(EmptyTree) + def Try(body: Tree,cases: (Tree, Tree)*): Try = Try(EmptyTree) + def TypeDef(sym: Symbol): TypeDef = TypeDef(DummyModifiers, DummyName, Nil, EmptyTree) + def TypeDef(sym: Symbol,rhs: Tree): TypeDef = TypeDef(DummyModifiers, DummyName, Nil, EmptyTree) + def ValDef(sym: Symbol): ValDef = ValDef(DummyModifiers, DummyName, EmptyTree, EmptyTree) + def ValDef(sym: Symbol,rhs: Tree): ValDef = ValDef(DummyModifiers, DummyName, EmptyTree, EmptyTree) + protected def duplicateTree(tree: Tree): Tree = notSupported() + object emptyValDef extends ValDef(DummyModifiers, DummyName, EmptyTree, EmptyTree) { override def isEmpty = true } + type TreeCopier = DummyTreeCopier.type + def newStrictTreeCopier: TreeCopier = DummyTreeCopier + def newLazyTreeCopier: TreeCopier = DummyTreeCopier + object DummyTreeCopier extends TreeCopierOps { + def ClassDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], impl: Template): ClassDef = notSupported() + def PackageDef(tree: Tree, pid: RefTree, stats: List[Tree]): PackageDef = notSupported() + def ModuleDef(tree: Tree, mods: Modifiers, name: Name, impl: Template): ModuleDef = notSupported() + def ValDef(tree: Tree, mods: Modifiers, name: Name, tpt: Tree, rhs: Tree): ValDef = notSupported() + def DefDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree): DefDef = notSupported() + def TypeDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], rhs: Tree): TypeDef = notSupported() + def LabelDef(tree: Tree, name: Name, params: List[Ident], rhs: Tree): LabelDef = notSupported() + def Import(tree: Tree, expr: Tree, selectors: List[ImportSelector]): Import = notSupported() + def Template(tree: Tree, parents: List[Tree], self: ValDef, body: List[Tree]): Template = notSupported() + def Block(tree: Tree, stats: List[Tree], expr: Tree): Block = notSupported() + def CaseDef(tree: Tree, pat: Tree, guard: Tree, body: Tree): CaseDef = notSupported() + def Alternative(tree: Tree, trees: List[Tree]): Alternative = notSupported() + def Star(tree: Tree, elem: Tree): Star = notSupported() + def Bind(tree: Tree, name: Name, body: Tree): Bind = notSupported() + def UnApply(tree: Tree, fun: Tree, args: List[Tree]): UnApply = notSupported() + def ArrayValue(tree: Tree, elemtpt: Tree, trees: List[Tree]): ArrayValue = notSupported() + def Function(tree: Tree, vparams: List[ValDef], body: Tree): Function = notSupported() + def Assign(tree: Tree, lhs: Tree, rhs: Tree): Assign = notSupported() + def AssignOrNamedArg(tree: Tree, lhs: Tree, rhs: Tree): AssignOrNamedArg = notSupported() + def If(tree: Tree, cond: Tree, thenp: Tree, elsep: Tree): If = notSupported() + def Match(tree: Tree, selector: Tree, cases: List[CaseDef]): Match = notSupported() + def Return(tree: Tree, expr: Tree): Return = notSupported() + def Try(tree: Tree, block: Tree, catches: List[CaseDef], finalizer: Tree): Try = notSupported() + def Throw(tree: Tree, expr: Tree): Throw = notSupported() + def New(tree: Tree, tpt: Tree): New = notSupported() + def Typed(tree: Tree, expr: Tree, tpt: Tree): Typed = notSupported() + def TypeApply(tree: Tree, fun: Tree, args: List[Tree]): TypeApply = notSupported() + def Apply(tree: Tree, fun: Tree, args: List[Tree]): Apply = notSupported() + def ApplyDynamic(tree: Tree, qual: Tree, args: List[Tree]): ApplyDynamic = notSupported() + def Super(tree: Tree, qual: Tree, mix: TypeName): Super = notSupported() + def This(tree: Tree, qual: Name): This = notSupported() + def Select(tree: Tree, qualifier: Tree, selector: Name): Select = notSupported() + def Ident(tree: Tree, name: Name): Ident = notSupported() + def ReferenceToBoxed(tree: Tree, idt: Ident): ReferenceToBoxed = notSupported() + def Literal(tree: Tree, value: Constant): Literal = notSupported() + def TypeTree(tree: Tree): TypeTree = notSupported() + def Annotated(tree: Tree, annot: Tree, arg: Tree): Annotated = notSupported() + def SingletonTypeTree(tree: Tree, ref: Tree): SingletonTypeTree = notSupported() + def SelectFromTypeTree(tree: Tree, qualifier: Tree, selector: Name): SelectFromTypeTree = notSupported() + def CompoundTypeTree(tree: Tree, templ: Template): CompoundTypeTree = notSupported() + def AppliedTypeTree(tree: Tree, tpt: Tree, args: List[Tree]): AppliedTypeTree = notSupported() + def TypeBoundsTree(tree: Tree, lo: Tree, hi: Tree): TypeBoundsTree = notSupported() + def ExistentialTypeTree(tree: Tree, tpt: Tree, whereClauses: List[Tree]): ExistentialTypeTree = notSupported() + } + + // Members declared in scala.reflect.api.Types + type Type = DummyType.type + type SingletonType = DummyType.type + type CompoundType = DummyType.type + type AnnotatedType = DummyType.type + val AnnotatedType: AnnotatedTypeExtractor = DummyAnnotatedTypeExtractor + type BoundedWildcardType = DummyType.type + val BoundedWildcardType: BoundedWildcardTypeExtractor = DummyBoundedWildcardTypeExtractor + type ClassInfoType = DummyType.type + val ClassInfoType: ClassInfoTypeExtractor = DummyClassInfoTypeExtractor + type ConstantType = DummyType.type + val ConstantType: ConstantTypeExtractor = DummyConstantTypeExtractor + type ExistentialType = DummyType.type + val ExistentialType: ExistentialTypeExtractor = DummyExistentialTypeExtractor + type MethodType = DummyType.type + val MethodType: MethodTypeExtractor = DummyMethodTypeExtractor + val NoPrefix: Type = DummyType + val NoType: Type = DummyType + type NullaryMethodType = DummyType.type + val NullaryMethodType: NullaryMethodTypeExtractor = DummyNullaryMethodTypeExtractor + type PolyType = DummyType.type + val PolyType: PolyTypeExtractor = DummyPolyTypeExtractor + type RefinedType = DummyType.type + val RefinedType: RefinedTypeExtractor = DummyRefinedTypeExtractor + type SingleType = DummyType.type + val SingleType: SingleTypeExtractor = DummySingleTypeExtractor + type SuperType = DummyType.type + val SuperType: SuperTypeExtractor = DummySuperTypeExtractor + type ThisType = DummyType.type + val ThisType: ThisTypeExtractor = DummyThisTypeExtractor + type TypeBounds = DummyType.type + val TypeBounds: TypeBoundsExtractor = DummyTypeBoundsExtractor + type TypeRef = DummyType.type + val TypeRef: TypeRefExtractor = DummyTypeRefExtractor + val WildcardType: Type = DummyType + def appliedType(tycon: Type,args: List[Type]): Type = DummyType + def existentialAbstraction(tparams: List[Symbol],tpe0: Type): Type = DummyType + def glb(ts: List[Type]): Type = DummyType + def intersectionType(tps: List[Type],owner: Symbol): Type = DummyType + def intersectionType(tps: List[Type]): Type = DummyType + def lub(xs: List[Type]): Type = DummyType + def polyType(tparams: List[Symbol],tpe: Type): Type = DummyType + def refinedType(parents: List[Type],owner: Symbol): Type = DummyType + def refinedType(parents: List[Type],owner: Symbol,decls: Scope,pos: Position): Type = DummyType + def singleType(pre: Type,sym: Symbol): Type = DummyType + def typeRef(pre: Type,sym: Symbol,args: List[Type]): Type = DummyType + object DummyType extends AbsType { + def =:=(that: Type): Boolean = notSupported() + def <:<(that: Type): Boolean = notSupported() + def asSeenFrom(pre: Type,clazz: Symbol): Type = notSupported() + def baseClasses: List[Symbol] = notSupported() + def baseType(clazz: Symbol): Type = notSupported() + def contains(sym: Symbol): Boolean = notSupported() + def declaration(name: Name): Symbol = notSupported() + def declarations: Iterable[Symbol] = notSupported() + def erasure: Type = notSupported() + def exists(p: Type => Boolean): Boolean = notSupported() + def find(p: Type => Boolean): Option[Type] = notSupported() + def foreach(f: Type => Unit): Unit = notSupported() + def isConcrete: Boolean = notSupported() + def isHigherKinded: Boolean = notSupported() + def isSpliceable: Boolean = notSupported() + def kind: String = notSupported() + def map(f: Type => Type): Type = notSupported() + def member(name: Name): Symbol = notSupported() + def members: Iterable[Symbol] = notSupported() + def nonPrivateMember(name: Name): Symbol = notSupported() + def nonPrivateMembers: Iterable[Symbol] = notSupported() + def normalize: Type = notSupported() + def parents: List[Type] = notSupported() + def substituteTypes(from: List[Symbol],to: List[Type]): Type = notSupported() + def typeArguments: List[Type] = notSupported() + def typeConstructor: Type = notSupported() + def typeParams: List[Symbol] = notSupported() + def typeSymbol: Symbol = notSupported() + def underlying: Type = notSupported() + def widen: Type = notSupported() + } + object DummyAnnotatedTypeExtractor extends AnnotatedTypeExtractor { + def apply(annotations: List[AnnotationInfo], underlying: Type, selfsym: Symbol): AnnotatedType = DummyType + def unapply(tpe: AnnotatedType): Option[(List[AnnotationInfo], Type, Symbol)] = notSupported() + } + object DummyBoundedWildcardTypeExtractor extends BoundedWildcardTypeExtractor { + def apply(bounds: TypeBounds): BoundedWildcardType = DummyType + def unapply(tpe: BoundedWildcardType): Option[TypeBounds] = notSupported() + } + object DummyClassInfoTypeExtractor extends ClassInfoTypeExtractor { + def apply(parents: List[Type], decls: Scope, clazz: Symbol): ClassInfoType = DummyType + def unapply(tpe: ClassInfoType): Option[(List[Type], Scope, Symbol)] = notSupported() + } + object DummyConstantTypeExtractor extends ConstantTypeExtractor { + def apply(value: Constant): ConstantType = DummyType + def unapply(tpe: ConstantType): Option[Constant] = notSupported() + } + object DummyExistentialTypeExtractor extends ExistentialTypeExtractor { + def apply(quantified: List[Symbol], underlying: Type): ExistentialType = DummyType + def unapply(tpe: ExistentialType): Option[(List[Symbol], Type)] = notSupported() + } + object DummyMethodTypeExtractor extends MethodTypeExtractor { + def apply(params: List[Symbol], resultType: Type): MethodType = DummyType + def unapply(tpe: MethodType): Option[(List[Symbol], Type)] = notSupported() + } + object DummyNullaryMethodTypeExtractor extends NullaryMethodTypeExtractor { + def apply(resultType: Type): NullaryMethodType = DummyType + def unapply(tpe: NullaryMethodType): Option[(Type)] = notSupported() + } + object DummyPolyTypeExtractor extends PolyTypeExtractor { + def apply(typeParams: List[Symbol], resultType: Type): PolyType = DummyType + def unapply(tpe: PolyType): Option[(List[Symbol], Type)] = notSupported() + } + object DummyRefinedTypeExtractor extends RefinedTypeExtractor { + def apply(parents: List[Type], decls: Scope): RefinedType = DummyType + def apply(parents: List[Type], decls: Scope, clazz: Symbol): RefinedType = DummyType + def unapply(tpe: RefinedType): Option[(List[Type], Scope)] = notSupported() + } + object DummySingleTypeExtractor extends SingleTypeExtractor { + def apply(pre: Type, sym: Symbol): Type = DummyType + def unapply(tpe: SingleType): Option[(Type, Symbol)] = notSupported() + } + object DummySuperTypeExtractor extends SuperTypeExtractor { + def apply(thistpe: Type, supertpe: Type): Type = DummyType + def unapply(tpe: SuperType): Option[(Type, Type)] = notSupported() + } + object DummyThisTypeExtractor extends ThisTypeExtractor { + def apply(sym: Symbol): Type = DummyType + def unapply(tpe: ThisType): Option[Symbol] = notSupported() + } + object DummyTypeBoundsExtractor extends TypeBoundsExtractor { + def apply(lo: Type, hi: Type): TypeBounds = DummyType + def unapply(tpe: TypeBounds): Option[(Type, Type)] = notSupported() + } + object DummyTypeRefExtractor extends TypeRefExtractor { + def apply(pre: Type, sym: Symbol, args: List[Type]): Type = DummyType + def unapply(tpe: TypeRef): Option[(Type, Symbol, List[Type])] = notSupported() + } + + // Utils + def notSupported() = { + throw new UnsupportedOperationException("Scala reflection not available on this platform." + mirrorDiagnostics(cl)) + } +} \ No newline at end of file diff --git a/src/library/scala/reflect/api/TypeTags.scala b/src/library/scala/reflect/api/TypeTags.scala index 85755cd2f2..f7c4c63e94 100644 --- a/src/library/scala/reflect/api/TypeTags.scala +++ b/src/library/scala/reflect/api/TypeTags.scala @@ -67,9 +67,13 @@ trait TypeTags { self: Universe => def toConcrete: ConcreteTypeTag[T] = ConcreteTypeTag[T](tpe) override def toString = { - var prefix = if (isConcrete) "ConcreteTypeTag" else "TypeTag" - if (prefix != this.productPrefix) prefix = "*" + prefix - prefix + "[" + tpe + "]" + if (!self.isInstanceOf[DummyMirror]) { + var prefix = if (isConcrete) "ConcreteTypeTag" else "TypeTag" + if (prefix != this.productPrefix) prefix = "*" + prefix + prefix + "[" + tpe + "]" + } else { + this.productPrefix + "[?]" + } } } @@ -121,10 +125,12 @@ trait TypeTags { self: Universe => */ @annotation.implicitNotFound(msg = "No ConcreteTypeTag available for ${T}") abstract class ConcreteTypeTag[T](tpe: Type, val erasure: jClass[_]) extends TypeTag[T](tpe) { - // it's unsafe to use assert here, because we might run into deadlocks with Predef - // also see comments in ClassTags.scala - //assert(isConcrete, tpe) - if (notConcrete) throw new Error("%s (%s) is not concrete and cannot be used to construct a concrete type tag".format(tpe, tpe.kind)) + if (!self.isInstanceOf[DummyMirror]) { +// it's unsafe to use assert here, because we might run into deadlocks with Predef +// also see comments in ClassTags.scala +// assert(isConcrete, tpe) + if (notConcrete) throw new Error("%s (%s) is not concrete and cannot be used to construct a concrete type tag".format(tpe, tpe.kind)) + } override def productPrefix = "ConcreteTypeTag" } diff --git a/src/library/scala/reflect/package.scala b/src/library/scala/reflect/package.scala index 93fd0bb711..0958f2ce9a 100644 --- a/src/library/scala/reflect/package.scala +++ b/src/library/scala/reflect/package.scala @@ -11,18 +11,19 @@ package object reflect { // initialization, but in response to a doomed attempt to utilize it. // todo. default mirror (a static object) might become a source for memory leaks (because it holds a strong reference to a classloader)! - lazy val mirror: api.Mirror = mkMirror(defaultReflectionClassLoader) + lazy val mirror: api.Mirror = + try mkMirror(defaultReflectionClassLoader) + catch { + case ex: UnsupportedOperationException => + new DummyMirror(defaultReflectionClassLoader) + } - private def mirrorDiagnostics(cl: ClassLoader): String = """ + private[scala] def mirrorDiagnostics(cl: ClassLoader): String = """ | | This error has happened because `scala.reflect.runtime.package` located in | scala-compiler.jar cannot be loaded. Classloader you are using is: | %s. | - | In Scala 2.10.0 M3, scala-compiler.jar is required to be on the classpath - | for manifests and type tags to function. This will change in the final release, - | but for now you need to adjust your scripts or the build system to proceed. - | | For the instructions for some of the situations that might be relevant | visit our knowledge base at https://gist.github.com/2391081. """.stripMargin('|').format(show(cl)) -- cgit v1.2.3 From 40c1fe388be22c0ea9c68afcb08b41b69148026e Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Sun, 15 Apr 2012 22:27:42 +0200 Subject: assorted stability fixes --- .../scala/reflect/internal/StdAttachments.scala | 12 + .../scala/reflect/internal/SymbolTable.scala | 1 + .../scala/reflect/makro/runtime/Enclosures.scala | 2 +- .../scala/reflect/makro/runtime/Typers.scala | 10 +- .../scala/reflect/reify/codegen/Symbols.scala | 23 +- src/compiler/scala/tools/nsc/Global.scala | 14 +- .../doc/model/ModelFactoryImplicitSupport.scala | 1 + .../scala/tools/nsc/typechecker/Implicits.scala | 5 +- .../scala/tools/nsc/typechecker/Macros.scala | 730 +++++++++++---------- .../scala/tools/nsc/typechecker/Typers.scala | 8 +- src/library/scala/reflect/api/Attachment.scala | 9 +- src/library/scala/reflect/api/Trees.scala | 43 +- ...and-implicit-macro-defeats-type-inference.check | 6 + ...and-implicit-macro-defeats-type-inference.flags | 1 + .../Impls_1.scala | 10 + .../Macros_Test_2.scala | 6 + 16 files changed, 510 insertions(+), 371 deletions(-) create mode 100644 src/compiler/scala/reflect/internal/StdAttachments.scala create mode 100644 test/pending/run/macro-expand-implicit-macro-defeats-type-inference.check create mode 100644 test/pending/run/macro-expand-implicit-macro-defeats-type-inference.flags create mode 100644 test/pending/run/macro-expand-implicit-macro-defeats-type-inference/Impls_1.scala create mode 100644 test/pending/run/macro-expand-implicit-macro-defeats-type-inference/Macros_Test_2.scala diff --git a/src/compiler/scala/reflect/internal/StdAttachments.scala b/src/compiler/scala/reflect/internal/StdAttachments.scala new file mode 100644 index 0000000000..488195b7dd --- /dev/null +++ b/src/compiler/scala/reflect/internal/StdAttachments.scala @@ -0,0 +1,12 @@ +package scala.reflect +package internal + +import scala.reflect.makro.runtime.{Context => MacroContext} + +trait StdAttachments { + self: SymbolTable => + + case class ReifyAttachment(original: Symbol) + + case class MacroAttachment(delayed: Boolean, context: Option[MacroContext]) +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/internal/SymbolTable.scala b/src/compiler/scala/reflect/internal/SymbolTable.scala index 0268339ed0..0688d13ae5 100644 --- a/src/compiler/scala/reflect/internal/SymbolTable.scala +++ b/src/compiler/scala/reflect/internal/SymbolTable.scala @@ -38,6 +38,7 @@ abstract class SymbolTable extends api.Universe with TreeBuildUtil with Reporters with CapturedVariables + with StdAttachments { def rootLoader: LazyType def log(msg: => AnyRef): Unit diff --git a/src/compiler/scala/reflect/makro/runtime/Enclosures.scala b/src/compiler/scala/reflect/makro/runtime/Enclosures.scala index f9a6987e48..72e9e568c0 100644 --- a/src/compiler/scala/reflect/makro/runtime/Enclosures.scala +++ b/src/compiler/scala/reflect/makro/runtime/Enclosures.scala @@ -11,7 +11,7 @@ trait Enclosures { val macroApplication: Tree = expandee - val enclosingMacros: List[Context] = this :: mirror.analyzer.openMacros + val enclosingMacros: List[Context] = this :: mirror.analyzer.openMacros // include self val enclosingImplicits: List[(Type, Tree)] = callsiteTyper.context.openImplicits diff --git a/src/compiler/scala/reflect/makro/runtime/Typers.scala b/src/compiler/scala/reflect/makro/runtime/Typers.scala index b32d4fb7b1..98dbd65b72 100644 --- a/src/compiler/scala/reflect/makro/runtime/Typers.scala +++ b/src/compiler/scala/reflect/makro/runtime/Typers.scala @@ -4,9 +4,9 @@ package runtime trait Typers { self: Context => - val openMacros: List[Context] = this :: mirror.analyzer.openMacros + def openMacros: List[Context] = this :: mirror.analyzer.openMacros - val openImplicits: List[(Type, Tree)] = callsiteTyper.context.openImplicits + def openImplicits: List[(Type, Tree)] = callsiteTyper.context.openImplicits def typeCheck(tree: Tree, pt: Type = mirror.WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree = { def trace(msg: Any) = if (mirror.settings.Ymacrodebug.value) println(msg) @@ -34,7 +34,7 @@ trait Typers { def trace(msg: Any) = if (mirror.settings.Ymacrodebug.value) println(msg) trace("inferring implicit value of type %s, macros = %s".format(pt, !withMacrosDisabled)) import mirror.analyzer.SearchResult - val context = callsiteTyper.context.makeImplicit(true) + val context = callsiteTyper.context val wrapper1 = if (!withMacrosDisabled) (context.withMacrosEnabled[SearchResult] _) else (context.withMacrosDisabled[SearchResult] _) def wrapper (inference: => SearchResult) = wrapper1(inference) wrapper(mirror.analyzer.inferImplicit(mirror.EmptyTree, pt, true, false, context, !silent, pos)) match { @@ -51,12 +51,12 @@ trait Typers { def trace(msg: Any) = if (mirror.settings.Ymacrodebug.value) println(msg) trace("inferring implicit view from %s to %s for %s, macros = %s, reportAmbiguous = %s".format(from, to, tree, !withMacrosDisabled, reportAmbiguous)) import mirror.analyzer.SearchResult - val context = callsiteTyper.context.makeImplicit(reportAmbiguous) + val context = callsiteTyper.context val wrapper1 = if (!withMacrosDisabled) (context.withMacrosEnabled[SearchResult] _) else (context.withMacrosDisabled[SearchResult] _) def wrapper (inference: => SearchResult) = wrapper1(inference) val fun1 = mirror.definitions.FunctionClass(1) val viewTpe = mirror.TypeRef(fun1.typeConstructor.prefix, fun1, List(from, to)) - wrapper(mirror.analyzer.inferImplicit(mirror.EmptyTree, viewTpe, reportAmbiguous, true, context, !silent, pos)) match { + wrapper(mirror.analyzer.inferImplicit(tree, viewTpe, reportAmbiguous, true, context, !silent, pos)) match { case failure if failure.tree.isEmpty => trace("implicit search has failed. to find out the reason, turn on -Xlog-implicits") if (context.hasErrors) throw new mirror.TypeError(context.errBuffer.head.errPos, context.errBuffer.head.errMsg) diff --git a/src/compiler/scala/reflect/reify/codegen/Symbols.scala b/src/compiler/scala/reflect/reify/codegen/Symbols.scala index 0513f99366..7f8b9c53b6 100644 --- a/src/compiler/scala/reflect/reify/codegen/Symbols.scala +++ b/src/compiler/scala/reflect/reify/codegen/Symbols.scala @@ -105,9 +105,9 @@ trait Symbols { filledIn = false newSymbolTable foreach { case entry => - val att = entry.attachment + val att = entry.attachmentOpt[ReifyAttachment] att match { - case sym: Symbol => + case Some(ReifyAttachment(sym)) => // don't duplicate reified symbols when merging inlined reifee if (!(locallyReified contains sym)) { val ValDef(_, name, _, _) = entry @@ -134,7 +134,7 @@ trait Symbols { // todo. tried to declare a private class here to carry an attachment, but it's path-dependent // so got troubles with exchanging free variables between nested and enclosing quasiquotes // attaching just Symbol isn't good either, so we need to think of a principled solution - val local = ValDef(NoMods, name, TypeTree(), reified) setAttachment sym + val local = ValDef(NoMods, name, TypeTree(), reified) withAttachment ReifyAttachment(sym) localReifications += local filledIn = false locallyReified(sym) = Ident(name) @@ -149,8 +149,9 @@ trait Symbols { while (i < localReifications.length) { // fillInSymbol might create new locallyReified symbols, that's why this is done iteratively val reified = localReifications(i) - reified.attachment match { - case sym: Symbol => fillIns += fillInSymbol(sym) + val att = reified.attachmentOpt[ReifyAttachment] + att match { + case Some(ReifyAttachment(sym)) => fillIns += fillInSymbol(sym) case other => // do nothing } i += 1 @@ -169,9 +170,15 @@ trait Symbols { if (sym.annotations.isEmpty) EmptyTree else Apply(Select(locallyReified(sym), nme.setAnnotations), List(reify(sym.annotations))) } else { - val rset = Apply(Select(locallyReified(sym), nme.setTypeSignature), List(reify(sym.info))) - if (sym.annotations.isEmpty) rset - else Apply(Select(rset, nme.setAnnotations), List(reify(sym.annotations))) + import scala.reflect.internal.Flags._ + if (sym hasFlag LOCKED) { + // [Eugene] better to have a symbol without a type signature, than to crash with a CyclicReference + EmptyTree + } else { + val rset = Apply(Select(locallyReified(sym), nme.setTypeSignature), List(reify(sym.info))) + if (sym.annotations.isEmpty) rset + else Apply(Select(rset, nme.setAnnotations), List(reify(sym.annotations))) + } } } } \ No newline at end of file diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 73c68f44d4..c9394b37b5 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -8,7 +8,6 @@ package scala.tools.nsc import java.io.{ File, FileOutputStream, PrintWriter, IOException, FileNotFoundException } import java.nio.charset.{ Charset, CharsetDecoder, IllegalCharsetNameException, UnsupportedCharsetException } import compat.Platform.currentTime - import scala.tools.util.{ Profiling, PathResolver } import scala.collection.{ mutable, immutable } import io.{ SourceReader, AbstractFile, Path } @@ -16,7 +15,6 @@ import reporters.{ Reporter => NscReporter, ConsoleReporter } import util.{ NoPosition, Exceptional, ClassPath, SourceFile, NoSourceFile, Statistics, StatisticsInfo, BatchSourceFile, ScriptSourceFile, ShowPickled, ScalaClassLoader, returning } import scala.reflect.internal.pickling.{ PickleBuffer, PickleFormat } import settings.{ AestheticSettings } - import symtab.{ Flags, SymbolTable, SymbolLoaders, SymbolTrackers } import symtab.classfile.Pickler import dependencies.DependencyAnalysis @@ -25,13 +23,13 @@ import ast._ import ast.parser._ import typechecker._ import transform._ - import backend.icode.{ ICodes, GenICode, ICodeCheckers } import backend.{ ScalaPrimitives, Platform, MSILPlatform, JavaPlatform } import backend.jvm.GenJVM import backend.opt.{ Inliners, InlineExceptionHandlers, ClosureElimination, DeadCodeElimination } import backend.icode.analysis._ import language.postfixOps +import reflect.internal.StdAttachments class Global(var currentSettings: Settings, var reporter: NscReporter) extends SymbolTable with ClassLoaders @@ -135,6 +133,16 @@ class Global(var currentSettings: Settings, var reporter: NscReporter) extends S infolevel = InfoLevel.Verbose } + def withInfoLevel[T](infolevel: nodePrinters.InfoLevel.Value)(op: => T) = { + val saved = nodePrinters.infolevel + try { + nodePrinters.infolevel = infolevel + op + } finally { + nodePrinters.infolevel = saved + } + } + /** Representing ASTs as graphs */ object treeBrowsers extends { val global: Global.this.type = Global.this diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala index 0e44933ac6..4e03dc8788 100644 --- a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala +++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala @@ -246,6 +246,7 @@ trait ModelFactoryImplicitSupport { val appliedTree = new ApplyImplicitView(viewTree, List(Ident("") setType viewTree.tpe.paramTypes.head)) val appliedTreeTyped: Tree = { val newContext = context.makeImplicit(context.ambiguousErrors) + newContext.macrosEnabled = false // [Eugene] I assume you want macro signature, not macro expansion val newTyper = global.analyzer.newTyper(newContext) newTyper.silent(_.typed(appliedTree, global.analyzer.EXPRmode, WildcardType), false) match { diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index 30a79917c9..651120db4f 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -32,10 +32,10 @@ trait Implicits { import global.typer.{ printTyping, deindentTyping, indentTyping, printInference } def inferImplicit(tree: Tree, pt: Type, reportAmbiguous: Boolean, isView: Boolean, context: Context): SearchResult = - inferImplicit(tree, pt, reportAmbiguous, isView, context, true, NoPosition) + inferImplicit(tree, pt, reportAmbiguous, isView, context, true, tree.pos) def inferImplicit(tree: Tree, pt: Type, reportAmbiguous: Boolean, isView: Boolean, context: Context, saveAmbiguousDivergent: Boolean): SearchResult = - inferImplicit(tree, pt, reportAmbiguous, isView, context, saveAmbiguousDivergent, NoPosition) + inferImplicit(tree, pt, reportAmbiguous, isView, context, saveAmbiguousDivergent, tree.pos) /** Search for an implicit value. See the comment on `result` at the end of class `ImplicitSearch` * for more info how the search is conducted. @@ -633,6 +633,7 @@ trait Implicits { else { val subst = new TreeTypeSubstituter(okParams, okArgs) subst traverse itree2 + notifyUndetparamsInferred(okParams, okArgs) subst } diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index 62a0e08aad..539ddfb19c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -294,6 +294,8 @@ trait Macros { self: Analyzer => } finally { openMacros = openMacros.tail } + case Delay(result) => + result case Fallback(fallback) => typer.typed1(fallback, EXPRmode, WildcardType) case Other(result) => @@ -641,139 +643,147 @@ trait Macros { self: Analyzer => * @return Some(runtime) if macro implementation can be loaded successfully from either of the mirrors, * None otherwise. */ - private def macroRuntime(macroDef: Symbol): Option[List[Any] => Any] = { - macroTrace("looking for macro implementation: ")(macroDef) - macroTrace("macroDef is annotated with: ")(macroDef.annotations) - - val ann = macroDef.getAnnotation(MacroImplAnnotation) - if (ann == None) { - macroTrace("@macroImpl annotation is missing (this means that macro definition failed to typecheck)")(macroDef) - return None - } - - val macroImpl = ann.get.args(0).symbol - if (macroImpl == NoSymbol) { - macroTrace("@macroImpl annotation is malformed (this means that macro definition failed to typecheck)")(macroDef) - return None - } - - if (macroDebug) println("resolved implementation %s at %s".format(macroImpl, macroImpl.pos)) - if (macroImpl.isErroneous) { - macroTrace("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 - - macroTrace("loading implementation class from %s: ".format(macroMirror))(macroImpl.owner.fullName) - macroTrace("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 _ => "" + 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 = { + macroTrace("looking for macro implementation: ")(macroDef) + macroTrace("macroDef is annotated with: ")(macroDef.annotations) + + val ann = macroDef.getAnnotation(MacroImplAnnotation) + if (ann == None) { + macroTrace("@macroImpl annotation is missing (this means that macro definition failed to typecheck)")(macroDef) + return None } - macroTrace("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) + val macroImpl = ann.get.args(0).symbol + if (macroImpl == NoSymbol) { + macroTrace("@macroImpl annotation is malformed (this means that macro definition failed to typecheck)")(macroDef) + return None } - // [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 (macroDebug) { - 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 (macroDebug) println("resolved implementation %s at %s".format(macroImpl, macroImpl.pos)) + if (macroImpl.isErroneous) { + macroTrace("macro implementation is erroneous (this means that either macro body or macro implementation signature failed to typecheck)")(macroDef) + return None } - val implObjSymbol = implClassSymbol.companionModule - macroTrace("implObjSymbol is: ")(implObjSymbol.fullNameString) + 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 + + macroTrace("loading implementation class from %s: ".format(macroMirror))(macroImpl.owner.fullName) + macroTrace("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 _ => "" + } + macroTrace("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 (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 => macroTrace("exception when loading implObj: ")(ex); null - case ex: NoClassDefFoundError => macroTrace("exception when loading implObj: ")(ex); null - case ex: ClassNotFoundException => macroTrace("exception when loading implObj: ")(ex); null - } + 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) - if (implObj == null) None - else { - val implMethSymbol = implObjSymbol.info.member(macroMirror.newTermName(macroImpl.name.toString)) if (macroDebug) { - println("implMethSymbol is: " + implMethSymbol.fullNameString) - println("jimplMethSymbol is: " + macroMirror.methodToJava(implMethSymbol)) + 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 (implMethSymbol == macroMirror.NoSymbol) None + val implObjSymbol = implClassSymbol.companionModule + macroTrace("implObjSymbol is: ")(implObjSymbol.fullNameString) + + if (implObjSymbol == macroMirror.NoSymbol) None else { - if (macroDebug) println("successfully loaded macro impl as (%s, %s)".format(implObj, implMethSymbol)) - Some((implObj, 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 => macroTrace("exception when loading implObj: ")(ex); null + case ex: NoClassDefFoundError => macroTrace("exception when loading implObj: ")(ex); null + case ex: ClassNotFoundException => macroTrace("exception when loading implObj: ")(ex); null + } + + if (implObj == null) None + else { + val implMethSymbol = implObjSymbol.info.member(macroMirror.newTermName(macroImpl.name.toString)) + if (macroDebug) { + println("implMethSymbol is: " + implMethSymbol.fullNameString) + println("jimplMethSymbol is: " + macroMirror.methodToJava(implMethSymbol)) + } + + if (implMethSymbol == macroMirror.NoSymbol) None + else { + if (macroDebug) println("successfully loaded macro impl as (%s, %s)".format(implObj, implMethSymbol)) + Some((implObj, implMethSymbol)) + } + } } + } catch { + case ex: ClassNotFoundException => + macroTrace("implementation class failed to load: ")(ex.toString) + None } } - } catch { - case ex: ClassNotFoundException => - macroTrace("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 != "") { - if (macroDebug) println("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 => + 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 != "") { + if (macroDebug) println("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 + }) /** 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 } = @@ -784,7 +794,7 @@ trait Macros { self: Analyzer => val prefix = Expr(prefixTree)(TypeTag.Nothing) val expandee = expandeeTree } with MacroContext { - override def toString = "MacroContext(%s@%s +%d)".format(expandee.symbol.name, expandee.pos, openMacros.length - 1 /* exclude myself */) + override def toString = "MacroContext(%s@%s +%d)".format(expandee.symbol.name, expandee.pos, enclosingMacros.length - 1 /* exclude myself */) } /** Calculate the arguments to pass to a macro implementation when expanding the provided tree. @@ -795,6 +805,10 @@ trait Macros { self: Analyzer => * @return list of runtime objects to pass to the implementation obtained by ``macroRuntime'' */ private def macroArgs(typer: Typer, expandee: Tree): Option[List[Any]] = { + val macroDef = expandee.symbol + val runtime = macroRuntime(macroDef) + if (runtime == None) return None + var prefixTree: Tree = EmptyTree var typeArgs = List[Tree]() val exprArgs = new ListBuffer[List[Expr[_]]] @@ -811,11 +825,10 @@ trait Macros { self: Analyzer => case _ => } collectMacroArgs(expandee) - val context = macroContext(typer, prefixTree, expandee) + val context = expandee.attachmentOpt[MacroAttachment].flatMap(_.context).getOrElse(macroContext(typer, prefixTree, expandee)) var argss: List[List[Any]] = List(context) :: exprArgs.toList macroTrace("argss: ")(argss) - val macroDef = expandee.symbol val ann = macroDef.getAnnotation(MacroImplAnnotation).getOrElse(throw new Error("assertion failed. %s: %s".format(macroDef, macroDef.annotations))) val macroImpl = ann.args(0).symbol var paramss = macroImpl.paramss @@ -923,62 +936,92 @@ trait Macros { self: Analyzer => * the expandee with an error marker set if the expansion has been cancelled due malformed arguments or implementation * the expandee with an error marker set if there has been an error */ - def macroExpand(typer: Typer, expandee: Tree, pt: Type): Tree = - macroExpand1(typer, expandee) match { - case Success(expanded) => - try { - var expectedTpe = expandee.tpe - - // [Eugene] weird situation. what's the conventional way to deal with it? - val isNullaryInvocation = expandee match { - case TypeApply(Select(_, _), _) => true - case Select(_, _) => true - case _ => false - } - if (isNullaryInvocation) expectedTpe match { - case MethodType(Nil, restpe) => - macroTrace("nullary invocation of a method with an empty parameter list. unwrapping expectedTpe from " + expectedTpe + " to:")(restpe) - expectedTpe = restpe - case _ => ; - } + def macroExpand(typer: Typer, expandee: Tree, mode: Int = EXPRmode, pt: Type = WildcardType): Tree = { + val start = startTimer(macroExpandNanos) + incCounter(macroExpandCount) + try { + macroExpand1(typer, expandee) match { + case Success(expanded) => + try { + var expectedTpe = expandee.tpe + + // [Eugene] weird situation. what's the conventional way to deal with it? + val isNullaryInvocation = expandee match { + case TypeApply(Select(_, _), _) => true + case TypeApply(Ident(_), _) => true + case Select(_, _) => true + case Ident(_) => true + case _ => false + } + if (isNullaryInvocation) expectedTpe match { + case NullaryMethodType(restpe) => + macroTrace("nullary invocation of a nullary method. unwrapping expectedTpe from " + expectedTpe + " to: ")(restpe) + expectedTpe = restpe + case MethodType(Nil, restpe) => + macroTrace("nullary invocation of a method with an empty parameter list. unwrapping expectedTpe from " + expectedTpe + " to: ")(restpe) + expectedTpe = restpe + case _ => ; + } - var typechecked = typer.context.withImplicitsEnabled(typer.typed(expanded, EXPRmode, expectedTpe)) - if (macroDebug) { - println("typechecked1:") - println(typechecked) - println(showRaw(typechecked)) - } + def fail(what: String): Tree = { + val err = typer.context.errBuffer.head + this.fail(typer, expanded, "failed to perform %s: %s at %s".format(what, err.errMsg, err.errPos)) + return expandee + } - typechecked = typer.context.withImplicitsEnabled(typer.typed(typechecked, EXPRmode, pt)) - if (macroDebug) { - println("typechecked2:") - println(typechecked) - println(showRaw(typechecked)) - } + if (macroDebug) println("typechecking1 against %s: %s".format(expectedTpe, expanded)) + var typechecked = typer.context.withImplicitsEnabled(typer.typed(expanded, EXPRmode, expectedTpe)) + if (typer.context.hasErrors) fail("typecheck1") + if (macroDebug) { + println("typechecked1:") + println(typechecked) + println(showRaw(typechecked)) + } - typechecked - } finally { - openMacros = openMacros.tail - } - case Fallback(fallback) => - typer.context.withImplicitsEnabled(typer.typed(fallback, EXPRmode, pt)) - case Other(result) => - result + if (macroDebug) println("typechecking2 against %s: %s".format(pt, expanded)) + typechecked = typer.context.withImplicitsEnabled(typer.typed(typechecked, EXPRmode, pt)) + if (typer.context.hasErrors) fail("typecheck2") + if (macroDebug) { + println("typechecked2:") + println(typechecked) + println(showRaw(typechecked)) + } + + typechecked + } finally { + openMacros = openMacros.tail + } + case Delay(expandee) => + // need to save the context to preserve enclosures + val args = macroArgs(typer, expandee) + assert(args.isDefined, expandee) + val context = args.get.head.asInstanceOf[MacroContext] + var result = expandee withAttachment MacroAttachment(delayed = true, context = Some(context)) + // adapting here would be premature, we must wait until undetparams are inferred +// result = typer.adapt(result, mode, pt) + result + case Fallback(fallback) => + typer.context.withImplicitsEnabled(typer.typed(fallback, EXPRmode, pt)) + case Other(result) => + result + } + } finally { + stopTimer(macroExpandNanos, start) } + } private sealed abstract class MacroExpansionResult extends Product with Serializable private case class Success(expanded: Tree) extends MacroExpansionResult private case class Fallback(fallback: Tree) extends MacroExpansionResult + private case class Delay(expandee: Tree) extends MacroExpansionResult private case class Other(result: Tree) extends MacroExpansionResult - private def Delay(expandee: Tree) = Other(expandee) private def Skip(expanded: Tree) = Other(expanded) private def Cancel(expandee: Tree) = Other(expandee) private def Failure(expandee: Tree) = Other(expandee) private def fail(typer: Typer, expandee: Tree, msg: String = null) = { if (macroDebug || macroCopypaste) { var msg1 = if (msg contains "exception during macro expansion") msg.split(EOL).drop(1).headOption.getOrElse("?") else msg - if (macroDebug) msg1 = msg - println("macro expansion has failed: %s".format(msg1)) + if (macroDebug) println("macro expansion has failed: %s".format(msg1)) } val pos = if (expandee.pos != NoPosition) expandee.pos else openMacros.find(c => c.expandee.pos != NoPosition).map(_.expandee.pos).getOrElse(NoPosition) if (msg != null) typer.context.error(pos, msg) @@ -989,191 +1032,200 @@ trait Macros { self: Analyzer => /** Does the same as ``macroExpand'', but without typechecking the expansion * Meant for internal use within the macro infrastructure, don't use it elsewhere. */ - private def macroExpand1(typer: Typer, expandee: Tree): MacroExpansionResult = { - // if a macro implementation is incompatible or any of the arguments are erroneous - // there is no sense to expand the macro itself => it will only make matters worse - if (expandee.symbol.isErroneous || (expandee exists (_.isErroneous))) { - val reason = if (expandee.symbol.isErroneous) "incompatible macro implementation" else "erroneous arguments" - macroTrace("cancelled macro expansion because of %s: ".format(reason))(expandee) - return Cancel(typer.infer.setError(expandee)) - } + private def macroExpand1(typer: Typer, expandee: Tree): MacroExpansionResult = + // InfoLevel.Verbose examines and prints out infos of symbols + // by the means of this'es these symbols can climb up the lexical scope + // when these symbols will be examined by a node printer + // they will enumerate and analyze their children (ask for infos and tpes) + // if one of those children involves macro expansion, things might get nasty + // that's why I'm temporarily turning this behavior off + withInfoLevel(nodePrinters.InfoLevel.Quiet) { + // if a macro implementation is incompatible or any of the arguments are erroneous + // there is no sense to expand the macro itself => it will only make matters worse + if (expandee.symbol.isErroneous || (expandee exists (_.isErroneous))) { + val reason = if (expandee.symbol.isErroneous) "incompatible macro implementation" else "erroneous arguments" + macroTrace("cancelled macro expansion because of %s: ".format(reason))(expandee) + return Cancel(typer.infer.setError(expandee)) + } - if (!isDelayed(expandee)) { - if (macroDebug || macroCopypaste) println("typechecking macro expansion %s at %s".format(expandee, expandee.pos)) + macroRuntime(expandee.symbol) match { + case Some(runtime) => + macroExpandWithRuntime(typer, expandee, runtime) + case None => + macroExpandWithoutRuntime(typer, expandee) + } + } + /** Expands a macro when a runtime (i.e. the macro implementation) can be successfully loaded + * Meant for internal use within the macro infrastructure, don't use it elsewhere. + */ + private def macroExpandWithRuntime(typer: Typer, expandee: Tree, runtime: MacroRuntime): MacroExpansionResult = + try { + val wasDelayed = isDelayed(expandee) val undetparams = calculateUndetparams(expandee) - if (undetparams.size != 0) { - macroTrace("macro expansion is delayed: ")(expandee) - delayed += expandee -> (typer.context, undetparams) - Delay(expandee) - } else { - val start = startTimer(macroExpandNanos) - incCounter(macroExpandCount) - try { - val macroDef = expandee.symbol - macroRuntime(macroDef) match { - case Some(runtime) => - val savedInfolevel = nodePrinters.infolevel - try { - // InfoLevel.Verbose examines and prints out infos of symbols - // by the means of this'es these symbols can climb up the lexical scope - // when these symbols will be examined by a node printer - // they will enumerate and analyze their children (ask for infos and tpes) - // if one of those children involves macro expansion, things might get nasty - // that's why I'm temporarily turning this behavior off - nodePrinters.infolevel = nodePrinters.InfoLevel.Quiet - val args = macroArgs(typer, expandee) - args match { - case Some(args) => - // adding stuff to openMacros is easy, but removing it is a nightmare - // it needs to be sprinkled over several different code locations - val (context: MacroContext) :: _ = args - openMacros = context :: openMacros - val expanded: MacroExpansionResult = try { - val prevNumErrors = reporter.ERROR.count - val expanded = runtime(args) + val nowDelayed = !typer.context.macrosEnabled || undetparams.size != 0 + + if (!wasDelayed) { + if (macroDebug || macroCopypaste) println("typechecking macro expansion %s at %s".format(expandee, expandee.pos)) + if (nowDelayed) { + if (macroDebug || macroCopypaste) println("macro expansion is delayed: %s".format(expandee)) + delayed += expandee -> (typer.context, undetparams) + Delay(expandee) + } else { + val args = macroArgs(typer, expandee) + args match { + case Some(args) => + // adding stuff to openMacros is easy, but removing it is a nightmare + // it needs to be sprinkled over several different code locations + val (context: MacroContext) :: _ = args + openMacros = context :: openMacros + val expanded: MacroExpansionResult = try { + val prevNumErrors = reporter.ERROR.count + expandee.detach(null) + val expanded = runtime(args) + val currNumErrors = reporter.ERROR.count + if (currNumErrors != prevNumErrors) { + fail(typer, expandee) // errors have been reported by the macro itself + } else { + expanded match { + case expanded: Expr[_] => + if (macroDebug || macroCopypaste) { + if (macroDebug) println("original:") + println(expanded.tree) + println(showRaw(expanded.tree)) + } + + freeTerms(expanded.tree) foreach (fte => typer.context.error(expandee.pos, + ("macro expansion contains free term variable %s %s. "+ + "have you forgot to use eval when splicing this variable into a reifee? " + + "if you have troubles tracking free term variables, consider using -Xlog-free-terms").format(fte.name, fte.origin))) + freeTypes(expanded.tree) foreach (fty => typer.context.error(expandee.pos, + ("macro expansion contains free type variable %s %s. "+ + "have you forgot to use c.TypeTag annotation for this type parameter? " + + "if you have troubles tracking free type variables, consider using -Xlog-free-types").format(fty.name, fty.origin))) + val currNumErrors = reporter.ERROR.count if (currNumErrors != prevNumErrors) { - fail(typer, expandee) // errors have been reported by the macro itself + fail(typer, expandee) } else { - expanded match { - case expanded: Expr[_] => - if (macroDebug || macroCopypaste) { - if (macroDebug) println("original:") - println(expanded.tree) - println(showRaw(expanded.tree)) - } - - freeTerms(expanded.tree) foreach (fte => typer.context.error(expandee.pos, - ("macro expansion contains free term variable %s %s. "+ - "have you forgot to use eval when splicing this variable into a reifee? " + - "if you have troubles tracking free term variables, consider using -Xlog-free-terms").format(fte.name, fte.origin))) - freeTypes(expanded.tree) foreach (fty => typer.context.error(expandee.pos, - ("macro expansion contains free type variable %s %s. "+ - "have you forgot to use c.TypeTag annotation for this type parameter? " + - "if you have troubles tracking free type variables, consider using -Xlog-free-types").format(fty.name, fty.origin))) - - val currNumErrors = reporter.ERROR.count - if (currNumErrors != prevNumErrors) { - fail(typer, expandee) - } else { - // inherit the position from the first position-ful expandee in macro callstack - // this is essential for sane error messages - var tree = expanded.tree - var position = openMacros.find(c => c.expandee.pos != NoPosition).map(_.expandee.pos).getOrElse(NoPosition) - tree = atPos(position.focus)(tree) - - // now macro expansion gets typechecked against the macro definition return type - // however, this happens in macroExpand, not here in macroExpand1 - Success(tree) - } - case expanded if expanded.isInstanceOf[Expr[_]] => - val msg = "macro must return a compiler-specific expr; returned value is Expr, but it doesn't belong to this compiler's universe" - fail(typer, expandee, msg) - case expanded => - val msg = "macro must return a compiler-specific expr; returned value is of class: %s".format(expanded.getClass) - fail(typer, expandee, msg) - } + // inherit the position from the first position-ful expandee in macro callstack + // this is essential for sane error messages + var tree = expanded.tree + var position = openMacros.find(c => c.expandee.pos != NoPosition).map(_.expandee.pos).getOrElse(NoPosition) + tree = atPos(position.focus)(tree) + + // now macro expansion gets typechecked against the macro definition return type + // however, this happens in macroExpand, not here in macroExpand1 + Success(tree) } - } catch { - case ex: Throwable => - openMacros = openMacros.tail - throw ex - } - if (!expanded.isInstanceOf[Success]) openMacros = openMacros.tail - expanded - case None => - fail(typer, expandee) // error has been reported by macroArgs + case expanded if expanded.isInstanceOf[Expr[_]] => + val msg = "macro must return a compiler-specific expr; returned value is Expr, but it doesn't belong to this compiler's universe" + fail(typer, expandee, msg) + case expanded => + val msg = "macro must return a compiler-specific expr; returned value is of class: %s".format(expanded.getClass) + fail(typer, expandee, msg) + } } } catch { - case ex => - // [Eugene] any ideas about how to improve this one? - val realex = ReflectionUtils.unwrapThrowable(ex) - realex match { - case realex: reflect.makro.runtime.AbortMacroException => - if (macroDebug || macroCopypaste) println("macro expansion has failed: %s".format(realex.msg)) - fail(typer, expandee) // error has been reported by abort - case _ => - val message = { - try { - // the most reliable way of obtaining currently executing method - // http://stackoverflow.com/questions/442747/getting-the-name-of-the-current-executing-method - val currentMethodName = new Object(){}.getClass().getEnclosingMethod().getName - val relevancyThreshold = realex.getStackTrace().indexWhere(este => este.getMethodName == currentMethodName) - if (relevancyThreshold == -1) None - else { - var relevantElements = realex.getStackTrace().take(relevancyThreshold + 1) - var framesTillReflectiveInvocationOfMacroImpl = relevantElements.reverse.indexWhere(_.isNativeMethod) + 1 - relevantElements = relevantElements dropRight framesTillReflectiveInvocationOfMacroImpl - - realex.setStackTrace(relevantElements) - val message = new java.io.StringWriter() - realex.printStackTrace(new java.io.PrintWriter(message)) - Some(EOL + message) - } - } catch { - // if the magic above goes boom, just fall back to uninformative, but better than nothing, getMessage - case ex: Throwable => - None - } - } getOrElse realex.getMessage - fail(typer, expandee, "exception during macro expansion: " + message) - } - } finally { - nodePrinters.infolevel = savedInfolevel + case ex: Throwable => + openMacros = openMacros.tail + throw ex } + if (!expanded.isInstanceOf[Success]) openMacros = openMacros.tail + expanded case None => - def notFound() = { - typer.context.error(expandee.pos, "macro implementation not found: " + macroDef.name + " " + - "(the most common reason for that is that you cannot use macro implementations in the same compilation run that defines them)\n" + - "if you do need to define macro implementations along with the rest of your program, consider two-phase compilation with -Xmacro-fallback-classpath " + - "in the second phase pointing to the output of the first phase") - None - } - def fallBackToOverridden(tree: Tree): Option[Tree] = { - tree match { - case Select(qual, name) if (macroDef.isTermMacro) => - macroDef.allOverriddenSymbols match { - case first :: _ => - Some(Select(qual, name) setPos tree.pos setSymbol first) - case _ => - macroTrace("macro is not overridden: ")(tree) - notFound() - } - case Apply(fn, args) => - fallBackToOverridden(fn) match { - case Some(fn1) => Some(Apply(fn1, args) setPos tree.pos) - case _ => None - } - case TypeApply(fn, args) => - fallBackToOverridden(fn) match { - case Some(fn1) => Some(TypeApply(fn1, args) setPos tree.pos) - case _ => None - } - case _ => - macroTrace("unexpected tree in fallback: ")(tree) - notFound() - } - } - fallBackToOverridden(expandee) match { - case Some(tree1) => - macroTrace("falling back to ")(tree1) - currentRun.macroExpansionFailed = true - Fallback(tree1) - case None => - fail(typer, expandee) - } + fail(typer, expandee) // error has been reported by macroArgs } - } finally { - stopTimer(macroExpandNanos, start) } + } else { + if (nowDelayed) + Delay(expandee) + else + Skip(macroExpandAll(typer, expandee)) } - } else { - val undetparams = calculateUndetparams(expandee) - if (undetparams.size != 0) - Delay(expandee) - else - Skip(macroExpandAll(typer, expandee)) + } catch { + case ex => handleMacroExpansionException(typer, expandee, ex) + } finally { + expandee.detach(classOf[MacroAttachment]) + } + + private def macroExpandWithoutRuntime(typer: Typer, expandee: Tree): MacroExpansionResult = { + val macroDef = expandee.symbol + def notFound() = { + typer.context.error(expandee.pos, "macro implementation not found: " + macroDef.name + " " + + "(the most common reason for that is that you cannot use macro implementations in the same compilation run that defines them)\n" + + "if you do need to define macro implementations along with the rest of your program, consider two-phase compilation with -Xmacro-fallback-classpath " + + "in the second phase pointing to the output of the first phase") + None + } + def fallBackToOverridden(tree: Tree): Option[Tree] = { + tree match { + case Select(qual, name) if (macroDef.isTermMacro) => + macroDef.allOverriddenSymbols match { + case first :: _ => + Some(Select(qual, name) setPos tree.pos setSymbol first) + case _ => + macroTrace("macro is not overridden: ")(tree) + notFound() + } + case Apply(fn, args) => + fallBackToOverridden(fn) match { + case Some(fn1) => Some(Apply(fn1, args) setPos tree.pos) + case _ => None + } + case TypeApply(fn, args) => + fallBackToOverridden(fn) match { + case Some(fn1) => Some(TypeApply(fn1, args) setPos tree.pos) + case _ => None + } + case _ => + macroTrace("unexpected tree in fallback: ")(tree) + notFound() + } + } + fallBackToOverridden(expandee) match { + case Some(tree1) => + macroTrace("falling back to: ")(tree1) + currentRun.macroExpansionFailed = true + Fallback(tree1) + case None => + fail(typer, expandee) + } + } + + private def handleMacroExpansionException(typer: Typer, expandee: Tree, ex: Throwable): MacroExpansionResult = { + // [Eugene] any ideas about how to improve this one? + val realex = ReflectionUtils.unwrapThrowable(ex) + realex match { + case realex: reflect.makro.runtime.AbortMacroException => + if (macroDebug || macroCopypaste) println("macro expansion has failed: %s".format(realex.msg)) + fail(typer, expandee) // error has been reported by abort + case err: TypeError => + if (macroDebug || macroCopypaste) println("macro expansion has failed: %s at %s".format(err.msg, err.pos)) + throw err // error should be propagated, don't report + case _ => + val message = { + try { + // [Eugene] is there a better way? + val relevancyThreshold = realex.getStackTrace().indexWhere(este => este.getMethodName == "macroExpand1") + if (relevancyThreshold == -1) None + else { + var relevantElements = realex.getStackTrace().take(relevancyThreshold + 1) + var framesTillReflectiveInvocationOfMacroImpl = relevantElements.reverse.indexWhere(_.isNativeMethod) + 1 + relevantElements = relevantElements dropRight framesTillReflectiveInvocationOfMacroImpl + + realex.setStackTrace(relevantElements) + val message = new java.io.StringWriter() + realex.printStackTrace(new java.io.PrintWriter(message)) + Some(EOL + message) + } + } catch { + // if the magic above goes boom, just fall back to uninformative, but better than nothing, getMessage + case ex: Throwable => + None + } + } getOrElse realex.getMessage + fail(typer, expandee, "exception during macro expansion: " + message) } } @@ -1194,18 +1246,23 @@ trait Macros { self: Analyzer => private def isDelayed(expandee: Tree) = delayed contains expandee private def calculateUndetparams(expandee: Tree): collection.mutable.Set[Int] = delayed.get(expandee).map(_._2).getOrElse { - val calculated = collection.mutable.Set[Int]() + val calculated = collection.mutable.Set[Symbol]() expandee foreach (sub => { - def traverse(sym: Symbol) = if (sym != null && (undetparams contains sym.id)) calculated += sym.id + def traverse(sym: Symbol) = if (sym != null && (undetparams contains sym.id)) calculated += sym if (sub.symbol != null) traverse(sub.symbol) if (sub.tpe != null) sub.tpe foreach (sub => traverse(sub.typeSymbol)) }) - calculated + if (macroDebug) println("calculateUndetparams: %s".format(calculated)) + calculated map (_.id) } private val undetparams = perRunCaches.newSet[Int] - def notifyUndetparamsAdded(newUndets: List[Symbol]): Unit = undetparams ++= newUndets map (_.id) + def notifyUndetparamsAdded(newUndets: List[Symbol]): Unit = { + undetparams ++= newUndets map (_.id) + if (macroDebug) newUndets foreach (sym => println("undetParam added: %s".format(sym))) + } def notifyUndetparamsInferred(undetNoMore: List[Symbol], inferreds: List[Type]): Unit = { undetparams --= undetNoMore map (_.id) + if (macroDebug) (undetNoMore zip inferreds) foreach {case (sym, tpe) => println("undetParam inferred: %s as %s".format(sym, tpe))} if (!delayed.isEmpty) delayed.toList foreach { case (expandee, (_, undetparams)) if !undetparams.isEmpty => @@ -1230,7 +1287,10 @@ trait Macros { self: Analyzer => case wannabe if (delayed contains wannabe) && calculateUndetparams(wannabe).isEmpty => val (context, _) = delayed(wannabe) delayed -= wannabe - macroExpand(newTyper(context), wannabe, WildcardType) + context.implicitsEnabled = typer.context.implicitsEnabled + context.enrichmentEnabled = typer.context.enrichmentEnabled + context.macrosEnabled = typer.context.macrosEnabled + macroExpand(newTyper(context), wannabe, EXPRmode, WildcardType) case _ => tree }) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 8f5b3fb519..9a59d8f28a 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1082,10 +1082,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { } if (tree.isType) adaptType() - else if (context.macrosEnabled && // when macros are enabled - inExprModeButNot(mode, FUNmode) && !tree.isDef && // and typechecking application - tree.symbol != null && tree.symbol.isTermMacro) // of a term macro - macroExpand(this, tree, pt) + else if ( + inExprModeButNot(mode, FUNmode) && !tree.isDef && // typechecking application + tree.symbol != null && tree.symbol.isTermMacro) // of a macro + macroExpand(this, tree, mode, pt) else if ((mode & (PATTERNmode | FUNmode)) == (PATTERNmode | FUNmode)) adaptConstrPattern() else if (inAllModes(mode, EXPRmode | FUNmode) && diff --git a/src/library/scala/reflect/api/Attachment.scala b/src/library/scala/reflect/api/Attachment.scala index 9fa5ceb0fb..50f55b4aa5 100644 --- a/src/library/scala/reflect/api/Attachment.scala +++ b/src/library/scala/reflect/api/Attachment.scala @@ -7,8 +7,6 @@ package api * Attachments have to carry positions, because we don't want to introduce even a single additional field in Tree * imposing an unnecessary memory tax because of something that will not be used in most cases. */ -// [Eugene] with the introduction of `attach` and `payload[T]` users don't need to create custom attachments anymore -// however, we cannot move attachments to scala.reflect.internal, because they are used in Trees, which are implemented completely in scala.reflect.api trait Attachment { /** Gets the underlying position */ def pos: Position @@ -22,3 +20,10 @@ trait Attachment { /** Creates a copy of this attachment with its payload updated */ def withPayload(newPayload: Any): Attachment } + +// [Eugene] with the introduction of `attach` and `attachment[T]` users don't need to create custom attachments anymore +// however, we cannot move attachments to scala.reflect.internal, because they are used in Trees, which are implemented completely in scala.reflect.api +private[scala] case class NontrivialAttachment(pos: api.Position, payload: collection.mutable.ListBuffer[Any]) extends Attachment { + def withPos(newPos: api.Position) = copy(pos = newPos, payload = payload) + def withPayload(newPayload: Any) = copy(pos = pos, payload = newPayload.asInstanceOf[collection.mutable.ListBuffer[Any]]) +} \ No newline at end of file diff --git a/src/library/scala/reflect/api/Trees.scala b/src/library/scala/reflect/api/Trees.scala index 7548a6bdc0..6e2e8261e7 100644 --- a/src/library/scala/reflect/api/Trees.scala +++ b/src/library/scala/reflect/api/Trees.scala @@ -85,18 +85,39 @@ trait Trees { self: Universe => def pos_=(pos: Position): Unit = rawatt = (rawatt withPos pos) // the "withPos" part is crucial to robustness def setPos(newpos: Position): this.type = { pos = newpos; this } + // [Eugene] can we make this more type-safe private var rawatt: Attachment = NoPosition - private case class NontrivialAttachment(pos: api.Position, payload: Any) extends Attachment { - def withPos(newPos: api.Position) = copy(pos = newPos, payload = payload) - def withPayload(newPayload: Any) = copy(pos = pos, payload = newPayload) - } - // todo. annotate T with ClassTag and make pattern matcher use it - // todo. support multiple attachments, and remove the assignment. only leave attach/detach -// def attachment[T]: T = rawatt.payload.asInstanceOf[T] -// def attachmentOpt[T]: Option[T] = try { Some(rawatt.payload.asInstanceOf[T]) } catch { case _: Throwable => None } - def attachment: Any = rawatt.payload - def attachment_=(att: Any): Unit = rawatt = NontrivialAttachment(pos, att) - def setAttachment(att: Any): this.type = { attachment = att; this } + def attach(att: Any): Unit = + rawatt match { + case NontrivialAttachment(pos, payload) => + val index = payload.indexWhere(p => p.getClass == att.getClass) + if (index == -1) payload += att + else payload(index) = att + case _ => + rawatt = NontrivialAttachment(pos, collection.mutable.ListBuffer[Any](att)) + } + def withAttachment(att: Any): this.type = { attach(att); this } + def detach(att: Any): Unit = + detach(att.getClass) + def detach(clazz: java.lang.Class[_]): Unit = + rawatt match { + case NontrivialAttachment(pos, payload) => + val index = payload.indexWhere(p => p.getClass == clazz) + if (index != -1) payload.remove(index) + case _ => + // do nothing + } + def withoutAttachment(att: Any): this.type = { detach(att); this } + def attachment[T: ClassTag]: T = attachmentOpt[T] getOrElse { throw new Error("no attachment of type %s".format(classTag[T].erasure)) } + def attachmentOpt[T: ClassTag]: Option[T] = + rawatt match { + case NontrivialAttachment(pos, payload) => + val index = payload.indexWhere(p => p.getClass == classTag[T].erasure) + if (index != -1) Some(payload(index).asInstanceOf[T]) + else None + case _ => + None + } private[this] var rawtpe: Type = _ diff --git a/test/pending/run/macro-expand-implicit-macro-defeats-type-inference.check b/test/pending/run/macro-expand-implicit-macro-defeats-type-inference.check new file mode 100644 index 0000000000..08f7cb9e3e --- /dev/null +++ b/test/pending/run/macro-expand-implicit-macro-defeats-type-inference.check @@ -0,0 +1,6 @@ +openImplicits are: List() +enclosingImplicits are: List((List[Int],scala.this.Predef.implicitly[List[Int]])) +typetag is: ConcreteTypeTag[Nothing] +openImplicits are: List() +enclosingImplicits are: List((List[String],Test.this.bar[String])) +typetag is: ConcreteTypeTag[Nothing] diff --git a/test/pending/run/macro-expand-implicit-macro-defeats-type-inference.flags b/test/pending/run/macro-expand-implicit-macro-defeats-type-inference.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/pending/run/macro-expand-implicit-macro-defeats-type-inference.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/pending/run/macro-expand-implicit-macro-defeats-type-inference/Impls_1.scala b/test/pending/run/macro-expand-implicit-macro-defeats-type-inference/Impls_1.scala new file mode 100644 index 0000000000..c096a83c5e --- /dev/null +++ b/test/pending/run/macro-expand-implicit-macro-defeats-type-inference/Impls_1.scala @@ -0,0 +1,10 @@ +import scala.reflect.makro.Context + +object Impls { + def foo[T: c.TypeTag](c: Context): c.Expr[List[T]] = c.reify { + println("openImplicits are: " + c.literal(c.openImplicits.toString).eval) + println("enclosingImplicits are: " + c.literal(c.enclosingImplicits.toString).eval) + println("typetag is: " + c.literal(c.tag[T].toString).eval) + null + } +} \ No newline at end of file diff --git a/test/pending/run/macro-expand-implicit-macro-defeats-type-inference/Macros_Test_2.scala b/test/pending/run/macro-expand-implicit-macro-defeats-type-inference/Macros_Test_2.scala new file mode 100644 index 0000000000..27d0662799 --- /dev/null +++ b/test/pending/run/macro-expand-implicit-macro-defeats-type-inference/Macros_Test_2.scala @@ -0,0 +1,6 @@ +object Test extends App { + implicit def foo[T]: List[T] = macro Impls.foo[T] + def bar[T](implicit foo: List[T]) {} + implicitly[List[Int]] + bar[String] +} \ No newline at end of file -- cgit v1.2.3 From 2093bccc56cbfb77dbcb6e8e3224d2416feb39fb Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Tue, 17 Apr 2012 12:26:18 +0200 Subject: reintroduces prematurely removed manifest factories --- src/library/scala/reflect/ClassTag.scala | 135 ++++++++++++++++++--------- src/library/scala/reflect/api/TypeTags.scala | 45 ++++++++- 2 files changed, 134 insertions(+), 46 deletions(-) diff --git a/src/library/scala/reflect/ClassTag.scala b/src/library/scala/reflect/ClassTag.scala index fe8a16a484..06960a5478 100644 --- a/src/library/scala/reflect/ClassTag.scala +++ b/src/library/scala/reflect/ClassTag.scala @@ -122,51 +122,96 @@ object ClassTag { else ClassTag[T](ttag.tpe) implicit def toDeprecatedClassManifestApis[T](ctag: ClassTag[T]): DeprecatedClassManifestApis[T] = new DeprecatedClassManifestApis[T](ctag) -} - -// this class should not be used directly in client code -class DeprecatedClassManifestApis[T](ctag: ClassTag[T]) { - import scala.collection.mutable.{ WrappedArray, ArrayBuilder } - - @deprecated("Use `tpe` to analyze the underlying type", "2.10.0") - def <:<(that: ClassManifest[_]): Boolean = ctag.tpe <:< that.tpe - - @deprecated("Use `tpe` to analyze the underlying type", "2.10.0") - def >:>(that: ClassManifest[_]): Boolean = that <:< ctag - - @deprecated("Use `wrap` instead", "2.10.0") - def arrayManifest: ClassManifest[Array[T]] = ctag.wrap - - @deprecated("Use a combination of `wrap` and `newArray` instead", "2.10.0") - def newArray2(len: Int): Array[Array[T]] = ctag.wrap.newArray(len) - - @deprecated("Use a combination of `wrap` and `newArray` instead", "2.10.0") - def newArray3(len: Int): Array[Array[Array[T]]] = ctag.wrap.wrap.newArray(len) - @deprecated("Use a combination of `wrap` and `newArray` instead", "2.10.0") - def newArray4(len: Int): Array[Array[Array[Array[T]]]] = ctag.wrap.wrap.wrap.newArray(len) - - @deprecated("Use a combination of `wrap` and `newArray` instead", "2.10.0") - def newArray5(len: Int): Array[Array[Array[Array[Array[T]]]]] = ctag.wrap.wrap.wrap.wrap.newArray(len) - - @deprecated("Use `@scala.collection.mutable.WrappedArray` object instead", "2.10.0") - def newWrappedArray(len: Int): WrappedArray[T] = - ctag.erasure match { - case java.lang.Byte.TYPE => new WrappedArray.ofByte(new Array[Byte](len)).asInstanceOf[WrappedArray[T]] - case java.lang.Short.TYPE => new WrappedArray.ofShort(new Array[Short](len)).asInstanceOf[WrappedArray[T]] - case java.lang.Character.TYPE => new WrappedArray.ofChar(new Array[Char](len)).asInstanceOf[WrappedArray[T]] - case java.lang.Integer.TYPE => new WrappedArray.ofInt(new Array[Int](len)).asInstanceOf[WrappedArray[T]] - case java.lang.Long.TYPE => new WrappedArray.ofLong(new Array[Long](len)).asInstanceOf[WrappedArray[T]] - case java.lang.Float.TYPE => new WrappedArray.ofFloat(new Array[Float](len)).asInstanceOf[WrappedArray[T]] - case java.lang.Double.TYPE => new WrappedArray.ofDouble(new Array[Double](len)).asInstanceOf[WrappedArray[T]] - case java.lang.Boolean.TYPE => new WrappedArray.ofBoolean(new Array[Boolean](len)).asInstanceOf[WrappedArray[T]] - case java.lang.Void.TYPE => new WrappedArray.ofUnit(new Array[Unit](len)).asInstanceOf[WrappedArray[T]] - case _ => new WrappedArray.ofRef[T with AnyRef](ctag.newArray(len).asInstanceOf[Array[T with AnyRef]]).asInstanceOf[WrappedArray[T]] - } - - @deprecated("Use `@scala.collection.mutable.ArrayBuilder` object instead", "2.10.0") - def newArrayBuilder(): ArrayBuilder[T] = ArrayBuilder.make[T]()(ctag) + /** Manifest for the singleton type `value.type'. */ + @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") + def singleType[T <: AnyRef](value: AnyRef): Manifest[T] = ??? + + /** ClassManifest for the class type `clazz', where `clazz' is + * a top-level or static class. + * @note This no-prefix, no-arguments case is separate because we + * it's called from ScalaRunTime.boxArray itself. If we + * pass varargs as arrays into this, we get an infinitely recursive call + * to boxArray. (Besides, having a separate case is more efficient) + */ + @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") + def classType[T <: AnyRef](clazz: jClass[_]): ClassManifest[T] = ClassTag[T](clazz) + + /** ClassManifest for the class type `clazz[args]', where `clazz' is + * a top-level or static class and `args` are its type arguments */ + @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") + def classType[T <: AnyRef](clazz: jClass[_], arg1: OptManifest[_], args: OptManifest[_]*): ClassManifest[T] = ClassTag[T](clazz) + + /** ClassManifest for the class type `clazz[args]', where `clazz' is + * a class with non-package prefix type `prefix` and type arguments `args`. + */ + @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") + def classType[T <: AnyRef](prefix: OptManifest[_], clazz: jClass[_], args: OptManifest[_]*): ClassManifest[T] = ClassTag[T](clazz) + + @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") + def arrayType[T](arg: OptManifest[_]): ClassManifest[Array[T]] = arg match { + case x: ConcreteTypeTag[_] => ClassManifest[Array[T]](x.erasure) + case _ => Object.asInstanceOf[ClassManifest[Array[T]]] // was there in 2.9.x + } - @deprecated("`typeArguments` is no longer supported, and will always return an empty list. Use `@scala.reflect.TypeTag` or `@scala.reflect.ConcreteTypeTag` to capture and analyze type arguments", "2.10.0") - def typeArguments: List[OptManifest[_]] = List() + /** ClassManifest for the abstract type `prefix # name'. `upperBound' is not + * strictly necessary as it could be obtained by reflection. It was + * added so that erasure can be calculated without reflection. */ + @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") + def abstractType[T](prefix: OptManifest[_], name: String, clazz: jClass[_], args: OptManifest[_]*): ClassManifest[T] = ClassTag[T](clazz) + + /** ClassManifest for the abstract type `prefix # name'. `upperBound' is not + * strictly necessary as it could be obtained by reflection. It was + * added so that erasure can be calculated without reflection. + * todo: remove after next boostrap + */ + @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") + def abstractType[T](prefix: OptManifest[_], name: String, upperbound: ClassManifest[_], args: OptManifest[_]*): ClassManifest[T] = ClassTag[T](upperbound.erasure) + + class DeprecatedClassManifestApis[T](ctag: ClassTag[T]) { + import scala.collection.mutable.{ WrappedArray, ArrayBuilder } + + @deprecated("Use `tpe` to analyze the underlying type", "2.10.0") + def <:<(that: ClassManifest[_]): Boolean = ctag.tpe <:< that.tpe + + @deprecated("Use `tpe` to analyze the underlying type", "2.10.0") + def >:>(that: ClassManifest[_]): Boolean = that <:< ctag + + @deprecated("Use `wrap` instead", "2.10.0") + def arrayManifest: ClassManifest[Array[T]] = ctag.wrap + + @deprecated("Use a combination of `wrap` and `newArray` instead", "2.10.0") + def newArray2(len: Int): Array[Array[T]] = ctag.wrap.newArray(len) + + @deprecated("Use a combination of `wrap` and `newArray` instead", "2.10.0") + def newArray3(len: Int): Array[Array[Array[T]]] = ctag.wrap.wrap.newArray(len) + + @deprecated("Use a combination of `wrap` and `newArray` instead", "2.10.0") + def newArray4(len: Int): Array[Array[Array[Array[T]]]] = ctag.wrap.wrap.wrap.newArray(len) + + @deprecated("Use a combination of `wrap` and `newArray` instead", "2.10.0") + def newArray5(len: Int): Array[Array[Array[Array[Array[T]]]]] = ctag.wrap.wrap.wrap.wrap.newArray(len) + + @deprecated("Use `@scala.collection.mutable.WrappedArray` object instead", "2.10.0") + def newWrappedArray(len: Int): WrappedArray[T] = + ctag.erasure match { + case java.lang.Byte.TYPE => new WrappedArray.ofByte(new Array[Byte](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Short.TYPE => new WrappedArray.ofShort(new Array[Short](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Character.TYPE => new WrappedArray.ofChar(new Array[Char](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Integer.TYPE => new WrappedArray.ofInt(new Array[Int](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Long.TYPE => new WrappedArray.ofLong(new Array[Long](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Float.TYPE => new WrappedArray.ofFloat(new Array[Float](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Double.TYPE => new WrappedArray.ofDouble(new Array[Double](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Boolean.TYPE => new WrappedArray.ofBoolean(new Array[Boolean](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Void.TYPE => new WrappedArray.ofUnit(new Array[Unit](len)).asInstanceOf[WrappedArray[T]] + case _ => new WrappedArray.ofRef[T with AnyRef](ctag.newArray(len).asInstanceOf[Array[T with AnyRef]]).asInstanceOf[WrappedArray[T]] + } + + @deprecated("Use `@scala.collection.mutable.ArrayBuilder` object instead", "2.10.0") + def newArrayBuilder(): ArrayBuilder[T] = ArrayBuilder.make[T]()(ctag) + + @deprecated("`typeArguments` is no longer supported, and will always return an empty list. Use `@scala.reflect.TypeTag` or `@scala.reflect.ConcreteTypeTag` to capture and analyze type arguments", "2.10.0") + def typeArguments: List[OptManifest[_]] = List() + } } + diff --git a/src/library/scala/reflect/api/TypeTags.scala b/src/library/scala/reflect/api/TypeTags.scala index f7c4c63e94..b90475b15a 100644 --- a/src/library/scala/reflect/api/TypeTags.scala +++ b/src/library/scala/reflect/api/TypeTags.scala @@ -180,7 +180,7 @@ trait TypeTags { self: Universe => implicit def toDeprecatedManifestApis[T](ttag: rm.ConcreteTypeTag[T]): DeprecatedManifestApis[T] = new DeprecatedManifestApis[T](ttag) // this class should not be used directly in client code - class DeprecatedManifestApis[T](ttag: rm.ConcreteTypeTag[T]) extends DeprecatedClassManifestApis[T](toClassTag(ttag)) { + class DeprecatedManifestApis[T](ttag: rm.ConcreteTypeTag[T]) extends ClassTag.DeprecatedClassManifestApis[T](toClassTag(ttag)) { @deprecated("Use `tpe` to analyze the underlying type", "2.10.0") def <:<(that: Manifest[_]): Boolean = ttag.tpe <:< that.tpe @@ -190,6 +190,49 @@ trait TypeTags { self: Universe => @deprecated("Use `tpe` to analyze the type arguments", "2.10.0") override def typeArguments: List[Manifest[_]] = ttag.tpe.typeArguments map (targ => rm.ConcreteTypeTag(targ)) } + + /** Manifest for the singleton type `value.type'. */ + @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") + def singleType[T <: AnyRef](value: AnyRef): Manifest[T] = Manifest[T](???, value.getClass) + + /** Manifest for the class type `clazz[args]', where `clazz' is + * a top-level or static class. + * @note This no-prefix, no-arguments case is separate because we + * it's called from ScalaRunTime.boxArray itself. If we + * pass varargs as arrays into this, we get an infinitely recursive call + * to boxArray. (Besides, having a separate case is more efficient) + */ + @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") + def classType[T](clazz: Predef.Class[_]): Manifest[T] = Manifest[T](???, clazz) + + /** Manifest for the class type `clazz', where `clazz' is + * a top-level or static class and args are its type arguments. */ + @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") + def classType[T](clazz: Predef.Class[T], arg1: Manifest[_], args: Manifest[_]*): Manifest[T] = Manifest[T](???, clazz) + + /** Manifest for the class type `clazz[args]', where `clazz' is + * a class with non-package prefix type `prefix` and type arguments `args`. + */ + @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") + def classType[T](prefix: Manifest[_], clazz: Predef.Class[_], args: Manifest[_]*): Manifest[T] = Manifest[T](???, clazz) + + @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") + def arrayType[T](arg: Manifest[_]): Manifest[Array[T]] = Manifest[Array[T]](???, arg.asInstanceOf[Manifest[T]].arrayManifest.erasure) + + /** Manifest for the abstract type `prefix # name'. `upperBound' is not + * strictly necessary as it could be obtained by reflection. It was + * added so that erasure can be calculated without reflection. */ + @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") + def abstractType[T](prefix: Manifest[_], name: String, clazz: Predef.Class[_], args: Manifest[_]*): Manifest[T] = Manifest[T](???, clazz) + + /** Manifest for the unknown type `_ >: L <: U' in an existential. + */ + @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") + def wildcardType[T](lowerBound: Manifest[_], upperBound: Manifest[_]): Manifest[T] = Manifest[T](???, upperBound.erasure) + + /** Manifest for the intersection type `parents_0 with ... with parents_n'. */ + @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") + def intersectionType[T](parents: Manifest[_]*): Manifest[T] = Manifest[T](???, parents.head.erasure) } // incantations for summoning -- cgit v1.2.3 From 745fe4e36631f86665eb1bef9cb22e6623894a56 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Tue, 17 Apr 2012 22:49:07 +0200 Subject: fixes tests --- src/compiler/scala/reflect/makro/runtime/Reifiers.scala | 2 +- test/files/jvm/interpreter.check | 5 ++--- test/files/run/existentials3.check | 16 ++++++++-------- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/compiler/scala/reflect/makro/runtime/Reifiers.scala b/src/compiler/scala/reflect/makro/runtime/Reifiers.scala index 3586adc590..7c96b568bd 100644 --- a/src/compiler/scala/reflect/makro/runtime/Reifiers.scala +++ b/src/compiler/scala/reflect/makro/runtime/Reifiers.scala @@ -27,7 +27,7 @@ trait Reifiers { def reifyErasure(tpe: Type): Tree = { val positionBearer = enclosingMacros.find(c => c.macroApplication.pos != NoPosition).map(_.macroApplication).getOrElse(EmptyTree).asInstanceOf[Tree] - val typetagInScope = callsiteTyper.context.withMacrosDisabled(callsiteTyper.resolveTypeTag(positionBearer, gen.mkAttributedRef(Reflect_mirror).tpe, tpe, full = true)) + val typetagInScope = callsiteTyper.context.withMacrosDisabled(callsiteTyper.resolveTypeTag(positionBearer, singleType(Reflect_mirror.owner.thisPrefix, Reflect_mirror), tpe, full = true)) def typetagIsSynthetic(tree: Tree) = tree.isInstanceOf[Block] || (tree exists (sub => sub.symbol == TypeTagModule || sub.symbol == ConcreteTypeTagModule)) typetagInScope match { case success if !success.isEmpty && !typetagIsSynthetic(success) => diff --git a/test/files/jvm/interpreter.check b/test/files/jvm/interpreter.check index 85ec46c5f5..dc835bf8b6 100644 --- a/test/files/jvm/interpreter.check +++ b/test/files/jvm/interpreter.check @@ -316,9 +316,8 @@ scala> /* */ */ -scala> -scala> +You typed two blank lines. Starting a new command. scala> // multi-line string @@ -326,7 +325,7 @@ scala> """ hello there """ -res9: String = +res12: String = " hello there diff --git a/test/files/run/existentials3.check b/test/files/run/existentials3.check index 85bc430a21..e2c9382ab4 100644 --- a/test/files/run/existentials3.check +++ b/test/files/run/existentials3.check @@ -1,24 +1,24 @@ -ConcreteTypeTag[Bar.type], t=TypeRef, s= <: scala.runtime.AbstractFunction0[Bar] with Serializable{case def unapply(x$0: Bar): Boolean} with Singleton -ConcreteTypeTag[Bar], t=TypeRef, s= <: Test.ToS with Product with Serializable{def copy(): Bar} +ConcreteTypeTag[Bar.type], t=AbstractTypeRef, s= <: scala.runtime.AbstractFunction0[Bar] with Serializable{case def unapply(x$0: Bar): Boolean} with Singleton +ConcreteTypeTag[Bar], t=AbstractTypeRef, s= <: Test.ToS with Product with Serializable{def copy(): Bar} ConcreteTypeTag[Test.ToS], t=RefinedType, s=f3 ConcreteTypeTag[Test.ToS], t=RefinedType, s=f4 ConcreteTypeTag[Test.ToS], t=RefinedType, s=f5 ConcreteTypeTag[() => Test.ToS], t=TypeRef, s=class Function0 ConcreteTypeTag[() => Test.ToS], t=TypeRef, s=class Function0 -ConcreteTypeTag[$anon], t=TypeRef, s= <: B with Test.ToS -ConcreteTypeTag[$anon], t=TypeRef, s= <: B with A with Test.ToS +ConcreteTypeTag[$anon], t=AbstractTypeRef, s= <: B with Test.ToS +ConcreteTypeTag[$anon], t=AbstractTypeRef, s= <: B with A with Test.ToS TypeTag[List[Object{type T1}#T1]], t=TypeRef, s=class List ConcreteTypeTag[List[Seq[Int]]], t=TypeRef, s=class List ConcreteTypeTag[List[Seq[U forSome { type U <: Int }]]], t=TypeRef, s=class List -ConcreteTypeTag[Bar.type], t=TypeRef, s= <: scala.runtime.AbstractFunction0[Bar] with Serializable{case def unapply(x$0: Bar): Boolean} with Singleton -ConcreteTypeTag[Bar], t=TypeRef, s= <: Test.ToS with Product with Serializable{def copy(): Bar} +ConcreteTypeTag[Bar.type], t=AbstractTypeRef, s= <: scala.runtime.AbstractFunction0[Bar] with Serializable{case def unapply(x$0: Bar): Boolean} with Singleton +ConcreteTypeTag[Bar], t=AbstractTypeRef, s= <: Test.ToS with Product with Serializable{def copy(): Bar} ConcreteTypeTag[Test.ToS], t=RefinedType, s=g3 ConcreteTypeTag[Test.ToS], t=RefinedType, s=g4 ConcreteTypeTag[Test.ToS], t=RefinedType, s=g5 ConcreteTypeTag[() => Test.ToS], t=TypeRef, s=class Function0 ConcreteTypeTag[() => Test.ToS], t=TypeRef, s=class Function0 -ConcreteTypeTag[$anon], t=TypeRef, s= <: B with Test.ToS -ConcreteTypeTag[$anon], t=TypeRef, s= <: B with A with Test.ToS +ConcreteTypeTag[$anon], t=AbstractTypeRef, s= <: B with Test.ToS +ConcreteTypeTag[$anon], t=AbstractTypeRef, s= <: B with A with Test.ToS TypeTag[List[Object{type T1}#T1]], t=TypeRef, s=class List ConcreteTypeTag[List[Seq[Int]]], t=TypeRef, s=class List ConcreteTypeTag[List[Seq[U forSome { type U <: Int }]]], t=TypeRef, s=class List -- cgit v1.2.3