diff options
122 files changed, 1051 insertions, 470 deletions
diff --git a/src/compiler/scala/reflect/makro/runtime/Enclosures.scala b/src/compiler/scala/reflect/makro/runtime/Enclosures.scala index 80c35d22ff..360a4b8e8a 100644 --- a/src/compiler/scala/reflect/makro/runtime/Enclosures.scala +++ b/src/compiler/scala/reflect/makro/runtime/Enclosures.scala @@ -14,7 +14,6 @@ trait Enclosures { // vals are eager to simplify debugging // after all we wouldn't save that much time by making them lazy val macroApplication: Tree = expandee - val enclosingApplication: Tree = enclTrees collectFirst { case t: Apply => t } getOrElse EmptyTree val enclosingClass: Tree = site.enclClass.tree val enclosingImplicits: List[(Type, Tree)] = site.openImplicits val enclosingMacros: List[Context] = this :: universe.analyzer.openMacros // include self diff --git a/src/compiler/scala/tools/nsc/Driver.scala b/src/compiler/scala/tools/nsc/Driver.scala index 0051c3bdec..15e2929ff1 100644 --- a/src/compiler/scala/tools/nsc/Driver.scala +++ b/src/compiler/scala/tools/nsc/Driver.scala @@ -1,10 +1,12 @@ package scala.tools.nsc import scala.tools.nsc.reporters.{Reporter, ConsoleReporter} -import Properties.{ versionString, copyrightString } +import Properties.{ versionString, copyrightString, residentPromptString } import scala.reflect.internal.util.{ BatchSourceFile, FakePos } abstract class Driver { + + val prompt = residentPromptString val versionMsg = "Scala compiler " + versionString + " -- " + diff --git a/src/compiler/scala/tools/nsc/Main.scala b/src/compiler/scala/tools/nsc/Main.scala index 19c872b6d3..8b7e76e994 100644 --- a/src/compiler/scala/tools/nsc/Main.scala +++ b/src/compiler/scala/tools/nsc/Main.scala @@ -12,15 +12,13 @@ import scala.tools.nsc.interactive.{ RefinedBuildManager, SimpleBuildManager } import scala.tools.nsc.io.AbstractFile import scala.tools.nsc.reporters.{Reporter, ConsoleReporter} import scala.reflect.internal.util.{ BatchSourceFile, FakePos } //{Position} -import Properties.{ versionString, copyrightString, residentPromptString, msilLibPath } +import Properties.msilLibPath /** The main class for NSC, a compiler for the programming - * language Scala. + * language Scala. */ object Main extends Driver with EvalLoop { - val prompt = residentPromptString - def resident(compiler: Global) { loop { line => val args = line.split(' ').toList diff --git a/src/compiler/scala/tools/nsc/MainBench.scala b/src/compiler/scala/tools/nsc/MainBench.scala new file mode 100644 index 0000000000..0037de7b94 --- /dev/null +++ b/src/compiler/scala/tools/nsc/MainBench.scala @@ -0,0 +1,48 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2011 LAMP/EPFL + * @author Martin Odersky + */ + +package scala.tools.nsc + +import java.io.File +import File.pathSeparator + +import scala.tools.nsc.interactive.{ RefinedBuildManager, SimpleBuildManager } +import scala.tools.nsc.io.AbstractFile +import scala.tools.nsc.reporters.{Reporter, ConsoleReporter} +import scala.reflect.internal.util.{ BatchSourceFile, FakePos } //{Position} +import Properties.{ versionString, copyrightString, residentPromptString, msilLibPath } +import scala.reflect.internal.util.Statistics + +/** The main class for NSC, a compiler for the programming + * language Scala. + */ +object MainBench extends Driver with EvalLoop { + + lazy val theCompiler = Global(settings, reporter) + + override def newCompiler() = theCompiler + + val NIter = 50 + val NBest = 10 + + override def main(args: Array[String]) = { + val times = new Array[Long](NIter) + var start = System.nanoTime() + for (i <- 0 until NIter) { + if (i == NIter-1) { + theCompiler.settings.Ystatistics.value = true + Statistics.enabled = true + } + process(args) + val end = System.nanoTime() + val duration = (end-start)/1000000 + println(s"${duration}ms") + times(i) = duration + start = end + } + val avg = times.sorted.take(NBest).sum / NBest + println(s"avg shortest $NBest times ${avg}ms") + } +} diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala index 0c988ceae4..9b4e793241 100644 --- a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala +++ b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala @@ -34,8 +34,7 @@ abstract class SymbolLoaders { /** Enter class with given `name` into scope of `root` * and give them `completer` as type. */ - def enterClass(root: Symbol, name: String, completer: SymbolLoader): Symbol = { - val owner = root.ownerOfNewSymbols + def enterClass(owner: Symbol, name: String, completer: SymbolLoader): Symbol = { val clazz = owner.newClass(newTypeName(name)) clazz setInfo completer enterIfNew(owner, clazz, completer) @@ -44,8 +43,7 @@ abstract class SymbolLoaders { /** Enter module with given `name` into scope of `root` * and give them `completer` as type. */ - def enterModule(root: Symbol, name: String, completer: SymbolLoader): Symbol = { - val owner = root.ownerOfNewSymbols + def enterModule(owner: Symbol, name: String, completer: SymbolLoader): Symbol = { val module = owner.newModule(newTermName(name)) module setInfo completer module.moduleClass setInfo moduleClassLoader @@ -217,15 +215,18 @@ abstract class SymbolLoaders { root.setInfo(new PackageClassInfoType(newScope, root)) val sourcepaths = classpath.sourcepaths - for (classRep <- classpath.classes if platform.doLoad(classRep)) { - initializeFromClassPath(root, classRep) + if (!root.isRoot) { + for (classRep <- classpath.classes if platform.doLoad(classRep)) { + initializeFromClassPath(root, classRep) + } } + if (!root.isEmptyPackageClass) { + for (pkg <- classpath.packages) { + enterPackage(root, pkg.name, new PackageLoader(pkg)) + } - for (pkg <- classpath.packages) { - enterPackage(root, pkg.name, new PackageLoader(pkg)) + openPackageModule(root) } - - openPackageModule(root) } } diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala index fad41ae98d..bee5aa5f4f 100644 --- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala +++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala @@ -56,6 +56,31 @@ abstract class LambdaLift extends InfoTransform { /** The set of symbols that need to be renamed. */ private val renamable = newSymSet + /** + * The new names for free variables proxies. If we simply renamed the + * free variables, we would transform: + * {{{ + * def closure(x: Int) = { () => x } + * }}} + * + * To: + * {{{ + * def closure(x$1: Int) = new anonFun$1(this, x$1) + * class anonFun$1(outer$: Outer, x$1: Int) { def apply() => x$1 } + * }}} + * + * This is fatally bad for named arguments (0e170e4b), extremely impolite to tools + * reflecting on the method parameter names in the generated bytecode (SI-6028), + * and needlessly bothersome to anyone using a debugger. + * + * Instead, we transform to: + * {{{ + * def closure(x: Int) = new anonFun$1(this, x) + * class anonFun$1(outer$: Outer, x$1: Int) { def apply() => x$1 } + * }}} + */ + private val proxyNames = mutable.HashMap[Symbol, Name]() + // (trait, name) -> owner private val localTraits = mutable.HashMap[(Symbol, Name), Symbol]() // (owner, name) -> implClass @@ -117,15 +142,6 @@ abstract class LambdaLift extends InfoTransform { if (!ss(sym)) { ss addEntry sym renamable addEntry sym - beforePickler { - // The param symbol in the MethodType should not be renamed, only the symbol in scope. This way, - // parameter names for named arguments are not changed. Example: without cloning the MethodType, - // def closure(x: Int) = { () => x } - // would have the signature - // closure: (x$1: Int)() => Int - if (sym.isParameter && sym.owner.info.paramss.exists(_ contains sym)) - sym.owner modifyInfo (_ cloneInfo sym.owner) - } changedFreeVars = true debuglog("" + sym + " is free in " + enclosure); if (sym.isVariable) sym setFlag CAPTURED @@ -215,24 +231,26 @@ abstract class LambdaLift extends InfoTransform { def renameSym(sym: Symbol) { val originalName = sym.name + sym setName newName(sym) + debuglog("renaming in %s: %s => %s".format(sym.owner.fullLocationString, originalName, sym.name)) + } + + def newName(sym: Symbol): Name = { + val originalName = sym.name def freshen(prefix: String): Name = if (originalName.isTypeName) unit.freshTypeName(prefix) else unit.freshTermName(prefix) - val newName: Name = ( - if (sym.isAnonymousFunction && sym.owner.isMethod) { - freshen(sym.name + nme.NAME_JOIN_STRING + sym.owner.name + nme.NAME_JOIN_STRING) - } else { - // SI-5652 If the lifted symbol is accessed from an inner class, it will be made public. (where?) - // Generating a a unique name, mangled with the enclosing class name, avoids a VerifyError - // in the case that a sub-class happens to lifts out a method with the *same* name. - val name = freshen(sym.name + nme.NAME_JOIN_STRING) - if (originalName.isTermName && !sym.enclClass.isImplClass && calledFromInner(sym)) nme.expandedName(name, sym.enclClass) - else name - } - ) - sym setName newName - debuglog("renaming in %s: %s => %s".format(sym.owner.fullLocationString, originalName, sym.name)) + if (sym.isAnonymousFunction && sym.owner.isMethod) { + freshen(sym.name + nme.NAME_JOIN_STRING + sym.owner.name + nme.NAME_JOIN_STRING) + } else { + // SI-5652 If the lifted symbol is accessed from an inner class, it will be made public. (where?) + // Generating a a unique name, mangled with the enclosing class name, avoids a VerifyError + // in the case that a sub-class happens to lifts out a method with the *same* name. + val name = freshen(sym.name + nme.NAME_JOIN_STRING) + if (originalName.isTermName && !sym.enclClass.isImplClass && calledFromInner(sym)) nme.expandedName(name, sym.enclClass) + else name + } } /** Rename a trait's interface and implementation class in coordinated fashion. @@ -245,6 +263,8 @@ abstract class LambdaLift extends InfoTransform { debuglog("renaming impl class in step with %s: %s => %s".format(traitSym, originalImplName, implSym.name)) } + val allFree: Set[Symbol] = free.values.flatMap(_.iterator).toSet + for (sym <- renamable) { // If we renamed a trait from Foo to Foo$1, we must rename the implementation // class from Foo$class to Foo$1$class. (Without special consideration it would @@ -252,7 +272,9 @@ abstract class LambdaLift extends InfoTransform { // under us, and there's no reliable link between trait symbol and impl symbol, // we have maps from ((trait, name)) -> owner and ((owner, name)) -> impl. localTraits remove ((sym, sym.name)) match { - case None => renameSym(sym) + case None => + if (allFree(sym)) proxyNames(sym) = newName(sym) + else renameSym(sym) case Some(owner) => localImplClasses remove ((owner, sym.name)) match { case Some(implSym) => renameTrait(sym, implSym) @@ -267,7 +289,8 @@ abstract class LambdaLift extends InfoTransform { debuglog("free var proxy: %s, %s".format(owner.fullLocationString, freeValues.toList.mkString(", "))) proxies(owner) = for (fv <- freeValues.toList) yield { - val proxy = owner.newValue(fv.name, owner.pos, newFlags) setInfo fv.info + val proxyName = proxyNames.getOrElse(fv, fv.name) + val proxy = owner.newValue(proxyName, owner.pos, newFlags) setInfo fv.info if (owner.isClass) owner.info.decls enter proxy proxy } @@ -280,9 +303,9 @@ abstract class LambdaLift extends InfoTransform { if (enclosure eq NoSymbol) throw new IllegalArgumentException("Could not find proxy for "+ sym.defString +" in "+ sym.ownerChain +" (currentOwner= "+ currentOwner +" )") debuglog("searching for " + sym + "(" + sym.owner + ") in " + enclosure + " " + enclosure.logicallyEnclosingMember) - val ps = (proxies get enclosure.logicallyEnclosingMember).toList.flatten filter (_.name == sym.name) - if (ps.isEmpty) searchIn(enclosure.skipConstructor.owner) - else ps.head + val proxyName = proxyNames.getOrElse(sym, sym.name) + val ps = (proxies get enclosure.logicallyEnclosingMember).toList.flatten find (_.name == proxyName) + ps getOrElse searchIn(enclosure.skipConstructor.owner) } debuglog("proxy %s from %s has logical enclosure %s".format( sym.debugLocationString, @@ -501,8 +524,10 @@ abstract class LambdaLift extends InfoTransform { } override def transformUnit(unit: CompilationUnit) { - computeFreeVars - afterOwnPhase(super.transformUnit(unit)) + computeFreeVars() + afterOwnPhase { + super.transformUnit(unit) + } assert(liftedDefs.isEmpty, liftedDefs.keys mkString ", ") } } // class LambdaLifter diff --git a/src/compiler/scala/tools/nsc/transform/PostErasure.scala b/src/compiler/scala/tools/nsc/transform/PostErasure.scala index 999d00520d..151bc66a79 100644 --- a/src/compiler/scala/tools/nsc/transform/PostErasure.scala +++ b/src/compiler/scala/tools/nsc/transform/PostErasure.scala @@ -21,6 +21,8 @@ trait PostErasure extends InfoTransform with TypingTransformers { object elimErasedValueType extends TypeMap { def apply(tp: Type) = tp match { + case ConstantType(Constant(tp: Type)) => + ConstantType(Constant(apply(tp))) case ErasedValueType(tref) => atPhase(currentRun.erasurePhase)(erasure.erasedValueClassArg(tref)) case _ => mapOver(tp) diff --git a/src/compiler/scala/tools/nsc/transform/TailCalls.scala b/src/compiler/scala/tools/nsc/transform/TailCalls.scala index 4c9d855413..d5bbc578fc 100644 --- a/src/compiler/scala/tools/nsc/transform/TailCalls.scala +++ b/src/compiler/scala/tools/nsc/transform/TailCalls.scala @@ -373,7 +373,7 @@ abstract class TailCalls extends Transform { // the labels all look like: matchEnd(x) {x} // then, in a forward jump `matchEnd(expr)`, `expr` is considered in tail position (and the matchEnd jump is replaced by the jump generated by expr) class TailPosLabelsTraverser extends Traverser { - val tailLabels = new collection.mutable.ListBuffer[Symbol]() + val tailLabels = new collection.mutable.HashSet[Symbol]() private var maybeTail: Boolean = true // since we start in the rhs of a DefDef @@ -388,9 +388,15 @@ abstract class TailCalls extends Transform { def traverseTreesNoTail(trees: List[Tree]) = trees foreach traverseNoTail override def traverse(tree: Tree) = tree match { - case LabelDef(_, List(arg), body@Ident(_)) if arg.symbol == body.symbol => // we're looking for label(x){x} in tail position, since that means `a` is in tail position in a call `label(a)` + // we're looking for label(x){x} in tail position, since that means `a` is in tail position in a call `label(a)` + case LabelDef(_, List(arg), body@Ident(_)) if arg.symbol == body.symbol => if (maybeTail) tailLabels += tree.symbol + // jumps to matchEnd are transparent; need this case for nested matches + // (and the translated match case below does things in reverse for this case's sake) + case Apply(fun, arg :: Nil) if hasSynthCaseSymbol(fun) && tailLabels(fun.symbol) => + traverse(arg) + // a translated casedef case LabelDef(_, _, body) if hasSynthCaseSymbol(tree) => traverse(body) @@ -400,9 +406,9 @@ abstract class TailCalls extends Transform { // the assumption is once we encounter a case, the remainder of the block will consist of cases // the prologue may be empty, usually it is the valdef that stores the scrut val (prologue, cases) = stats span (s => !s.isInstanceOf[LabelDef]) - traverseTreesNoTail(prologue) // selector (may be absent) - traverseTrees(cases) traverse(expr) + traverseTrees(cases.reverse) // reverse so that we enter the matchEnd LabelDef before we see jumps to it + traverseTreesNoTail(prologue) // selector (may be absent) case CaseDef(pat, guard, body) => traverse(body) @@ -426,7 +432,7 @@ abstract class TailCalls extends Transform { traverseTreesNoTail(catches) traverseNoTail(finalizer) - case EmptyTree | Super(_, _) | This(_) | Select(_, _) | Ident(_) | Literal(_) | Function(_, _) | TypeTree() => + case Apply(_, _) | EmptyTree | Super(_, _) | This(_) | Select(_, _) | Ident(_) | Literal(_) | Function(_, _) | TypeTree() => case _ => super.traverse(tree) } } diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index 663b3dd2e9..efc3d25ed0 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -33,6 +33,14 @@ import language.postfixOps * - convert implicit method types to method types * - convert non-trivial catches in try statements to matches * - convert non-local returns to throws with enclosing try statements. + * - convert try-catch expressions in contexts where there might be values on the stack to + * a local method and a call to it (since an exception empties the evaluation stack): + * + * meth(x_1,..., try { x_i } catch { ..}, .. x_b0) ==> + * { + * def liftedTry$1 = try { x_i } catch { .. } + * meth(x_1, .., liftedTry$1(), .. ) + * } */ /*</export> */ abstract class UnCurry extends InfoTransform @@ -564,12 +572,6 @@ abstract class UnCurry extends InfoTransform } val sym = tree.symbol - // Take a pass looking for @specialize annotations and set all - // their SPECIALIZE flags for cheaper recognition. - if ((sym ne null) && (sym.isClass || sym.isMethod)) { - for (tp <- sym.typeParams ; if tp hasAnnotation SpecializedClass) - tp setFlag SPECIALIZED - } val result = ( // TODO - settings.noassertions.value temporarily retained to avoid // breakage until a reasonable interface is settled upon. @@ -640,6 +642,13 @@ abstract class UnCurry extends InfoTransform case ret @ Return(_) if (isNonLocalReturn(ret)) => withNeedLift(true) { super.transform(ret) } + case Try(_, Nil, _) => + // try-finally does not need lifting: lifting is needed only for try-catch + // expressions that are evaluated in a context where the stack might not be empty. + // `finally` does not attempt to continue evaluation after an exception, so the fact + // that values on the stack are 'lost' does not matter + super.transform(tree) + case Try(block, catches, finalizer) => if (needTryLift || shouldBeLiftedAnyway(tree)) transform(liftTree(tree)) else super.transform(tree) diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index bcf529ecd2..805f60ba87 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -636,6 +636,12 @@ trait Contexts { self: Analyzer => collect(imp.tree.selectors) } + /* SI-5892 / SI-4270: `implicitss` can return results which are not accessible at the + * point where implicit search is triggered. Example: implicits in (annotations of) + * class type parameters (SI-5892). The `context.owner` is the class symbol, therefore + * `implicitss` will return implicit conversions defined inside the class. These are + * filtered out later by `eligibleInfos` (SI-4270 / 9129cfe9), as they don't type-check. + */ def implicitss: List[List[ImplicitInfo]] = { if (implicitsRunId != currentRunId) { implicitsRunId = currentRunId diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index 322b9ebb25..b7043e58de 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -26,7 +26,7 @@ import java.lang.reflect.{Array => jArray, Method => jMethod} * def fooBar[T: c.TypeTag] * (c: scala.reflect.makro.Context) * (xs: c.Expr[List[T]]) - * : c.Tree = { + * : c.Expr[T] = { * ... * } * @@ -601,7 +601,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { if (settings.XmacroPrimaryClasspath.value != "") { macroLogVerbose("primary macro classloader: initializing from -Xmacro-primary-classpath: %s".format(settings.XmacroPrimaryClasspath.value)) - val classpath = toURLs(settings.XmacroFallbackClasspath.value) + val classpath = toURLs(settings.XmacroPrimaryClasspath.value) ScalaClassLoader.fromURLs(classpath, self.getClass.getClassLoader) } else { macroLogVerbose("primary macro classloader: initializing from -cp: %s".format(global.classPath.asURLs)) diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 48fd6ba928..dc9f07cad9 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -1214,8 +1214,8 @@ trait Namers extends MethodSynthesis { if (!annotated.isInitialized) tree match { case defn: MemberDef => val ainfos = defn.mods.annotations filterNot (_ eq null) map { ann => - // need to be lazy, #1782 - AnnotationInfo lazily (typer typedAnnotation ann) + // need to be lazy, #1782. beforeTyper to allow inferView in annotation args, SI-5892. + AnnotationInfo lazily beforeTyper(typer typedAnnotation ann) } if (ainfos.nonEmpty) { annotated setAnnotations ainfos diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala index da45b9bde3..4e4176e531 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala @@ -47,8 +47,11 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL val phaseName: String = "patmat" // TODO: the inliner fails to inline the closures to patmatDebug - // private val printPatmat = settings.Ypatmatdebug.value - // @inline final def patmatDebug(s: => String) = if (printPatmat) println(s) + object debugging { + val printPatmat = settings.Ypatmatdebug.value + @inline final def patmatDebug(s: => String) = if (printPatmat) println(s) + } + import debugging.patmatDebug def newTransformer(unit: CompilationUnit): Transformer = if (opt.virtPatmat) new MatchTransformer(unit) @@ -185,7 +188,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL // (that would require more sophistication when generating trees, // and the only place that emits Matches after typers is for exception handling anyway) if(phase.id >= currentRun.uncurryPhase.id) debugwarn("running translateMatch at "+ phase +" on "+ selector +" match "+ cases) - // patmatDebug ("translating "+ cases.mkString("{", "\n", "}")) + patmatDebug("translating "+ cases.mkString("{", "\n", "}")) def repeatedToSeq(tp: Type): Type = (tp baseType RepeatedParamClass) match { case TypeRef(_, RepeatedParamClass, arg :: Nil) => seqType(arg) @@ -310,14 +313,14 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL if (!extractor.isTyped) ErrorUtils.issueNormalTypeError(patTree, "Could not typecheck extractor call: "+ extractor)(context) // if (extractor.resultInMonad == ErrorType) throw new TypeError(pos, "Unsupported extractor type: "+ extractor.tpe) - // patmatDebug ("translateExtractorPattern checking parameter type: "+ (patBinder, patBinder.info.widen, extractor.paramType, patBinder.info.widen <:< extractor.paramType)) + patmatDebug("translateExtractorPattern checking parameter type: "+ (patBinder, patBinder.info.widen, extractor.paramType, patBinder.info.widen <:< extractor.paramType)) // must use type `tp`, which is provided by extractor's result, not the type expected by binder, // as b.info may be based on a Typed type ascription, which has not been taken into account yet by the translation // (it will later result in a type test when `tp` is not a subtype of `b.info`) // TODO: can we simplify this, together with the Bound case? (extractor.subPatBinders, extractor.subPatTypes).zipped foreach { case (b, tp) => - // patmatDebug ("changing "+ b +" : "+ b.info +" -> "+ tp) + patmatDebug("changing "+ b +" : "+ b.info +" -> "+ tp) b setInfo tp } @@ -424,7 +427,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL */ case Bind(n, p) => // this happens in certain ill-formed programs, there'll be an error later - // patmatDebug ("WARNING: Bind tree with unbound symbol "+ patTree) + patmatDebug("WARNING: Bind tree with unbound symbol "+ patTree) noFurtherSubPats() // there's no symbol -- something's wrong... don't fail here though (or should we?) // case Star(_) | ArrayValue | This => error("stone age pattern relics encountered!") @@ -634,7 +637,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL // binder has type paramType def treeMaker(binder: Symbol, pos: Position): TreeMaker = { // checks binder ne null before chaining to the next extractor - ProductExtractorTreeMaker(binder, lengthGuard(binder), Substitution(subPatBinders, subPatRefs(binder))) + ProductExtractorTreeMaker(binder, lengthGuard(binder))(Substitution(subPatBinders, subPatRefs(binder))) } // reference the (i-1)th case accessor if it exists, otherwise the (i-1)th tuple component @@ -678,7 +681,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL // the extractor call (applied to the binder bound by the flatMap corresponding to the previous (i.e., enclosing/outer) pattern) val extractorApply = atPos(pos)(spliceApply(patBinderOrCasted)) val binder = freshSym(pos, pureType(resultInMonad)) // can't simplify this when subPatBinders.isEmpty, since UnitClass.tpe is definitely wrong when isSeq, and resultInMonad should always be correct since it comes directly from the extractor's result type - ExtractorTreeMaker(extractorApply, lengthGuard(binder), binder, Substitution(subPatBinders, subPatRefs(binder)))(resultType.typeSymbol == BooleanClass, checkedLength, patBinderOrCasted) + ExtractorTreeMaker(extractorApply, lengthGuard(binder), binder)(Substitution(subPatBinders, subPatRefs(binder)), resultType.typeSymbol == BooleanClass, checkedLength, patBinderOrCasted) } override protected def seqTree(binder: Symbol): Tree = @@ -827,7 +830,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL private[TreeMakers] def incorporateOuterSubstitution(outerSubst: Substitution): Unit = { if (currSub ne null) { - // patmatDebug ("BUG: incorporateOuterSubstitution called more than once for "+ (this, currSub, outerSubst)) + patmatDebug("BUG: incorporateOuterSubstitution called more than once for "+ (this, currSub, outerSubst)) Thread.dumpStack() } else currSub = outerSubst >> substitution @@ -889,7 +892,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL * the function's body is determined by the next TreeMaker * in this function's body, and all the subsequent ones, references to the symbols in `from` will be replaced by the corresponding tree in `to` */ - case class ExtractorTreeMaker(extractor: Tree, extraCond: Option[Tree], nextBinder: Symbol, localSubstitution: Substitution)(extractorReturnsBoolean: Boolean, val checkedLength: Option[Int], val prevBinder: Symbol) extends FunTreeMaker { + case class ExtractorTreeMaker(extractor: Tree, extraCond: Option[Tree], nextBinder: Symbol)(val localSubstitution: Substitution, extractorReturnsBoolean: Boolean, val checkedLength: Option[Int], val prevBinder: Symbol) extends FunTreeMaker { def chainBefore(next: Tree)(casegen: Casegen): Tree = { val condAndNext = extraCond map (casegen.ifThenElseZero(_, next)) getOrElse next atPos(extractor.pos)( @@ -902,7 +905,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL } // TODO: allow user-defined unapplyProduct - case class ProductExtractorTreeMaker(prevBinder: Symbol, extraCond: Option[Tree], localSubstitution: Substitution) extends FunTreeMaker { import CODE._ + case class ProductExtractorTreeMaker(prevBinder: Symbol, extraCond: Option[Tree])(val localSubstitution: Substitution) extends FunTreeMaker { import CODE._ val nextBinder = prevBinder // just passing through def chainBefore(next: Tree)(casegen: Casegen): Tree = { val nullCheck = REF(prevBinder) OBJ_NE NULL @@ -993,7 +996,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL **/ case class TypeTestTreeMaker(prevBinder: Symbol, testedBinder: Symbol, expectedTp: Type, nextBinderTp: Type)(override val pos: Position, extractorArgTypeTest: Boolean = false) extends CondTreeMaker { import TypeTestTreeMaker._ - // patmatDebug ("TTTM"+(prevBinder, extractorArgTypeTest, testedBinder, expectedTp, nextBinderTp)) + patmatDebug("TTTM"+(prevBinder, extractorArgTypeTest, testedBinder, expectedTp, nextBinderTp)) lazy val outerTestNeeded = ( !((expectedTp.prefix eq NoPrefix) || expectedTp.prefix.typeSymbol.isPackageClass) @@ -1121,7 +1124,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL def combineCasesNoSubstOnly(scrut: Tree, scrutSym: Symbol, casesNoSubstOnly: List[List[TreeMaker]], pt: Type, owner: Symbol, matchFailGenOverride: Option[Tree => Tree]): Tree = fixerUpper(owner, scrut.pos){ def matchFailGen = (matchFailGenOverride orElse Some(CODE.MATCHERROR(_: Tree))) - // patmatDebug ("combining cases: "+ (casesNoSubstOnly.map(_.mkString(" >> ")).mkString("{", "\n", "}"))) + patmatDebug("combining cases: "+ (casesNoSubstOnly.map(_.mkString(" >> ")).mkString("{", "\n", "}"))) val (unchecked, requireSwitch) = if (settings.XnoPatmatAnalysis.value) (true, false) @@ -1175,12 +1178,12 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL t match { case Function(_, _) if t.symbol == NoSymbol => t.symbol = currentOwner.newAnonymousFunctionValue(t.pos) - // patmatDebug ("new symbol for "+ (t, t.symbol.ownerChain)) + patmatDebug("new symbol for "+ (t, t.symbol.ownerChain)) case Function(_, _) if (t.symbol.owner == NoSymbol) || (t.symbol.owner == origOwner) => - // patmatDebug ("fundef: "+ (t, t.symbol.ownerChain, currentOwner.ownerChain)) + patmatDebug("fundef: "+ (t, t.symbol.ownerChain, currentOwner.ownerChain)) t.symbol.owner = currentOwner case d : DefTree if (d.symbol != NoSymbol) && ((d.symbol.owner == NoSymbol) || (d.symbol.owner == origOwner)) => // don't indiscriminately change existing owners! (see e.g., pos/t3440, pos/t3534, pos/unapplyContexts2) - // patmatDebug ("def: "+ (d, d.symbol.ownerChain, currentOwner.ownerChain)) + patmatDebug("def: "+ (d, d.symbol.ownerChain, currentOwner.ownerChain)) if(d.symbol.isLazy) { // for lazy val's accessor -- is there no tree?? assert(d.symbol.lazyAccessor != NoSymbol && d.symbol.lazyAccessor.owner == d.symbol.owner, d.symbol.lazyAccessor) d.symbol.lazyAccessor.owner = currentOwner @@ -1190,7 +1193,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL d.symbol.owner = currentOwner // case _ if (t.symbol != NoSymbol) && (t.symbol ne null) => - // patmatDebug ("untouched "+ (t, t.getClass, t.symbol.ownerChain, currentOwner.ownerChain)) + patmatDebug("untouched "+ (t, t.getClass, t.symbol.ownerChain, currentOwner.ownerChain)) case _ => } super.traverse(t) @@ -1386,7 +1389,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL case object FalseCond extends Cond {override def toString = "F"} case class AndCond(a: Cond, b: Cond) extends Cond {override def toString = a +"/\\"+ b} - case class OrCond(a: Cond, b: Cond) extends Cond {override def toString = "("+a+") \\/ ("+ b +")"} + case class OrCond(a: Cond, b: Cond) extends Cond {override def toString = "("+a+") \\/ ("+ b +")"} object EqualityCond { private val uniques = new collection.mutable.HashMap[(Tree, Tree), EqualityCond] @@ -1445,9 +1448,9 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL case _ => false } - def unapply(xtm: ExtractorTreeMaker): Option[(Tree, Symbol, Substitution)] = xtm match { - case ExtractorTreeMaker(extractor, None, nextBinder, subst) if irrefutableExtractorType(extractor.tpe) => - Some(extractor, nextBinder, subst) + def unapply(xtm: ExtractorTreeMaker): Option[(Tree, Symbol)] = xtm match { + case ExtractorTreeMaker(extractor, None, nextBinder) if irrefutableExtractorType(extractor.tpe) => + Some(extractor, nextBinder) case _ => None } @@ -1455,18 +1458,13 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL // returns (tree, tests), where `tree` will be used to refer to `root` in `tests` class TreeMakersToConds(val root: Symbol) { - def discard() = { - pointsToBound.clear() - trees.clear() - normalize = EmptySubstitution - accumSubst = EmptySubstitution - } // a variable in this set should never be replaced by a tree that "does not consist of a selection on a variable in this set" (intuitively) private val pointsToBound = collection.mutable.HashSet(root) private val trees = collection.mutable.HashSet.empty[Tree] // the substitution that renames variables to variables in pointsToBound private var normalize: Substitution = EmptySubstitution + private var substitutionComputed = false // replaces a variable (in pointsToBound) by a selection on another variable in pointsToBound // in the end, instead of having x1, x1.hd, x2, x2.hd, ... flying around, @@ -1476,29 +1474,6 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL // pointsToBound -- accumSubst.from == Set(root) && (accumSubst.from.toSet -- pointsToBound) isEmpty private var accumSubst: Substitution = EmptySubstitution - private def updateSubstitution(subst: Substitution) = { - // find part of substitution that replaces bound symbols by new symbols, and reverse that part - // so that we don't introduce new aliases for existing symbols, thus keeping the set of bound symbols minimal - val (boundSubst, unboundSubst) = (subst.from zip subst.to) partition { - case (f, t) => - t.isInstanceOf[Ident] && (t.symbol ne NoSymbol) && pointsToBound(f) - } - val (boundFrom, boundTo) = boundSubst.unzip - val (unboundFrom, unboundTo) = unboundSubst.unzip - - // reverse substitution that would otherwise replace a variable we already encountered by a new variable - // NOTE: this forgets the more precise type we have for these later variables, but that's probably okay - normalize >>= Substitution(boundTo map (_.symbol), boundFrom map (CODE.REF(_))) - // patmatDebug ("normalize subst: "+ normalize) - - val okSubst = Substitution(unboundFrom, unboundTo map (normalize(_))) // it's important substitution does not duplicate trees here -- it helps to keep hash consing simple, anyway - pointsToBound ++= ((okSubst.from, okSubst.to).zipped filter { (f, t) => pointsToBound exists (sym => t.exists(_.symbol == sym)) })._1 - // patmatDebug ("pointsToBound: "+ pointsToBound) - - accumSubst >>= okSubst - // patmatDebug ("accumSubst: "+ accumSubst) - } - // hashconsing trees (modulo value-equality) def unique(t: Tree, tpOverride: Type = NoType): Tree = trees find (a => a.correspondsStructure(t)(sameValue)) match { @@ -1529,74 +1504,120 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL // note that the sequencing of operations is important: must visit in same order as match execution // binderToUniqueTree uses the type of the first symbol that was encountered as the type for all future binders - final def treeMakerToCond(tm: TreeMaker, handleUnknown: TreeMaker => Cond, updateSubst: Boolean, rewriteNil: Boolean = false): Cond = { - if (updateSubst) updateSubstitution(tm.substitution) - - tm match { - case ttm@TypeTestTreeMaker(prevBinder, testedBinder, pt, _) => - object condStrategy extends TypeTestTreeMaker.TypeTestCondStrategy { - type Result = Cond - def and(a: Result, b: Result) = AndCond(a, b) - def outerTest(testedBinder: Symbol, expectedTp: Type) = TrueCond // TODO OuterEqCond(testedBinder, expectedType) - def typeTest(b: Symbol, pt: Type) = { // a type test implies the tested path is non-null (null.isInstanceOf[T] is false for all T) - val p = binderToUniqueTree(b); AndCond(NonNullCond(p), TypeCond(p, uniqueTp(pt))) + abstract class TreeMakerToCond extends (TreeMaker => Cond) { + // requires(if (!substitutionComputed)) + def updateSubstitution(subst: Substitution): Unit = { + // find part of substitution that replaces bound symbols by new symbols, and reverse that part + // so that we don't introduce new aliases for existing symbols, thus keeping the set of bound symbols minimal + val (boundSubst, unboundSubst) = (subst.from zip subst.to) partition { + case (f, t) => + t.isInstanceOf[Ident] && (t.symbol ne NoSymbol) && pointsToBound(f) + } + val (boundFrom, boundTo) = boundSubst.unzip + val (unboundFrom, unboundTo) = unboundSubst.unzip + + // reverse substitution that would otherwise replace a variable we already encountered by a new variable + // NOTE: this forgets the more precise type we have for these later variables, but that's probably okay + normalize >>= Substitution(boundTo map (_.symbol), boundFrom map (CODE.REF(_))) + // patmatDebug ("normalize subst: "+ normalize) + + val okSubst = Substitution(unboundFrom, unboundTo map (normalize(_))) // it's important substitution does not duplicate trees here -- it helps to keep hash consing simple, anyway + pointsToBound ++= ((okSubst.from, okSubst.to).zipped filter { (f, t) => pointsToBound exists (sym => t.exists(_.symbol == sym)) })._1 + // patmatDebug("pointsToBound: "+ pointsToBound) + + accumSubst >>= okSubst + // patmatDebug("accumSubst: "+ accumSubst) + } + + def handleUnknown(tm: TreeMaker): Cond + + /** apply itself must render a faithful representation of the TreeMaker + * + * Concretely, TrueCond must only be used to represent a TreeMaker that is sure to match and that does not do any computation at all + * e.g., doCSE relies on apply itself being sound in this sense (since it drops TreeMakers that are approximated to TrueCond -- SI-6077) + * + * handleUnknown may be customized by the caller to approximate further + * + * TODO: don't ignore outer-checks + */ + def apply(tm: TreeMaker): Cond = { + if (!substitutionComputed) updateSubstitution(tm.substitution) + + tm match { + case ttm@TypeTestTreeMaker(prevBinder, testedBinder, pt, _) => + object condStrategy extends TypeTestTreeMaker.TypeTestCondStrategy { + type Result = Cond + def and(a: Result, b: Result) = AndCond(a, b) + def outerTest(testedBinder: Symbol, expectedTp: Type) = TrueCond // TODO OuterEqCond(testedBinder, expectedType) + def typeTest(b: Symbol, pt: Type) = { // a type test implies the tested path is non-null (null.isInstanceOf[T] is false for all T) + val p = binderToUniqueTree(b); AndCond(NonNullCond(p), TypeCond(p, uniqueTp(pt))) + } + def nonNullTest(testedBinder: Symbol) = NonNullCond(binderToUniqueTree(testedBinder)) + def equalsTest(pat: Tree, testedBinder: Symbol) = EqualityCond(binderToUniqueTree(testedBinder), unique(pat)) + def eqTest(pat: Tree, testedBinder: Symbol) = EqualityCond(binderToUniqueTree(testedBinder), unique(pat)) // TODO: eq, not == } - def nonNullTest(testedBinder: Symbol) = NonNullCond(binderToUniqueTree(testedBinder)) - def equalsTest(pat: Tree, testedBinder: Symbol) = EqualityCond(binderToUniqueTree(testedBinder), unique(pat)) - def eqTest(pat: Tree, testedBinder: Symbol) = EqualityCond(binderToUniqueTree(testedBinder), unique(pat)) // TODO: eq, not == - } - ttm.renderCondition(condStrategy) - case EqualityTestTreeMaker(prevBinder, patTree, _) => EqualityCond(binderToUniqueTree(prevBinder), unique(patTree)) - case AlternativesTreeMaker(_, altss, _) => \/(altss map (alts => /\(alts map (treeMakerToCond(_, handleUnknown, updateSubst))))) - case ProductExtractorTreeMaker(testedBinder, None, subst) => NonNullCond(binderToUniqueTree(testedBinder)) - case IrrefutableExtractorTreeMaker(_, _, _) => - // the extra condition is None, the extractor's result indicates it always succeeds, - // and the potential type-test for the argument is represented by a separate TypeTestTreeMaker - TrueCond - case GuardTreeMaker(guard) => - guard.tpe match { - case ConstantType(Constant(true)) => TrueCond - case ConstantType(Constant(false)) => FalseCond - case _ => handleUnknown(tm) - } - case p @ ExtractorTreeMaker(extractor, Some(lenCheck), testedBinder, _) => - p.checkedLength match { - // special-case: interpret pattern `List()` as `Nil` - // TODO: make it more general List(1, 2) => 1 :: 2 :: Nil -- not sure this is a good idea... - case Some(0) if rewriteNil && testedBinder.tpe.typeSymbol == ListClass => // extractor.symbol.owner == SeqFactory - EqualityCond(binderToUniqueTree(p.prevBinder), unique(Ident(NilModule) setType NilModule.tpe)) - case _ => handleUnknown(tm) - } - case SubstOnlyTreeMaker(_, _) => TrueCond - case ProductExtractorTreeMaker(_, Some(_), _) | - ExtractorTreeMaker(_, _, _, _) | BodyTreeMaker(_, _) => handleUnknown(tm) + ttm.renderCondition(condStrategy) + case EqualityTestTreeMaker(prevBinder, patTree, _) => EqualityCond(binderToUniqueTree(prevBinder), unique(patTree)) + case AlternativesTreeMaker(_, altss, _) => \/(altss map (alts => /\(alts map this))) + case ProductExtractorTreeMaker(testedBinder, None) => NonNullCond(binderToUniqueTree(testedBinder)) + case SubstOnlyTreeMaker(_, _) => TrueCond + case GuardTreeMaker(guard) => + guard.tpe match { + case ConstantType(Constant(true)) => TrueCond + case ConstantType(Constant(false)) => FalseCond + case _ => handleUnknown(tm) + } + case ExtractorTreeMaker(_, _, _) | + ProductExtractorTreeMaker(_, _) | + BodyTreeMaker(_, _) => handleUnknown(tm) + } } } - val constFalse = (_: TreeMaker) => FalseCond - val constTrue = (_: TreeMaker) => TrueCond - final def approximateMatch(cases: List[List[TreeMaker]], handleUnknown: TreeMaker => Cond = constFalse, rewriteNil: Boolean = false): List[List[Test]] = - cases.map { _ map (tm => Test(treeMakerToCond(tm, handleUnknown, updateSubst = true, rewriteNil), tm)) } + private val irrefutableExtractor: PartialFunction[TreeMaker, Cond] = { + // the extra condition is None, the extractor's result indicates it always succeeds, + // (the potential type-test for the argument is represented by a separate TypeTestTreeMaker) + case IrrefutableExtractorTreeMaker(_, _) => TrueCond + } - final def approximateMatchAgain(cases: List[List[TreeMaker]], handleUnknown: TreeMaker => Cond = constFalse, rewriteNil: Boolean = false): List[List[Test]] = - cases.map { _ map (tm => Test(treeMakerToCond(tm, handleUnknown, updateSubst = false, rewriteNil), tm)) } - } + // special-case: interpret pattern `List()` as `Nil` + // TODO: make it more general List(1, 2) => 1 :: 2 :: Nil -- not sure this is a good idea... + private val rewriteListPattern: PartialFunction[TreeMaker, Cond] = { + case p @ ExtractorTreeMaker(_, _, testedBinder) + if testedBinder.tpe.typeSymbol == ListClass && p.checkedLength == Some(0) => + EqualityCond(binderToUniqueTree(p.prevBinder), unique(Ident(NilModule) setType NilModule.tpe)) + } + val fullRewrite = (irrefutableExtractor orElse rewriteListPattern) + val refutableRewrite = irrefutableExtractor + @inline def onUnknown(handler: TreeMaker => Cond) = new TreeMakerToCond { + def handleUnknown(tm: TreeMaker) = handler(tm) + } - def approximateMatch(root: Symbol, cases: List[List[TreeMaker]]): List[List[Test]] = { - object approximator extends TreeMakersToConds(root) - approximator.approximateMatch(cases) + // used for CSE -- rewrite all unknowns to False (the most conserative option) + object conservative extends TreeMakerToCond { + def handleUnknown(tm: TreeMaker) = FalseCond + } + + final def approximateMatch(cases: List[List[TreeMaker]], treeMakerToCond: TreeMakerToCond = conservative) ={ + val testss = cases.map { _ map (tm => Test(treeMakerToCond(tm), tm)) } + substitutionComputed = true // a second call to approximateMatch should not re-compute the substitution (would be wrong) + testss + } } + def approximateMatchConservative(root: Symbol, cases: List[List[TreeMaker]]): List[List[Test]] = + (new TreeMakersToConds(root)).approximateMatch(cases) + def showTreeMakers(cases: List[List[TreeMaker]]) = { - // patmatDebug ("treeMakers:") - // patmatDebug (alignAcrossRows(cases, ">>")) + patmatDebug("treeMakers:") + patmatDebug(alignAcrossRows(cases, ">>")) } def showTests(testss: List[List[Test]]) = { - // patmatDebug ("tests: ") - // patmatDebug (alignAcrossRows(testss, "&")) + patmatDebug("tests: ") + patmatDebug(alignAcrossRows(testss, "&")) } } @@ -1788,7 +1809,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL override def hashCode = a.hashCode ^ b.hashCode } - // patmatDebug ("removeVarEq vars: "+ vars) + patmatDebug("removeVarEq vars: "+ vars) vars.foreach { v => val excludedPair = new collection.mutable.HashSet[ExcludedPair] @@ -1807,16 +1828,17 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL } val syms = v.equalitySyms - // patmatDebug ("eqSyms "+(v, syms)) + patmatDebug("eqSyms "+(v, syms)) syms foreach { sym => // if we've already excluded the pair at some point (-A \/ -B), then don't exclude the symmetric one (-B \/ -A) // (nor the positive implications -B \/ A, or -A \/ B, which would entail the equality axioms falsifying the whole formula) val todo = syms filterNot (b => (b.const == sym.const) || excludedPair(ExcludedPair(b.const, sym.const))) val (excluded, notExcluded) = todo partition (b => sym.const.excludes(b.const)) val implied = notExcluded filter (b => sym.const.implies(b.const)) - // patmatDebug ("eq axioms for: "+ sym.const) - // patmatDebug ("excluded: "+ excluded) - // patmatDebug ("implied: "+ implied) + + patmatDebug("eq axioms for: "+ sym.const) + patmatDebug("excluded: "+ excluded) + patmatDebug("implied: "+ implied) // when this symbol is true, what must hold... implied foreach (impliedSym => addAxiom(Or(Not(sym), impliedSym))) @@ -1829,8 +1851,8 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL } } - // patmatDebug ("eqAxioms:\n"+ cnfString(eqFreePropToSolvable(eqAxioms))) - // patmatDebug ("pure:"+ pure.map(p => cnfString(eqFreePropToSolvable(p))).mkString("\n")) + patmatDebug("eqAxioms:\n"+ cnfString(eqFreePropToSolvable(eqAxioms))) + patmatDebug("pure:"+ pure.map(p => cnfString(eqFreePropToSolvable(p))).mkString("\n")) Statistics.stopTimer(patmatAnaVarEq, start) @@ -1972,12 +1994,12 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL def findAllModels(f: Formula, models: List[Model], recursionDepthAllowed: Int = 10): List[Model]= if (recursionDepthAllowed == 0) models else { - // patmatDebug ("find all models for\n"+ cnfString(f)) + patmatDebug("find all models for\n"+ cnfString(f)) val model = findModelFor(f) // if we found a solution, conjunct the formula with the model's negation and recurse if (model ne NoModel) { val unassigned = (vars -- model.keySet).toList - // patmatDebug ("unassigned "+ unassigned +" in "+ model) + patmatDebug("unassigned "+ unassigned +" in "+ model) def force(lit: Lit) = { val model = withLit(findModelFor(dropUnit(f, lit)), lit) if (model ne NoModel) List(model) @@ -1986,7 +2008,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL val forced = unassigned flatMap { s => force(Lit(s, true)) ++ force(Lit(s, false)) } - // patmatDebug ("forced "+ forced) + patmatDebug("forced "+ forced) val negated = negateModel(model) findAllModels(f :+ negated, model :: (forced ++ models), recursionDepthAllowed - 1) } @@ -2009,7 +2031,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL def findModelFor(f: Formula): Model = { @inline def orElse(a: Model, b: => Model) = if (a ne NoModel) a else b - // patmatDebug ("DPLL\n"+ cnfString(f)) + patmatDebug("DPLL\n"+ cnfString(f)) val start = Statistics.startTimer(patmatAnaDPLL) @@ -2153,11 +2175,11 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL uniques.get(tp).getOrElse( uniques.find {case (oldTp, oldC) => oldTp =:= tp} match { case Some((_, c)) => - // patmatDebug ("unique const: "+ (tp, c)) + patmatDebug("unique const: "+ (tp, c)) c case _ => val fresh = mkFresh - // patmatDebug ("uniqued const: "+ (tp, fresh)) + patmatDebug("uniqued const: "+ (tp, fresh)) uniques(tp) = fresh fresh }) @@ -2173,12 +2195,12 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL if (!t.symbol.isStable) t.tpe.narrow else trees find (a => a.correspondsStructure(t)(sameValue)) match { case Some(orig) => - // patmatDebug ("unique tp for tree: "+ (orig, orig.tpe)) + patmatDebug("unique tp for tree: "+ (orig, orig.tpe)) orig.tpe case _ => // duplicate, don't mutate old tree (TODO: use a map tree -> type instead?) val treeWithNarrowedType = t.duplicate setType t.tpe.narrow - // patmatDebug ("uniqued: "+ (t, t.tpe, treeWithNarrowedType.tpe)) + patmatDebug("uniqued: "+ (t, t.tpe, treeWithNarrowedType.tpe)) trees += treeWithNarrowedType treeWithNarrowedType.tpe } @@ -2349,11 +2371,15 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL // use the same approximator so we share variables, // but need different conditions depending on whether we're conservatively looking for failure or success - val reachabilityApproximation = new TreeMakersToConds(prevBinder) - val testCasesOk = reachabilityApproximation.approximateMatch(cases, reachabilityApproximation.constTrue) - val testCasesFail = reachabilityApproximation.approximateMatchAgain(cases, reachabilityApproximation.constFalse) + // don't rewrite List-like patterns, as List() and Nil need to distinguished for unreachability + val approx = new TreeMakersToConds(prevBinder) + def approximate(default: Cond) = approx.approximateMatch(cases, approx.onUnknown { tm => + approx.refutableRewrite.applyOrElse(tm, (_: TreeMaker) => default ) + }) + + val testCasesOk = approximate(TrueCond) + val testCasesFail = approximate(FalseCond) - reachabilityApproximation.discard() prepareNewAnalysis() val propsCasesOk = testCasesOk map (t => symbolicCase(t, modelNull = true)) @@ -2373,8 +2399,8 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL var reachable = true var caseIndex = 0 - // patmatDebug ("reachability, vars:\n"+ ((propsCasesFail flatMap gatherVariables) map (_.describe) mkString ("\n"))) - // patmatDebug ("equality axioms:\n"+ cnfString(eqAxiomsCNF)) + patmatDebug("reachability, vars:\n"+ ((propsCasesFail flatMap gatherVariables) map (_.describe) mkString ("\n"))) + patmatDebug("equality axioms:\n"+ cnfString(eqAxiomsCNF)) // invariant (prefixRest.length == current.length) && (prefix.reverse ++ prefixRest == symbolicCasesFail) // termination: prefixRest.length decreases by 1 @@ -2421,7 +2447,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL Some(List(tp)) // make sure it's not a primitive, else (5: Byte) match { case 5 => ... } sees no Byte case sym if !sym.isSealed || isPrimitiveValueClass(sym) => - // patmatDebug ("enum unsealed "+ (tp, sym, sym.isSealed, isPrimitiveValueClass(sym))) + patmatDebug("enum unsealed "+ (tp, sym, sym.isSealed, isPrimitiveValueClass(sym))) None case sym => val subclasses = ( @@ -2429,7 +2455,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL // symbols which are both sealed and abstract need not be covered themselves, because // all of their children must be and they cannot otherwise be created. filterNot (x => x.isSealed && x.isAbstractClass && !isPrimitiveValueClass(x))) - // patmatDebug ("enum sealed -- subclasses: "+ (sym, subclasses)) + patmatDebug("enum sealed -- subclasses: "+ (sym, subclasses)) val tpApprox = typer.infer.approximateAbstracts(tp) val pre = tpApprox.prefix @@ -2445,7 +2471,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL if (subTpApprox <:< tpApprox) Some(checkableType(subTp)) else None }) - // patmatDebug ("enum sealed "+ (tp, tpApprox) + " as "+ validSubTypes) + patmatDebug("enum sealed "+ (tp, tpApprox) + " as "+ validSubTypes) Some(validSubTypes) } @@ -2465,7 +2491,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL } } val res = toCheckable(tp) - // patmatDebug ("checkable "+(tp, res)) + patmatDebug("checkable "+(tp, res)) res } @@ -2490,19 +2516,19 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL val start = Statistics.startTimer(patmatAnaExhaust) var backoff = false - val exhaustivityApproximation = new TreeMakersToConds(prevBinder) - val tests = exhaustivityApproximation.approximateMatch(cases, { - case BodyTreeMaker(_, _) => TrueCond // will be discarded by symbolCase later - case tm => - // patmatDebug("backing off due to "+ tm) + val approx = new TreeMakersToConds(prevBinder) + val tests = approx.approximateMatch(cases, approx.onUnknown { tm => + approx.fullRewrite.applyOrElse[TreeMaker, Cond](tm, { + case BodyTreeMaker(_, _) => TrueCond // irrelevant -- will be discarded by symbolCase later + case _ => // patmatDebug("backing off due to "+ tm) backoff = true FalseCond - }, rewriteNil = true) + }) + }) if (backoff) Nil else { - val prevBinderTree = exhaustivityApproximation.binderToUniqueTree(prevBinder) + val prevBinderTree = approx.binderToUniqueTree(prevBinder) - exhaustivityApproximation.discard() prepareNewAnalysis() val symbolicCases = tests map (symbolicCase(_, modelNull = false)) @@ -2523,7 +2549,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL val vars = gatherVariables(matchFails) // debug output: - // patmatDebug ("analysing:") + patmatDebug("analysing:") showTreeMakers(cases) showTests(tests) @@ -2543,7 +2569,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL pruned } catch { case e : CNFBudgetExceeded => - // patmatDebug (util.Position.formatMessage(prevBinder.pos, "Cannot check match for exhaustivity", false)) + patmatDebug(util.Position.formatMessage(prevBinder.pos, "Cannot check match for exhaustivity", false)) // e.printStackTrace() Nil // CNF budget exceeded } @@ -2633,7 +2659,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL // ... val varAssignment = modelToVarAssignment(model) - // patmatDebug ("var assignment for model "+ model +":\n"+ varAssignmentString(varAssignment)) + patmatDebug("var assignment for model "+ model +":\n"+ varAssignmentString(varAssignment)) // chop a path into a list of symbols def chop(path: Tree): List[Symbol] = path match { @@ -2700,7 +2726,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL def toCounterExample(beBrief: Boolean = false): CounterExample = if (!allFieldAssignmentsLegal) NoExample else { - // patmatDebug ("describing "+ (variable, equalTo, notEqualTo, fields, cls, allFieldAssignmentsLegal)) + patmatDebug("describing "+ (variable, equalTo, notEqualTo, fields, cls, allFieldAssignmentsLegal)) val res = prunedEqualTo match { // a definite assignment to a value case List(eq: ValueConst) if fields.isEmpty => ValueExample(eq) @@ -2741,7 +2767,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL // TODO: improve reasoning -- in the mean time, a false negative is better than an annoying false positive case _ => NoExample } - // patmatDebug ("described as: "+ res) + patmatDebug("described as: "+ res) res } @@ -2766,7 +2792,10 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL * we generalize sharing to implication, where b reuses a if a => b and priors(a) => priors(b) (the priors of a sub expression form the path through the decision tree) */ def doCSE(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type): List[List[TreeMaker]] = { - val testss = approximateMatch(prevBinder, cases) + patmatDebug("before CSE:") + showTreeMakers(cases) + + val testss = approximateMatchConservative(prevBinder, cases) // interpret: val dependencies = new collection.mutable.LinkedHashMap[Test, Set[Cond]] @@ -2776,10 +2805,10 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL val cond = test.cond def simplify(c: Cond): Set[Cond] = c match { - case AndCond(a, b) => simplify(a) ++ simplify(b) + case AndCond(a, b) => simplify(a) ++ simplify(b) case OrCond(_, _) => Set(FalseCond) // TODO: make more precise case NonNullCond(_) => Set(TrueCond) // not worth remembering - case _ => Set(c) + case _ => Set(c) } val conds = simplify(cond) @@ -2794,7 +2823,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL case (priorTest, deps) => ((simplify(priorTest.cond) == nonTrivial) || // our conditions are implied by priorTest if it checks the same thing directly (nonTrivial subsetOf deps) // or if it depends on a superset of our conditions - ) && (deps subsetOf tested) // the conditions we've tested when we are here in the match satisfy the prior test, and hence what it tested + ) && (deps subsetOf tested) // the conditions we've tested when we are here in the match satisfy the prior test, and hence what it tested } foreach { case (priorTest, _) => // if so, note the dependency in both tests @@ -2812,7 +2841,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL tested.clear() tests dropWhile storeDependencies } - // patmatDebug ("dependencies: "+ dependencies) + patmatDebug("dependencies: "+ dependencies) // find longest prefix of tests that reuse a prior test, and whose dependent conditions monotonically increase // then, collapse these contiguous sequences of reusing tests @@ -2846,7 +2875,8 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL case _ => } - // patmatDebug("sharedPrefix: "+ sharedPrefix) + patmatDebug("sharedPrefix: "+ sharedPrefix) + patmatDebug("suffix: "+ sharedPrefix) // if the shared prefix contains interesting conditions (!= TrueCond) // and the last of such interesting shared conditions reuses another treemaker's test // replace the whole sharedPrefix by a ReusingCondTreeMaker @@ -2862,7 +2892,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL // replace original treemakers that are reused (as determined when computing collapsed), // by ReusedCondTreeMakers val reusedMakers = collapsed mapConserve (_ mapConserve reusedOrOrig) - // patmatDebug ("after CSE:") + patmatDebug("after CSE:") showTreeMakers(reusedMakers) reusedMakers } diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 7318538de7..3518316fbb 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -119,7 +119,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R // those with the DEFAULTPARAM flag, and infer the methods. Looking for the methods // directly requires inspecting the parameter list of every one. That modification // shaved 95% off the time spent in this method. - val defaultGetters = clazz.info.findMember(nme.ANYNAME, 0L, DEFAULTPARAM, false).alternatives + val defaultGetters = clazz.info.findMembers(0L, DEFAULTPARAM) val defaultMethodNames = defaultGetters map (sym => nme.defaultGetterToMethod(sym.name)) defaultMethodNames.distinct foreach { name => diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala index f67cec730b..b544407286 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala @@ -19,6 +19,10 @@ import symtab.Flags._ * of class-members which are private up to an enclosing non-package * class, in order to avoid overriding conflicts. * + * This phase also sets SPECIALIZED flag on type parameters with + * `@specialized` annotation. We put this logic here because the + * flag must be set before pickling. + * * @author Martin Odersky * @version 1.0 */ @@ -208,6 +212,15 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT case TypeApply(sel @ Select(This(_), name), args) => mayNeedProtectedAccessor(sel, args, false) + // set a flag for all type parameters with `@specialized` annotation so it can be pickled + case typeDef: TypeDef if typeDef.symbol.deSkolemize.hasAnnotation(definitions.SpecializedClass) => + debuglog("setting SPECIALIZED flag on typeDef.symbol.deSkolemize where typeDef = " + typeDef) + // we need to deSkolemize symbol so we get the same symbol as others would get when + // inspecting type parameter from "outside"; see the discussion of skolems here: + // https://groups.google.com/d/topic/scala-internals/0j8laVNTQsI/discussion + typeDef.symbol.deSkolemize.setFlag(SPECIALIZED) + typeDef + case sel @ Select(qual @ This(_), name) => // warn if they are selecting a private[this] member which // also exists in a superclass, because they may be surprised diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index a570cd74d6..9371af4848 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -4509,6 +4509,8 @@ trait Typers extends Modes with Adaptations with Tags { assert(errorContainer == null, "Cannot set ambiguous error twice for identifier") errorContainer = tree } + + val fingerPrint: Long = name.fingerPrint var defSym: Symbol = tree.symbol // the directly found symbol var pre: Type = NoPrefix // the prefix type of defSym, if a class member @@ -4547,7 +4549,10 @@ trait Typers extends Modes with Adaptations with Tags { var cx = startingIdentContext while (defSym == NoSymbol && cx != NoContext && (cx.scope ne null)) { // cx.scope eq null arises during FixInvalidSyms in Duplicators pre = cx.enclClass.prefix - defEntry = cx.scope.lookupEntry(name) + defEntry = { + val scope = cx.scope + if ((fingerPrint & scope.fingerPrints) != 0) scope.lookupEntry(name) else null + } if ((defEntry ne null) && qualifies(defEntry.sym)) { // Right here is where SI-1987, overloading in package objects, can be // seen to go wrong. There is an overloaded symbol, but when referring diff --git a/src/compiler/scala/tools/reflect/FastTrack.scala b/src/compiler/scala/tools/reflect/FastTrack.scala index 8ea66979bc..63ecfa32b2 100644 --- a/src/compiler/scala/tools/reflect/FastTrack.scala +++ b/src/compiler/scala/tools/reflect/FastTrack.scala @@ -43,7 +43,7 @@ trait FastTrack { ApiUniverseReify bindTo { case (c, Apply(TypeApply(_, List(tt)), List(expr))) => c.materializeExpr(c.prefix.tree, EmptyTree, expr) } MacroContextReify bindTo { case (c, Apply(TypeApply(_, List(tt)), List(expr))) => c.materializeExprForMacroContext(c.prefix.tree, expr) } ReflectRuntimeCurrentMirror bindTo { case (c, _) => scala.reflect.runtime.Macros.currentMirror(c).tree } - StringContext_f bindTo { case (c, Apply(Select(Apply(_, parts), _), args)) => c.macro_StringInterpolation_f(parts, args) } + StringContext_f bindTo { case (c, app@Apply(Select(Apply(_, parts), _), args)) => c.macro_StringInterpolation_f(parts, args, app.pos) } registry } }
\ No newline at end of file diff --git a/src/compiler/scala/tools/reflect/MacroImplementations.scala b/src/compiler/scala/tools/reflect/MacroImplementations.scala index a5f7928f55..604bd7cd1a 100644 --- a/src/compiler/scala/tools/reflect/MacroImplementations.scala +++ b/src/compiler/scala/tools/reflect/MacroImplementations.scala @@ -8,9 +8,9 @@ import scala.collection.mutable.Stack abstract class MacroImplementations { val c: Context - import c.universe._ + import c.universe.{Position => SPosition, _} - def macro_StringInterpolation_f(parts: List[Tree], args: List[Tree]): Tree = { + def macro_StringInterpolation_f(parts: List[Tree], args: List[Tree], origApplyPos: SPosition): Tree = { // the parts all have the same position information (as the expression is generated by the compiler) // the args have correct position information @@ -25,7 +25,6 @@ abstract class MacroImplementations { c.abort(args(parts.length-1).pos, "too many arguments for interpolated string") } - val stringParts = parts map { case Literal(Constant(s: String)) => s; case _ => throw new IllegalArgumentException("argument parts must be a list of string literals") @@ -39,7 +38,7 @@ abstract class MacroImplementations { def defval(value: Tree, tpe: Type): Unit = { val freshName = newTermName(c.fresh("arg$")) - evals += ValDef(Modifiers(), freshName, TypeTree(tpe), value) + evals += ValDef(Modifiers(), freshName, TypeTree(tpe) setPos value.pos.focus, value) setPos value.pos ids += Ident(freshName) } @@ -141,7 +140,7 @@ abstract class MacroImplementations { List(ids: _* ) ); - Block(evals.toList, expr) + Block(evals.toList, atPos(origApplyPos.focus)(expr)) setPos origApplyPos.makeTransparent } }
\ No newline at end of file diff --git a/src/eclipse/partest/.classpath b/src/eclipse/partest/.classpath new file mode 100644 index 0000000000..b14e465aa6 --- /dev/null +++ b/src/eclipse/partest/.classpath @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="partest"/> + <classpathentry combineaccessrules="false" kind="src" path="/reflect"/> + <classpathentry combineaccessrules="false" kind="src" path="/scala-library"/> + <classpathentry combineaccessrules="false" kind="src" path="/scala-compiler"/> + <classpathentry combineaccessrules="false" kind="src" path="/scalap"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="lib" path="lib/ant/ant.jar"/> + <classpathentry kind="lib" path="lib/jline.jar"/> + <classpathentry kind="lib" path="lib/msil.jar"/> + <classpathentry combineaccessrules="false" kind="src" path="/asm"/> + <classpathentry kind="output" path="build-quick-partest"/> +</classpath> diff --git a/src/eclipse/partest/.project b/src/eclipse/partest/.project new file mode 100644 index 0000000000..45c24332ba --- /dev/null +++ b/src/eclipse/partest/.project @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>partest</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.scala-ide.sdt.core.scalabuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.scala-ide.sdt.core.scalanature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> + <linkedResources> + <link> + <name>build-quick-partest</name> + <type>2</type> + <locationURI>SCALA_BASEDIR/build/quick/classes/partest</locationURI> + </link> + <link> + <name>lib</name> + <type>2</type> + <locationURI>SCALA_BASEDIR/lib</locationURI> + </link> + <link> + <name>partest</name> + <type>2</type> + <locationURI>SCALA_BASEDIR/src/partest</locationURI> + </link> + </linkedResources> +</projectDescription> diff --git a/src/eclipse/reflect/.classpath b/src/eclipse/reflect/.classpath index 3fb1d08d4d..57a3928dc3 100644 --- a/src/eclipse/reflect/.classpath +++ b/src/eclipse/reflect/.classpath @@ -2,7 +2,6 @@ <classpath> <classpathentry kind="src" path="reflect"/> <classpathentry combineaccessrules="false" kind="src" path="/scala-library"/> - <classpathentry kind="con" path="org.scala-ide.sdt.launching.SCALA_CONTAINER"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/> <classpathentry kind="output" path="build-quick-reflect"/> </classpath> diff --git a/src/eclipse/scala-compiler/.classpath b/src/eclipse/scala-compiler/.classpath index e0264b9856..40a4ed9996 100644 --- a/src/eclipse/scala-compiler/.classpath +++ b/src/eclipse/scala-compiler/.classpath @@ -5,7 +5,6 @@ <classpathentry combineaccessrules="false" kind="src" path="/scala-library"/> <classpathentry combineaccessrules="false" kind="src" path="/fjbg"/> <classpathentry combineaccessrules="false" kind="src" path="/asm"/> - <classpathentry kind="con" path="org.scala-ide.sdt.launching.SCALA_CONTAINER"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> <classpathentry kind="lib" path="lib/ant/ant.jar"/> <classpathentry kind="lib" path="lib/jline.jar"/> diff --git a/src/eclipse/scalap/.classpath b/src/eclipse/scalap/.classpath new file mode 100644 index 0000000000..2b44ad19b2 --- /dev/null +++ b/src/eclipse/scalap/.classpath @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="scalap"/> + <classpathentry combineaccessrules="false" kind="src" path="/reflect"/> + <classpathentry combineaccessrules="false" kind="src" path="/scala-library"/> + <classpathentry combineaccessrules="false" kind="src" path="/scala-compiler"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="lib" path="lib/ant/ant.jar"/> + <classpathentry kind="lib" path="lib/jline.jar"/> + <classpathentry kind="lib" path="lib/msil.jar"/> + <classpathentry kind="output" path="build-quick-scalap"/> +</classpath> diff --git a/src/eclipse/scalap/.project b/src/eclipse/scalap/.project new file mode 100644 index 0000000000..3599168e32 --- /dev/null +++ b/src/eclipse/scalap/.project @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>scalap</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.scala-ide.sdt.core.scalabuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.scala-ide.sdt.core.scalanature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> + <linkedResources> + <link> + <name>build-quick-scalap</name> + <type>2</type> + <locationURI>SCALA_BASEDIR/build/quick/classes/scalap</locationURI> + </link> + <link> + <name>lib</name> + <type>2</type> + <locationURI>SCALA_BASEDIR/lib</locationURI> + </link> + <link> + <name>scalap</name> + <type>2</type> + <locationURI>SCALA_BASEDIR/src/scalap</locationURI> + </link> + </linkedResources> +</projectDescription> diff --git a/src/library/scala/Double.scala b/src/library/scala/Double.scala index 2ff46c433d..510de92a2a 100644 --- a/src/library/scala/Double.scala +++ b/src/library/scala/Double.scala @@ -370,9 +370,6 @@ object Double extends AnyValCompanion { final val PositiveInfinity = java.lang.Double.POSITIVE_INFINITY final val NegativeInfinity = java.lang.Double.NEGATIVE_INFINITY - @deprecated("use Double.MinPositiveValue instead", "2.9.0") - final val Epsilon = MinPositiveValue - /** The negative number with the greatest (finite) absolute value which is representable * by a Double. Note that it differs from [[java.lang.Double.MIN_VALUE]], which * is the smallest positive value representable by a Double. In Scala that number diff --git a/src/library/scala/Enumeration.scala b/src/library/scala/Enumeration.scala index 2b658ee4f7..1151b04ca0 100644 --- a/src/library/scala/Enumeration.scala +++ b/src/library/scala/Enumeration.scala @@ -194,7 +194,10 @@ abstract class Enumeration (initial: Int) extends Serializable { /** a marker so we can tell whose values belong to whom come reflective-naming time */ private[Enumeration] val outerEnum = thisenum - override def compare(that: Value): Int = this.id - that.id + override def compare(that: Value): Int = + if (this.id < that.id) -1 + else if (this.id == that.id) 0 + else 1 override def equals(other: Any) = other match { case that: Enumeration#Value => (outerEnum eq that.outerEnum) && (id == that.id) case _ => false @@ -236,7 +239,7 @@ abstract class Enumeration (initial: Int) extends Serializable { /** An ordering by id for values of this set */ object ValueOrdering extends Ordering[Value] { - def compare(x: Value, y: Value): Int = x.id - y.id + def compare(x: Value, y: Value): Int = x compare y } /** A class for sets of values. diff --git a/src/library/scala/Float.scala b/src/library/scala/Float.scala index bd7a07fece..b9c116da0b 100644 --- a/src/library/scala/Float.scala +++ b/src/library/scala/Float.scala @@ -370,9 +370,6 @@ object Float extends AnyValCompanion { final val PositiveInfinity = java.lang.Float.POSITIVE_INFINITY final val NegativeInfinity = java.lang.Float.NEGATIVE_INFINITY - @deprecated("use Float.MinPositiveValue instead", "2.9.0") - final val Epsilon = MinPositiveValue - /** The negative number with the greatest (finite) absolute value which is representable * by a Float. Note that it differs from [[java.lang.Float.MIN_VALUE]], which * is the smallest positive value representable by a Float. In Scala that number diff --git a/src/library/scala/collection/immutable/Vector.scala b/src/library/scala/collection/immutable/Vector.scala index d100bf93df..4dfe147a65 100644 --- a/src/library/scala/collection/immutable/Vector.scala +++ b/src/library/scala/collection/immutable/Vector.scala @@ -18,8 +18,14 @@ import scala.collection.parallel.immutable.ParVector /** Companion object to the Vector class */ object Vector extends SeqFactory[Vector] { + private[collection] class VectorReusableCBF extends GenericCanBuildFrom[Nothing] { + override def apply() = newBuilder[Nothing] + } + + private val VectorReusableCBF: GenericCanBuildFrom[Nothing] = new VectorReusableCBF + @inline implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, Vector[A]] = - ReusableCBF.asInstanceOf[CanBuildFrom[Coll, A, Vector[A]]] + VectorReusableCBF.asInstanceOf[CanBuildFrom[Coll, A, Vector[A]]] def newBuilder[A]: Builder[A, Vector[A]] = new VectorBuilder[A] private[immutable] val NIL = new Vector[Nothing](0, 0, 0) @inline override def empty[A]: Vector[A] = NIL @@ -140,19 +146,19 @@ override def companion: GenericCompanion[Vector] = Vector // SeqLike api - @inline override def updated[B >: A, That](index: Int, elem: B)(implicit bf: CanBuildFrom[Vector[A], B, That]): That = { - // just ignore bf - updateAt(index, elem).asInstanceOf[That] + @inline override def updated[B >: A, That](index: Int, elem: B)(implicit bf: CanBuildFrom[Vector[A], B, That]): That = bf match { + case _: Vector.VectorReusableCBF => updateAt(index, elem).asInstanceOf[That] // just ignore bf + case _ => super.updated(index, elem)(bf) } - @inline override def +:[B >: A, That](elem: B)(implicit bf: CanBuildFrom[Vector[A], B, That]): That = { - // just ignore bf - appendFront(elem).asInstanceOf[That] + @inline override def +:[B >: A, That](elem: B)(implicit bf: CanBuildFrom[Vector[A], B, That]): That = bf match { + case _: Vector.VectorReusableCBF => appendFront(elem).asInstanceOf[That] // just ignore bf + case _ => super.+:(elem)(bf) } - @inline override def :+[B >: A, That](elem: B)(implicit bf: CanBuildFrom[Vector[A], B, That]): That = { - // just ignore bf - appendBack(elem).asInstanceOf[That] + @inline override def :+[B >: A, That](elem: B)(implicit bf: CanBuildFrom[Vector[A], B, That]): That = bf match { + case _: Vector.VectorReusableCBF => appendBack(elem).asInstanceOf[That] // just ignore bf + case _ => super.:+(elem)(bf) } override def take(n: Int): Vector[A] = { diff --git a/src/library/scala/concurrent/ExecutionContext.scala b/src/library/scala/concurrent/ExecutionContext.scala index debfc226db..8081bb32da 100644 --- a/src/library/scala/concurrent/ExecutionContext.scala +++ b/src/library/scala/concurrent/ExecutionContext.scala @@ -77,7 +77,7 @@ object ExecutionContext { /** The default reporter simply prints the stack trace of the `Throwable` to System.err. */ - def defaultReporter: Throwable => Unit = { case t => t.printStackTrace() } + def defaultReporter: Throwable => Unit = (t: Throwable) => t.printStackTrace() } diff --git a/src/library/scala/concurrent/Future.scala b/src/library/scala/concurrent/Future.scala index e556be4fe3..f82b79cb18 100644 --- a/src/library/scala/concurrent/Future.scala +++ b/src/library/scala/concurrent/Future.scala @@ -14,7 +14,6 @@ import java.util.concurrent.{ ConcurrentLinkedQueue, TimeUnit, Callable } import java.util.concurrent.TimeUnit.{ NANOSECONDS => NANOS, MILLISECONDS ⇒ MILLIS } import java.lang.{ Iterable => JIterable } import java.util.{ LinkedList => JLinkedList } -import java.{ lang => jl } import java.util.concurrent.atomic.{ AtomicReferenceFieldUpdater, AtomicInteger, AtomicBoolean } import scala.concurrent.util.Duration @@ -565,17 +564,15 @@ trait Future[+T] extends Awaitable[T] { */ object Future { - import java.{ lang => jl } - private[concurrent] val toBoxed = Map[Class[_], Class[_]]( - classOf[Boolean] -> classOf[jl.Boolean], - classOf[Byte] -> classOf[jl.Byte], - classOf[Char] -> classOf[jl.Character], - classOf[Short] -> classOf[jl.Short], - classOf[Int] -> classOf[jl.Integer], - classOf[Long] -> classOf[jl.Long], - classOf[Float] -> classOf[jl.Float], - classOf[Double] -> classOf[jl.Double], + classOf[Boolean] -> classOf[java.lang.Boolean], + classOf[Byte] -> classOf[java.lang.Byte], + classOf[Char] -> classOf[java.lang.Character], + classOf[Short] -> classOf[java.lang.Short], + classOf[Int] -> classOf[java.lang.Integer], + classOf[Long] -> classOf[java.lang.Long], + classOf[Float] -> classOf[java.lang.Float], + classOf[Double] -> classOf[java.lang.Double], classOf[Unit] -> classOf[scala.runtime.BoxedUnit] ) @@ -604,9 +601,6 @@ object Future { */ def apply[T](body: =>T)(implicit execctx: ExecutionContext): Future[T] = impl.Future(body) - import scala.collection.mutable.Builder - import scala.collection.generic.CanBuildFrom - /** Simple version of `Futures.traverse`. Transforms a `TraversableOnce[Future[A]]` into a `Future[TraversableOnce[A]]`. * Useful for reducing many `Future`s into a single `Future`. */ diff --git a/src/library/scala/concurrent/FutureTaskRunner.scala b/src/library/scala/concurrent/FutureTaskRunner.scala index 9d6f8a7a88..d7f1e1c2f9 100644 --- a/src/library/scala/concurrent/FutureTaskRunner.scala +++ b/src/library/scala/concurrent/FutureTaskRunner.scala @@ -15,7 +15,7 @@ import language.{implicitConversions, higherKinds} * * @author Philipp Haller */ -@deprecated("Use `ExecutionContext`s instead.", "2.10.0") +@deprecated("Use `ExecutionContext` instead.", "2.10.0") trait FutureTaskRunner extends TaskRunner { /** The type of the futures that the underlying task runner supports. @@ -33,6 +33,7 @@ trait FutureTaskRunner extends TaskRunner { /* Possibly blocks the current thread, for example, waiting for * a lock or condition. */ + @deprecated("Use `blocking` instead.", "2.10.0") def managedBlock(blocker: ManagedBlocker): Unit } diff --git a/src/library/scala/concurrent/ManagedBlocker.scala b/src/library/scala/concurrent/ManagedBlocker.scala index 9c6f4d51d6..47bbb91f6f 100644 --- a/src/library/scala/concurrent/ManagedBlocker.scala +++ b/src/library/scala/concurrent/ManagedBlocker.scala @@ -12,6 +12,7 @@ package scala.concurrent * * @author Philipp Haller */ +@deprecated("Use `blocking` instead.", "2.10.0") trait ManagedBlocker { /** diff --git a/src/library/scala/concurrent/Scheduler.scala b/src/library/scala/concurrent/Scheduler.scala deleted file mode 100644 index 6645abcc4e..0000000000 --- a/src/library/scala/concurrent/Scheduler.scala +++ /dev/null @@ -1,54 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.concurrent - -import scala.concurrent.util.Duration - -/** A service for scheduling tasks and thunks for one-time, or periodic execution. - */ -trait Scheduler { - - /** Schedules a thunk for repeated execution with an initial delay and a frequency. - * - * @param delay the initial delay after which the thunk should be executed - * the first time - * @param frequency the frequency with which the thunk should be executed, - * as a time period between subsequent executions - */ - def schedule(delay: Duration, frequency: Duration)(thunk: => Unit): Cancellable - - /** Schedules a task for execution after a given delay. - * - * @param delay the duration after which the task should be executed - * @param task the task that is scheduled for execution - * @return a `Cancellable` that may be used to cancel the execution - * of the task - */ - def scheduleOnce(delay: Duration, task: Runnable): Cancellable - - /** Schedules a thunk for execution after a given delay. - * - * @param delay the duration after which the thunk should be executed - * @param task the thunk that is scheduled for execution - * @return a `Cancellable` that may be used to cancel the execution - * of the thunk - */ - def scheduleOnce(delay: Duration)(task: => Unit): Cancellable - -} - - - -trait Cancellable { - - /** Cancels the underlying task. - */ - def cancel(): Unit - -} diff --git a/src/library/scala/concurrent/Task.scala b/src/library/scala/concurrent/Task.scala deleted file mode 100644 index eb3efbb422..0000000000 --- a/src/library/scala/concurrent/Task.scala +++ /dev/null @@ -1,13 +0,0 @@ -package scala.concurrent - - - -trait Task[+T] { - - def start(): Unit - - def future: Future[T] - -} - - diff --git a/src/library/scala/concurrent/TaskRunner.scala b/src/library/scala/concurrent/TaskRunner.scala index 3180e9ce8a..2e11ac42b0 100644 --- a/src/library/scala/concurrent/TaskRunner.scala +++ b/src/library/scala/concurrent/TaskRunner.scala @@ -14,7 +14,7 @@ import language.{higherKinds, implicitConversions} * * @author Philipp Haller */ -@deprecated("Use `ExecutionContext`s instead.", "2.10.0") +@deprecated("Use `ExecutionContext` instead.", "2.10.0") trait TaskRunner { type Task[T] diff --git a/src/library/scala/concurrent/TaskRunners.scala b/src/library/scala/concurrent/TaskRunners.scala index 7994255b25..8f7d952ed8 100644 --- a/src/library/scala/concurrent/TaskRunners.scala +++ b/src/library/scala/concurrent/TaskRunners.scala @@ -14,7 +14,7 @@ import java.util.concurrent.{ThreadPoolExecutor, LinkedBlockingQueue, TimeUnit} * * @author Philipp Haller */ -@deprecated("Use `ExecutionContext`s instead.", "2.10.0") +@deprecated("Use `ExecutionContext` instead.", "2.10.0") object TaskRunners { implicit val threadRunner: FutureTaskRunner = diff --git a/src/library/scala/concurrent/ThreadPoolRunner.scala b/src/library/scala/concurrent/ThreadPoolRunner.scala index fd6882348a..594555d49b 100644 --- a/src/library/scala/concurrent/ThreadPoolRunner.scala +++ b/src/library/scala/concurrent/ThreadPoolRunner.scala @@ -16,7 +16,7 @@ import language.implicitConversions * * @author Philipp Haller */ -@deprecated("Use `ExecutionContext`s instead.", "2.10.0") +@deprecated("Use `ExecutionContext` instead.", "2.10.0") trait ThreadPoolRunner extends FutureTaskRunner { type Task[T] = Callable[T] with Runnable @@ -43,6 +43,7 @@ trait ThreadPoolRunner extends FutureTaskRunner { executor execute task } + @deprecated("Use `blocking` instead.", "2.10.0") def managedBlock(blocker: ManagedBlocker) { blocker.block() } diff --git a/src/library/scala/concurrent/ThreadRunner.scala b/src/library/scala/concurrent/ThreadRunner.scala index 76be94aa6b..ab709e0210 100644 --- a/src/library/scala/concurrent/ThreadRunner.scala +++ b/src/library/scala/concurrent/ThreadRunner.scala @@ -15,6 +15,7 @@ import language.implicitConversions * * @author Philipp Haller */ +@deprecated("Use `ExecutionContext` instead.", "2.10.0") class ThreadRunner extends FutureTaskRunner { type Task[T] = () => T @@ -47,6 +48,7 @@ class ThreadRunner extends FutureTaskRunner { () => result.get.fold[S](throw _, identity _) } + @deprecated("Use `blocking` instead.", "2.10.0") def managedBlock(blocker: ManagedBlocker) { blocker.block() } diff --git a/src/library/scala/concurrent/impl/Future.scala b/src/library/scala/concurrent/impl/Future.scala index 0c031743db..132e1d79e7 100644 --- a/src/library/scala/concurrent/impl/Future.scala +++ b/src/library/scala/concurrent/impl/Future.scala @@ -21,19 +21,6 @@ private[concurrent] trait Future[+T] extends scala.concurrent.Future[T] with Awa } private[concurrent] object Future { - import java.{ lang => jl } - - private val toBoxed = Map[Class[_], Class[_]]( - classOf[Boolean] -> classOf[jl.Boolean], - classOf[Byte] -> classOf[jl.Byte], - classOf[Char] -> classOf[jl.Character], - classOf[Short] -> classOf[jl.Short], - classOf[Int] -> classOf[jl.Integer], - classOf[Long] -> classOf[jl.Long], - classOf[Float] -> classOf[jl.Float], - classOf[Double] -> classOf[jl.Double], - classOf[Unit] -> classOf[scala.runtime.BoxedUnit] - ) /** Wraps a block of code into an awaitable object. */ private[concurrent] def body2awaitable[T](body: =>T) = new Awaitable[T] { @@ -44,7 +31,7 @@ private[concurrent] object Future { def result(atMost: Duration)(implicit permit: CanAwait) = body } - def boxedType(c: Class[_]): Class[_] = if (c.isPrimitive) toBoxed(c) else c + def boxedType(c: Class[_]): Class[_] = if (c.isPrimitive) scala.concurrent.Future.toBoxed(c) else c private[impl] class PromiseCompletingRunnable[T](body: => T) extends Runnable { diff --git a/src/library/scala/concurrent/impl/Promise.scala b/src/library/scala/concurrent/impl/Promise.scala index ccfcd30c97..84638586cf 100644 --- a/src/library/scala/concurrent/impl/Promise.scala +++ b/src/library/scala/concurrent/impl/Promise.scala @@ -10,14 +10,11 @@ package scala.concurrent.impl -import java.util.concurrent.TimeUnit.{ NANOSECONDS, MILLISECONDS } -import scala.concurrent.{ Awaitable, ExecutionContext, blocking, CanAwait, OnCompleteRunnable, TimeoutException, ExecutionException } -//import scala.util.continuations._ +import java.util.concurrent.TimeUnit.NANOSECONDS +import scala.concurrent.{ ExecutionContext, CanAwait, OnCompleteRunnable, TimeoutException, ExecutionException } import scala.concurrent.util.Duration -import scala.util import scala.annotation.tailrec import scala.util.control.NonFatal -//import scala.concurrent.NonDeterministic @@ -41,7 +38,7 @@ private class CallbackRunnable[T](val executor: ExecutionContext, val onComplete } } -object Promise { +private[concurrent] object Promise { private def resolveEither[T](source: Either[Throwable, T]): Either[Throwable, T] = source match { case Left(t) => resolver(t) diff --git a/src/library/scala/concurrent/ops.scala b/src/library/scala/concurrent/ops.scala index 2cea29aefe..4de8f6cba3 100644 --- a/src/library/scala/concurrent/ops.scala +++ b/src/library/scala/concurrent/ops.scala @@ -15,7 +15,7 @@ import scala.util.control.Exception.allCatch * * @author Martin Odersky, Stepan Koltsov, Philipp Haller */ -@deprecated("Use `future` instead.", "2.10.0") +@deprecated("Use `Future` instead.", "2.10.0") object ops { val defaultRunner: FutureTaskRunner = TaskRunners.threadRunner diff --git a/src/library/scala/reflect/ClassManifest.scala b/src/library/scala/reflect/ClassManifest.scala index f143bf8712..d226e43e77 100644 --- a/src/library/scala/reflect/ClassManifest.scala +++ b/src/library/scala/reflect/ClassManifest.scala @@ -184,18 +184,18 @@ object ClassManifestFactory { * pass varargs as arrays into this, we get an infinitely recursive call * to boxArray. (Besides, having a separate case is more efficient) */ - def classType[T <: AnyRef](clazz: jClass[_]): ClassManifest[T] = + def classType[T](clazz: jClass[_]): ClassManifest[T] = new ClassTypeManifest[T](None, clazz, Nil) /** ClassManifest for the class type `clazz[args]`, where `clazz` is * a top-level or static class and `args` are its type arguments */ - def classType[T <: AnyRef](clazz: jClass[_], arg1: OptManifest[_], args: OptManifest[_]*): ClassManifest[T] = + def classType[T](clazz: jClass[_], arg1: OptManifest[_], args: OptManifest[_]*): ClassManifest[T] = new ClassTypeManifest[T](None, clazz, arg1 :: args.toList) /** ClassManifest for the class type `clazz[args]`, where `clazz` is * a class with non-package prefix type `prefix` and type arguments `args`. */ - def classType[T <: AnyRef](prefix: OptManifest[_], clazz: jClass[_], args: OptManifest[_]*): ClassManifest[T] = + def classType[T](prefix: OptManifest[_], clazz: jClass[_], args: OptManifest[_]*): ClassManifest[T] = new ClassTypeManifest[T](Some(prefix), clazz, args.toList) def arrayType[T](arg: OptManifest[_]): ClassManifest[Array[T]] = arg match { @@ -228,7 +228,7 @@ object ClassManifestFactory { /** Manifest for the class type `clazz[args]`, where `clazz` is * a top-level or static class */ -private class ClassTypeManifest[T <: AnyRef]( +private class ClassTypeManifest[T]( prefix: Option[OptManifest[_]], val runtimeClass: jClass[_], override val typeArguments: List[OptManifest[_]]) extends ClassManifest[T] diff --git a/src/partest/scala/tools/partest/nest/DirectRunner.scala b/src/partest/scala/tools/partest/nest/DirectRunner.scala index 2bb373d9c5..6c239721c3 100644 --- a/src/partest/scala/tools/partest/nest/DirectRunner.scala +++ b/src/partest/scala/tools/partest/nest/DirectRunner.scala @@ -59,7 +59,8 @@ trait DirectRunner { val futures = kindFiles map (f => (f, pool submit callable(manager runTest f))) toMap pool.shutdown() - pool.awaitTermination(1, TimeUnit.HOURS) + if (!pool.awaitTermination(4, TimeUnit.HOURS)) + NestUI.warning("Thread pool timeout elapsed before all tests were complete!") for ((file, future) <- futures) yield { val state = if (future.isCancelled) TestState.Timeout else future.get diff --git a/src/reflect/scala/reflect/api/StandardNames.scala b/src/reflect/scala/reflect/api/StandardNames.scala index 9ec66b8531..eb1ecda900 100644 --- a/src/reflect/scala/reflect/api/StandardNames.scala +++ b/src/reflect/scala/reflect/api/StandardNames.scala @@ -43,7 +43,6 @@ trait StandardNames extends base.StandardNames { val SUPER_PREFIX_STRING: String val TRAIT_SETTER_SEPARATOR_STRING: String - val ANYNAME: TermName val FAKE_LOCAL_THIS: TermName val INITIALIZER: TermName val LAZY_LOCAL: TermName diff --git a/src/reflect/scala/reflect/internal/AnnotationInfos.scala b/src/reflect/scala/reflect/internal/AnnotationInfos.scala index c283ae408e..2bcc95b9a8 100644 --- a/src/reflect/scala/reflect/internal/AnnotationInfos.scala +++ b/src/reflect/scala/reflect/internal/AnnotationInfos.scala @@ -160,12 +160,7 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable => */ final class LazyAnnotationInfo(lazyInfo: => AnnotationInfo) extends AnnotationInfo { private var forced = false - private lazy val forcedInfo = - try { - val result = lazyInfo - if (result.pos == NoPosition) result setPos pos - result - } finally forced = true + private lazy val forcedInfo = try lazyInfo finally forced = true def atp: Type = forcedInfo.atp def args: List[Tree] = forcedInfo.args diff --git a/src/reflect/scala/reflect/internal/Constants.scala b/src/reflect/scala/reflect/internal/Constants.scala index 820dfe0868..d6a168ee11 100644 --- a/src/reflect/scala/reflect/internal/Constants.scala +++ b/src/reflect/scala/reflect/internal/Constants.scala @@ -221,7 +221,12 @@ trait Constants extends api.Constants { tag match { case NullTag => "null" case StringTag => "\"" + escape(stringValue) + "\"" - case ClazzTag => "classOf[" + signature(typeValue) + "]" + case ClazzTag => + def show(tpe: Type) = "classOf[" + signature(tpe) + "]" + typeValue match { + case ErasedValueType(orig) => show(orig) + case _ => show(typeValue) + } case CharTag => "'" + escapedChar(charValue) + "'" case LongTag => longValue.toString() + "L" case EnumTag => symbolValue.name.toString() diff --git a/src/reflect/scala/reflect/internal/Mirrors.scala b/src/reflect/scala/reflect/internal/Mirrors.scala index 210af661ee..761b993539 100644 --- a/src/reflect/scala/reflect/internal/Mirrors.scala +++ b/src/reflect/scala/reflect/internal/Mirrors.scala @@ -180,7 +180,7 @@ trait Mirrors extends api.Mirrors { // Still fiddling with whether it's cleaner to do some of this setup here // or from constructors. The latter approach tends to invite init order issues. - EmptyPackageClass setInfo ClassInfoType(Nil, newPackageScope(EmptyPackageClass), EmptyPackageClass) + EmptyPackageClass setInfo rootLoader EmptyPackage setInfo EmptyPackageClass.tpe connectModuleToClass(EmptyPackage, EmptyPackageClass) @@ -231,7 +231,6 @@ trait Mirrors extends api.Mirrors { override def isEffectiveRoot = true override def isStatic = true override def isNestedClass = false - override def ownerOfNewSymbols = EmptyPackageClass } // The empty package, which holds all top level types without given packages. final object EmptyPackage extends ModuleSymbol(RootClass, NoPosition, nme.EMPTY_PACKAGE_NAME) with WellKnownSymbol { diff --git a/src/reflect/scala/reflect/internal/Names.scala b/src/reflect/scala/reflect/internal/Names.scala index 20da38fd63..72e6707f57 100644 --- a/src/reflect/scala/reflect/internal/Names.scala +++ b/src/reflect/scala/reflect/internal/Names.scala @@ -415,6 +415,9 @@ trait Names extends api.Names with LowPriorityNames { } else toString } + + @inline + final def fingerPrint: Long = (1L << start) /** TODO - find some efficiency. */ def append(ch: Char) = newName("" + this + ch) diff --git a/src/reflect/scala/reflect/internal/Scopes.scala b/src/reflect/scala/reflect/internal/Scopes.scala index ceacd2afb0..89e3c52de6 100644 --- a/src/reflect/scala/reflect/internal/Scopes.scala +++ b/src/reflect/scala/reflect/internal/Scopes.scala @@ -41,10 +41,15 @@ trait Scopes extends api.Scopes { self: SymbolTable => * This is necessary because when run from reflection every scope needs to have a * SynchronizedScope as mixin. */ - class Scope protected[Scopes] (initElems: ScopeEntry = null) extends Iterable[Symbol] { + class Scope protected[Scopes] (initElems: ScopeEntry = null, initFingerPrints: Long = 0L) extends Iterable[Symbol] { + + /** A bitset containing the last 6 bits of the start value of every name + * stored in this scope. + */ + var fingerPrints: Long = initFingerPrints protected[Scopes] def this(base: Scope) = { - this(base.elems) + this(base.elems, base.fingerPrints) nestinglevel = base.nestinglevel + 1 } @@ -95,7 +100,7 @@ trait Scopes extends api.Scopes { self: SymbolTable => * * @param e ... */ - protected def enter(e: ScopeEntry) { + protected def enterEntry(e: ScopeEntry) { elemsCache = null if (hashtable ne null) enterInHash(e) @@ -113,7 +118,11 @@ trait Scopes extends api.Scopes { self: SymbolTable => * * @param sym ... */ - def enter[T <: Symbol](sym: T): T = { enter(newScopeEntry(sym, this)); sym } + def enter[T <: Symbol](sym: T): T = { + fingerPrints |= sym.name.fingerPrint + enterEntry(newScopeEntry(sym, this)) + sym + } /** enter a symbol, asserting that no symbol with same name exists in scope * @@ -147,6 +156,7 @@ trait Scopes extends api.Scopes { self: SymbolTable => } def rehash(sym: Symbol, newname: Name) { + fingerPrints |= newname.fingerPrint if (hashtable ne null) { val index = sym.name.start & HASHMASK var e1 = hashtable(index) @@ -344,7 +354,7 @@ trait Scopes extends api.Scopes { self: SymbolTable => /** The empty scope (immutable). */ object EmptyScope extends Scope { - override def enter(e: ScopeEntry) { + override def enterEntry(e: ScopeEntry) { abort("EmptyScope.enter") } } diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala index 165e04863c..c8a2424118 100644 --- a/src/reflect/scala/reflect/internal/StdNames.scala +++ b/src/reflect/scala/reflect/internal/StdNames.scala @@ -297,7 +297,7 @@ trait StdNames { val WHILE_PREFIX = "while$" // Compiler internal names - val ANYNAME: NameType = "<anyname>" + val ANYname: NameType = "<anyname>" val CONSTRUCTOR: NameType = "<init>" val EQEQ_LOCAL_VAR: NameType = "eqEqTemp$" val FAKE_LOCAL_THIS: NameType = "this$" diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 04fa01c6f3..d484617767 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -100,13 +100,13 @@ trait Symbols extends api.Symbols { self: SymbolTable => case _ => false } - (tp <:< pt) || isCompatibleByName(tp, pt) + (tp weak_<:< pt) || isCompatibleByName(tp, pt) } def signatureAsSpecific(method1: MethodSymbol, method2: MethodSymbol): Boolean = { (substituteTypeParams(method1), substituteTypeParams(method2)) match { case (NullaryMethodType(r1), NullaryMethodType(r2)) => - r1 <:< r2 + r1 weak_<:< r2 case (NullaryMethodType(_), MethodType(_, _)) => true case (MethodType(_, _), NullaryMethodType(_)) => @@ -298,7 +298,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => else { val a = argTypes val p = extend(paramTypes, argTypes.length) - (a corresponds p)(_ <:< _) + (a corresponds p)(_ weak_<:< _) } } } @@ -813,11 +813,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => */ def isEffectiveRoot = false - /** For RootClass, this is EmptyPackageClass. For all other symbols, - * the symbol itself. - */ - def ownerOfNewSymbols = this - final def isLazyAccessor = isLazy && lazyAccessor != NoSymbol final def isOverridableMember = !(isClass || isEffectivelyFinal) && (this ne NoSymbol) && owner.isClass diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index f3dd1f03ad..01679a777d 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -14,6 +14,7 @@ import Flags._ import scala.util.control.ControlThrowable import scala.annotation.tailrec import util.Statistics +import scala.runtime.ObjectRef /* A standard type pattern match: case ErrorType => @@ -668,7 +669,8 @@ trait Types extends api.Types { self: SymbolTable => * Note: unfortunately it doesn't work to exclude DEFERRED this way. */ def membersBasedOnFlags(excludedFlags: Long, requiredFlags: Long): List[Symbol] = - findMember(nme.ANYNAME, excludedFlags, requiredFlags, false).alternatives + findMembers(excludedFlags, requiredFlags) +// findMember(nme.ANYNAME, excludedFlags, requiredFlags, false).alternatives def memberBasedOnName(name: Name, excludedFlags: Long): Symbol = findMember(name, excludedFlags, 0, false) @@ -1018,6 +1020,72 @@ trait Types extends api.Types { self: SymbolTable => else (baseClasses.head.newOverloaded(this, alts)) } + def findMembers(excludedFlags: Long, requiredFlags: Long): List[Symbol] = { + // if this type contains type variables, put them to sleep for a while -- don't just wipe them out by + // replacing them by the corresponding type parameter, as that messes up (e.g.) type variables in type refinements + // without this, the matchesType call would lead to type variables on both sides + // of a subtyping/equality judgement, which can lead to recursive types being constructed. + // See (t0851) for a situation where this happens. + val suspension: List[TypeVar] = if (this.isGround) null else suspendTypeVarsInType(this) + + Statistics.incCounter(findMembersCount) + val start = Statistics.pushTimer(typeOpsStack, findMembersNanos) + + //Console.println("find member " + name.decode + " in " + this + ":" + this.baseClasses)//DEBUG + var members: Scope = null + var required = requiredFlags + var excluded = excludedFlags | DEFERRED + var continue = true + var self: Type = null + while (continue) { + continue = false + val bcs0 = baseClasses + var bcs = bcs0 + while (!bcs.isEmpty) { + val decls = bcs.head.info.decls + var entry = decls.elems + while (entry ne null) { + val sym = entry.sym + val flags = sym.flags + if ((flags & required) == required) { + val excl = flags & excluded + if (excl == 0L && + (// omit PRIVATE LOCALS unless selector class is contained in class owning the def. + (bcs eq bcs0) || + (flags & PrivateLocal) != PrivateLocal || + (bcs0.head.hasTransOwner(bcs.head)))) { + if (members eq null) members = newScope + var others: ScopeEntry = members.lookupEntry(sym.name) + var symtpe: Type = null + while ((others ne null) && { + val other = others.sym + (other ne sym) && + ((other.owner eq sym.owner) || + (flags & PRIVATE) != 0 || { + if (self eq null) self = this.narrow + if (symtpe eq null) symtpe = self.memberType(sym) + !(self.memberType(other) matches symtpe) + })}) { + others = members lookupNextEntry others + } + if (others eq null) members enter sym + } else if (excl == DEFERRED) { + continue = true + } + } + entry = entry.next + } // while (entry ne null) + // excluded = excluded | LOCAL + bcs = bcs.tail + } // while (!bcs.isEmpty) + required |= DEFERRED + excluded &= ~(DEFERRED.toLong) + } // while (continue) + Statistics.popTimer(typeOpsStack, start) + if (suspension ne null) suspension foreach (_.suspended = false) + if (members eq null) Nil else members.toList + } + /** * Find member(s) in this type. If several members matching criteria are found, they are * returned in an OverloadedSymbol @@ -1040,75 +1108,83 @@ trait Types extends api.Types { self: SymbolTable => val start = Statistics.pushTimer(typeOpsStack, findMemberNanos) //Console.println("find member " + name.decode + " in " + this + ":" + this.baseClasses)//DEBUG - var members: Scope = null var member: Symbol = NoSymbol + var members: List[Symbol] = null + var lastM: ::[Symbol] = null + var membertpe: Type = null + var required = requiredFlags var excluded = excludedFlags | DEFERRED var continue = true var self: Type = null - var membertpe: Type = null + val fingerPrint: Long = name.fingerPrint + while (continue) { continue = false val bcs0 = baseClasses var bcs = bcs0 while (!bcs.isEmpty) { val decls = bcs.head.info.decls - var entry = - if (name == nme.ANYNAME) decls.elems else decls.lookupEntry(name) - while (entry ne null) { - val sym = entry.sym - if (sym hasAllFlags requiredFlags) { - val excl = sym.getFlag(excluded) - if (excl == 0L && - (// omit PRIVATE LOCALS unless selector class is contained in class owning the def. - (bcs eq bcs0) || - !sym.isPrivateLocal || - (bcs0.head.hasTransOwner(bcs.head)))) { - if (name.isTypeName || stableOnly && sym.isStable) { - Statistics.popTimer(typeOpsStack, start) - if (suspension ne null) suspension foreach (_.suspended = false) - return sym - } else if (member == NoSymbol) { - member = sym - } else if (members eq null) { - if (member.name != sym.name || - !(member == sym || - member.owner != sym.owner && - !sym.isPrivate && { - if (self eq null) self = this.narrow - if (membertpe eq null) membertpe = self.memberType(member) - (membertpe matches self.memberType(sym)) - })) { - members = newScope - members enter member - members enter sym - } - } else { - var prevEntry = members.lookupEntry(sym.name) - var symtpe: Type = null - while ((prevEntry ne null) && - !(prevEntry.sym == sym || - prevEntry.sym.owner != sym.owner && - !sym.hasFlag(PRIVATE) && { - if (self eq null) self = this.narrow - if (symtpe eq null) symtpe = self.memberType(sym) - self.memberType(prevEntry.sym) matches symtpe - })) { - prevEntry = members lookupNextEntry prevEntry - } - if (prevEntry eq null) { - members enter sym + if ((fingerPrint & decls.fingerPrints) != 0) { + var entry = decls.lookupEntry(name) + while (entry ne null) { + val sym = entry.sym + val flags = sym.flags + if ((flags & required) == required) { + val excl = flags & excluded + if (excl == 0L && + (// omit PRIVATE LOCALS unless selector class is contained in class owning the def. + (bcs eq bcs0) || + (flags & PrivateLocal) != PrivateLocal || + (bcs0.head.hasTransOwner(bcs.head)))) { + if (name.isTypeName || stableOnly && sym.isStable) { + Statistics.popTimer(typeOpsStack, start) + if (suspension ne null) suspension foreach (_.suspended = false) + return sym + } else if (member eq NoSymbol) { + member = sym + } else if (members eq null) { + if ((member ne sym) && + ((member.owner eq sym.owner) || + (flags & PRIVATE) != 0 || { + if (self eq null) self = this.narrow + if (membertpe eq null) membertpe = self.memberType(member) + !(membertpe matches self.memberType(sym)) + })) { + lastM = new ::(sym, null) + members = member :: lastM + } + } else { + var others: List[Symbol] = members + var symtpe: Type = null + while ((others ne null) && { + val other = others.head + (other ne sym) && + ((other.owner eq sym.owner) || + (flags & PRIVATE) != 0 || { + if (self eq null) self = this.narrow + if (symtpe eq null) symtpe = self.memberType(sym) + !(self.memberType(other) matches symtpe) + })}) { + others = others.tail + } + if (others eq null) { + val lastM1 = new ::(sym, null) + lastM.tl = lastM1 + lastM = lastM1 + } } + } else if (excl == DEFERRED) { + continue = true } - } else if (excl == DEFERRED.toLong) { - continue = true } - } - entry = if (name == nme.ANYNAME) entry.next else decls lookupNextEntry entry - } // while (entry ne null) + entry = decls lookupNextEntry entry + } // while (entry ne null) + } // if (fingerPrint matches) // excluded = excluded | LOCAL bcs = if (name == nme.CONSTRUCTOR) Nil else bcs.tail } // while (!bcs.isEmpty) - excluded = excludedFlags + required |= DEFERRED + excluded &= ~(DEFERRED.toLong) } // while (continue) Statistics.popTimer(typeOpsStack, start) if (suspension ne null) suspension foreach (_.suspended = false) @@ -1117,9 +1193,11 @@ trait Types extends api.Types { self: SymbolTable => member } else { Statistics.incCounter(multMemberCount) - baseClasses.head.newOverloaded(this, members.toList) + lastM.tl = Nil + baseClasses.head.newOverloaded(this, members) } } + /** The (existential or otherwise) skolems and existentially quantified variables which are free in this type */ def skolemsExceptMethodTypeParams: List[Symbol] = { var boundSyms: List[Symbol] = List() @@ -1610,8 +1688,13 @@ trait Types extends api.Types { self: SymbolTable => if (period != currentPeriod) { tpe.baseClassesPeriod = currentPeriod if (!isValidForBaseClasses(period)) { - tpe.baseClassesCache = null - tpe.baseClassesCache = tpe.memo(computeBaseClasses)(tpe.typeSymbol :: _.baseClasses.tail) + val start = Statistics.pushTimer(typeOpsStack, baseClassesNanos) + try { + tpe.baseClassesCache = null + tpe.baseClassesCache = tpe.memo(computeBaseClasses)(tpe.typeSymbol :: _.baseClasses.tail) + } finally { + Statistics.popTimer(typeOpsStack, start) + } } } if (tpe.baseClassesCache eq null) @@ -5066,7 +5149,7 @@ trait Types extends api.Types { self: SymbolTable => */ def needsOuterTest(patType: Type, selType: Type, currentOwner: Symbol) = { def createDummyClone(pre: Type): Type = { - val dummy = currentOwner.enclClass.newValue(nme.ANYNAME).setInfo(pre.widen) + val dummy = currentOwner.enclClass.newValue(nme.ANYname).setInfo(pre.widen) singleType(ThisType(currentOwner.enclClass), dummy) } def maybeCreateDummyClone(pre: Type, sym: Symbol): Type = pre match { @@ -6909,14 +6992,17 @@ object TypesStats { val lubCount = Statistics.newCounter ("#toplevel lubs/glbs") val nestedLubCount = Statistics.newCounter ("#all lubs/glbs") val findMemberCount = Statistics.newCounter ("#findMember ops") + val findMembersCount = Statistics.newCounter ("#findMembers ops") val noMemberCount = Statistics.newSubCounter(" of which not found", findMemberCount) val multMemberCount = Statistics.newSubCounter(" of which multiple overloaded", findMemberCount) val typerNanos = Statistics.newTimer ("time spent typechecking", "typer") val lubNanos = Statistics.newStackableTimer("time spent in lubs", typerNanos) val subtypeNanos = Statistics.newStackableTimer("time spent in <:<", typerNanos) val findMemberNanos = Statistics.newStackableTimer("time spent in findmember", typerNanos) + val findMembersNanos = Statistics.newStackableTimer("time spent in findmembers", typerNanos) val asSeenFromNanos = Statistics.newStackableTimer("time spent in asSeenFrom", typerNanos) val baseTypeSeqNanos = Statistics.newStackableTimer("time spent in baseTypeSeq", typerNanos) + val baseClassesNanos = Statistics.newStackableTimer("time spent in baseClasses", typerNanos) val compoundBaseTypeSeqCount = Statistics.newSubCounter(" of which for compound types", baseTypeSeqCount) val typerefBaseTypeSeqCount = Statistics.newSubCounter(" of which for typerefs", baseTypeSeqCount) val singletonBaseTypeSeqCount = Statistics.newSubCounter(" of which for singletons", baseTypeSeqCount) diff --git a/src/reflect/scala/reflect/makro/Enclosures.scala b/src/reflect/scala/reflect/makro/Enclosures.scala index 69bd8d09c7..ff5c13a785 100644 --- a/src/reflect/scala/reflect/makro/Enclosures.scala +++ b/src/reflect/scala/reflect/makro/Enclosures.scala @@ -36,10 +36,6 @@ trait Enclosures { */ val enclosingPosition: Position - /** Tree that corresponds to the enclosing application, or EmptyTree if not applicable. - */ - val enclosingApplication: Tree - /** Tree that corresponds to the enclosing method, or EmptyTree if not applicable. */ val enclosingMethod: Tree diff --git a/src/reflect/scala/reflect/runtime/SymbolLoaders.scala b/src/reflect/scala/reflect/runtime/SymbolLoaders.scala index c1cd5d2911..eb48e9dc79 100644 --- a/src/reflect/scala/reflect/runtime/SymbolLoaders.scala +++ b/src/reflect/scala/reflect/runtime/SymbolLoaders.scala @@ -99,8 +99,10 @@ trait SymbolLoaders { self: SymbolTable => 0 < dp && dp < (name.length - 1) } - class PackageScope(pkgClass: Symbol) extends Scope() with SynchronizedScope { + class PackageScope(pkgClass: Symbol) extends Scope(initFingerPrints = -1L) // disable fingerprinting as we do not know entries beforehand + with SynchronizedScope { assert(pkgClass.isType) + // disable fingerprinting as we do not know entries beforehand private val negatives = mutable.Set[Name]() // Syncnote: Performance only, so need not be protected. override def lookupEntry(name: Name): ScopeEntry = { val e = super.lookupEntry(name) diff --git a/test/files/neg/t5892.check b/test/files/neg/t5892.check new file mode 100644 index 0000000000..839bf9de23 --- /dev/null +++ b/test/files/neg/t5892.check @@ -0,0 +1,17 @@ +t5892.scala:5: error: type mismatch; + found : Boolean(false) + required: String +class C[@annot(false) X] { + ^ +t5892.scala:9: error: not found: value b2s +class D[@annot(b2s(false)) X] { + ^ +t5892.scala:13: error: type mismatch; + found : Boolean(false) + required: String +@annot(false) class E { + ^ +t5892.scala:17: error: not found: value b2s +@annot(b2s(false)) class F { + ^ +four errors found diff --git a/test/files/neg/t5892.scala b/test/files/neg/t5892.scala new file mode 100644 index 0000000000..5e3b2f313e --- /dev/null +++ b/test/files/neg/t5892.scala @@ -0,0 +1,25 @@ +import language.implicitConversions + +class annot(a: String) extends annotation.StaticAnnotation + +class C[@annot(false) X] { + implicit def b2s(b: Boolean): String = "" +} + +class D[@annot(b2s(false)) X] { + implicit def b2s(b: Boolean): String = "" +} + +@annot(false) class E { + implicit def b2s(b: Boolean): String = "" +} + +@annot(b2s(false)) class F { + implicit def b2s(b: Boolean): String = "" +} + +object T { + implicit def b2s(b: Boolean): String = "" + @annot(false) val x = 0 + @annot(b2s(false)) val y = 0 +} diff --git a/test/files/pos/t5892.scala b/test/files/pos/t5892.scala new file mode 100644 index 0000000000..241e59860a --- /dev/null +++ b/test/files/pos/t5892.scala @@ -0,0 +1,5 @@ +class foo(a: String) extends annotation.StaticAnnotation +object o { + implicit def i2s(i: Int) = "" + @foo(1: String) def blerg { } +} diff --git a/test/files/pos/t6028/t6028_1.scala b/test/files/pos/t6028/t6028_1.scala new file mode 100644 index 0000000000..6edb76069e --- /dev/null +++ b/test/files/pos/t6028/t6028_1.scala @@ -0,0 +1,3 @@ +class C { + def foo(a: Int): Unit = () => a +} diff --git a/test/files/pos/t6028/t6028_2.scala b/test/files/pos/t6028/t6028_2.scala new file mode 100644 index 0000000000..f44048c0ab --- /dev/null +++ b/test/files/pos/t6028/t6028_2.scala @@ -0,0 +1,4 @@ +object Test { + // ensure that parameter names are untouched by lambdalift + new C().foo(a = 0) +} diff --git a/test/files/run/nullable-lazyvals.check b/test/files/run/nullable-lazyvals.check new file mode 100644 index 0000000000..4db5783257 --- /dev/null +++ b/test/files/run/nullable-lazyvals.check @@ -0,0 +1,3 @@ + +param1: null +param2: null diff --git a/test/files/run/nullable-lazyvals.scala b/test/files/run/nullable-lazyvals.scala new file mode 100644 index 0000000000..c201e74e75 --- /dev/null +++ b/test/files/run/nullable-lazyvals.scala @@ -0,0 +1,36 @@ + +/** Test that call-by-name parameters are set to null if + * they are used only to initialize a lazy value, after the + * value has been initialized. + */ + +class Foo(param1: => Object, param2: => String) { + lazy val field1 = param1 + lazy val field2 = try param2 finally println("") +} + +object Test extends App { + val foo = new Foo(new Object, "abc") + + foo.field1 + foo.field2 + + for (f <- foo.getClass.getDeclaredFields) { + f.setAccessible(true) + if (f.getName.startsWith("param")) { + println("%s: %s".format(f.getName, f.get(foo))) + } + } + + // test that try-finally does not generated a liftedTry + // helper. This would already fail the first part of the test, + // but this check will help diganose it (if the single access to a + // private field does not happen directly in the lazy val, it won't + // be nulled). + for (f <- foo.getClass.getDeclaredMethods) { + f.setAccessible(true) + if (f.getName.startsWith("lifted")) { + println("not expected: %s".format(f)) + } + } +} diff --git a/test/files/run/reflect-resolveoverload-invalid.scala b/test/files/run/reflect-resolveoverload-invalid.scala index def28ccbb4..8c5dc9f94b 100644 --- a/test/files/run/reflect-resolveoverload-invalid.scala +++ b/test/files/run/reflect-resolveoverload-invalid.scala @@ -27,7 +27,7 @@ object Test extends App { val d = t member u.newTermName("d") asTermSymbol val e = t member u.newTermName("e") asTermSymbol - val n1 = a.resolveOverloaded(posVargs = List(u.typeOf[Char])) + val n1 = a.resolveOverloaded(posVargs = List(u.typeOf[Long])) val n2 = b.resolveOverloaded(posVargs = List(u.typeOf[A])) val n3 = c.resolveOverloaded(posVargs = List(u.typeOf[B], u.typeOf[B])) val n4 = d.resolveOverloaded(targs = List(u.typeOf[Int])) diff --git a/test/files/run/reflect-resolveoverload2.scala b/test/files/run/reflect-resolveoverload2.scala index b5f719814b..a800a3e92c 100644 --- a/test/files/run/reflect-resolveoverload2.scala +++ b/test/files/run/reflect-resolveoverload2.scala @@ -2,16 +2,20 @@ class A class B extends A class C { - def a(x: Int) = 1 - def a(x: String) = 2 - //def b(x: => Int)(s: String) = 1 - //def b(x: => String)(a: Array[_]) = 2 - def c(x: A) = 1 - def c(x: B) = 2 - //def d(x: => A)(s: String) = 1 - //def d(x: => B)(a: Array[_]) = 2 - def e(x: A) = 1 - def e(x: B = new B) = 2 + def a(x: Int) = 1 + def a(x: String) = 2 + //def b(x: => Int)(s: String) = 1 + //def b(x: => String)(a: Array[_]) = 2 + def c(x: A) = 1 + def c(x: B) = 2 + //def d(x: => A)(s: String) = 1 + //def d(x: => B)(a: Array[_]) = 2 + def e(x: A) = 1 + def e(x: B = new B) = 2 + def f(x: Int) = 1 + def f(x: String) = 2 + def f(x: Long) = 3 + def f(x: Double) = 4 } object Test extends App { @@ -29,6 +33,8 @@ object Test extends App { } assert(c.a(1) == invoke("a", 1, u.typeOf[Int])) assert(c.a("a") == invoke("a", "a", u.typeOf[String])) + assert(c.a('a') == invoke("a", 'a', u.typeOf[Char])) + assert(c.a(3: Byte) == invoke("a", 3: Byte, u.typeOf[Byte])) //assert(c.b(1)(null) == invoke("b", 1, u.typeOf[Int])) //assert(c.b("a")(null) == invoke("b", "a", u.typeOf[String])) assert(c.c(new A) == invoke("c", new A, u.typeOf[A])) @@ -37,4 +43,9 @@ object Test extends App { //assert(c.d(new B)(null) == invoke("d", new B, u.typeOf[B])) assert(c.e(new A) == invoke("e", new A, u.typeOf[A])) assert(c.e(new B) == invoke("e", new B, u.typeOf[B])) + assert(c.f(1: Short) == invoke("f", 1: Short, u.typeOf[Short])) + assert(c.f(2) == invoke("f", 2, u.typeOf[Int])) + assert(c.f(3L) == invoke("f", 3L, u.typeOf[Long])) + assert(c.f(4f) == invoke("f", 4f, u.typeOf[Float])) + assert(c.f(5d) == invoke("f", 5d, u.typeOf[Double])) } diff --git a/test/files/run/t5588.check b/test/files/run/t5588.check new file mode 100644 index 0000000000..bb101b641b --- /dev/null +++ b/test/files/run/t5588.check @@ -0,0 +1,2 @@ +true +true diff --git a/test/files/run/t5588.scala b/test/files/run/t5588.scala new file mode 100644 index 0000000000..f214d16684 --- /dev/null +++ b/test/files/run/t5588.scala @@ -0,0 +1,14 @@ +object Test { + object MyEnum extends Enumeration { + val Foo = Value(2000000000) + val Bar = Value(-2000000000) + val X = Value(Integer.MAX_VALUE) + val Y = Value(Integer.MIN_VALUE) + } + + import MyEnum._ + def main(args: Array[String]) { + println(Foo > Bar) + println(X > Y) + } +} diff --git a/test/files/run/t5937.scala b/test/files/run/t5937.scala new file mode 100644 index 0000000000..e5bf6617af --- /dev/null +++ b/test/files/run/t5937.scala @@ -0,0 +1,12 @@ + + + +import collection._ + + + +object Test extends App { + + val list: List[Int] = (immutable.Vector(1, 2, 3) :+ 4)(breakOut) + +} diff --git a/test/files/run/t6028.check b/test/files/run/t6028.check new file mode 100644 index 0000000000..dca61115ad --- /dev/null +++ b/test/files/run/t6028.check @@ -0,0 +1,84 @@ +[[syntax trees at end of lambdalift]] // newSource1 +package <empty> { + class T extends Object { + <paramaccessor> val T$$classParam: Int = _; + def <init>(classParam: Int): T = { + T.super.<init>(); + () + }; + private[this] val field: Int = 0; + <stable> <accessor> def field(): Int = T.this.field; + def foo(methodParam: Int): Function0 = { + val methodLocal: Int = 0; + { + (new anonymous class $anonfun$foo$1(T.this, methodParam, methodLocal): Function0) + } + }; + def bar(barParam: Int): Object = { + @volatile var MethodLocalObject$module: scala.runtime.VolatileObjectRef = new scala.runtime.VolatileObjectRef(<empty>); + T.this.MethodLocalObject$1(barParam, MethodLocalObject$module) + }; + def tryy(tryyParam: Int): Function0 = { + var tryyLocal: scala.runtime.IntRef = new scala.runtime.IntRef(0); + { + (new anonymous class $anonfun$tryy$1(T.this, tryyParam, tryyLocal): Function0) + } + }; + @SerialVersionUID(0) final <synthetic> class $anonfun$foo$1 extends scala.runtime.AbstractFunction0$mcI$sp with Serializable { + def <init>($outer: T, methodParam$1: Int, methodLocal$1: Int): anonymous class $anonfun$foo$1 = { + $anonfun$foo$1.super.<init>(); + () + }; + final def apply(): Int = $anonfun$foo$1.this.apply$mcI$sp(); + <specialized> def apply$mcI$sp(): Int = $anonfun$foo$1.this.$outer.T$$classParam.+($anonfun$foo$1.this.$outer.field()).+($anonfun$foo$1.this.methodParam$1).+($anonfun$foo$1.this.methodLocal$1); + <synthetic> <paramaccessor> private[this] val $outer: T = _; + <synthetic> <stable> def T$$anonfun$$$outer(): T = $anonfun$foo$1.this.$outer; + final <bridge> def apply(): Object = scala.Int.box($anonfun$foo$1.this.apply()); + <synthetic> <paramaccessor> private[this] val methodParam$1: Int = _; + <synthetic> <paramaccessor> private[this] val methodLocal$1: Int = _ + }; + abstract trait MethodLocalTrait$1 extends Object { + <synthetic> <stable> def T$MethodLocalTrait$$$outer(): T + }; + object MethodLocalObject$2 extends Object with T#MethodLocalTrait$1 { + def <init>($outer: T, barParam$1: Int): ... = { + MethodLocalObject$2.super.<init>(); + MethodLocalObject$2.this.$asInstanceOf[T#MethodLocalTrait$1$class]()./*MethodLocalTrait$1$class*/$init$(barParam$1); + () + }; + <synthetic> <paramaccessor> private[this] val $outer: T = _; + <synthetic> <stable> def T$MethodLocalObject$$$outer(): T = MethodLocalObject$2.this.$outer; + <synthetic> <stable> def T$MethodLocalTrait$$$outer(): T = MethodLocalObject$2.this.$outer + }; + final <stable> private[this] def MethodLocalObject$1(barParam$1: Int, MethodLocalObject$module$1: scala.runtime.VolatileObjectRef): ... = { + MethodLocalObject$module$1.elem = new ...(T.this, barParam$1); + MethodLocalObject$module$1.elem.$asInstanceOf[...]() + }; + abstract trait MethodLocalTrait$1$class extends Object with T#MethodLocalTrait$1 { + def /*MethodLocalTrait$1$class*/$init$(barParam$1: Int): Unit = { + () + }; + scala.this.Predef.print(scala.Int.box(barParam$1)) + }; + @SerialVersionUID(0) final <synthetic> class $anonfun$tryy$1 extends scala.runtime.AbstractFunction0$mcV$sp with Serializable { + def <init>($outer: T, tryyParam$1: Int, tryyLocal$1: scala.runtime.IntRef): anonymous class $anonfun$tryy$1 = { + $anonfun$tryy$1.super.<init>(); + () + }; + final def apply(): Unit = $anonfun$tryy$1.this.apply$mcV$sp(); + <specialized> def apply$mcV$sp(): Unit = try { + $anonfun$tryy$1.this.tryyLocal$1.elem = $anonfun$tryy$1.this.tryyParam$1 + } finally (); + <synthetic> <paramaccessor> private[this] val $outer: T = _; + <synthetic> <stable> def T$$anonfun$$$outer(): T = $anonfun$tryy$1.this.$outer; + final <bridge> def apply(): Object = { + $anonfun$tryy$1.this.apply(); + scala.runtime.BoxedUnit.UNIT + }; + <synthetic> <paramaccessor> private[this] val tryyParam$1: Int = _; + <synthetic> <paramaccessor> private[this] val tryyLocal$1: scala.runtime.IntRef = _ + } + } +} + +warning: there were 1 feature warnings; re-run with -feature for details diff --git a/test/files/run/t6028.scala b/test/files/run/t6028.scala new file mode 100644 index 0000000000..cab17535fc --- /dev/null +++ b/test/files/run/t6028.scala @@ -0,0 +1,21 @@ +import scala.tools.partest._ +import java.io.{Console => _, _} + +object Test extends DirectTest { + + override def extraSettings: String = "-usejavacp -Xprint:lambdalift -d " + testOutput.path + + override def code = """class T(classParam: Int) { + | val field: Int = 0 + | def foo(methodParam: Int) = {val methodLocal = 0 ; () => classParam + field + methodParam + methodLocal } + | def bar(barParam: Int) = { trait MethodLocalTrait { print(barParam) }; object MethodLocalObject extends MethodLocalTrait; MethodLocalObject } + | def tryy(tryyParam: Int) = { var tryyLocal = 0; () => try { tryyLocal = tryyParam } finally () } + |} + |""".stripMargin.trim + + override def show(): Unit = { + Console.withErr(System.out) { + compile() + } + } +} diff --git a/test/files/run/t6077_patmat_cse_irrefutable.check b/test/files/run/t6077_patmat_cse_irrefutable.check new file mode 100644 index 0000000000..9766475a41 --- /dev/null +++ b/test/files/run/t6077_patmat_cse_irrefutable.check @@ -0,0 +1 @@ +ok diff --git a/test/files/run/t6077_patmat_cse_irrefutable.scala b/test/files/run/t6077_patmat_cse_irrefutable.scala new file mode 100644 index 0000000000..b130ae7813 --- /dev/null +++ b/test/files/run/t6077_patmat_cse_irrefutable.scala @@ -0,0 +1,13 @@ +class LiteralNode(val value: Any) + +object LiteralNode { + // irrefutable + def unapply(n: LiteralNode) = Some(n.value) +} + +object Test extends App { + ((new LiteralNode(false)): Any) match { + case LiteralNode(true) => println("uh-oh") + case LiteralNode(false) => println("ok") + } +}
\ No newline at end of file diff --git a/test/files/run/t6089.check b/test/files/run/t6089.check new file mode 100644 index 0000000000..a8d4424106 --- /dev/null +++ b/test/files/run/t6089.check @@ -0,0 +1 @@ +scala.MatchError: Foo(0) (of class Foo) diff --git a/test/files/run/t6089.scala b/test/files/run/t6089.scala new file mode 100644 index 0000000000..c72d7ba792 --- /dev/null +++ b/test/files/run/t6089.scala @@ -0,0 +1,13 @@ +case class Foo(x: Int) + +object Test { + def bippo(result: Boolean): Boolean = result + def bungus(m: Foo): Boolean = + bippo(m match { case Foo(2) => bungus(m) }) + + def main(args: Array[String]): Unit = try { + bungus(Foo(0)) + } catch { + case x: MatchError => println(x) + } +}
\ No newline at end of file diff --git a/test/files/run/valueclasses-classmanifest-basic.check b/test/files/run/valueclasses-classmanifest-basic.check new file mode 100644 index 0000000000..554c75e074 --- /dev/null +++ b/test/files/run/valueclasses-classmanifest-basic.check @@ -0,0 +1 @@ +Foo
diff --git a/test/files/run/valueclasses-classmanifest-basic.scala b/test/files/run/valueclasses-classmanifest-basic.scala new file mode 100644 index 0000000000..c2aa08ef86 --- /dev/null +++ b/test/files/run/valueclasses-classmanifest-basic.scala @@ -0,0 +1,5 @@ +class Foo(val x: Int) extends AnyVal + +object Test extends App { + println(classManifest[Foo]) +}
\ No newline at end of file diff --git a/test/files/run/valueclasses-classmanifest-existential.check b/test/files/run/valueclasses-classmanifest-existential.check new file mode 100644 index 0000000000..e9fc6e27ea --- /dev/null +++ b/test/files/run/valueclasses-classmanifest-existential.check @@ -0,0 +1 @@ +Foo[<?>]
diff --git a/test/files/run/valueclasses-classmanifest-existential.scala b/test/files/run/valueclasses-classmanifest-existential.scala new file mode 100644 index 0000000000..11999df678 --- /dev/null +++ b/test/files/run/valueclasses-classmanifest-existential.scala @@ -0,0 +1,5 @@ +class Foo[T](val x: T) extends AnyVal + +object Test extends App { + println(classManifest[Foo[_]]) +}
\ No newline at end of file diff --git a/test/files/run/valueclasses-classmanifest-generic.check b/test/files/run/valueclasses-classmanifest-generic.check new file mode 100644 index 0000000000..1418c5cff9 --- /dev/null +++ b/test/files/run/valueclasses-classmanifest-generic.check @@ -0,0 +1 @@ +Foo[java.lang.String]
diff --git a/test/files/run/valueclasses-classmanifest-generic.scala b/test/files/run/valueclasses-classmanifest-generic.scala new file mode 100644 index 0000000000..280152dc1d --- /dev/null +++ b/test/files/run/valueclasses-classmanifest-generic.scala @@ -0,0 +1,5 @@ +class Foo[T](val x: T) extends AnyVal + +object Test extends App { + println(classManifest[Foo[String]]) +}
\ No newline at end of file diff --git a/test/files/run/valueclasses-classtag-basic.check b/test/files/run/valueclasses-classtag-basic.check new file mode 100644 index 0000000000..0c13986b32 --- /dev/null +++ b/test/files/run/valueclasses-classtag-basic.check @@ -0,0 +1 @@ +ClassTag[class Foo]
diff --git a/test/files/run/valueclasses-classtag-basic.scala b/test/files/run/valueclasses-classtag-basic.scala new file mode 100644 index 0000000000..912a4bb019 --- /dev/null +++ b/test/files/run/valueclasses-classtag-basic.scala @@ -0,0 +1,5 @@ +class Foo(val x: Int) extends AnyVal + +object Test extends App { + println(scala.reflect.classTag[Foo]) +}
\ No newline at end of file diff --git a/test/files/run/valueclasses-classtag-existential.check b/test/files/run/valueclasses-classtag-existential.check new file mode 100644 index 0000000000..95e94e7aee --- /dev/null +++ b/test/files/run/valueclasses-classtag-existential.check @@ -0,0 +1 @@ +ClassTag[class java.lang.Object]
diff --git a/test/files/run/valueclasses-classtag-existential.scala b/test/files/run/valueclasses-classtag-existential.scala new file mode 100644 index 0000000000..e0db9cdd75 --- /dev/null +++ b/test/files/run/valueclasses-classtag-existential.scala @@ -0,0 +1,5 @@ +class Foo[T](val x: T) extends AnyVal + +object Test extends App { + println(scala.reflect.classTag[Foo[_]]) +}
\ No newline at end of file diff --git a/test/files/run/valueclasses-classtag-generic.check b/test/files/run/valueclasses-classtag-generic.check new file mode 100644 index 0000000000..0c13986b32 --- /dev/null +++ b/test/files/run/valueclasses-classtag-generic.check @@ -0,0 +1 @@ +ClassTag[class Foo]
diff --git a/test/files/run/valueclasses-classtag-generic.scala b/test/files/run/valueclasses-classtag-generic.scala new file mode 100644 index 0000000000..bd1f213835 --- /dev/null +++ b/test/files/run/valueclasses-classtag-generic.scala @@ -0,0 +1,5 @@ +class Foo[T](val x: T) extends AnyVal + +object Test extends App { + println(scala.reflect.classTag[Foo[String]]) +}
\ No newline at end of file diff --git a/test/files/run/valueclasses-manifest-basic.check b/test/files/run/valueclasses-manifest-basic.check new file mode 100644 index 0000000000..554c75e074 --- /dev/null +++ b/test/files/run/valueclasses-manifest-basic.check @@ -0,0 +1 @@ +Foo
diff --git a/test/files/run/valueclasses-manifest-basic.scala b/test/files/run/valueclasses-manifest-basic.scala new file mode 100644 index 0000000000..eefab20168 --- /dev/null +++ b/test/files/run/valueclasses-manifest-basic.scala @@ -0,0 +1,5 @@ +class Foo(val x: Int) extends AnyVal + +object Test extends App { + println(manifest[Foo]) +}
\ No newline at end of file diff --git a/test/files/run/valueclasses-manifest-existential.check b/test/files/run/valueclasses-manifest-existential.check new file mode 100644 index 0000000000..fdce051039 --- /dev/null +++ b/test/files/run/valueclasses-manifest-existential.check @@ -0,0 +1 @@ +Foo[_ <: Any]
diff --git a/test/files/run/valueclasses-manifest-existential.scala b/test/files/run/valueclasses-manifest-existential.scala new file mode 100644 index 0000000000..47eb6d64dd --- /dev/null +++ b/test/files/run/valueclasses-manifest-existential.scala @@ -0,0 +1,5 @@ +class Foo[T](val x: T) extends AnyVal + +object Test extends App { + println(manifest[Foo[_]]) +}
\ No newline at end of file diff --git a/test/files/run/valueclasses-manifest-generic.check b/test/files/run/valueclasses-manifest-generic.check new file mode 100644 index 0000000000..1418c5cff9 --- /dev/null +++ b/test/files/run/valueclasses-manifest-generic.check @@ -0,0 +1 @@ +Foo[java.lang.String]
diff --git a/test/files/run/valueclasses-manifest-generic.scala b/test/files/run/valueclasses-manifest-generic.scala new file mode 100644 index 0000000000..18313fba6f --- /dev/null +++ b/test/files/run/valueclasses-manifest-generic.scala @@ -0,0 +1,5 @@ +class Foo[T](val x: T) extends AnyVal + +object Test extends App { + println(manifest[Foo[String]]) +}
\ No newline at end of file diff --git a/test/files/run/valueclasses-typetag-basic.check b/test/files/run/valueclasses-typetag-basic.check new file mode 100644 index 0000000000..554c75e074 --- /dev/null +++ b/test/files/run/valueclasses-typetag-basic.check @@ -0,0 +1 @@ +Foo
diff --git a/test/files/run/valueclasses-typetag-basic.scala b/test/files/run/valueclasses-typetag-basic.scala new file mode 100644 index 0000000000..d0243f7378 --- /dev/null +++ b/test/files/run/valueclasses-typetag-basic.scala @@ -0,0 +1,5 @@ +class Foo(val x: Int) extends AnyVal + +object Test extends App { + println(scala.reflect.runtime.universe.typeOf[Foo]) +}
\ No newline at end of file diff --git a/test/files/run/valueclasses-typetag-existential.check b/test/files/run/valueclasses-typetag-existential.check new file mode 100644 index 0000000000..0efa24a45f --- /dev/null +++ b/test/files/run/valueclasses-typetag-existential.check @@ -0,0 +1 @@ +Foo[_]
diff --git a/test/files/run/valueclasses-typetag-existential.scala b/test/files/run/valueclasses-typetag-existential.scala new file mode 100644 index 0000000000..4cdaa44a83 --- /dev/null +++ b/test/files/run/valueclasses-typetag-existential.scala @@ -0,0 +1,5 @@ +class Foo[T](val x: T) extends AnyVal + +object Test extends App { + println(scala.reflect.runtime.universe.typeOf[Foo[_]]) +}
\ No newline at end of file diff --git a/test/files/run/valueclasses-typetag-generic.check b/test/files/run/valueclasses-typetag-generic.check new file mode 100644 index 0000000000..fce2e64f79 --- /dev/null +++ b/test/files/run/valueclasses-typetag-generic.check @@ -0,0 +1 @@ +Foo[String]
diff --git a/test/files/run/valueclasses-typetag-generic.scala b/test/files/run/valueclasses-typetag-generic.scala new file mode 100644 index 0000000000..eb32dfcadb --- /dev/null +++ b/test/files/run/valueclasses-typetag-generic.scala @@ -0,0 +1,5 @@ +class Foo[T](val x: T) extends AnyVal + +object Test extends App { + println(scala.reflect.runtime.universe.typeOf[Foo[String]]) +}
\ No newline at end of file diff --git a/test/files/specialized/t6035.check b/test/files/specialized/t6035.check new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/test/files/specialized/t6035.check @@ -0,0 +1 @@ +0 diff --git a/test/files/specialized/t6035/first_1.scala b/test/files/specialized/t6035/first_1.scala new file mode 100644 index 0000000000..1289e9f48e --- /dev/null +++ b/test/files/specialized/t6035/first_1.scala @@ -0,0 +1,5 @@ +trait Foo[@specialized(Int) A] { + def foo(x: A): A +} + +abstract class Inter extends Foo[Int] diff --git a/test/files/specialized/t6035/second_2.scala b/test/files/specialized/t6035/second_2.scala new file mode 100644 index 0000000000..fb317e2a6a --- /dev/null +++ b/test/files/specialized/t6035/second_2.scala @@ -0,0 +1,13 @@ +class Baz extends Inter { + def foo(x: Int) = x + 1 +} + +object Test { + def main(args: Array[String]) { + // it's important that the type is Inter so we do not call Baz.foo(I)I directly! + val baz: Inter = new Baz + // here we should go through specialized version of foo and thus have zero boxing + baz.foo(1) + println(runtime.BoxesRunTime.integerBoxCount) + } +} diff --git a/test/files/pos/t1751.cmds b/test/pending/pos/t1751.cmds index d4a4898ffd..d4a4898ffd 100644 --- a/test/files/pos/t1751.cmds +++ b/test/pending/pos/t1751.cmds diff --git a/test/files/pos/t1751/A1_2.scala b/test/pending/pos/t1751/A1_2.scala index 354d5eecd0..354d5eecd0 100644 --- a/test/files/pos/t1751/A1_2.scala +++ b/test/pending/pos/t1751/A1_2.scala diff --git a/test/files/pos/t1751/A2_1.scala b/test/pending/pos/t1751/A2_1.scala index c768062e43..c768062e43 100644 --- a/test/files/pos/t1751/A2_1.scala +++ b/test/pending/pos/t1751/A2_1.scala diff --git a/test/files/pos/t1751/SuiteClasses.java b/test/pending/pos/t1751/SuiteClasses.java index a415e4f572..a415e4f572 100644 --- a/test/files/pos/t1751/SuiteClasses.java +++ b/test/pending/pos/t1751/SuiteClasses.java diff --git a/test/files/pos/t1782.cmds b/test/pending/pos/t1782.cmds index 61f3d3788e..61f3d3788e 100644 --- a/test/files/pos/t1782.cmds +++ b/test/pending/pos/t1782.cmds diff --git a/test/files/pos/t1782/Ann.java b/test/pending/pos/t1782/Ann.java index 0dcfbd2ed7..0dcfbd2ed7 100644 --- a/test/files/pos/t1782/Ann.java +++ b/test/pending/pos/t1782/Ann.java diff --git a/test/files/pos/t1782/Days.java b/test/pending/pos/t1782/Days.java index 203a87b1c2..203a87b1c2 100644 --- a/test/files/pos/t1782/Days.java +++ b/test/pending/pos/t1782/Days.java diff --git a/test/files/pos/t1782/ImplementedBy.java b/test/pending/pos/t1782/ImplementedBy.java index 6aa8b4fa9e..6aa8b4fa9e 100644 --- a/test/files/pos/t1782/ImplementedBy.java +++ b/test/pending/pos/t1782/ImplementedBy.java diff --git a/test/files/pos/t1782/Test_1.scala b/test/pending/pos/t1782/Test_1.scala index 6467a74c29..6467a74c29 100644 --- a/test/files/pos/t1782/Test_1.scala +++ b/test/pending/pos/t1782/Test_1.scala diff --git a/test/files/pos/t294.cmds b/test/pending/pos/t294.cmds index 62c9a5a068..62c9a5a068 100644 --- a/test/files/pos/t294.cmds +++ b/test/pending/pos/t294.cmds diff --git a/test/files/pos/t294/Ann.java b/test/pending/pos/t294/Ann.java index 934ca46297..934ca46297 100644 --- a/test/files/pos/t294/Ann.java +++ b/test/pending/pos/t294/Ann.java diff --git a/test/files/pos/t294/Ann2.java b/test/pending/pos/t294/Ann2.java index 025b79e794..025b79e794 100644 --- a/test/files/pos/t294/Ann2.java +++ b/test/pending/pos/t294/Ann2.java diff --git a/test/files/pos/t294/Test_1.scala b/test/pending/pos/t294/Test_1.scala index ff1f34b10e..ff1f34b10e 100644 --- a/test/files/pos/t294/Test_1.scala +++ b/test/pending/pos/t294/Test_1.scala diff --git a/test/files/pos/t294/Test_2.scala b/test/pending/pos/t294/Test_2.scala index 9fb1c6e175..9fb1c6e175 100644 --- a/test/files/pos/t294/Test_2.scala +++ b/test/pending/pos/t294/Test_2.scala diff --git a/test/files/run/t3897.check b/test/pending/run/t3897.check index 244b83716f..244b83716f 100644 --- a/test/files/run/t3897.check +++ b/test/pending/run/t3897.check diff --git a/test/files/run/t3897/J_2.java b/test/pending/run/t3897/J_2.java index 178412dc92..178412dc92 100644 --- a/test/files/run/t3897/J_2.java +++ b/test/pending/run/t3897/J_2.java diff --git a/test/files/run/t3897/a_1.scala b/test/pending/run/t3897/a_1.scala index 4da959e2ac..4da959e2ac 100644 --- a/test/files/run/t3897/a_1.scala +++ b/test/pending/run/t3897/a_1.scala diff --git a/test/files/run/t3897/a_2.scala b/test/pending/run/t3897/a_2.scala index 4d9e59ef05..4d9e59ef05 100644 --- a/test/files/run/t3897/a_2.scala +++ b/test/pending/run/t3897/a_2.scala diff --git a/test/files/run/t5293-map.scala b/test/pending/run/t5293-map.scala index 2707aed07e..2707aed07e 100644 --- a/test/files/run/t5293-map.scala +++ b/test/pending/run/t5293-map.scala diff --git a/test/files/run/t5293.scala b/test/pending/run/t5293.scala index 01ead45d2a..01ead45d2a 100644 --- a/test/files/run/t5293.scala +++ b/test/pending/run/t5293.scala diff --git a/test/pending/run/t5695.check b/test/pending/run/t5695.check deleted file mode 100644 index d50069ab4f..0000000000 --- a/test/pending/run/t5695.check +++ /dev/null @@ -1,2 +0,0 @@ -.. -.. diff --git a/test/pending/run/t5695/part_1.scala b/test/pending/run/t5695/part_1.scala deleted file mode 100644 index b8e8f8e52f..0000000000 --- a/test/pending/run/t5695/part_1.scala +++ /dev/null @@ -1,12 +0,0 @@ -import language.experimental.macros -import scala.reflect.makro.Context - -object Defs { - - def mkInt = macro mkIntImpl - def mkIntImpl(c: Context): c.Expr[Any] = { - println(c.enclosingApplication) - c.reify{ 23 } - } - -} diff --git a/test/pending/run/t5695/part_2.scala b/test/pending/run/t5695/part_2.scala deleted file mode 100644 index d34219437d..0000000000 --- a/test/pending/run/t5695/part_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -import Defs._ - -object Test extends App { - - val i1 = mkInt - val i2 = identity(mkInt) - -} |