From e51207992f525ed9e32a7a9a39512b4d7e503c03 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 5 Jun 2007 15:57:59 +0000 Subject: deprecated &f, .f, requires. Added existential types. --- src/actors/scala/actors/Future.scala | 6 +- src/compiler/scala/tools/ant/FastScalac.scala | 2 +- src/compiler/scala/tools/ant/ScalaTool.scala | 18 +- src/compiler/scala/tools/ant/Scalac.scala | 16 +- src/compiler/scala/tools/ant/Scaladoc.scala | 14 +- .../scala/tools/nsc/CompilationUnits.scala | 2 +- src/compiler/scala/tools/nsc/CompilerCommand.scala | 4 +- src/compiler/scala/tools/nsc/Global.scala | 2 +- src/compiler/scala/tools/nsc/Interpreter.scala | 2 +- src/compiler/scala/tools/nsc/ScriptRunner.scala | 4 +- src/compiler/scala/tools/nsc/ast/TreeInfo.scala | 3 +- src/compiler/scala/tools/nsc/ast/Trees.scala | 23 +- .../scala/tools/nsc/ast/parser/Parsers.scala | 73 ++- .../scala/tools/nsc/ast/parser/Scanners.scala | 3 +- .../scala/tools/nsc/ast/parser/Tokens.scala | 3 +- .../scala/tools/nsc/ast/parser/TreeBuilder.scala | 4 +- .../tools/nsc/backend/icode/BasicBlocks.scala | 4 +- .../scala/tools/nsc/backend/icode/Checkers.scala | 6 +- .../nsc/backend/icode/ExceptionHandlers.scala | 2 +- .../scala/tools/nsc/backend/icode/GenICode.scala | 16 +- .../tools/nsc/backend/icode/Linearizers.scala | 10 +- .../scala/tools/nsc/backend/icode/Members.scala | 2 +- .../scala/tools/nsc/backend/icode/Opcodes.scala | 8 +- .../scala/tools/nsc/backend/icode/Primitives.scala | 2 +- .../scala/tools/nsc/backend/icode/Printers.scala | 4 +- .../scala/tools/nsc/backend/icode/TypeKinds.scala | 2 +- .../scala/tools/nsc/backend/icode/TypeStacks.scala | 2 +- .../backend/icode/analysis/CopyPropagation.scala | 6 +- .../backend/icode/analysis/TypeFlowAnalysis.scala | 4 +- .../scala/tools/nsc/backend/jvm/GenJVM.scala | 16 +- .../scala/tools/nsc/backend/msil/GenMSIL.scala | 16 +- .../nsc/backend/opt/DeadCodeElimination.scala | 2 +- .../scala/tools/nsc/backend/opt/Inliners.scala | 10 +- src/compiler/scala/tools/nsc/doc/DocDriver.scala | 10 +- .../scala/tools/nsc/doc/ModelExtractor.scala | 8 +- src/compiler/scala/tools/nsc/io/PlainFile.scala | 2 +- .../scala/tools/nsc/matching/CodeFactory.scala | 2 +- .../tools/nsc/matching/ParallelMatching.scala | 4 +- .../scala/tools/nsc/matching/PatternMatchers.scala | 2 +- .../scala/tools/nsc/matching/PatternNodes.scala | 2 +- .../scala/tools/nsc/matching/TransMatcher.scala | 5 +- .../scala/tools/nsc/symtab/AnnotationInfos.scala | 8 +- .../scala/tools/nsc/symtab/Definitions.scala | 6 +- src/compiler/scala/tools/nsc/symtab/Scopes.scala | 2 +- src/compiler/scala/tools/nsc/symtab/StdNames.scala | 1 + src/compiler/scala/tools/nsc/symtab/Symbols.scala | 16 +- src/compiler/scala/tools/nsc/symtab/Types.scala | 625 ++++++++++++++------- .../nsc/symtab/classfile/ClassfileParser.scala | 6 +- .../tools/nsc/symtab/classfile/PickleFormat.scala | 1 + .../scala/tools/nsc/symtab/classfile/Pickler.scala | 6 +- .../tools/nsc/symtab/classfile/UnPickler.scala | 3 + .../scala/tools/nsc/symtab/clr/TypeParser.scala | 8 +- .../scala/tools/nsc/transform/Constructors.scala | 2 +- .../scala/tools/nsc/transform/Erasure.scala | 6 +- .../scala/tools/nsc/transform/LambdaLift.scala | 2 +- .../scala/tools/nsc/transform/LiftCode.scala | 6 +- src/compiler/scala/tools/nsc/transform/Mixin.scala | 2 +- .../scala/tools/nsc/transform/SymbolReifier.scala | 2 + .../scala/tools/nsc/transform/TailCalls.scala | 8 +- .../scala/tools/nsc/transform/UnCurry.scala | 4 +- .../scala/tools/nsc/typechecker/Contexts.scala | 4 +- .../scala/tools/nsc/typechecker/EtaExpansion.scala | 2 +- .../scala/tools/nsc/typechecker/Infer.scala | 91 +-- .../scala/tools/nsc/typechecker/Namers.scala | 20 +- .../scala/tools/nsc/typechecker/RefChecks.scala | 6 +- .../tools/nsc/typechecker/SuperAccessors.scala | 4 +- .../tools/nsc/typechecker/SyntheticMethods.scala | 4 +- .../scala/tools/nsc/typechecker/Typers.scala | 187 +++--- .../scala/tools/nsc/typechecker/Variances.scala | 2 + src/library/scala/List.scala | 4 + src/library/scala/Seq.scala | 2 +- src/library/scala/Symbol.scala | 2 +- src/library/scala/collection/Map.scala | 2 +- src/library/scala/collection/SortedMap.scala | 2 +- .../scala/collection/immutable/TreeSet.scala | 4 +- src/library/scala/collection/jcl/Map.scala | 6 +- src/library/scala/collection/jcl/Tests.scala | 4 +- .../collection/mutable/DoubleLinkedList.scala | 3 +- .../collection/mutable/ObservableBuffer.scala | 4 +- .../scala/collection/mutable/ObservableMap.scala | 4 +- .../scala/collection/mutable/ObservableSet.scala | 4 +- .../scala/collection/mutable/Publisher.scala | 2 +- .../collection/mutable/SingleLinkedList.scala | 3 +- src/library/scala/io/BytePickle.scala | 2 +- src/library/scala/ref/Reference.scala | 2 +- .../scala/xml/parsing/ExternalSources.scala | 2 +- src/library/scala/xml/parsing/MarkupParser.scala | 4 +- 87 files changed, 838 insertions(+), 578 deletions(-) (limited to 'src') diff --git a/src/actors/scala/actors/Future.scala b/src/actors/scala/actors/Future.scala index 66f6e7d163..9020c7e971 100644 --- a/src/actors/scala/actors/Future.scala +++ b/src/actors/scala/actors/Future.scala @@ -94,17 +94,17 @@ object Futures { val reaction: PartialFunction[Any, unit] = new PartialFunction[Any, unit] { def isDefinedAt(msg: Any) = msg match { case TIMEOUT => true - case _ => partFuns exists (.isDefinedAt(msg)) + case _ => partFuns exists (_ isDefinedAt msg) } def apply(msg: Any): unit = msg match { case TIMEOUT => // do nothing case _ => { - val pfOpt = partFuns find (.isDefinedAt(msg)) + val pfOpt = partFuns find (_ isDefinedAt msg) val pf = pfOpt.get // succeeds always val Pair(idx, subres) = pf(msg) resultsMap(idx) = Some(subres) - val partFunsRest = partFuns filter (.!=(pf)) + val partFunsRest = partFuns filter (_ != pf) // wait on rest of partial functions if (partFunsRest.length > 0) awaitWith(partFunsRest) diff --git a/src/compiler/scala/tools/ant/FastScalac.scala b/src/compiler/scala/tools/ant/FastScalac.scala index 1fd5155c09..36a312001e 100644 --- a/src/compiler/scala/tools/ant/FastScalac.scala +++ b/src/compiler/scala/tools/ant/FastScalac.scala @@ -95,7 +95,7 @@ class FastScalac extends Scalac { trim( List(settings.log) map (s => if (s.value.isEmpty) "" else s.name + ":" + s.value)) - val args = (cmdOptions ::: (sourceFiles map (.toString()))).toArray + val args = (cmdOptions ::: (sourceFiles map (_.toString))).toArray try { nsc.CompileClient.main0(args) } catch { diff --git a/src/compiler/scala/tools/ant/ScalaTool.scala b/src/compiler/scala/tools/ant/ScalaTool.scala index 0a18098b74..f53363623c 100644 --- a/src/compiler/scala/tools/ant/ScalaTool.scala +++ b/src/compiler/scala/tools/ant/ScalaTool.scala @@ -51,7 +51,7 @@ class ScalaTool extends MatchingTask { abstract class PermissibleValue { val values: List[String] def isPermissible(value: String): Boolean = - (value == "") || values.exists(.startsWith(value)) + (value == "") || values.exists(_.startsWith(value)) } /** Defines valid values for the platforms property. */ @@ -222,7 +222,7 @@ class ScalaTool extends MatchingTask { * @returns The file as a file. */ private def getFile: File = if (file.isEmpty) error("Member 'file' is empty.") - else getProject().resolveFile(file.get.toString()) + else getProject().resolveFile(file.get.toString) /** Gets the value of the bootclasspath attribute in a Scala-friendly form. * @returns The boot class path as a list of files. */ @@ -232,7 +232,7 @@ class ScalaTool extends MatchingTask { /** Gets the value of the bootclasspath attribute in a Scala-friendly form. * @returns The boot class path as a list of files. */ private def getWinBootClasspath: String = - bootclasspath.map(.replace('/', '\\')). + bootclasspath.map(_.replace('/', '\\')). mkString("", ";", "") /** Gets the value of the classpath attribute in a Scala-friendly form. @@ -243,7 +243,7 @@ class ScalaTool extends MatchingTask { /** Gets the value of the classpath attribute in a Scala-friendly form. * @returns The class path as a list of files. */ private def getWinExtClasspath: String = - extclasspath.map(.replace('/', '\\')). + extclasspath.map(_.replace('/', '\\')). mkString("", ";", "") /** Gets the value of the classpath attribute in a Scala-friendly form. @@ -289,15 +289,15 @@ class ScalaTool extends MatchingTask { token.append(char) char = chars.next } - if (tokens.contains(token.toString())) - builder.append(tokens(token.toString())) - else if (token.toString() == "") + if (tokens.contains(token.toString)) + builder.append(tokens(token.toString)) + else if (token.toString == "") builder.append('@') else - builder.append("@" + token.toString() + "@") + builder.append("@" + token.toString + "@") } else builder.append(char) } - builder.toString() + builder.toString } private def writeFile(file: File, content: String) = diff --git a/src/compiler/scala/tools/ant/Scalac.scala b/src/compiler/scala/tools/ant/Scalac.scala index 64d7280455..f84536543a 100644 --- a/src/compiler/scala/tools/ant/Scalac.scala +++ b/src/compiler/scala/tools/ant/Scalac.scala @@ -74,7 +74,7 @@ class Scalac extends MatchingTask { abstract class PermissibleValue { val values: List[String] def isPermissible(value: String): Boolean = - (value == "") || values.exists(.startsWith(value)) + (value == "") || values.exists(_.startsWith(value)) } /** Defines valid values for the logging property. */ @@ -352,7 +352,7 @@ class Scalac extends MatchingTask { * @return The destination as a file. */ private def getDestination: File = if (destination.isEmpty) error("Member 'destination' is empty.") - else existing(getProject().resolveFile(destination.get.toString())) + else existing(getProject().resolveFile(destination.get.toString)) /** Gets the value of the sourcepath attribute in a * Scala-friendly form. @@ -406,7 +406,7 @@ class Scalac extends MatchingTask { * @return The same file. */ private def existing(file: File): File = { if (!file.exists()) - log("Element '" + file.toString() + "' does not exist.", + log("Element '" + file.toString + "' does not exist.", Project.MSG_WARN) file } @@ -468,13 +468,13 @@ class Scalac extends MatchingTask { (if (list.length > 1) "s: " else ": "), ", ", " " - ) + "to " + getDestination.toString() + ) + "to " + getDestination.toString ) else if (list.length > 0) log( "Compiling " + list.length + " source file" + (if (list.length > 1) "s" else "") + - (" to " + getDestination.toString()) + (" to " + getDestination.toString) ) else log("No files selected for compilation", Project.MSG_VERBOSE) @@ -483,7 +483,7 @@ class Scalac extends MatchingTask { } } yield { - log(originFile.toString(), Project.MSG_DEBUG) + log(originFile.toString, Project.MSG_DEBUG) nameToFile(originDir)(originFile) } @@ -520,7 +520,7 @@ class Scalac extends MatchingTask { log("Scalac params = '" + addParams + "'", Project.MSG_DEBUG) var args = if (addParams.trim() == "") Nil - else List.fromArray(addParams.trim().split(" ")).map(.trim()) + else List.fromArray(addParams.trim().split(" ")).map(_.trim()) while (!args.isEmpty) { val argsBuf = args if (args.head startsWith "-") { @@ -542,7 +542,7 @@ class Scalac extends MatchingTask { // Compiles the actual code val compiler = new Global(settings, reporter) try { - (new compiler.Run).compile(sourceFiles.map (.toString())) + (new compiler.Run).compile(sourceFiles.map (_.toString)) } catch { case exception: Throwable if (exception.getMessage ne null) => diff --git a/src/compiler/scala/tools/ant/Scaladoc.scala b/src/compiler/scala/tools/ant/Scaladoc.scala index eef194c8e0..997b9140df 100644 --- a/src/compiler/scala/tools/ant/Scaladoc.scala +++ b/src/compiler/scala/tools/ant/Scaladoc.scala @@ -76,7 +76,7 @@ class Scaladoc extends MatchingTask { abstract class PermissibleValue { val values: List[String] def isPermissible(value: String): Boolean = - (value == "") || values.exists(.startsWith(value)) + (value == "") || values.exists(_.startsWith(value)) } /** Defines valid values for the deprecation and @@ -372,7 +372,7 @@ class Scaladoc extends MatchingTask { */ private def getDestination: File = if (destination.isEmpty) error("Member 'destination' is empty.") - else existing(getProject().resolveFile(destination.get.toString())) + else existing(getProject().resolveFile(destination.get.toString)) /** Gets the value of the sourcepath attribute in a * Scala-friendly form. @@ -439,7 +439,7 @@ class Scaladoc extends MatchingTask { */ private def existing(file: File): File = { if (!file.exists()) - log("Element '" + file.toString() + "' does not exist.", + log("Element '" + file.toString + "' does not exist.", Project.MSG_WARN) file } @@ -500,7 +500,7 @@ class Scaladoc extends MatchingTask { log( "Documenting " + list.length + " source file" + (if (list.length > 1) "s" else "") + - (" to " + getDestination.toString()) + (" to " + getDestination.toString) ) else log("No files selected for documentation", Project.MSG_VERBOSE) @@ -508,7 +508,7 @@ class Scaladoc extends MatchingTask { list } } yield { - log(originFile.toString(), Project.MSG_DEBUG) + log(originFile.toString, Project.MSG_DEBUG) nameToFile(originDir)(originFile) } @@ -549,7 +549,7 @@ class Scaladoc extends MatchingTask { log("Scaladoc params = '" + addParams + "'", Project.MSG_DEBUG) var args = if (addParams.trim() == "") Nil - else List.fromArray(addParams.trim().split(" ")).map(.trim()) + else List.fromArray(addParams.trim().split(" ")).map(_.trim()) while (!args.isEmpty) { val argsBuf = args if (args.head startsWith "-") { @@ -571,7 +571,7 @@ class Scaladoc extends MatchingTask { val compiler = new Global(commandSettings, reporter) try { val run = new compiler.Run - run.compile(sourceFiles.map (.toString())) + run.compile(sourceFiles.map (_.toString)) object generator extends DocDriver { val global: compiler.type = compiler def settings = commandSettings diff --git a/src/compiler/scala/tools/nsc/CompilationUnits.scala b/src/compiler/scala/tools/nsc/CompilationUnits.scala index b45ce29a27..0d3dff42a8 100644 --- a/src/compiler/scala/tools/nsc/CompilationUnits.scala +++ b/src/compiler/scala/tools/nsc/CompilationUnits.scala @@ -10,7 +10,7 @@ import scala.tools.nsc.util.{FreshNameCreator,OffsetPosition,Position,SourceFile import scala.tools.nsc.io.AbstractFile import scala.collection.mutable.HashSet -trait CompilationUnits requires Global { +trait CompilationUnits { self: Global => /** One unit of compilation that has been submitted to the compiler. * It typically corresponds to a single file of source code. It includes diff --git a/src/compiler/scala/tools/nsc/CompilerCommand.scala b/src/compiler/scala/tools/nsc/CompilerCommand.scala index d246e05959..a84dbeb172 100644 --- a/src/compiler/scala/tools/nsc/CompilerCommand.scala +++ b/src/compiler/scala/tools/nsc/CompilerCommand.scala @@ -26,10 +26,10 @@ class CompilerCommand(arguments: List[String], val settings: Settings, def usageMsg: String = { // todo: print -X and -javadoc options only on demand val helpSyntaxColumnWidth: int = - Iterable.max(settings.allSettings map (. helpSyntax.length())) + Iterable.max(settings.allSettings map (_.helpSyntax.length)) def format(s: String): String = { val buf = new StringBuilder(s) - var i = s.length() + var i = s.length while (i < helpSyntaxColumnWidth) { buf.append(' '); i += 1 } buf.toString() } diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index d47d48d750..abb588970c 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -574,7 +574,7 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable error("can only compile one script at a time") val sources = filenames map ( if (settings.Xscript.value) - (x => ScriptRunner.wrappedScript(x, &getSourceFile)) + (x => ScriptRunner.wrappedScript(x, getSourceFile _)) else getSourceFile) compileSources(sources) diff --git a/src/compiler/scala/tools/nsc/Interpreter.scala b/src/compiler/scala/tools/nsc/Interpreter.scala index c93dcf2ff3..25649d8941 100644 --- a/src/compiler/scala/tools/nsc/Interpreter.scala +++ b/src/compiler/scala/tools/nsc/Interpreter.scala @@ -845,7 +845,7 @@ class Interpreter(val settings: Settings, out: PrintWriter) { def importsWildcard = trees.exists { case Import(_, selectors) => - selectors.map(._1).contains(nme.USCOREkw) + selectors.map(_._1).contains(nme.USCOREkw) case _ => false } diff --git a/src/compiler/scala/tools/nsc/ScriptRunner.scala b/src/compiler/scala/tools/nsc/ScriptRunner.scala index ed67d1b951..2f0a0fdd4c 100644 --- a/src/compiler/scala/tools/nsc/ScriptRunner.scala +++ b/src/compiler/scala/tools/nsc/ScriptRunner.scala @@ -174,7 +174,7 @@ object ScriptRunner { setting.value = CompileClient.absFileNames(setting.value) val compSettingNames = - (new Settings(error)).allSettings.map(.name) + (new Settings(error)).allSettings.map(_.name) val compSettings = settings.allSettings.filter(stg => @@ -235,7 +235,7 @@ object ScriptRunner { val reporter = new ConsoleReporter(settings) val compiler = new Global(settings, reporter) val cr = new compiler.Run - cr.compileSources(List(wrappedScript(scriptFile, &compiler.getSourceFile))) + cr.compileSources(List(wrappedScript(scriptFile, compiler.getSourceFile _))) (compiledPath, !reporter.hasErrors) } else { val compok = compileWithDaemon(settings, scriptFile) diff --git a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala index 40a7e26229..eef8aa406c 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala @@ -193,7 +193,8 @@ abstract class TreeInfo { def mayBeTypePat(tree: Tree): boolean = tree match { case CompoundTypeTree(Template(tps, _, List())) => tps exists mayBeTypePat case Annotated(_, tp) => mayBeTypePat(tp) - case AppliedTypeTree(constr, args) => mayBeTypePat(constr) || args.exists(.isInstanceOf[Bind]) + case AppliedTypeTree(constr, args) => + mayBeTypePat(constr) || args.exists(_.isInstanceOf[Bind]) case SelectFromTypeTree(tp, _) => mayBeTypePat(tp) case _ => false } diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala index 90009ac9cd..f48c389646 100644 --- a/src/compiler/scala/tools/nsc/ast/Trees.scala +++ b/src/compiler/scala/tools/nsc/ast/Trees.scala @@ -348,7 +348,7 @@ trait Trees { def DefDef(sym: Symbol, mods: Modifiers, rhs: List[List[Symbol]] => Tree): DefDef = { val vparamss = syntheticParams(sym, sym.tpe) - DefDef(sym, mods, vparamss map (.map(ValDef)), rhs(vparamss)) + DefDef(sym, mods, vparamss map (_.map(ValDef)), rhs(vparamss)) } def DefDef(sym: Symbol, rhs: List[List[Symbol]] => Tree): DefDef = @@ -460,13 +460,13 @@ trait Trees { def Template(parents: List[Tree], self: ValDef, constrMods: Modifiers, vparamss: List[List[ValDef]], argss: List[List[Tree]], body: List[Tree]): Template = { /** Add constructor to template */ var vparamss1 = - vparamss map (.map (vd => { + vparamss map (vps => vps.map { vd => val ret = ValDef(Modifiers(vd.mods.flags & IMPLICIT | PARAM) withAnnotations vd.mods.annotations, vd.name, vd.tpt.duplicate, EmptyTree).setPos(vd.pos) if (inIDE && vd.symbol != NoSymbol) ret.symbol = vd.symbol ret - })) + }) val (vdefs, rest) = body span treeInfo.isPreSuper val (lvdefs, gvdefs) = List.unzip { vdefs map { @@ -728,6 +728,9 @@ trait Trees { case class WildcardTypeTree(lo: Tree, hi: Tree) extends TypTree + case class ExistentialTypeTree(tpt: Tree, whereClauses: List[Tree]) + extends TypTree + /* A standard pattern match case EmptyTree => case PackageDef(name, stats) => @@ -818,6 +821,8 @@ trait Trees { // tpt[args] case WildcardTypeTree(lo, hi) => (eliminated by uncurry) // todo: get rid of that! + case ExistentialTypeTree(tpt, whereClauses) => + */ abstract class TreeCopier { @@ -865,6 +870,7 @@ trait Trees { def CompoundTypeTree(tree: Tree, templ: Template): CompoundTypeTree def AppliedTypeTree(tree: Tree, tpt: Tree, args: List[Tree]): AppliedTypeTree def WildcardTypeTree(tree: Tree, lo: Tree, hi: Tree): WildcardTypeTree + def ExistentialTypeTree(tree: Tree, tpt: Tree, whereClauses: List[Tree]): ExistentialTypeTree } class StrictTreeCopier extends TreeCopier { @@ -956,6 +962,8 @@ trait Trees { new AppliedTypeTree(tpt, args).copyAttrs(tree) def WildcardTypeTree(tree: Tree, lo: Tree, hi: Tree) = new WildcardTypeTree(lo, hi).copyAttrs(tree) + def ExistentialTypeTree(tree: Tree, tpt: Tree, whereClauses: List[Tree]) = + new ExistentialTypeTree(tpt, whereClauses).copyAttrs(tree) } class LazyTreeCopier(copy: TreeCopier) extends TreeCopier { @@ -1180,6 +1188,11 @@ trait Trees { if (lo0 == lo) && (hi0 == hi) => t case _ => copy.WildcardTypeTree(tree, lo, hi) } + def ExistentialTypeTree(tree: Tree, tpt: Tree, whereClauses: List[Tree]) = tree match { + case t @ ExistentialTypeTree(tpt0, whereClauses0) + if (tpt0 == tpt) && (whereClauses0 == whereClauses) => t + case _ => copy.ExistentialTypeTree(tree, tpt, whereClauses) + } } abstract class Transformer { @@ -1296,6 +1309,8 @@ trait Trees { copy.AppliedTypeTree(tree, transform(tpt), transformTrees(args)) case WildcardTypeTree(lo, hi) => copy.WildcardTypeTree(tree, transform(lo), transform(hi)) + case ExistentialTypeTree(tpt, whereClauses) => + copy.ExistentialTypeTree(tree, transform(tpt), transformTrees(whereClauses)) } def transformTrees(trees: List[Tree]): List[Tree] = @@ -1440,6 +1455,8 @@ trait Trees { traverse(tpt); traverseTrees(args) case WildcardTypeTree(lo, hi) => traverse(lo); traverse(hi) + case ExistentialTypeTree(tpt, whereClauses) => + traverse(tpt); traverseTrees(whereClauses) } def traverseTrees(trees: List[Tree]): unit = diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 3637a8f050..a6fccb50c2 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -127,6 +127,11 @@ trait Parsers { */ var implicitParams: List[ValDef] = Nil + /** The wildcards introduced by `_' in the current type. + * Parameters appear in reverse order + */ + var wildcards: List[AbsTypeDef] = Nil + /** this is the general parse method */ def parse(): Tree = { @@ -618,12 +623,10 @@ trait Parsers { /** RequiresTypedOpt ::= [requires AnnotType] */ def requiresTypeOpt(): Tree = - if (inToken == COLON | inToken == REQUIRES) { - if (inToken == COLON) - warning("`:' has been deprecated; use `requires' instead") + if (inToken == REQUIRES) { + warning("`requires T' has been deprecated; use `{ self: T => ...' instead") inNextToken; annotType(false) - } - else TypeTree() + } else TypeTree() /** Types ::= Type {`,' Type} * ArgTypePats ::= ArgTypePat {`,' ArgTypePat} @@ -645,32 +648,63 @@ trait Parsers { private final val LeftOp = 1 // left associative private final val RightOp = 2 // right associative - /** Type ::= InfixType [`=>' Type] - * | `(' [`=>' Type] `)' `=>' Type - * XXX: Hook for IDE. + /** GlobalType ::= Type + */ + def globalTyp(): Tree = { + val savedWildcards = wildcards + wildcards = List() + var t = typ() + if (!wildcards.isEmpty) t = ExistentialTypeTree(t, wildcards) + wildcards = savedWildcards + t + } + + /** Type ::= Type1 [where `{' {WhereClause} `}'] */ def typ(): Tree = { + val t = typ1() + if (inToken == FORSOME) { + atPos(inSkipToken) { + val whereClauses = refinement() + for (wc <- whereClauses) { + wc match { + case AbsTypeDef(_, _, _, _, _) | ValDef(_, _, _, EmptyTree) => + ; + case _ => + syntaxError(wc.pos, "not a legal where clause", false) + } + } + ExistentialTypeTree(t, whereClauses) + } + } else t + } + + /** Type1 ::= InfixType [`=>' Type1] + * | `(' [`=>' Type] `)' `=>' Type1 + * XXX: Hook for IDE. + */ + def typ1(): Tree = { val t = if (inToken == LPAREN) { val pos = inSkipToken if (inToken == RPAREN) { inNextToken - atPos(accept(ARROW)) { makeFunctionTypeTree(List(), typ()) } + atPos(accept(ARROW)) { makeFunctionTypeTree(List(), typ1()) } } else if (inToken == ARROW) { inNextToken - val t0 = typ() + val t0 = typ1() accept(RPAREN) - atPos(accept(ARROW)) { makeByNameFunctionTypeTree(t0, typ()) } + atPos(accept(ARROW)) { makeByNameFunctionTypeTree(t0, typ1()) } } else { val ts = types(false) accept(RPAREN) - if (inToken == ARROW) atPos(inSkipToken) { makeFunctionTypeTree(ts, typ()) } + if (inToken == ARROW) atPos(inSkipToken) { makeFunctionTypeTree(ts, typ1()) } else infixTypeRest(pos, makeTupleType(ts, true), false, FirstOp) } } else { infixType(false, FirstOp) } - if (inToken == ARROW) atPos(inSkipToken) { makeFunctionTypeTree(List(t), typ()) } + if (inToken == ARROW) atPos(inSkipToken) { makeFunctionTypeTree(List(t), typ1()) } else t } @@ -856,8 +890,8 @@ trait Parsers { * | Expr1 * ResultExpr ::= (Bindings | Id `:' CompoundType) `=>' Block * | Expr1 - * Expr1 ::= if `(' Expr `)' {nl} Expr [semi] else Expr] - * | try `{' block `}' [catch `{' caseClauses `}'] [finally Expr] + * Expr1 ::= if `(' Expr `)' {nl} Expr [[semi] else Expr] + * | try `{' Block `}' [catch `{' CaseClauses `}'] [finally Expr] * | while `(' Expr `)' {nl} Expr * | do Expr [semi] while `(' Expr `)' * | for (`(' Enumerators `)' | '{' Enumerators '}') {nl} [yield] Expr @@ -865,10 +899,8 @@ trait Parsers { * | return [Expr] * | [SimpleExpr `.'] Id `=' Expr * | SimpleExpr1 ArgumentExprs `=' Expr - * | `.' SimpleExpr * | PostfixExpr Ascription * | PostfixExpr match `{' CaseClauses `}' - * | `.' Id {`.' Id | TypeArgs | ArgumentExprs} * Bindings ::= `(' [Binding {`,' Binding}] `)' * Binding ::= Id [`:' Type] * Ascription ::= `:' CompoundType @@ -956,7 +988,7 @@ trait Parsers { Throw(expr()) } case DOT => - //todo: deprecate + warning("`.f' has been deprecated; use `_.f' instead") atPos(inSkipToken) { if (isIdent) { makeDotClosure(stripParens(simpleExpr())) @@ -1066,6 +1098,7 @@ trait Parsers { val name = unaryOp() atPos(pos) { Select(stripParens(simpleExpr()), name) } } else if (isIdent && inName == AMP) { + warning("`&f' has been deprecated; use `f _' instead") val pos = inCurrentPos val name = ident() atPos(pos) { Typed(stripParens(simpleExpr()), Function(List(), EmptyTree)) } @@ -1218,7 +1251,7 @@ trait Parsers { * | val Pattern1 `=' Expr */ def enumerators(): List[Enumerator] = { - val newStyle = inToken != VAL + val newStyle = inToken != VAL // todo: deprecate old style val enums = new ListBuffer[Enumerator] generator(enums, false) while (isStatSep) { @@ -1940,7 +1973,7 @@ trait Parsers { atPos(inSkipToken) { if (inToken == THIS) { inNextToken - val vparamss = paramClauses(nme.CONSTRUCTOR, implicitClassViews map (.duplicate), false) + val vparamss = paramClauses(nme.CONSTRUCTOR, implicitClassViews map (_.duplicate), false) newLineOptWhenFollowedBy(LBRACE) val rhs = if (inToken == LBRACE) constrBlock(vparamss) else { accept(EQUALS); constrExpr(vparamss) } diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala index 045d60c005..a68188c3d7 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala @@ -120,6 +120,7 @@ trait Scanners { enterKeyword(nme.FINALkw, FINAL) enterKeyword(nme.FINALLYkw, FINALLY) enterKeyword(nme.FORkw, FOR) + enterKeyword(nme.FORSOMEkw, FORSOME) enterKeyword(nme.IFkw, IF) enterKeyword(nme.IMPLICITkw, IMPLICIT) enterKeyword(nme.IMPORTkw, IMPORT) @@ -675,7 +676,7 @@ trait Scanners { } def inFirstOfStat(token: int) = token match { - case EOF | CASE | CATCH | ELSE | EXTENDS | FINALLY | MATCH | REQUIRES | WITH | YIELD | + case EOF | CASE | CATCH | ELSE | EXTENDS | FINALLY | FORSOME | MATCH | REQUIRES | WITH | YIELD | COMMA | SEMI | NEWLINE | NEWLINES | DOT | USCORE | COLON | EQUALS | ARROW | LARROW | SUBTYPE | VIEWBOUND | SUPERTYPE | HASH | // todo: add LBRACKET RPAREN | RBRACKET | RBRACE => diff --git a/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala b/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala index 4803fbfcce..49a497a669 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala @@ -72,7 +72,8 @@ object Tokens { final val WHILE = 56 final val RETURN = 57 final val MATCH = 58 - final val REQUIRES = 59 + final val FORSOME = 59 + final val REQUIRES = 60 def isKeyword(code : Int) = code >= IF && code <= REQUIRES diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala index 333005fc54..b3ad88caef 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala @@ -300,7 +300,7 @@ abstract class TreeBuilder { ValFrom(pos, pat, makeCombination(nme.filter, rhs, pat.duplicate, test)) :: rest, body) case ValFrom(pos, pat, rhs) :: rest => - val valeqs = rest.take(definitions.MaxTupleArity - 1).takeWhile(.isInstanceOf[ValEq]); + val valeqs = rest.take(definitions.MaxTupleArity - 1).takeWhile(_.isInstanceOf[ValEq]); assert(!valeqs.isEmpty) val rest1 = rest.drop(valeqs.length) val pats = valeqs map { case ValEq(_, pat, _) => pat } @@ -408,7 +408,7 @@ abstract class TreeBuilder { val matchExpr = atPos(pat1.pos){ Match( makeUnchecked(rhs), - List(CaseDef(pat1, EmptyTree, makeTupleTerm(vars map (._1) map Ident, true)))) + List(CaseDef(pat1, EmptyTree, makeTupleTerm(vars map (_._1) map Ident, true)))) } vars match { case List() => diff --git a/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala b/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala index dc38fef872..cd2d56fb9e 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala @@ -380,7 +380,7 @@ trait BasicBlocks { // TODO: Take care of exception handlers! def successors : List[BasicBlock] = if (isEmpty) Nil else { var res = lastInstruction match { - case JUMP (where) => List(where) + case JUMP (whereto) => List(whereto) case CJUMP(success, failure, _, _) => success :: failure :: Nil case CZJUMP(success, failure, _, _) => success :: failure :: Nil case SWITCH(_,labels) => labels @@ -404,7 +404,7 @@ trait BasicBlocks { * in different code 'chunks' than the rest of the method. */ def predecessors: List[BasicBlock] = { - preds = code.blocks.elements.filter (.successors.contains(this)).toList + preds = code.blocks.elements.filter (_.successors.contains(this)).toList preds } diff --git a/src/compiler/scala/tools/nsc/backend/icode/Checkers.scala b/src/compiler/scala/tools/nsc/backend/icode/Checkers.scala index 97f42e12a8..cf8e14819f 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/Checkers.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/Checkers.scala @@ -479,9 +479,9 @@ abstract class Checkers { checkBool(labels forall (b => code.blocks contains b), "Switch target cannot be found in code.") - case JUMP(where) => - checkBool(code.blocks contains where, - "Jump to non-existant block " + where) + case JUMP(whereto) => + checkBool(code.blocks contains whereto, + "Jump to non-existant block " + whereto) case CJUMP(success, failure, cond, kind) => checkBool(code.blocks contains success, diff --git a/src/compiler/scala/tools/nsc/backend/icode/ExceptionHandlers.scala b/src/compiler/scala/tools/nsc/backend/icode/ExceptionHandlers.scala index 43f6a8d3dd..86be9019e0 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/ExceptionHandlers.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/ExceptionHandlers.scala @@ -17,7 +17,7 @@ import scala.collection.mutable.HashSet; * all our handlers will catch `Throwable' and rely on proper ordering * in the generated code to preserve nesting. */ -trait ExceptionHandlers requires ICodes { +trait ExceptionHandlers { self: ICodes => import global.{Symbol, NoSymbol}; class ExceptionHandler(val method: IMethod, val label: String, val cls: Symbol) { diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala index 69c9008e38..408d49b940 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala @@ -197,7 +197,7 @@ abstract class GenICode extends SubComponent { private def genLoad(tree: Tree, ctx: Context, expectedType: TypeKind): Context = { var generatedType = expectedType if (settings.debug.value) - log("at line: " + (tree.pos).line.map(.toString).get(tree.pos.toString)) + log("at line: " + (tree.pos).line.map(_.toString).get(tree.pos.toString)) /** * Generate code for primitive arithmetic operations. @@ -387,7 +387,7 @@ abstract class GenICode extends SubComponent { label.patch(ctx.method.code) case None => - ctx1.labels += tree.symbol -> (new Label(tree.symbol) anchor ctx1.bb setParams (params map (.symbol))); + ctx1.labels += tree.symbol -> (new Label(tree.symbol) anchor ctx1.bb setParams (params map (_.symbol))); ctx.method.addLocals(params map (p => new Local(p.symbol, toTypeKind(p.symbol.info), false))); if (settings.debug.value) log("Adding label " + tree.symbol); @@ -1231,7 +1231,7 @@ abstract class GenICode extends SubComponent { case LabelDef(name, params, rhs) => if (!ctx.labels.contains(tree.symbol)) { - ctx.labels += tree.symbol -> (new Label(tree.symbol) setParams(params map (.symbol))); + ctx.labels += tree.symbol -> (new Label(tree.symbol) setParams(params map (_.symbol))); ctx.method.addLocals(params map (p => new Local(p.symbol, toTypeKind(p.symbol.info), false))); } super.traverse(rhs) @@ -1574,8 +1574,8 @@ abstract class GenICode extends SubComponent { log("Removing block: " + block) method.code.removeBlock(block) for (e <- method.exh) { - e.covered = e.covered filter (.!=(block)) - e.blocks = e.blocks filter (.!=(block)) + e.covered = e.covered filter (_ != block) + e.blocks = e.blocks filter (_ != block) if (e.startBlock eq block) e setStartBlock cont; } @@ -1654,7 +1654,7 @@ abstract class GenICode extends SubComponent { val tree = copy.LabelDef(t, name1, params, transform(rhs)) tree.symbol = labels(t.symbol) - ctx.labels += tree.symbol -> (new Label(tree.symbol) setParams(params map (.symbol))); + ctx.labels += tree.symbol -> (new Label(tree.symbol) setParams(params map (_.symbol))); ctx.method.addLocals(params map (p => new Local(p.symbol, toTypeKind(p.symbol.info), false))); tree @@ -1962,7 +1962,7 @@ abstract class GenICode extends SubComponent { } val map = substMap - code traverse (.subst(map)) + code traverse (_.subst(map)) } /** @@ -2019,7 +2019,7 @@ abstract class GenICode extends SubComponent { label.addCallingInstruction(this); } - case class PJUMP(where: Label) extends PseudoJUMP(where) + case class PJUMP(whereto: Label) extends PseudoJUMP(whereto) case class PCJUMP(success: Label, failure: Label, cond: TestOp, kind: TypeKind) extends PseudoJUMP(success) { diff --git a/src/compiler/scala/tools/nsc/backend/icode/Linearizers.scala b/src/compiler/scala/tools/nsc/backend/icode/Linearizers.scala index dd60378bcd..cdc1023f88 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/Linearizers.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/Linearizers.scala @@ -10,7 +10,7 @@ package scala.tools.nsc.backend.icode; import scala.tools.nsc.ast._; import scala.collection.mutable.{Stack, HashSet}; -trait Linearizers requires ICodes { +trait Linearizers { self: ICodes => import opcodes._; abstract class Linearizer { @@ -38,7 +38,7 @@ trait Linearizers requires ICodes { blocks = Nil; run { - worklist ++= (m.exh map (.startBlock)); + worklist ++= (m.exh map (_.startBlock)); worklist.push(b); } @@ -62,8 +62,8 @@ trait Linearizers requires ICodes { if (b.size > 0) { add(b); b.lastInstruction match { - case JUMP(where) => - add(where); + case JUMP(whereto) => + add(whereto); case CJUMP(success, failure, _, _) => add(success); add(failure); @@ -154,7 +154,7 @@ trait Linearizers requires ICodes { if (m.code.startBlock.predecessors eq Nil) blocks else - m.code.startBlock :: (blocks.remove(.==(m.code.startBlock))) + m.code.startBlock :: (blocks.remove(_ == m.code.startBlock)) } def linearizeAt(m: IMethod, start: BasicBlock): List[BasicBlock] = { diff --git a/src/compiler/scala/tools/nsc/backend/icode/Members.scala b/src/compiler/scala/tools/nsc/backend/icode/Members.scala index d3ecef16a8..a742956a48 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/Members.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/Members.scala @@ -15,7 +15,7 @@ import scala.{Symbol => scala_Symbol}; import scala.tools.nsc.symtab.Flags; -trait Members requires ICodes { +trait Members { self: ICodes => import global._; /** diff --git a/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala b/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala index db89fe4912..109c6ef8a9 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala @@ -30,7 +30,7 @@ import scala.tools.nsc.util.{Position,NoPosition}; case IS_INSTANCE(tpe) => case CHECK_CAST(tpe) => case SWITCH(tags, labels) => - case JUMP(where) => + case JUMP(whereto) => case CJUMP(success, failure, cond, kind) => case CZJUMP(success, failure, cond, kind) => case RETURN(kind) => @@ -51,7 +51,7 @@ import scala.tools.nsc.util.{Position,NoPosition}; * erased types of Scala and references Symbols to refer named entities * in the source files. */ -trait Opcodes requires ICodes { +trait Opcodes { self: ICodes => import global.{Symbol, NoSymbol, Type, Name, Constant}; /** This class represents an instruction of the intermediate code. @@ -420,9 +420,9 @@ trait Opcodes requires ICodes { * Stack: ... * ->: ... */ - case class JUMP(where: BasicBlock) extends Instruction { + case class JUMP(whereto: BasicBlock) extends Instruction { /** Returns a string representation of this instruction */ - override def toString(): String ="JUMP "+where.label; + override def toString(): String ="JUMP "+whereto.label; override def consumed = 0; override def produced = 0; diff --git a/src/compiler/scala/tools/nsc/backend/icode/Primitives.scala b/src/compiler/scala/tools/nsc/backend/icode/Primitives.scala index c07b7b0829..3f07856dce 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/Primitives.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/Primitives.scala @@ -9,7 +9,7 @@ package scala.tools.nsc.backend.icode; import java.io.PrintWriter; -trait Primitives requires ICodes { +trait Primitives { self: ICodes => /** This class represents a primitive operation. */ class Primitive { diff --git a/src/compiler/scala/tools/nsc/backend/icode/Printers.scala b/src/compiler/scala/tools/nsc/backend/icode/Printers.scala index 97fb9c2d21..37139e0ed4 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/Printers.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/Printers.scala @@ -12,8 +12,8 @@ import java.io.PrintWriter; import scala.tools.nsc.util.Position; import scala.tools.nsc.symtab.Flags; -trait Printers requires ICodes { -// val global: Global; +trait Printers { self: ICodes => + // val global: Global; import global._; import global.icodes.opcodes._; import global.icodes._; diff --git a/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala b/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala index f9476842a0..5ba58a0b56 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala @@ -25,7 +25,7 @@ package scala.tools.nsc.backend.icode import scala.collection.mutable.{Map, HashMap} -trait TypeKinds requires ICodes { +trait TypeKinds { self: ICodes => import global._ /** This class represents a type kind. Type kinds diff --git a/src/compiler/scala/tools/nsc/backend/icode/TypeStacks.scala b/src/compiler/scala/tools/nsc/backend/icode/TypeStacks.scala index 1639b9fd12..53a1c13dc8 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/TypeStacks.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/TypeStacks.scala @@ -12,7 +12,7 @@ package scala.tools.nsc.backend.icode * @author Iulian Dragos * @version 1.0 */ -trait TypeStacks requires ICodes { +trait TypeStacks { self: ICodes => import opcodes._ import global.{Symbol, Type, definitions} diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala index 2a13a37cfc..eda889ae76 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala @@ -175,7 +175,7 @@ abstract class CopyPropagation { init { worklist += m.code.startBlock - worklist ++= (m.exh map (.startBlock)) + worklist ++= (m.exh map (_.startBlock)) m.code.blocks.foreach { b => in(b) = lattice.bottom out(b) = lattice.bottom @@ -340,7 +340,7 @@ abstract class CopyPropagation { case SWITCH(tags, labels) => out.stack = out.stack.drop(1) - case JUMP(where) => + case JUMP(whereto) => () case CJUMP(success, failure, cond, kind) => @@ -467,7 +467,7 @@ abstract class CopyPropagation { // this relies on having the same order in paramAccessors and // the arguments on the stack. It should be the same! for (val (p, i) <- paramAccessors.zipWithIndex) { -// assert(p.tpe == ctor.tpe.paramTypes(i), "In: " + ctor.fullNameString + " having: " + (paramAccessors map (.tpe))+ " vs. " + ctor.tpe.paramTypes) +// assert(p.tpe == ctor.tpe.paramTypes(i), "In: " + ctor.fullNameString + " having: " + (paramAccessors map (_.tpe))+ " vs. " + ctor.tpe.paramTypes) if (p.tpe == ctor.tpe.paramTypes(i)) bindings += p -> values.head; values = values.tail; diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala index e7f4738b5e..01167c2986 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala @@ -121,7 +121,7 @@ abstract class TypeFlowAnalysis { init { worklist += m.code.startBlock - worklist ++= (m.exh map (.startBlock)) + worklist ++= (m.exh map (_.startBlock)) m.code.blocks.foreach { b => in(b) = typeFlowLattice.bottom out(b) = typeFlowLattice.bottom @@ -289,7 +289,7 @@ abstract class TypeFlowAnalysis { case SWITCH(tags, labels) => stack.pop - case JUMP(where) => + case JUMP(whereto) => () case CJUMP(success, failure, cond, kind) => diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index 2a54f0eb6b..bc8f4b1dd9 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -301,7 +301,7 @@ abstract class GenJVM extends SubComponent { } def addAnnotations(jmember: JMember, attributes: List[AnnotationInfo]): Unit = { - val toEmit = attributes.filter(.isConstant) + val toEmit = attributes.filter(_.isConstant) if (toEmit.isEmpty) return @@ -317,7 +317,7 @@ abstract class GenJVM extends SubComponent { for (attr @ AnnotationInfo(tpe, _, _) <- attrs; if attr.isConstant; if tpe.symbol isNonBottomSubClass definitions.ClassfileAnnotationClass) yield attr; - if (attributes.forall(.isEmpty)) return; + if (attributes.forall(_.isEmpty)) return; val buf: ByteBuffer = ByteBuffer.allocate(2048) @@ -407,8 +407,8 @@ abstract class GenJVM extends SubComponent { jmethod = jclass.addNewMethod(flags, javaName(m.symbol), resTpe, - javaTypes(m.params map (.kind)), - javaNames(m.params map (.sym))); + javaTypes(m.params map (_.kind)), + javaNames(m.params map (_.sym))); if (m.symbol.hasFlag(Flags.BRIDGE)) jmethod.addAttribute(fjbgContext.JOtherAttribute(jclass, jmethod, "Bridge", @@ -455,7 +455,7 @@ abstract class GenJVM extends SubComponent { addExceptionsAttribute(m.symbol) addAnnotations(jmethod, m.symbol.attributes) - addParamAnnotations(m.params.map(.sym.attributes)) + addParamAnnotations(m.params.map(_.sym.attributes)) } def isClosureApply(sym: Symbol): Boolean = { @@ -850,9 +850,9 @@ abstract class GenJVM extends SubComponent { labels(branches.last), MIN_SWITCH_DENSITY); - case JUMP(where) => - if (nextBlock != where) - jcode.emitGOTO_maybe_W(labels(where), false); // default to short jumps + case JUMP(whereto) => + if (nextBlock != whereto) + jcode.emitGOTO_maybe_W(labels(whereto), false); // default to short jumps case CJUMP(success, failure, cond, kind) => kind match { diff --git a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala index 2240f5db38..fc95c4bfd9 100644 --- a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala +++ b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala @@ -325,7 +325,7 @@ abstract class GenMSIL extends SubComponent { val args: Array[Byte] = getAttributeArgs( - annArgs map (.constant.get), + annArgs map (_.constant.get), (for((n,v) <- nvPairs) yield (n, v.constant.get))) member.SetCustomAttribute(constr, args) } @@ -715,7 +715,7 @@ abstract class GenMSIL extends SubComponent { cb.basicBlocks = bb :: cb.basicBlocks } override def close() { - blocks.foreach(.close) + blocks.foreach(_.close) blocks = blocks.reverse closed = true } @@ -790,7 +790,7 @@ abstract class GenMSIL extends SubComponent { } override def close() { tryBlock.close - catchBlocks.foreach(.close) + catchBlocks.foreach(_.close) catchBlocks = catchBlocks.reverse finallyBlock.close closed = true @@ -920,8 +920,8 @@ abstract class GenMSIL extends SubComponent { def replaceOutJumps(blocks: List[BasicBlock], leaving: List[(BasicBlock, List[BasicBlock])], exh: ExceptionHandler): (List[BasicBlock], Option[BasicBlock]) = { def replaceJump(block: BasicBlock, from: BasicBlock, to: BasicBlock) = block.lastInstruction match { - case JUMP(where) => - //assert(from == where) + case JUMP(whereto) => + //assert(from == whereto) block.replaceInstruction(block.lastInstruction, JUMP(to)) case CJUMP(success, failure, cond, kind) => if (from == success) @@ -1522,9 +1522,9 @@ abstract class GenMSIL extends SubComponent { mcode.Emit(OpCodes.Br, defaultTarget) - case JUMP(where) => - if (nextBlock != where && !omitJumpBlocks.contains(currentBlock)) - mcode.Emit(OpCodes.Br, labels(where)) + case JUMP(whereto) => + if (nextBlock != whereto && !omitJumpBlocks.contains(currentBlock)) + mcode.Emit(OpCodes.Br, labels(whereto)) case CJUMP(success, failure, cond, kind) => diff --git a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala index 7eb29b3722..accd7d5aec 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala @@ -260,7 +260,7 @@ abstract class DeadCodeElimination extends SubComponent { } else { val stack = rdef.in(bb)._2 assert(stack.length >= m, "entry stack is too small, expected: " + m + " found: " + stack) - stack.take(m) flatMap (.toList) + stack.take(m) flatMap (_.toList) } /** Is 'sym' a side-effecting method? TODO: proper analysis. */ diff --git a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala index c8dbfc85f0..4f5fce2258 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala @@ -76,7 +76,7 @@ abstract class Inliners extends SubComponent { val a = new analysis.MethodTFA(callee) /* The exception handlers that are active at the current block. */ - val activeHandlers = caller.exh.filter(.covered.contains(block)) + val activeHandlers = caller.exh.filter(_.covered.contains(block)) /* Map 'original' blocks to the ones inlined in the caller. */ val inlinedBlock: Map[BasicBlock, BasicBlock] = new HashMap @@ -106,7 +106,7 @@ abstract class Inliners extends SubComponent { /** Add a new block in the current context. */ def newBlock = { val b = caller.code.newBlock - activeHandlers.foreach (.addCoveredBlock(b)) + activeHandlers.foreach (_.addCoveredBlock(b)) if (retVal ne null) b.varsInScope += retVal b.varsInScope += inlinedThis b.varsInScope ++= varsInScope @@ -147,8 +147,8 @@ abstract class Inliners extends SubComponent { case THIS(clasz) => LOAD_LOCAL(inlinedThis); - case JUMP(where) => - JUMP(inlinedBlock(where)); + case JUMP(whereto) => + JUMP(inlinedBlock(whereto)); case CJUMP(success, failure, cond, kind) => CJUMP(inlinedBlock(success), inlinedBlock(failure), cond, kind); @@ -422,7 +422,7 @@ abstract class Inliners extends SubComponent { if (stack.length > (1 + callee.symbol.info.paramTypes.length) && callee.exh != Nil) { -// (callee.exh exists (.covered.contains(callee.code.startBlock)))) { +// (callee.exh exists (_.covered.contains(callee.code.startBlock)))) { if (settings.debug.value) log("method " + callee.symbol + " is used on a non-empty stack with finalizer."); false } else diff --git a/src/compiler/scala/tools/nsc/doc/DocDriver.scala b/src/compiler/scala/tools/nsc/doc/DocDriver.scala index f20afd405e..3ef6d0ca28 100644 --- a/src/compiler/scala/tools/nsc/doc/DocDriver.scala +++ b/src/compiler/scala/tools/nsc/doc/DocDriver.scala @@ -37,7 +37,7 @@ abstract class DocDriver extends ModelFrames with ModelToXML { def g(pkg: Package, clazz: ClassOrObject) { allClasses(pkg) += clazz; - clazz.decls.map(._2).foreach { + clazz.decls.map(_._2).foreach { case clazz : ClassOrObject => g(pkg, clazz) case _ => } @@ -71,7 +71,7 @@ abstract class DocDriver extends ModelFrames with ModelToXML { object organized extends jcl.LinkedHashMap[(List[String],Boolean),List[ClassOrObject]] { override def default(key : (List[String],Boolean)) = Nil; classes.foreach(cls => { - val path = cls.path.map(.name); + val path = cls.path.map(_.name); this((path,cls.isInstanceOf[Clazz])) = cls :: this((path,cls.isInstanceOf[Clazz])); }); } @@ -81,8 +81,8 @@ abstract class DocDriver extends ModelFrames with ModelToXML { def navLabel = null; // "root-page" // override protected def navSuffix = ".html"; override def optional(cls : ClassOrObject) : NodeSeq = { - val path = cls.path.map(.name); - val key = (cls.path.map(.name), cls.isInstanceOf[Clazz]); + val path = cls.path.map(_.name); + val key = (cls.path.map(_.name), cls.isInstanceOf[Clazz]); assert(!organized(key).isEmpty); (if (!organized(key).tail.isEmpty) Text(" (" +{ //Console.println("CONFLICT: " + path + " " + organized(key)); @@ -157,7 +157,7 @@ abstract class DocDriver extends ModelFrames with ModelToXML {
Direct Known Subclasses:
{symbols.mkXML("",", ","")(cls => { - aref(urlFor(cls.sym), cls.path.map(.name).mkString("",".","")); + aref(urlFor(cls.sym), cls.path.map(_.name).mkString("",".","")); })}

; case None => diff --git a/src/compiler/scala/tools/nsc/doc/ModelExtractor.scala b/src/compiler/scala/tools/nsc/doc/ModelExtractor.scala index 44c17e4b74..40a998be5a 100644 --- a/src/compiler/scala/tools/nsc/doc/ModelExtractor.scala +++ b/src/compiler/scala/tools/nsc/doc/ModelExtractor.scala @@ -208,7 +208,7 @@ trait ModelExtractor { trait ClassOrObject extends Entity { def path : List[ClassOrObject] = this :: Nil; - override def listName = path.map(.name).mkString("",".",""); + override def listName = path.map(_.name).mkString("",".",""); object freshParents extends jcl.LinkedHashSet[Type] { this addAll sym.tpe.parents; @@ -286,7 +286,7 @@ trait ModelExtractor { override def typeParams = sym.tpe.typeParams.map(TypeParam); override def params = methodArgumentNames.get(sym) match { case Some(argss) if argss.length > 1 || (!argss.isEmpty && !argss(0).isEmpty) => - argss.map(.map(Param)); + argss.map(_.map(Param)); case _ => var i = 0 val ret = for (tpe <- sym.tpe.paramTypes) yield { @@ -371,8 +371,8 @@ trait ModelExtractor { val Constructors = new Category("Additional Constructor")(e => e.isConstructor && !e.isPrimaryConstructor) { // override def plural = "Additional Constructors"; } - val Objects = Category("Object")(.isModule); - val Classes = new Category("Class")(.isClass) { + val Objects = Category("Object")(_.isModule); + val Classes = new Category("Class")(_.isClass) { override def plural = "Classes"; } val Values = new Category("Value")(e => (e.isValue) && e.hasFlag(symtab.Flags.ACCESSOR)) { diff --git a/src/compiler/scala/tools/nsc/io/PlainFile.scala b/src/compiler/scala/tools/nsc/io/PlainFile.scala index ff4f6126d5..c69123a19e 100644 --- a/src/compiler/scala/tools/nsc/io/PlainFile.scala +++ b/src/compiler/scala/tools/nsc/io/PlainFile.scala @@ -59,7 +59,7 @@ class PlainFile(val file: File) extends AbstractFile { val names: Array[String] = file.list() if ((names eq null) || names.length == 0) Iterator.empty else Iterator.fromArray(names).map { name: String => new File(file, name) } - .filter(.exists()).map(file => new PlainFile(file)) + .filter(_.exists).map(file => new PlainFile(file)) } /** diff --git a/src/compiler/scala/tools/nsc/matching/CodeFactory.scala b/src/compiler/scala/tools/nsc/matching/CodeFactory.scala index a1cddb604c..9013a49185 100644 --- a/src/compiler/scala/tools/nsc/matching/CodeFactory.scala +++ b/src/compiler/scala/tools/nsc/matching/CodeFactory.scala @@ -8,7 +8,7 @@ package scala.tools.nsc.matching import scala.tools.nsc.util.Position -trait CodeFactory requires transform.ExplicitOuter { +trait CodeFactory { self: transform.ExplicitOuter => import global._ diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala index b028f42d86..81267e4cfe 100644 --- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala +++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala @@ -52,7 +52,7 @@ trait ParallelMatching { val isExhaustive = !scrutinee.tpe.symbol.hasFlag(symtab.Flags.SEALED) || { //DEBUG("check exha for column "+column) - val tpes = column.map (.tpe.symbol) + val tpes = column.map (_.tpe.symbol) scrutinee.tpe.symbol.children.forall { sym => tpes.contains(sym) } } @@ -231,7 +231,7 @@ trait ParallelMatching { // this weird thing should only be done for shared states. var nbody: Tree = b val vrefs = vdefs.map { p:ValDef => Ident(p.symbol) } - nbody = Block(vdefs:::List(Apply(Ident(theLabel), vrefs)), LabelDef(theLabel, subst.map(._1), nbody)) + nbody = Block(vdefs:::List(Apply(Ident(theLabel), vrefs)), LabelDef(theLabel, subst.map(_._1), nbody)) bodies(b) = (EmptyTree, nbody, theLabel) nbody } diff --git a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala index 539834e692..cbdb58633e 100644 --- a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala +++ b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala @@ -13,7 +13,7 @@ import scala.tools.nsc.util.{Position, NoPosition} * @author Burak Emir * @version 1.0 */ -trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes with ParallelMatching) { +trait PatternMatchers { self: transform.ExplicitOuter with PatternNodes with ParallelMatching => import global._ import typer.typed import symtab.Flags diff --git a/src/compiler/scala/tools/nsc/matching/PatternNodes.scala b/src/compiler/scala/tools/nsc/matching/PatternNodes.scala index cafefc0e16..ad6de9ca1c 100644 --- a/src/compiler/scala/tools/nsc/matching/PatternNodes.scala +++ b/src/compiler/scala/tools/nsc/matching/PatternNodes.scala @@ -9,7 +9,7 @@ package scala.tools.nsc.matching import compat.StringBuilder import scala.tools.nsc.util.{Position, NoPosition} -trait PatternNodes requires transform.ExplicitOuter { +trait PatternNodes { self: transform.ExplicitOuter => import global._ diff --git a/src/compiler/scala/tools/nsc/matching/TransMatcher.scala b/src/compiler/scala/tools/nsc/matching/TransMatcher.scala index 8fa8bb6437..331507532d 100644 --- a/src/compiler/scala/tools/nsc/matching/TransMatcher.scala +++ b/src/compiler/scala/tools/nsc/matching/TransMatcher.scala @@ -10,10 +10,7 @@ package scala.tools.nsc.matching * * @author Burak Emir */ -trait TransMatcher requires transform.ExplicitOuter /*extends transform.Transform -with PatternNodes -with CodeFactory -with PatternMatchers */ { +trait TransMatcher { self: transform.ExplicitOuter => import global._ import definitions._ diff --git a/src/compiler/scala/tools/nsc/symtab/AnnotationInfos.scala b/src/compiler/scala/tools/nsc/symtab/AnnotationInfos.scala index 8b36ad819f..601d9d5069 100644 --- a/src/compiler/scala/tools/nsc/symtab/AnnotationInfos.scala +++ b/src/compiler/scala/tools/nsc/symtab/AnnotationInfos.scala @@ -59,11 +59,11 @@ trait AnnotationInfos { val mems = trees.map(refltree2cons) - if(mems.exists(.isEmpty)) + if(mems.exists(_.isEmpty)) None else Some(new ArrayConstant( - mems.map(.get).toArray, + mems.map(_.get).toArray, symbolReifier.unreify(arrayType))) } @@ -141,7 +141,7 @@ trait AnnotationInfos { /** Check whether all arguments and assocations are constants */ def isConstant = - ((args forall (.isConstant)) && - (assocs map (._2) forall (.isConstant))) + ((args forall (_.isConstant)) && + (assocs map (_._2) forall (_.isConstant))) } } diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala index 6c663d4e8c..c0c66fc68b 100644 --- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala +++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala @@ -35,6 +35,7 @@ trait Definitions { var AllRefClass: Symbol = _ var AllClass: Symbol = _ + var SingletonClass: Symbol = _ var ClassClass: Symbol = _ var StringClass: Symbol = _ @@ -392,7 +393,7 @@ trait Definitions { j = fullname.pos('.', i) } val result = - if (module) sym.info.member(fullname.subName(i, j)).suchThat(.hasFlag(MODULE)) + if (module) sym.info.member(fullname.subName(i, j)).suchThat(_ hasFlag MODULE) else sym.info.member(fullname.subName(i, j).toTypeName) if (result == NoSymbol) { if (settings.debug.value) @@ -751,6 +752,9 @@ trait Definitions { AllClass = newClass(ScalaPackageClass, nme.Nothing, anyparam) .setFlag(ABSTRACT | TRAIT | FINAL) + SingletonClass = newClass(RootClass, "", anyparam) + .setFlag(ABSTRACT | TRAIT | FINAL) + StringClass = getClass(if (forMSIL) "System.String" else "java.lang.String") ClassClass = getClass(if (forMSIL) "System.Type" else "java.lang.Class") diff --git a/src/compiler/scala/tools/nsc/symtab/Scopes.scala b/src/compiler/scala/tools/nsc/symtab/Scopes.scala index 64f83ca75d..5a60a899da 100644 --- a/src/compiler/scala/tools/nsc/symtab/Scopes.scala +++ b/src/compiler/scala/tools/nsc/symtab/Scopes.scala @@ -266,7 +266,7 @@ trait Scopes { if (!(toList forall p)) newScope(toList filter p) else this def mkString(start: String, sep: String, end: String) = - toList.map(.defString).mkString(start, sep, end) + toList.map(_.defString).mkString(start, sep, end) override def toString(): String = mkString("{\n ", ";\n ", "\n}") diff --git a/src/compiler/scala/tools/nsc/symtab/StdNames.scala b/src/compiler/scala/tools/nsc/symtab/StdNames.scala index d6efdb32cb..12fbe8cf80 100644 --- a/src/compiler/scala/tools/nsc/symtab/StdNames.scala +++ b/src/compiler/scala/tools/nsc/symtab/StdNames.scala @@ -26,6 +26,7 @@ trait StdNames { val FINALkw = newTermName("final") val FINALLYkw = newTermName("finally") val FORkw = newTermName("for") + val FORSOMEkw = newTermName("for_some") val IFkw = newTermName("if") val IMPLICITkw = newTermName("implicit") val IMPORTkw = newTermName("import") diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala index e31f7d4c22..1b6dabd6f6 100644 --- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala +++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala @@ -555,7 +555,7 @@ trait Symbols { if (isMonomorphicType) List() else { rawInfo.load(this); rawInfo.typeParams } def getAttributes(clazz: Symbol): List[AnnotationInfo] = - attributes.filter(.atp.symbol.isNonBottomSubClass(clazz)) + attributes.filter(_.atp.symbol.isNonBottomSubClass(clazz)) /** Reset symbol to initial state */ @@ -841,12 +841,12 @@ trait Symbols { */ final def getter(base: Symbol): Symbol = { val getterName = if (isSetter) nme.setterToGetter(name) else nme.getterName(name) - base.info.decl(getterName) filter (.hasFlag(ACCESSOR)) + base.info.decl(getterName) filter (_.hasFlag(ACCESSOR)) } /** The setter of this value or getter definition, or NoSymbol if none exists */ final def setter(base: Symbol): Symbol = - base.info.decl(nme.getterToSetter(nme.getterName(name))) filter (.hasFlag(ACCESSOR)) + base.info.decl(nme.getterToSetter(nme.getterName(name))) filter (_.hasFlag(ACCESSOR)) /** The case factory corresponding to this case class * @pre case class is a member of some other class or package @@ -855,7 +855,7 @@ trait Symbols { var facname = name.toTermName if (privateWithin.isClass && !privateWithin.isModuleClass && !hasFlag(EXPANDEDNAME)) facname = privateWithin.expandedName(facname) - initialize.owner.info.decl(facname).suchThat(.isCaseFactory) + initialize.owner.info.decl(facname).suchThat(_.isCaseFactory) } /** If this symbol is a skolem, its corresponding type parameter, otherwise this */ @@ -1008,7 +1008,7 @@ trait Symbols { final def infoString(tp: Type): String = { def typeParamsString: String = tp match { case PolyType(tparams, _) if (tparams.length != 0) => - (tparams map (.defString)).mkString("[", ",", "]") + (tparams map (_.defString)).mkString("[", ",", "]") case _ => "" } @@ -1164,7 +1164,7 @@ trait Symbols { if (isInitialized) tpePeriod = currentPeriod tpeCache = NoType val targs = if (phase.erasedTypes && this != ArrayClass) List() - else unsafeTypeParams map (.typeConstructor) //@M! use typeConstructor to generate dummy type arguments, + else unsafeTypeParams map (_.typeConstructor) //@M! use typeConstructor to generate dummy type arguments, // sym.tpe should not be called on a symbol that's supposed to be a higher-kinded type // memberType should be used instead, that's why it uses tpeHK and not tpe tpeCache = typeRef(if (isTypeParameterOrSkolem) NoPrefix else owner.thisType, this, targs) @@ -1353,13 +1353,13 @@ trait Symbols { def cloneSymbols(syms: List[Symbol]): List[Symbol] = { - val syms1 = syms map (.cloneSymbol) + val syms1 = syms map (_.cloneSymbol) for (sym1 <- syms1) sym1.setInfo(sym1.info.substSym(syms, syms1)) syms1 } def cloneSymbols(syms: List[Symbol], owner: Symbol): List[Symbol] = { - val syms1 = syms map (.cloneSymbol(owner)) + val syms1 = syms map (_.cloneSymbol(owner)) for (sym1 <- syms1) sym1.setInfo(sym1.info.substSym(syms, syms1)) syms1 } diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala index 7d72d2ee2f..f948afeed0 100644 --- a/src/compiler/scala/tools/nsc/symtab/Types.scala +++ b/src/compiler/scala/tools/nsc/symtab/Types.scala @@ -41,6 +41,10 @@ import Flags._ // (paramtypes)result case PolyType(tparams, result) => // [tparams]result where result is a MethodType or ClassInfoType + // or + // []T for a eval-by-name type + case ExistentialType(tparams, result) => + // exists[tparams]result // the last five types are not used after phase `typer'. @@ -69,8 +73,7 @@ trait Types { private var explainSwitch = false private var checkMalformedSwitch = true - private var globalVariance = 1//only necessary if healTypes = true? - private final val healTypes = false + private final val LubGlbMargin = 0 private final val LogPendingSubTypesThreshold = 50 @@ -474,11 +477,11 @@ trait Types { else str /** The string representation of this type used as a prefix */ - def prefixString = trimPrefix(toString()) + "#" + def prefixString = trimPrefix(toString) + "#" /** The string representation of this type, with singletypes explained */ def toLongString = { - val str = toString() + val str = toString if (str endsWith ".type") str + " (with underlying type " + widen + ")" else str } @@ -641,7 +644,7 @@ trait Types { override def supertype = tp override def isNotNull: boolean = true override def deconst: Type = tp - override def toString(): String = supertype.toString() + " with NotNull" + override def toString: String = supertype.toString + " with NotNull" } /** A base class for types that represent a single value @@ -656,7 +659,7 @@ trait Types { if (util.Statistics.enabled) singletonClosureCount = singletonClosureCount + 1 addClosure(this, supertype.closure) } - override def toString(): String = prefixString + "type" + override def toString: String = prefixString + "type" } /** An object representing an erroneous type */ @@ -674,25 +677,25 @@ trait Types { sym } override def baseType(clazz: Symbol): Type = this - override def toString(): String = "" + override def toString: String = "" override def narrow: Type = this // override def isNullable: boolean = true } /** An object representing an unknown type */ case object WildcardType extends Type { - override def toString(): String = "?" + override def toString: String = "?" // override def isNullable: boolean = true } case class BoundedWildcardType(override val bounds: TypeBounds) extends Type { - override def toString(): String = "?" + bounds + override def toString: String = "?" + bounds } /** An object representing a non-existing type */ case object NoType extends Type { override def isTrivial: boolean = true - override def toString(): String = "" + override def toString: String = "" // override def isNullable: boolean = true } @@ -701,7 +704,7 @@ trait Types { override def isTrivial: boolean = true override def isStable: boolean = true override def prefixString = "" - override def toString(): String = "" + override def toString: String = "" // override def isNullable: boolean = true } @@ -719,10 +722,10 @@ trait Types { else if (sym.isAnonymousClass || sym.isRefinementClass) "this." else if (sym.isPackageClass) sym.fullNameString + "." else sym.nameString + ".this." - override def toString(): String = + override def toString: String = if (sym.isRoot) "" else if (sym.isEmptyPackageClass) "" - else super.toString() + else super.toString override def narrow: Type = this } @@ -794,7 +797,7 @@ trait Types { override def bounds: TypeBounds = this def containsType(that: Type) = that <:< this || lo <:< that && that <:< hi; // override def isNullable: boolean = AllRefClass.tpe <:< lo; - override def toString() = ">: " + lo + " <: " + hi + override def toString = ">: " + lo + " <: " + hi } /** A common base class for intersection types and class types @@ -958,12 +961,12 @@ trait Types { symbol.thisType } - override def isNotNull: boolean = parents exists (.isNotNull) + override def isNotNull: boolean = parents exists (_.isNotNull) // override def isNullable: boolean = // parents forall (p => p.isNullable && !p.symbol.isAbstractType); - override def toString(): String = + override def toString: String = parents.mkString("", " with ", "") + (if (settings.debug.value || parents.isEmpty || (decls.elems ne null)) decls.mkString("{", "; ", "}") else "") @@ -1129,8 +1132,8 @@ trait Types { if (value.value.isInstanceOf[String]) value.tpe else value.tpe override def deconst: Type = value.tpe - override def toString(): String = - value.tpe.toString() + "(" + value.escapedStringValue + ")" + override def toString: String = + value.tpe.toString + "(" + value.escapedStringValue + ")" // override def isNullable: boolean = value.value eq null // override def isNonNull: boolean = value.value ne null } @@ -1156,8 +1159,11 @@ trait Types { private var closurePeriod = NoPeriod private var closureDepthCache: int = _ + override def isStable: boolean = + sym.isAbstractType && (sym.info.bounds.hi.symbol isSubClass SingletonClass) + override val isTrivial: boolean = - pre.isTrivial && !sym.isTypeParameter && args.forall(.isTrivial) + pre.isTrivial && !sym.isTypeParameter && args.forall(_.isTrivial) override def isNotNull = sym.isModuleClass || sym == AllClass || isValueClass(sym) || super.isNotNull @@ -1239,7 +1245,7 @@ A type's symbol should never be inspected directly. override def isHigherKinded = !typeParams.isEmpty //@M args.isEmpty is checked in typeParams - private def higherKindedArgs = typeParams map (.typeConstructor) //@M must be .typeConstructor + private def higherKindedArgs = typeParams map (_.typeConstructor) //@M must be .typeConstructor private def argsMaybeDummy = if (isHigherKinded) higherKindedArgs else args override def normalize = @@ -1299,12 +1305,12 @@ A type's symbol should never be inspected directly. // override def isNullable: boolean = sym.info.isNullable - override def toString(): String = { + override def toString: String = { if (!settings.debug.value) { if (sym == RepeatedParamClass && !args.isEmpty) - return args(0).toString() + "*" + return args(0).toString + "*" if (sym == ByNameParamClass && !args.isEmpty) - return "=> " + args(0).toString() + return "=> " + args(0).toString if (isFunctionType(this)) return normalize.typeArgs.init.mkString("(", ", ", ")") + " => " + normalize.typeArgs.last if (isTupleType(this)) @@ -1319,7 +1325,7 @@ A type's symbol should never be inspected directly. else if (sym.isAnonymousClass && sym.isInitialized && !settings.debug.value) thisInfo.parents.mkString("", " with ", "{ ... }") else if (sym.isRefinementClass && sym.isInitialized) - thisInfo.toString() + thisInfo.toString else str } @@ -1336,7 +1342,7 @@ A type's symbol should never be inspected directly. case class MethodType(override val paramTypes: List[Type], override val resultType: Type) extends Type { override val isTrivial: boolean = - paramTypes.forall(.isTrivial) && resultType.isTrivial + paramTypes.forall(_.isTrivial) && resultType.isTrivial //assert(paramTypes forall (pt => !pt.symbol.isImplClass))//DEBUG override def paramSectionCount: int = resultType.paramSectionCount + 1 @@ -1357,7 +1363,7 @@ A type's symbol should never be inspected directly. params.mkString(paramPrefix, ",", ")")+res } - override def toString(): String = + override def toString: String = if (resultType.isDependent) dependentToString(0) else paramTypes.mkString(paramPrefix, ",", ")") + resultType } @@ -1368,19 +1374,11 @@ A type's symbol should never be inspected directly. class JavaMethodType(pts: List[Type], rt: Type) extends MethodType(pts, rt) - /** A class representing a polymorphic type or, if tparams.length == 0, - * a parameterless method type. - * (@M: note that polymorphic nullary methods have non-empty tparams, e.g., isInstanceOf or def makeList[T] = new List[T] - * ideally, there would be a NullaryMethodType, so that higher-kinded types could use PolyType instead of TypeRef with empty args) - */ - case class PolyType(override val typeParams: List[Symbol], override val resultType: Type) - extends Type { - + /** A class containing the commonalities of existential and universal types */ + class QuantifiedType extends Type { override def paramSectionCount: int = resultType.paramSectionCount override def paramTypes: List[Type] = resultType.paramTypes - override def finalResultType: Type = resultType.finalResultType - override def parents: List[Type] = resultType.parents override def decls: Scope = resultType.decls override def symbol: Symbol = resultType.symbol @@ -1390,18 +1388,32 @@ A type's symbol should never be inspected directly. override def baseClasses: List[Symbol] = resultType.baseClasses override def baseType(clazz: Symbol): Type = resultType.baseType(clazz) override def narrow: Type = resultType.narrow + // override def isNullable: boolean = resultType.isNullable; + } - // @M: abstractTypeSig now wraps a TypeBounds in a PolyType to represent a higher-kinded type parameter - // wrap lo&hi in polytypes to bind variables - override def bounds: TypeBounds = TypeBounds(PolyType(typeParams, resultType.bounds.lo), PolyType(typeParams, resultType.bounds.hi)) + /** A class representing a polymorphic type or, if tparams.length == 0, + * a parameterless method type. + * (@M: note that polymorphic nullary methods have non-empty tparams, + * e.g., isInstanceOf or def makeList[T] = new List[T]. + * Ideally, there would be a NullaryMethodType, so that higher-kinded types + * could use PolyType instead of TypeRef with empty args) + */ + case class PolyType(override val typeParams: List[Symbol], override val resultType: Type) + extends QuantifiedType { - // override def isNullable: boolean = resultType.isNullable; + /** @M: abstractTypeSig now wraps a TypeBounds in a PolyType + * to represent a higher-kinded type parameter + * wrap lo&hi in polytypes to bind variables + */ + override def bounds: TypeBounds = + TypeBounds(PolyType(typeParams, resultType.bounds.lo), + PolyType(typeParams, resultType.bounds.hi)) override def isHigherKinded = !typeParams.isEmpty - override def toString(): String = + override def toString: String = (if (typeParams.isEmpty) "=> " - else (typeParams map (.defString)).mkString("[", ",", "]")) + resultType + else (typeParams map (_.defString) mkString ("[", ",", "]")))+resultType override def cloneInfo(owner: Symbol) = { val tparams = cloneSymbols(typeParams, owner) @@ -1409,12 +1421,35 @@ A type's symbol should never be inspected directly. } } + case class ExistentialType(override val typeParams: List[Symbol], + override val resultType: Type) extends QuantifiedType { + override def bounds: TypeBounds = + TypeBounds(ExistentialType(typeParams, resultType.bounds.lo), + ExistentialType(typeParams, resultType.bounds.hi)) + + override def toString: String = + resultType+(typeParams map tparamToString mkString(" for_some { ", "; ", " }")) + + private def tparamToString(tparam: Symbol) = { + val tname = tparam.name.toString + if ((tname endsWith ".type") && (tparam.info.bounds.hi.symbol isSubClass SingletonClass) && + !settings.debug.value) + "val "+tname.substring(0, tname.length - 5)+": "+dropSingletonType(tparam.info.bounds.hi) + else tparam.defString + } + + override def cloneInfo(owner: Symbol) = { + val tparams = cloneSymbols(typeParams, owner) + ExistentialType(tparams, resultType.substSym(typeParams, tparams)) + } + } + /** A class containing the alternatives and type prefix of an overloaded symbol. * Not used after phase `typer'. */ case class OverloadedType(pre: Type, alternatives: List[Symbol]) extends Type { override def prefix: Type = pre - override def toString() = + override def toString = (alternatives map pre.memberType).mkString("", " ", "") } @@ -1423,8 +1458,8 @@ A type's symbol should never be inspected directly. * Not used after phase `typer'. */ case class AntiPolyType(pre: Type, targs: List[Type]) extends Type { - override def toString() = - pre.toString() + targs.mkString("(with type arguments ", ",", ")"); + override def toString = + pre.toString + targs.mkString("(with type arguments ", ",", ")"); override def memberType(sym: Symbol) = pre.memberType(sym) match { case PolyType(tparams, restp) => restp.subst(tparams, targs) case ErrorType => ErrorType @@ -1437,7 +1472,7 @@ A type's symbol should never be inspected directly. case class TypeVar(origin: Type, constr: TypeConstraint) extends Type { //constr.self = this //DEBUG override def symbol = origin.symbol - override def toString(): String = + override def toString: String = if (constr.inst eq null) "" else if (constr.inst eq NoType) "?" + origin else constr.inst.toString; @@ -1448,7 +1483,7 @@ A type's symbol should never be inspected directly. * core compiler does take care to propagate attributes and to save them * in the symbol tables of object files. */ case class AnnotatedType(attributes: List[AnnotationInfo], tp: Type) extends TypeProxy { - override def toString(): String = { + override def toString: String = { val attString = if (attributes.isEmpty) "" @@ -1521,11 +1556,7 @@ A type's symbol should never be inspected directly. if (phase.erasedTypes) sym.tpe else unique(new ThisType(sym) with UniqueType) /** The canonical creator for single-types */ - def singleType(pre: Type, sym: Symbol): Type = singleType(pre, sym, 0) - - /** The canonical creator for single-types, - * with possibility of approximating in case of malformed types */ - def singleType(pre: Type, sym: Symbol, variance: int): Type = { + def singleType(pre: Type, sym: Symbol): Type = { if (phase.erasedTypes) sym.tpe.resultType else if (sym.isRootPackage) @@ -1534,13 +1565,10 @@ A type's symbol should never be inspected directly. var sym1 = rebind(pre, sym) val pre1 = removeSuper(pre, sym1) if (pre1 ne pre) sym1 = rebind(pre1, sym1) - if (checkMalformedSwitch && !pre1.isStable && !pre1.isError) { - if (healTypes && variance == 1) pre.memberType(sym).resultType -// else if (variance == -1) AllClass.tpe - else throw new MalformedType(pre, sym.nameString) - } else { + if (checkMalformedSwitch && !pre1.isStable && !pre1.isError) + throw new MalformedType(pre, sym.nameString) + else unique(new SingleType(pre1, sym1) with UniqueType) - } } } @@ -1595,12 +1623,8 @@ A type's symbol should never be inspected directly. def mkConstantType(value: Constant): ConstantType = unique(new ConstantType(value) with UniqueType) - /** The canonical creator for typerefs. */ - def typeRef(pre: Type, sym: Symbol, args: List[Type]): Type = typeRef(pre, sym, args, 0) - - /** The canonical creator for typerefs, - * with possibility of approximating in case of malformed types */ - def typeRef(pre: Type, sym: Symbol, args: List[Type], variance: int): Type = { + /** The canonical creator for typerefs */ + def typeRef(pre: Type, sym: Symbol, args: List[Type]): Type = { var sym1 = if (sym.isAbstractType) rebind(pre, sym) else sym def transform(tp: Type): Type = tp.resultType.asSeenFrom(pre, sym1.owner).instantiateTypeParams(sym1.typeParams, args) @@ -1619,17 +1643,15 @@ A type's symbol should never be inspected directly. val pre1 = removeSuper(pre, sym1) if (pre1 ne pre) { if (sym1.isAbstractType) sym1 = rebind(pre1, sym1) - typeRef(pre1, sym1, args, variance) + typeRef(pre1, sym1, args) } else if (checkMalformedSwitch && sym1.isAbstractType && !pre.isStable && !pre.isError) { - if (healTypes && variance == 1 && !(sym1.info.bounds.hi contains sym1)) transform(sym1.info.bounds.hi) - //else if (variance == -1 && !(sym1.info.bounds.lo contains sym1)) transform(sym1.info.bounds.lo) - else throw new MalformedType(pre, sym1.nameString) + throw new MalformedType(pre, sym1.nameString) } else if (sym1.isClass && pre.isInstanceOf[CompoundType]) { // sharpen prefix so that it is maximal and still contains the class. var p = pre.parents.reverse while (!p.isEmpty && p.head.member(sym1.name) != sym1) p = p.tail if (p.isEmpty) rawTypeRef(pre, sym1, args) - else typeRef(p.head, sym1, args, variance) + else typeRef(p.head, sym1, args) } else { rawTypeRef(pre, sym1, args) } @@ -1659,8 +1681,8 @@ A type's symbol should never be inspected directly. /* def merge(tps: List[Type]): List[Type] = tps match { case tp :: tps1 => - val tps1a = tps1 filter (.symbol.==(tp.symbol)) - val tps1b = tps1 filter (.symbol.!=(tp.symbol)) + val tps1a = tps1 filter (_.symbol.==(tp.symbol)) + val tps1b = tps1 filter (_.symbol.!=(tp.symbol)) mergePrefixAndArgs(tps1a, -1) match { case Some(tp1) => tp1 :: merge(tps1b) case None => throw new MalformedType( @@ -1694,7 +1716,7 @@ A type's symbol should never be inspected directly. throw new Error() } - /** A creater for type parameterizations + /** A creator for type parameterizations * If tparams is empty, simply returns result type */ def parameterizedType(tparams: List[Symbol], tpe: Type): Type = @@ -1705,6 +1727,71 @@ A type's symbol should never be inspected directly. case _ => tpe }) + /** A creator for existential types. This generates: + * + * tpe1 where { tparams } + * + * where `tpe1' is the result of extrapolating `tpe' wrt to `tparams'. Extrapolating means + * that type variables in `tparams' occurring in covariant positions are replaced by upper bounds, + * (minus any SingletonClass markers), + * type variables in `tparams' occurring in contravariant positions are replaced by upper bounds, + * provided the resulting type is legal wrt to stability, and does not contain any + * type varianble in `tparams'. + * The abstraction drops all type parameters that are not directly or indirectly + * referenced by type `tpe1'. + * If there are no such type parameters, simply returns result type `tpe'. + */ + def existentialAbstraction(tparams: List[Symbol], tpe: Type): Type = + if (tparams.isEmpty) tpe + else { + val extrapolate = new TypeMap { + variance = 1 + stableNeeded = false + def apply(tp: Type): Type = { + val tp1 = mapOver(tp) + tp1 match { + case TypeRef(pre, sym, args) if (tparams contains sym) && (variance != 0) => + val repl = if (variance == 1) dropSingletonType(tp1.bounds.hi) else tp1.bounds.lo + if ((!stableNeeded || repl.isStable) && !(tparams exists (repl.contains))) repl + else tp1 + case _ => + tp1 + } + } + } + val tpe1 = extrapolate(tpe) + var tparams0 = tparams + var tparams1 = tparams0 filter tpe1.contains + while (tparams1 != tparams0) { + tparams0 = tparams1 + tparams1 = tparams filter { p => + tparams1 exists { p1 => p1 == p || (p1.info contains p) } + } + } + if (tparams1.isEmpty) tpe1 + else tpe1 match { + case ExistentialType(tparams2, tpe2) => ExistentialType(tparams1 ::: tparams2, tpe2) + case _ => ExistentialType(tparams1, tpe1) + } + } + + /** Remove any occurrence of type from this type and its parents */ + private object dropSingletonType extends TypeMap { + def apply(tp: Type): Type = { + mapOver(tp) match { + case TypeRef(_, sym, _) if (sym == SingletonClass) => + AnyClass.tpe + case tp1 @ RefinedType(parents, decls) => + var parents1 = parents filter (_.symbol != SingletonClass) + if (parents1.isEmpty) parents1 = List(AnyClass.tpe) + if (parents1.tail.isEmpty && decls.isEmpty) parents1.head + else copyRefinedType(tp1, parents1, decls) + case tp1 => + tp1 + } + } + } + // Hash consing -------------------------------------------------------------- private var uniques: HashSet[AnyRef] = _ @@ -1745,11 +1832,11 @@ A type's symbol should never be inspected directly. */ def instantiate(tp: Type): boolean = - if (lobounds.forall(.<:<(tp)) && hibounds.forall(tp.<:<)) { + if (lobounds.forall(_ <:< tp) && hibounds.forall(tp <:< _)) { inst = tp; true } else false - override def toString() = + override def toString = lobounds.mkString("[ _>:(", ",", ") ") + hibounds.mkString("| _<:(", ",", ") | _= ") + inst } @@ -1759,7 +1846,15 @@ A type's symbol should never be inspected directly. abstract class TypeMap extends Function1[Type, Type] { // deferred inherited: def apply(tp: Type): Type - var variance = globalVariance + /** The variance relative to start. If you want variances to be significant, set + * variance = 1 + * at the top of the typemap. + */ + var variance = 0 + + /** Is a stable type needed here? + */ + var stableNeeded = false /** Map this function over given type */ def mapOver(tp: Type): Type = tp match { @@ -1774,10 +1869,12 @@ A type's symbol should never be inspected directly. if (sym.isPackageClass) tp // short path else { val v = variance; variance = 0 + val s = stableNeeded; stableNeeded = true val pre1 = this(pre) variance = v + stableNeeded = s if (pre1 eq pre) tp - else singleType(pre1, sym, variance) + else singleType(pre1, sym) } case SuperType(thistp, supertp) => val thistp1 = this(thistp) @@ -1785,7 +1882,9 @@ A type's symbol should never be inspected directly. if ((thistp1 eq thistp) && (supertp1 eq supertp)) tp else mkSuperType(thistp1, supertp1) case TypeRef(pre, sym, args) => + val s = stableNeeded; stableNeeded = true val pre1 = this(pre) + stableNeeded = s //val args1 = List.mapConserve(args)(this) val args1 = if (args.isEmpty) args else { @@ -1794,7 +1893,7 @@ A type's symbol should never be inspected directly. else mapOverArgs(args, tparams) } if ((pre1 eq pre) && (args1 eq args)) tp - else typeRef(pre1, sym, args1, variance) + else typeRef(pre1, sym, args1) case TypeBounds(lo, hi) => variance = -variance val lo1 = this(lo) @@ -1833,6 +1932,11 @@ A type's symbol should never be inspected directly. var result1 = this(result) if ((tparams1 eq tparams) && (result1 eq result)) tp else PolyType(tparams1, result1.substSym(tparams, tparams1)) + case ExistentialType(tparams, result) => + val tparams1 = mapOver(tparams) + var result1 = this(result) + if ((tparams1 eq tparams) && (result1 eq result)) tp + else ExistentialType(tparams1, result1.substSym(tparams, tparams1)) case OverloadedType(pre, alts) => val pre1 = if (pre.isInstanceOf[ClassInfoType]) pre else this(pre) if (pre1 eq pre) tp @@ -1878,11 +1982,11 @@ A type's symbol should never be inspected directly. /** Map this function over given list of symbols */ def mapOver(syms: List[Symbol]): List[Symbol] = { - val infos = syms map (.info) + val infos = syms map (_.info) val infos1 = List.mapConserve(infos)(this) if (infos1 eq infos) syms else { - val syms1 = syms map (.cloneSymbol) + val syms1 = syms map (_.cloneSymbol) List.map2(syms1, infos1) { ((sym1, info1) => sym1.setInfo(info1.substSym(syms, syms1))) } @@ -1935,7 +2039,7 @@ A type's symbol should never be inspected directly. val pre1 = this(pre) variance = v if (pre1 eq pre) tp - else if (pre1.isStable) singleType(pre1, sym, variance) + else if (pre1.isStable) singleType(pre1, sym) else pre1.memberType(sym).resultType } case TypeRef(prefix, sym, args) if (sym.isTypeParameter) => @@ -1959,7 +2063,7 @@ A type's symbol should never be inspected directly. throw new TypeError( "something is wrong (wrong class file?): "+basesym+ " with type parameters "+ - basesym.typeParams.map(.name).mkString("[",",","]")+ + basesym.typeParams.map(_.name).mkString("[",",","]")+ " gets applied to arguments "+baseargs.mkString("(",",",")")+", phase = "+phase) instParam(basesym.typeParams, baseargs); case _ => @@ -1995,10 +2099,14 @@ A type's symbol should never be inspected directly. tp match { // @M - // 1) arguments must also be substituted (even when the "head" of the applied type has already been substituted) - // example: (subst RBound[RT] from [type RT,type RBound] to [type RT&,type RBound&]) = RBound&[RT&] - // 2) avoid loops (which occur because alpha-conversion is not performed properly imo) - // e.g. if in class Iterable[a] there is a new Iterable[(a,b)], we must replace the a in Iterable[a] by (a,b) + // 1) arguments must also be substituted (even when the "head" of the + // applied type has already been substituted) + // example: (subst RBound[RT] from [type RT,type RBound] to + // [type RT&,type RBound&]) = RBound&[RT&] + // 2) avoid loops (which occur because alpha-conversion is + // not performed properly imo) + // e.g. if in class Iterable[a] there is a new Iterable[(a,b)], + // we must replace the a in Iterable[a] by (a,b) // (must not recurse --> loops) // 3) replacing m by List in m[Int] should yield List[Int], not just List case TypeRef(NoPrefix, sym, args) => @@ -2014,6 +2122,9 @@ A type's symbol should never be inspected directly. case PolyType(tparams, restp) => assert(!(tparams exists (from contains))) tp + case ExistentialType(tparams, restp) => + assert(!(tparams exists (from contains))) + tp case _ => tp } @@ -2024,8 +2135,8 @@ A type's symbol should never be inspected directly. class SubstSymMap(from: List[Symbol], to: List[Symbol]) extends SubstMap(from, to) { protected def toType(fromtp: Type, sym: Symbol) = fromtp match { - case TypeRef(pre, _, args) => typeRef(pre, sym, args, variance) - case SingleType(pre, _) => singleType(pre, sym, variance) + case TypeRef(pre, _, args) => typeRef(pre, sym, args) + case SingleType(pre, _) => singleType(pre, sym) } override def apply(tp: Type): Type = if (from.isEmpty) tp else { def subst(sym: Symbol, from: List[Symbol], to: List[Symbol]): Symbol = @@ -2034,9 +2145,10 @@ A type's symbol should never be inspected directly. else subst(sym, from.tail, to.tail) tp match { case TypeRef(pre, sym, args) if !(pre eq NoPrefix) => - mapOver(typeRef(pre, subst(sym, from, to), args, variance)) //@M TODO subst args? List.mapConserve(args)(this) + mapOver(typeRef(pre, subst(sym, from, to), args)) + //@M TODO subst args? List.mapConserve(args)(this) case SingleType(pre, sym) if !(pre eq NoPrefix) => - mapOver(singleType(pre, subst(sym, from, to), variance)) + mapOver(singleType(pre, subst(sym, from, to))) case _ => super.apply(tp) } @@ -2213,7 +2325,7 @@ A type's symbol should never be inspected directly. val pre1 = this(pre) val sym1 = adaptToNewRun(pre1, sym) if ((pre1 eq pre) && (sym1 eq sym)) tp - else singleType(pre1, sym1, variance) + else singleType(pre1, sym1) } case TypeRef(pre, sym, args) => if (sym.isPackageClass) tp @@ -2222,7 +2334,7 @@ A type's symbol should never be inspected directly. val args1 = List.mapConserve(args)(this) val sym1 = adaptToNewRun(pre1, sym) if ((pre1 eq pre) && (sym1 eq sym) && (args1 eq args)/* && sym.isExternal*/) tp - else typeRef(pre1, sym1, args1, variance) + else typeRef(pre1, sym1, args1) } case PolyType(tparams, restp) => val restp1 = this(restp) @@ -2245,6 +2357,7 @@ A type's symbol should never be inspected directly. case TypeVar(_, _) => mapOver(tp) case AnnotatedType(_,_) => mapOver(tp) case NotNullType(_) => mapOver(tp) + case ExistentialType(_, _) => mapOver(tp) case _ => tp } } @@ -2283,13 +2396,15 @@ A type's symbol should never be inspected directly. case TypeRef(pre, sym, args) => max(maxDepth(pre), maxDepth(args) + 1) case RefinedType(parents, decls) => - max(maxDepth(parents), maxDepth(decls.toList.map(.info)) + 1) + max(maxDepth(parents), maxDepth(decls.toList.map(_.info)) + 1) case TypeBounds(lo, hi) => max(maxDepth(lo), maxDepth(hi)) case MethodType(paramtypes, result) => maxDepth(result) case PolyType(tparams, result) => - max(maxDepth(result), maxDepth(tparams map (.info)) + 1) + max(maxDepth(result), maxDepth(tparams map (_.info)) + 1) + case ExistentialType(tparams, result) => + max(maxDepth(result), maxDepth(tparams map (_.info)) + 1) case _ => 1 } @@ -2376,6 +2491,11 @@ A type's symbol should never be inspected directly. List.forall2(tparams1, tparams2) ((p1, p2) => p1.info =:= p2.info.substSym(tparams2, tparams1)) && res1 =:= res2.substSym(tparams2, tparams1)) + case (ExistentialType(tparams1, res1), ExistentialType(tparams2, res2)) => + (tparams1.length == tparams2.length && + List.forall2(tparams1, tparams2) + ((p1, p2) => p1.info =:= p2.info.substSym(tparams2, tparams1)) && + res1 =:= res2.substSym(tparams2, tparams1)) case (TypeBounds(lo1, hi1), TypeBounds(lo2, hi2)) => lo1 =:= lo2 && hi1 =:= hi2 case (BoundedWildcardType(bounds), _) => @@ -2532,12 +2652,25 @@ A type's symbol should never be inspected directly. (if (!inIDE) true else trackTypeIDE(sym2)) || sym2 == NotNullClass && tp1.isNotNull) => true + case (_, TypeRef(pre2, sym2, args2)) + if (sym2 == SingletonClass && tp1.isStable) => + true case (_, RefinedType(parents2, ref2)) => (parents2 forall (tp2 => tp1 <:< tp2 || tp2.symbol == NotNullClass && tp1.isNotNull)) && (ref2.toList forall tp1.specializes) && - (!parents2.exists(.symbol.isAbstractType) || tp1.symbol != AllRefClass) + (!parents2.exists(_.symbol.isAbstractType) || tp1.symbol != AllRefClass) case (RefinedType(parents1, ref1), _) => - parents1 exists (.<:<(tp2)) + parents1 exists (_ <:< tp2) + case (_, ExistentialType(tparams2, res2)) => + val tvars = tparams2 map (tparam => new TypeVar(tparam.tpe, new TypeConstraint)) + val ires2 = res2.instantiateTypeParams(tparams2, tvars) + (tp1 <:< ires2) && { + solve(tvars, tparams2, tparams2 map (x => 0), false) + isWithinBounds(NoPrefix, NoSymbol, tparams2, tvars map (_.constr.inst)) + } + case (ExistentialType(tparams1, res1), _) => + res1 <:< tp2 + /* todo: replace following with case (ThisType(_), _) | {SingleType(_, _), _} @@ -2661,6 +2794,79 @@ A type's symbol should never be inspected directly. else x1 :: xs1 } + /** Solve constraint collected in types tvars. + * + * @param tvars All type variables to be instantiated. + * @param tparams The type parameters corresponding to tvars + * @param variances The variances of type parameters; need to reverse + * solution direction for all contravariant variables. + * @param upper When true search for max solution else min. + * @throws NoInstance + */ + def solve(tvars: List[TypeVar], tparams: List[Symbol], + variances: List[int], upper: boolean) { + val config = tvars zip (tparams zip variances) + + def solveOne(tvar: TypeVar, tparam: Symbol, variance: int): unit = { + if (tvar.constr.inst == NoType) { + val up = if (variance != CONTRAVARIANT) upper else !upper + tvar.constr.inst = null + val bound: Type = if (up) tparam.info.bounds.hi else tparam.info.bounds.lo + // Console.println("solveOne0 "+tvar+" "+config+" "+bound);//DEBUG + var cyclic = bound contains tparam + for ((tvar2, (tparam2, variance2)) <- config) { + if (tparam2 != tparam && + ((bound contains tparam2) || + up && (tparam2.info.bounds.lo =:= tparam.tpe) || //@M TODO: might be affected by change to tpe in Symbol + !up && (tparam2.info.bounds.hi =:= tparam.tpe))) { //@M TODO: might be affected by change to tpe in Symbol + if (tvar2.constr.inst eq null) cyclic = true + solveOne(tvar2, tparam2, variance2) + } + } + if (!cyclic) { + if (up) { + if (bound.symbol != AnyClass) { + tvar.constr.hibounds = + bound.instantiateTypeParams(tparams, tvars) :: tvar.constr.hibounds + } + for (tparam2 <- tparams) + if (tparam2.info.bounds.lo =:= tparam.tpe) //@M TODO: might be affected by change to tpe in Symbol + tvar.constr.hibounds = + tparam2.tpe.instantiateTypeParams(tparams, tvars) :: tvar.constr.hibounds + } else { + if (bound.symbol != AllClass && bound.symbol != tparam) { + tvar.constr.lobounds = + bound.instantiateTypeParams(tparams, tvars) :: tvar.constr.lobounds + } + for (tparam2 <- tparams) + if (tparam2.info.bounds.hi =:= tparam.tpe) //@M TODO: might be affected by change to tpe in Symbol + tvar.constr.lobounds = + tparam2.tpe.instantiateTypeParams(tparams, tvars) :: tvar.constr.lobounds + } + } + tvar.constr.inst = NoType // necessary because hibounds/lobounds may contain tvar + //Console.println("solving "+tvar+" "+up+" "+(if (up) (tvar.constr.hibounds) else tvar.constr.lobounds))//DEBUG + tvar.constr.inst = if (up) glb(tvar.constr.hibounds) else lub(tvar.constr.lobounds) + } + } + for ((tvar, (tparam, variance)) <- config) + solveOne(tvar, tparam, variance) + } + + /** Do type arguments targs conform to formal parameters + * tparams? + * + * @param tparams ... + * @param targs ... + * @return ... + */ + def isWithinBounds(pre: Type, owner: Symbol, tparams: List[Symbol], targs: List[Type]): boolean = { + val bounds = tparams map { tparam => + tparam.info.asSeenFrom(pre, owner).instantiateTypeParams(tparams, targs).bounds + } + !(List.map2(bounds, targs)((bound, targ) => bound containsType targ) contains false) + } + // Lubs and Glbs --------------------------------------------------------- /** The greatest sorted upwards closed lower bound of a list of lists of @@ -2675,9 +2881,9 @@ A type's symbol should never be inspected directly. if (tss1.isEmpty) List() else if (tss1.tail.isEmpty) tss.head else { - val ts0 = tss1 map (.head) + val ts0 = tss1 map (_.head) val sym = minSym(ts0) - val ts1 = elimSuper(ts0 filter (.symbol.==(sym))) + val ts1 = elimSuper(ts0 filter (_.symbol == sym)) mergePrefixAndArgs(ts1, -1, depth) match { case Some(tp0) => tp0 :: glbList(tss1 map (ts => if (ts.head.symbol == sym) ts.tail else ts), depth) @@ -2708,12 +2914,12 @@ A type's symbol should never be inspected directly. */ private def lubList(tss: List[List[Type]], depth: int): List[Type] = if (tss.tail.isEmpty) tss.head - else if (tss exists (.isEmpty)) List() + else if (tss exists (_.isEmpty)) List() else { - val ts0 = tss map (.head) + val ts0 = tss map (_.head) val sym = minSym(ts0) if (ts0 forall (t => t.symbol == sym)) - mergePrefixAndArgs(elimSub(ts0), 1, depth).toList ::: lubList(tss map (.tail), depth) + mergePrefixAndArgs(elimSub(ts0), 1, depth).toList ::: lubList(tss map (_.tail), depth) else lubList(tss map (ts => if (ts.head.symbol == sym) ts.tail else ts), depth) } @@ -2768,6 +2974,18 @@ A type's symbol should never be inspected directly. if (rest exists (t1 => t <:< t1)) rest else t :: rest } + private def stripExistentials(ts: List[Type]): (List[Type], List[Symbol]) = { + val typeParams = ts flatMap { + case ExistentialType(tparams, res) => tparams + case t => List() + } + val strippedTypes = List.mapConserve(ts) { + case ExistentialType(tparams, res) => res + case t => t + } + (strippedTypes, typeParams) + } + def lub(ts: List[Type]): Type = lub(ts, maxClosureDepth(ts) + LubGlbMargin) /** The least upper bound wrt <:< of a list of types */ @@ -2784,60 +3002,63 @@ A type's symbol should never be inspected directly. MethodType(pts, lub0(matchingRestypes(ts, pts))) case ts @ TypeBounds(_, _) :: rest => assert(false) - mkTypeBounds(glb(ts map (.bounds.lo), depth), lub(ts map (.bounds.hi), depth)) - case ts => - val closures: List[Array[Type]] = ts map (.closure) + mkTypeBounds(glb(ts map (_.bounds.lo), depth), lub(ts map (_.bounds.hi), depth)) + case ts0 => + val (ts, tparams) = stripExistentials(ts0) + val closures: List[Array[Type]] = ts map (_.closure) val lubBaseTypes: Array[Type] = lubArray(closures, depth) - //log("closures = " + (closures map (cl => List.fromArray(cl))) + ", lubbases = " + List.fromArray(lubBaseTypes));//DEBUG val lubParents = spanningTypes(List.fromArray(lubBaseTypes)) val lubOwner = commonOwner(ts) val lubBase = intersectionType(lubParents, lubOwner) - if (phase.erasedTypes || depth == 0) lubBase - else { - val lubType = refinedType(lubParents, lubOwner) - val lubThisType = lubType.symbol.thisType - val narrowts = ts map (.narrow) - def lubsym(proto: Symbol): Symbol = try { - val prototp = lubThisType.memberInfo(proto) - val syms = narrowts map (t => - t.nonPrivateMember(proto.name).suchThat(sym => - sym.tpe matches prototp.substThis(lubThisType.symbol, t))) - if (syms contains NoSymbol) NoSymbol - else { - val symtypes = - (List.map2(narrowts, syms) - ((t, sym) => t.memberInfo(sym).substThis(t.symbol, lubThisType))); - if (proto.isTerm) - proto.cloneSymbol(lubType.symbol).setInfo(lub(symtypes, depth-1)) - else if (symtypes.tail forall (symtypes.head =:=)) - proto.cloneSymbol(lubType.symbol).setInfo(symtypes.head) + val lubType = + if (phase.erasedTypes || depth == 0) lubBase + else { + val lubRefined = refinedType(lubParents, lubOwner) + val lubThisType = lubRefined.symbol.thisType + val narrowts = ts map (_.narrow) + def lubsym(proto: Symbol): Symbol = { + val prototp = lubThisType.memberInfo(proto) + val syms = narrowts map (t => + t.nonPrivateMember(proto.name).suchThat(sym => + sym.tpe matches prototp.substThis(lubThisType.symbol, t))) + if (syms contains NoSymbol) NoSymbol else { - def lubBounds(bnds: List[TypeBounds]): TypeBounds = - mkTypeBounds(glb(bnds map (.lo), depth-1), lub(bnds map (.hi), depth-1)) - proto.owner.newAbstractType(proto.pos, proto.name) - .setInfo(lubBounds(symtypes map (.bounds))) + val symtypes = + (List.map2(narrowts, syms) + ((t, sym) => t.memberInfo(sym).substThis(t.symbol, lubThisType))); + if (proto.isTerm) + proto.cloneSymbol(lubRefined.symbol).setInfo(lub(symtypes, depth-1)) + else if (symtypes.tail forall (symtypes.head =:=)) + proto.cloneSymbol(lubRefined.symbol).setInfo(symtypes.head) + else { + def lubBounds(bnds: List[TypeBounds]): TypeBounds = + mkTypeBounds(glb(bnds map (_.lo), depth-1), lub(bnds map (_.hi), depth-1)) + proto.owner.newAbstractType(proto.pos, proto.name) + .setInfo(lubBounds(symtypes map (_.bounds))) + } } } + def refines(tp: Type, sym: Symbol): boolean = { + val syms = tp.nonPrivateMember(sym.name).alternatives; + !syms.isEmpty && (syms forall (alt => + // todo alt != sym is strictly speaking not correct, but without it we lose + // efficiency. + alt != sym && !specializesSym(lubThisType, sym, tp, alt))) + } + for (sym <- lubBase.nonPrivateMembers) { + // add a refinement symbol for all non-class members of lubBase + // which are refined by every type in ts. + if (!sym.isClass && !sym.isConstructor && (narrowts forall (t => refines(t, sym)))) + try { + val lsym = lubsym(sym) + if (lsym != NoSymbol) addMember(lubThisType, lubRefined, lubsym(sym)) + } catch { + case ex: NoCommonType => + } + } + if (lubRefined.decls.isEmpty) lubBase else lubRefined } - def refines(tp: Type, sym: Symbol): boolean = { - val syms = tp.nonPrivateMember(sym.name).alternatives; - !syms.isEmpty && (syms forall (alt => - // todo alt != sym is strictly speaking not correct, but without it we lose - // efficiency. - alt != sym && !specializesSym(lubThisType, sym, tp, alt))) - } - for (sym <- lubBase.nonPrivateMembers) - // add a refinement symbol for all non-class members of lubBase - // which are refined by every type in ts. - if (!sym.isClass && !sym.isConstructor && (narrowts forall (t => refines(t, sym)))) - try { - val lsym = lubsym(sym) - if (lsym != NoSymbol) addMember(lubThisType, lubType, lubsym(sym)) - } catch { - case ex: NoCommonType => - } - if (lubType.decls.isEmpty) lubBase else lubType - } + existentialAbstraction(tparams, lubType) } // if (settings.debug.value) { // log(indent + "lub of " + ts + " at depth "+depth)//debug @@ -2855,7 +3076,7 @@ A type's symbol should never be inspected directly. /** The greatest lower bound wrt <:< of a list of types */ private def glb(ts: List[Type], depth: int): Type = { - def glb0(ts0: List[Type]): Type = elimSuper(ts0 map (.deconst)) match { + def glb0(ts0: List[Type]): Type = elimSuper(ts0 map (_.deconst)) match { case List() => AnyClass.tpe case List(t) => t case ts @ PolyType(tparams, _) :: _ => @@ -2866,9 +3087,10 @@ A type's symbol should never be inspected directly. case ts @ MethodType(pts, _) :: rest => MethodType(pts, glb0(matchingRestypes(ts, pts))) case ts @ TypeBounds(_, _) :: rest => - mkTypeBounds(lub(ts map (.bounds.lo), depth), glb(ts map (.bounds.hi), depth)) - case ts => + mkTypeBounds(lub(ts map (_.bounds.lo), depth), glb(ts map (_.bounds.hi), depth)) + case ts0 => try { + val (ts, tparams) = stripExistentials(ts0) val glbOwner = commonOwner(ts) def refinedToParents(t: Type): List[Type] = t match { case RefinedType(ps, _) => ps flatMap refinedToParents @@ -2876,52 +3098,54 @@ A type's symbol should never be inspected directly. } val ts1 = ts flatMap refinedToParents val glbBase = intersectionType(ts1, glbOwner) - if (phase.erasedTypes || depth == 0) glbBase - else { - val glbType = refinedType(ts1, glbOwner) - val glbThisType = glbType.symbol.thisType - def glbsym(proto: Symbol): Symbol = try { - val prototp = glbThisType.memberInfo(proto) - val syms = for { - val t <- ts - val alt <- t.nonPrivateMember(proto.name).alternatives - glbThisType.memberInfo(alt) matches prototp - } yield alt - val symtypes = syms map glbThisType.memberInfo - assert(!symtypes.isEmpty) - proto.cloneSymbol(glbType.symbol).setInfo( - if (proto.isTerm) glb(symtypes, depth-1) - else { - def isTypeBound(tp: Type) = tp match { - case TypeBounds(_, _) => true - case _ => false - } - def glbBounds(bnds: List[Type]): TypeBounds = { - val lo = lub(bnds map (.bounds.lo), depth-1) - val hi = glb(bnds map (.bounds.hi), depth-1) - if (lo <:< hi) mkTypeBounds(lo, hi) - else throw new MalformedClosure(bnds) + val glbType = + if (phase.erasedTypes || depth == 0) glbBase + else { + val glbRefined = refinedType(ts1, glbOwner) + val glbThisType = glbRefined.symbol.thisType + def glbsym(proto: Symbol): Symbol = { + val prototp = glbThisType.memberInfo(proto) + val syms = for { + val t <- ts + val alt <- t.nonPrivateMember(proto.name).alternatives + glbThisType.memberInfo(alt) matches prototp + } yield alt + val symtypes = syms map glbThisType.memberInfo + assert(!symtypes.isEmpty) + proto.cloneSymbol(glbRefined.symbol).setInfo( + if (proto.isTerm) glb(symtypes, depth-1) + else { + def isTypeBound(tp: Type) = tp match { + case TypeBounds(_, _) => true + case _ => false + } + def glbBounds(bnds: List[Type]): TypeBounds = { + val lo = lub(bnds map (_.bounds.lo), depth-1) + val hi = glb(bnds map (_.bounds.hi), depth-1) + if (lo <:< hi) mkTypeBounds(lo, hi) + else throw new MalformedClosure(bnds) + } + val symbounds = symtypes filter isTypeBound + var result: Type = + if (symbounds.isEmpty) + mkTypeBounds(AllClass.tpe, AnyClass.tpe) + else glbBounds(symbounds) + for (t <- symtypes if !isTypeBound(t)) + if (result.bounds containsType t) result = t + else throw new MalformedClosure(symtypes); + result + }) + } + for (t <- ts; val sym <- t.nonPrivateMembers) + if (!sym.isClass && !sym.isConstructor && !(glbThisType specializes sym)) + try { + addMember(glbThisType, glbRefined, glbsym(sym)) + } catch { + case ex: NoCommonType => } - val symbounds = symtypes filter isTypeBound - var result: Type = - if (symbounds.isEmpty) - mkTypeBounds(AllClass.tpe, AnyClass.tpe) - else glbBounds(symbounds) - for (t <- symtypes if !isTypeBound(t)) - if (result.bounds containsType t) result = t - else throw new MalformedClosure(symtypes); - result - }) + if (glbRefined.decls.isEmpty) glbBase else glbRefined } - for (t <- ts; val sym <- t.nonPrivateMembers) - if (!sym.isClass && !sym.isConstructor && !(glbThisType specializes sym)) - try { - addMember(glbThisType, glbType, glbsym(sym)) - } catch { - case ex: NoCommonType => - } - if (glbType.decls.isEmpty) glbBase else glbType - } + existentialAbstraction(tparams, glbType) } catch { case _: MalformedClosure => if (ts forall (t => AllRefClass.tpe <:< t)) AllRefClass.tpe @@ -2970,9 +3194,9 @@ A type's symbol should never be inspected directly. case List(tp) => Some(tp) case TypeRef(_, sym, _) :: rest => - val pres = tps map (.prefix) + val pres = tps map (_.prefix) val pre = if (variance == 1) lub(pres, depth) else glb(pres, depth) - val argss = tps map (.typeArgs) + val argss = tps map (_.typeArgs) val args = List.map2(sym.typeParams, List.transpose(argss)) { (tparam, as) => if (depth == 0) @@ -2989,15 +3213,15 @@ A type's symbol should never be inspected directly. } try { if (args contains NoType) None - else Some(typeRef(pre, sym, args, variance)) + else Some(typeRef(pre, sym, args)) } catch { case ex: MalformedType => None } case SingleType(_, sym) :: rest => - val pres = tps map (.prefix) + val pres = tps map (_.prefix) val pre = if (variance == 1) lub(pres, depth) else glb(pres, depth) try { - Some(singleType(pre, sym, variance)) + Some(singleType(pre, sym)) } catch { case ex: MalformedType => None } @@ -3111,9 +3335,4 @@ A type's symbol should never be inspected directly. val s = checkMalformedSwitch try { checkMalformedSwitch = false; op } finally { checkMalformedSwitch = s } } - - def withNoGlobalVariance[T](op: => T): T = { - val s = globalVariance - try { globalVariance = 0; op } finally { globalVariance = s } - } } diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index 153c0a88d8..3a52959622 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -209,13 +209,13 @@ abstract class ClassfileParser { } else { val owner = if (static) ownerTpe.symbol.linkedClassOfClass else ownerTpe.symbol // println("\t" + owner.info.member(name).tpe.widen + " =:= " + tpe) - f = owner.info.member(name).suchThat(.tpe.widen.=:=(tpe)) + f = owner.info.member(name).suchThat(_.tpe.widen =:= tpe) if (f == NoSymbol) - f = owner.info.member(newTermName(name.toString + nme.LOCAL_SUFFIX)).suchThat(.tpe.=:=(tpe)) + f = owner.info.member(newTermName(name.toString + nme.LOCAL_SUFFIX)).suchThat(_.tpe =:= tpe) if (f == NoSymbol) { // if it's an impl class, try to find it's static member inside the class assert(ownerTpe.symbol.isImplClass, "Not an implementation class: " + owner + " couldn't find " + name + ": " + tpe + " inside: \n" + ownerTpe.members); - f = ownerTpe.member(name).suchThat(.tpe.=:=(tpe)) + f = ownerTpe.member(name).suchThat(_.tpe =:= tpe) // println("\townerTpe.decls: " + ownerTpe.decls) // println("Looking for: " + name + ": " + tpe + " inside: " + ownerTpe.symbol + "\n\tand found: " + ownerTpe.members) } diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/PickleFormat.scala b/src/compiler/scala/tools/nsc/symtab/classfile/PickleFormat.scala index b3a9d148b4..ca6e05a4f8 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/PickleFormat.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/PickleFormat.scala @@ -196,6 +196,7 @@ object PickleFormat { final val LABELSYMBOLrsym = 9 final val DEBRUIJNINDEXtpe = 47 + final val EXISTENTIALtpe = 48 final val firstSymTag = NONEsym final val lastSymTag = VALsym diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala index 516ba3b0d7..8167f58aaf 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala @@ -109,7 +109,7 @@ abstract class Pickler extends SubComponent { putType(sym.typeOfThis); putSymbol(sym.alias) if (!sym.children.isEmpty) { - val (locals, globals) = sym.children.toList.partition(.isLocalClass) + val (locals, globals) = sym.children.toList.partition(_.isLocalClass) val children = if (locals.isEmpty) globals else { @@ -158,6 +158,8 @@ abstract class Pickler extends SubComponent { putType(restpe); putTypes(formals) case PolyType(tparams, restpe) => putType(restpe); putSymbols(tparams) + case ExistentialType(tparams, restpe) => + putType(restpe); putSymbols(tparams) case AnnotatedType(attribs, tp) => putType(tp); putAnnotations(attribs) case _ => @@ -389,6 +391,8 @@ abstract class Pickler extends SubComponent { else METHODtpe case PolyType(tparams, restpe) => writeRef(restpe); writeRefs(tparams); POLYtpe + case ExistentialType(tparams, restpe) => + writeRef(restpe); writeRefs(tparams); EXISTENTIALtpe case DeBruijnIndex(l, i) => writeNat(l); writeNat(i); DEBRUIJNINDEXtpe case c @ Constant(_) => diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala index 70735b79ff..7783e7cb7c 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala @@ -254,6 +254,9 @@ abstract class UnPickler { case POLYtpe => val restpe = readTypeRef() PolyType(until(end, readSymbolRef), restpe) + case EXISTENTIALtpe => + val restpe = readTypeRef() + ExistentialType(until(end, readSymbolRef), restpe) case ANNOTATEDtpe => val tp = readTypeRef() val attribs = until(end, readTreeAttribRef) diff --git a/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala b/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala index a750bf0301..a82e398814 100644 --- a/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala @@ -199,7 +199,7 @@ abstract class TypeParser { || adder.IsFamilyAndAssembly)) { assert(adder.ReturnType == clrTypes.VOID); - assert(adder.GetParameters().map(.ParameterType).toList == List(event.EventHandlerType)); + assert(adder.GetParameters().map(_.ParameterType).toList == List(event.EventHandlerType)); val name = encode("+="); val flags = translateAttributes(adder); val mtype: Type = methodType(adder, adder.ReturnType); @@ -210,7 +210,7 @@ abstract class TypeParser { || remover.IsFamilyAndAssembly)) { assert(remover.ReturnType == clrTypes.VOID); - assert(remover.GetParameters().map(.ParameterType).toList == List(event.EventHandlerType)); + assert(remover.GetParameters().map(_.ParameterType).toList == List(event.EventHandlerType)); val name = encode("-="); val flags = translateAttributes(remover); val mtype: Type = methodType(remover, remover.ReturnType); @@ -301,7 +301,7 @@ abstract class TypeParser { private def createDelegateView(typ: MSILType) = { val invoke: MethodInfo = typ.GetMember("Invoke")(0).asInstanceOf[MethodInfo]; val invokeRetType: Type = getCLRType(invoke.ReturnType); - val invokeParamTypes: List[Type] =invoke.GetParameters().map(.ParameterType).map(getCLSType).toList; + val invokeParamTypes: List[Type] =invoke.GetParameters().map(_.ParameterType).map(getCLSType).toList; val funType: Type = definitions.functionType(invokeParamTypes, invokeRetType); val typClrType: Type = getCLRType(typ); @@ -355,7 +355,7 @@ abstract class TypeParser { /** Return a method type for the given method. */ private def methodType(method: MethodBase, rettype: Type): Type = - methodType(method.GetParameters().map(.ParameterType), rettype); + methodType(method.GetParameters().map(_.ParameterType), rettype); /** Return a method type for the provided argument types and return type. */ private def methodType(argtypes: Array[MSILType], rettype: Type): Type = { diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala index 98efdb426a..748d27dc98 100644 --- a/src/compiler/scala/tools/nsc/transform/Constructors.scala +++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala @@ -36,7 +36,7 @@ abstract class Constructors extends Transform { case ddef @ DefDef(_, _, _, List(vparams), _, rhs @ Block(_, Literal(_))) => if (ddef.symbol.isPrimaryConstructor) { constr = ddef - constrParams = vparams map (.symbol) + constrParams = vparams map (_.symbol) constrBody = rhs } case _ => diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index 1acaee1fa8..bb42922961 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -58,7 +58,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer { * */ val erasure = new TypeMap { - def apply(tp: Type): Type = { //val tp = tp0.normalize MARTIN: I don't think this is needed? + def apply(tp: Type): Type = { tp match { case ConstantType(_) => tp @@ -77,6 +77,8 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer { else apply(sym.info) case PolyType(tparams, restpe) => apply(restpe) + case ExistentialType(tparams, restpe) => + apply(restpe) case MethodType(formals, restpe) => MethodType( formals map apply, @@ -108,7 +110,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer { private def removeDoubleObject(tps: List[Type]): List[Type] = tps match { case List() => List() case tp :: tps1 => - if (tp.symbol == ObjectClass) tp :: tps1.filter(.symbol.!=(ObjectClass)) + if (tp.symbol == ObjectClass) tp :: tps1.filter(_.symbol != ObjectClass) else tp :: removeDoubleObject(tps1) } diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala index 981f137dcc..6cc8605b82 100644 --- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala +++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala @@ -319,7 +319,7 @@ abstract class LambdaLift extends InfoTransform { tree match { case DefDef(mods, name, tparams, List(vparams), tpt, rhs) => sym.updateInfo( - lifted(MethodType(sym.info.paramTypes ::: (ps map (.tpe)), sym.info.resultType))); + lifted(MethodType(sym.info.paramTypes ::: (ps map (_.tpe)), sym.info.resultType))); copy.DefDef(tree, mods, name, tparams, List(vparams ::: freeParams), tpt, rhs) case ClassDef(mods, name, tparams, impl @ Template(parents, self, body)) => copy.ClassDef(tree, mods, name, tparams, diff --git a/src/compiler/scala/tools/nsc/transform/LiftCode.scala b/src/compiler/scala/tools/nsc/transform/LiftCode.scala index 1359eafcf9..18f3983a62 100644 --- a/src/compiler/scala/tools/nsc/transform/LiftCode.scala +++ b/src/compiler/scala/tools/nsc/transform/LiftCode.scala @@ -56,7 +56,7 @@ abstract class LiftCode extends Transform { case Some(tgt) => tgt } def hasAllTargets: Boolean = - targets.elements.map(._2).forall { + targets.elements.map(_._2).forall { case Some(_) => true case None => false } @@ -100,7 +100,7 @@ abstract class LiftCode extends Transform { reflect.Apply(reify(fun), args map reify) case TypeApply(fun, args) => - reflect.TypeApply(reify(fun), args map (.tpe) map reify) + reflect.TypeApply(reify(fun), args map (_.tpe) map reify) case Function(vparams, body) => var env1 = env @@ -109,7 +109,7 @@ abstract class LiftCode extends Transform { currentOwner, vparam.symbol.name.toString(), reify(vparam.symbol.tpe)); env1.update(vparam.symbol, local); } - reflect.Function(vparams map (.symbol) map env1, + reflect.Function(vparams map (_.symbol) map env1, new Reifier(env1, currentOwner).reify(body)) case This(_) => reflect.This(reify(tree.symbol)) diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala index b41336c9f0..c02691aa5a 100644 --- a/src/compiler/scala/tools/nsc/transform/Mixin.scala +++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala @@ -452,7 +452,7 @@ abstract class Mixin extends InfoTransform { * newDefs. */ def add(stats: List[Tree], newDefs: List[Tree]) = { - val newSyms = newDefs map (.symbol) + val newSyms = newDefs map (_.symbol) def isNotDuplicate(tree: Tree) = tree match { case DefDef(_, _, _, _, _, _) => val sym = tree.symbol; diff --git a/src/compiler/scala/tools/nsc/transform/SymbolReifier.scala b/src/compiler/scala/tools/nsc/transform/SymbolReifier.scala index 5462451a5d..6e26ac8a07 100644 --- a/src/compiler/scala/tools/nsc/transform/SymbolReifier.scala +++ b/src/compiler/scala/tools/nsc/transform/SymbolReifier.scala @@ -84,6 +84,7 @@ trait SymbolReifier { tparams.map(reify), boundss, reify(result)) + //todo: treat ExistentialType case AnnotatedType(attribs, tp) => reify(tp) case _ => @@ -141,6 +142,7 @@ trait SymbolReifier { MethodType(formals.map(unreify), unreify(restpe)) case reflect.PolyType(typeParams, typeBounds, resultType) => PolyType(typeParams.map(unreify), unreify(resultType)) + //todo: treat ExistentialType case _ => NoType } diff --git a/src/compiler/scala/tools/nsc/transform/TailCalls.scala b/src/compiler/scala/tools/nsc/transform/TailCalls.scala index 7862398495..567afe73ea 100644 --- a/src/compiler/scala/tools/nsc/transform/TailCalls.scala +++ b/src/compiler/scala/tools/nsc/transform/TailCalls.scala @@ -159,9 +159,9 @@ abstract class TailCalls extends Transform log(" Considering " + name + " for tailcalls") tree.symbol.tpe match { case PolyType(tpes, restpe) => - newCtx.tparams = tparams map (.symbol) + newCtx.tparams = tparams map (_.symbol) newCtx.label.setInfo( - restpe.substSym(tpes, tparams map (.symbol))) + restpe.substSym(tpes, tparams map (_.symbol))) case _ => () } @@ -172,7 +172,7 @@ abstract class TailCalls extends Transform newRHS = typed(atPos(tree.pos)( LabelDef(newCtx.label, - List.flatten(vparams) map (.symbol), + List.flatten(vparams) map (_.symbol), newRHS))); copy.DefDef(tree, mods, name, tparams, vparams, tpt, newRHS); } else @@ -239,7 +239,7 @@ abstract class TailCalls extends Transform case Apply(tapply @ TypeApply(fun, targs), vargs) => if ( ctx.currentMethod.isFinal && ctx.tailPos && - isSameTypes(ctx.tparams, targs map (.tpe.symbol)) && + isSameTypes(ctx.tparams, targs map (_.tpe.symbol)) && isRecursiveCall(fun)) rewriteTailCall(fun, transformTrees(vargs, mkContext(ctx, false))) else diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index 1f4698c214..79f2b0c734 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -381,13 +381,13 @@ abstract class UnCurry extends InfoTransform with TypingTransformers { case Apply(Select(Block(List(), Function(vparams, body)), nme.apply), args) => // perform beta-reduction; this helps keep view applications small withNeedLift(true) { - mainTransform(new TreeSubstituter(vparams map (.symbol), args).transform(body)) + mainTransform(new TreeSubstituter(vparams map (_.symbol), args).transform(body)) } case Apply(Select(Function(vparams, body), nme.apply), args) => // perform beta-reduction; this helps keep view applications small withNeedLift(true) { - mainTransform(new TreeSubstituter(vparams map (.symbol), args).transform(body)) + mainTransform(new TreeSubstituter(vparams map (_.symbol), args).transform(body)) } case UnApply(fn, args) => diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 9f5b1e2b35..3dd67a2f96 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -14,7 +14,7 @@ import scala.tools.nsc.util.{Position,NoPosition} * @author Martin Odersky * @version 1.0 */ -trait Contexts requires Analyzer { +trait Contexts { self: Analyzer => import global._ val NoContext = new Context { @@ -470,7 +470,7 @@ trait Contexts requires Analyzer { /** Is name imported explicitly, not via wildcard? */ def isExplicitImport(name: Name): boolean = - tree.selectors exists (._2.==(name.toTermName)) + tree.selectors exists (_._2 == name.toTermName) /** The symbol with name name imported from import clause * tree. diff --git a/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala b/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala index 0077da5a8f..02ccd6322e 100644 --- a/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala +++ b/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala @@ -14,7 +14,7 @@ import symtab.Flags._ * @author Martin Odersky * @version 1.0 */ -trait EtaExpansion requires Analyzer { +trait EtaExpansion { self: Analyzer => import global._ import posAssigner.atPos diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index 6ce9514f54..0cb6aef48e 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -124,20 +124,6 @@ trait Infer { } } - /** Do type arguments targs conform to formal parameters - * tparams? - * - * @param tparams ... - * @param targs ... - * @return ... - */ - private def isWithinBounds(pre: Type, owner: Symbol, tparams: List[Symbol], targs: List[Type]): boolean = { - val bounds = tparams map { tparam => - tparam.info.asSeenFrom(pre, owner).instantiateTypeParams(tparams, targs).bounds - } - !(List.map2(bounds, targs)((bound, targ) => bound containsType targ) contains false) - } - /** Solve constraint collected in types tvars. * * @param tvars All type variables to be instantiated. @@ -147,55 +133,10 @@ trait Infer { * @param upper When true search for max solution else min. * @throws NoInstance */ - private def solve(tvars: List[TypeVar], tparams: List[Symbol], - variances: List[int], upper: boolean): List[Type] = { - val config = tvars zip (tparams zip variances) - - def solveOne(tvar: TypeVar, tparam: Symbol, variance: int): unit = { - if (tvar.constr.inst == NoType) { - val up = if (variance != CONTRAVARIANT) upper else !upper - tvar.constr.inst = null - val bound: Type = if (up) tparam.info.bounds.hi else tparam.info.bounds.lo - // Console.println("solveOne0 "+tvar+" "+config+" "+bound);//DEBUG - var cyclic = bound contains tparam - for ((tvar2, (tparam2, variance2)) <- config) { - if (tparam2 != tparam && - ((bound contains tparam2) || - up && (tparam2.info.bounds.lo =:= tparam.tpe) || //@M TODO: might be affected by change to tpe in Symbol - !up && (tparam2.info.bounds.hi =:= tparam.tpe))) { //@M TODO: might be affected by change to tpe in Symbol - if (tvar2.constr.inst eq null) cyclic = true - solveOne(tvar2, tparam2, variance2) - } - } - if (!cyclic) { - if (up) { - if (bound.symbol != AnyClass) { - tvar.constr.hibounds = - bound.instantiateTypeParams(tparams, tvars) :: tvar.constr.hibounds - } - for (tparam2 <- tparams) - if (tparam2.info.bounds.lo =:= tparam.tpe) //@M TODO: might be affected by change to tpe in Symbol - tvar.constr.hibounds = - tparam2.tpe.instantiateTypeParams(tparams, tvars) :: tvar.constr.hibounds - } else { - if (bound.symbol != AllClass && bound.symbol != tparam) { - tvar.constr.lobounds = - bound.instantiateTypeParams(tparams, tvars) :: tvar.constr.lobounds - } - for (tparam2 <- tparams) - if (tparam2.info.bounds.hi =:= tparam.tpe) //@M TODO: might be affected by change to tpe in Symbol - tvar.constr.lobounds = - tparam2.tpe.instantiateTypeParams(tparams, tvars) :: tvar.constr.lobounds - } - } - tvar.constr.inst = NoType // necessary because hibounds/lobounds may contain tvar - //Console.println("solving "+tvar+" "+up+" "+(if (up) (tvar.constr.hibounds) else tvar.constr.lobounds))//DEBUG - tvar.constr.inst = if (up) glb(tvar.constr.hibounds) else lub(tvar.constr.lobounds) - assertNonCyclic(tvar)//debug - } - } - for ((tvar, (tparam, variance)) <- config) - solveOne(tvar, tparam, variance) + private def solvedTypes(tvars: List[TypeVar], tparams: List[Symbol], + variances: List[int], upper: boolean): List[Type] = { + solve(tvars, tparams, variances, upper) + for (val tvar <- tvars) assert(tvar.constr.inst != tvar, tvar.origin) tvars map instantiate } @@ -445,7 +386,7 @@ trait Infer { val tvars = tparams map freshVar if (isCompatible(restpe.instantiateTypeParams(tparams, tvars), pt)) { try { - solve(tvars, tparams, tparams map varianceInType(restpe), false) + solvedTypes(tvars, tparams, tparams map varianceInType(restpe), false) } catch { case ex: NoInstance => null } @@ -550,7 +491,7 @@ trait Infer { } () } - val targs = solve(tvars, tparams, tparams map varianceInTypes(formals), false) + val targs = solvedTypes(tvars, tparams, tparams map varianceInTypes(formals), false) List.map2(tparams, targs) {(tparam, targ) => if (targ.symbol == AllClass && (varianceInType(restpe)(tparam) & COVARIANT) == 0) { uninstantiated += tparam @@ -657,11 +598,11 @@ trait Infer { " do not conform to the expected kinds of the type parameters "+ tparams.mkString("(", ",", ")") + tparams.head.locationString+ "." + kindErrors.toList.mkString("\n", ", ", "")) else if (!isWithinBounds(pre, owner, tparams, targs)) { - if (!(targs exists (.isErroneous)) && !(tparams exists (.isErroneous))) { + if (!(targs exists (_.isErroneous)) && !(tparams exists (_.isErroneous))) { error(pos, prefix + "type arguments " + targs.mkString("[", ",", "]") + " do not conform to " + tparams.head.owner + "'s type parameter bounds " + - (tparams map (.defString)).mkString("[", ",", "]")) + (tparams map (_.defString)).mkString("[", ",", "]")) } if (settings.explaintypes.value) { val bounds = tparams map (tp => tp.info.instantiateTypeParams(tparams, targs).bounds) @@ -816,7 +757,7 @@ trait Infer { case MethodType(formals0, _) => try { val formals = formalTypes(formals0, args.length) - val argtpes = actualTypes(args map (.tpe.deconst), formals.length) + val argtpes = actualTypes(args map (_.tpe.deconst), formals.length) val restpe = fn.tpe.resultType(argtpes) val uninstantiated = new ListBuffer[Symbol] val targs = methTypeArgs(undetparams, formals, restpe, argtpes, pt, uninstantiated) @@ -833,7 +774,7 @@ trait Infer { "no type parameters for " + applyErrorMsg( fn, " exist so that it can be applied to arguments ", - args map (.tpe.widen), WildcardType) + + args map (_.tpe.widen), WildcardType) + "\n --- because ---\n" + ex.getMessage()) List() } @@ -891,7 +832,7 @@ trait Infer { */ def computeArgs = try { - val targs = solve(tvars, undetparams, undetparams map varianceInType(restpe), true) + val targs = solvedTypes(tvars, undetparams, undetparams map varianceInType(restpe), true) checkBounds(tree.pos, NoPrefix, NoSymbol, undetparams, targs, "inferred ") new TreeTypeSubstituter(undetparams, targs).traverse(tree) } catch { @@ -933,7 +874,7 @@ trait Infer { tvar.constr.inst != NoType && isFullyDefined(tvar.constr.inst) && (tparam.info.bounds containsType tvar.constr.inst)) { - context.nextEnclosing(.tree.isInstanceOf[CaseDef]).pushTypeBounds(tparam) + context.nextEnclosing(_.tree.isInstanceOf[CaseDef]).pushTypeBounds(tparam) tparam setInfo tvar.constr.inst tparam resetFlag DEFERRED if (settings.debug.value) log("new alias of " + tparam + " = " + tparam.info) @@ -947,7 +888,7 @@ trait Infer { if (!(lo <:< hi)) { if (settings.debug.value) log("inconsistent: "+tparam+" "+lo+" "+hi) } else if (!((lo <:< tparam.info.bounds.lo) && (tparam.info.bounds.hi <:< hi))) { - context.nextEnclosing(.tree.isInstanceOf[CaseDef]).pushTypeBounds(tparam) + context.nextEnclosing(_.tree.isInstanceOf[CaseDef]).pushTypeBounds(tparam) tparam setInfo mkTypeBounds(lo, hi) if (settings.debug.value) log("new bounds of " + tparam + " = " + tparam.info) } else { @@ -1192,7 +1133,7 @@ trait Infer { inferMethodAlternative(tree, undetparams, argtpes, WildcardType) } } else if (!competing.isEmpty) { - if (!(argtpes exists (.isErroneous)) && !pt.isErroneous) + if (!(argtpes exists (_.isErroneous)) && !pt.isErroneous) context.ambiguousError(tree.pos, pre, best, competing.head, "argument types " + argtpes.mkString("(", ",", ")") + (if (pt == WildcardType) "" else " and expected result type " + pt)) @@ -1252,7 +1193,7 @@ trait Infer { if (sym0.hasFlag(OVERLOADED)) { val sym = sym0 filter { alt => isWithinBounds(pre, alt.owner, alt.typeParams, argtypes) } if (sym == NoSymbol) { - if (!(argtypes exists (.isErroneous))) { + if (!(argtypes exists (_.isErroneous))) { error( tree.pos, "type arguments " + argtypes.mkString("[", ",", "]") + @@ -1264,7 +1205,7 @@ trait Infer { if (sym.hasFlag(OVERLOADED)) { val tparams = new AsSeenFromMap(pre, sym.alternatives.head.owner).mapOver( sym.alternatives.head.typeParams) - val bounds = tparams map (.tpe) //@M TODO: might be affected by change to tpe in Symbol + val bounds = tparams map (_.tpe) //@M TODO: might be affected by change to tpe in Symbol val tpe = PolyType(tparams, OverloadedType(AntiPolyType(pre, bounds), sym.alternatives)) diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 2d48cef72c..2ea69a2914 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -15,7 +15,7 @@ import symtab.Flags._ * @author Martin Odersky * @version 1.0 */ -trait Namers requires Analyzer { +trait Namers { self: Analyzer => import global._ import definitions._ @@ -209,12 +209,12 @@ trait Namers requires Analyzer { } def newTypeSkolems(tparams: List[Symbol]): List[Symbol] = { - val tskolems = tparams map (.newTypeSkolem) + val tskolems = tparams map (_.newTypeSkolem) val ltp = new LazyType { override def complete(sym: Symbol): unit = sym setInfo sym.deSkolemize.info.substSym(tparams, tskolems) //@M the info of a skolem is the skolemized info of the actual type parameter of the skolem } - tskolems foreach (.setInfo(ltp)) + tskolems foreach (_.setInfo(ltp)) tskolems } @@ -222,7 +222,7 @@ trait Namers requires Analyzer { * (a skolem is a representation of a bound variable when viewed outside its scope) */ def skolemize(tparams: List[AbsTypeDef]): unit = { - val tskolems = newTypeSkolems(tparams map (.symbol)) + val tskolems = newTypeSkolems(tparams map (_.symbol)) for ((tparam, tskolem) <- tparams zip tskolems) tparam.symbol = tskolem } @@ -235,7 +235,7 @@ trait Namers requires Analyzer { /** A class representing a lazy type with known type parameters. */ class LazyPolyType(tparams: List[Tree], restp: Type, owner: Tree, ownerSym: Symbol, ctx: Context) extends LazyType { //@M - override val typeParams: List[Symbol]= tparams map (.symbol) //@M + override val typeParams: List[Symbol]= tparams map (_.symbol) //@M override def complete(sym: Symbol): unit = { if(ownerSym.isAbstractType) //@M an abstract type's type parameters are entered new Namer(ctx.makeNewScope(owner, ownerSym)).enterSyms(tparams) //@M @@ -420,7 +420,7 @@ trait Namers requires Analyzer { enterInScope(param.symbol) param.symbol } else param.symbol - vparamss.map(.map(enterValueParam)) + vparamss.map(_.map(enterValueParam)) } private def templateSig(templ: Template): Type = { @@ -473,7 +473,7 @@ trait Namers requires Analyzer { if (tpt.isEmpty && meth.name == nme.CONSTRUCTOR) tpt.tpe = context.enclClass.owner.tpe if (onlyPresentation) - methodArgumentNames(meth) = vparamss.map(.map(.symbol)); + methodArgumentNames(meth) = vparamss.map(_.map(_.symbol)); def convertToDeBruijn(vparams: List[Symbol], level: int): TypeMap = new TypeMap { def apply(tp: Type) = { @@ -534,7 +534,7 @@ trait Namers requires Analyzer { sym != NoSymbol && (site.memberType(sym) matches thisMethodType(resultPt))) // fill in result type and parameter types from overridden symbol if there is a unique one. - if (meth.owner.isClass && (tpt.isEmpty || vparamss.exists(.exists(.tpt.isEmpty)))) { + if (meth.owner.isClass && (tpt.isEmpty || vparamss.exists(_.exists(_.tpt.isEmpty)))) { // try to complete from matching definition in base type for (vparams <- vparamss; vparam <- vparams) if (vparam.tpt.isEmpty) vparam.symbol setInfo WildcardType @@ -570,7 +570,7 @@ trait Namers requires Analyzer { } // Add a () parameter section if this overrides dome method with () parameters. if (meth.owner.isClass && vparamss.isEmpty && overriddenSymbol.alternatives.exists( - .info.isInstanceOf[MethodType])) { + _.info.isInstanceOf[MethodType])) { vparamSymss = List(List()) } for (vparams <- vparamss; vparam <- vparams if vparam.tpt.isEmpty) { @@ -580,7 +580,7 @@ trait Namers requires Analyzer { thisMethodType( if (tpt.isEmpty) { - val pt = resultPt.substSym(tparamSyms, tparams map (.symbol)) + val pt = resultPt.substSym(tparamSyms, tparams map (_.symbol)) tpt.tpe = deconstIfNotFinal(meth, typer.computeType(rhs, pt)) tpt.tpe } else typer.typedType(tpt).tpe) diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index c16af6a066..c81e28a398 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -425,6 +425,8 @@ abstract class RefChecks extends InfoTransform { validateVariance(result, variance) case PolyType(tparams, result) => validateVariance(result, variance) + case ExistentialType(tparams, result) => + validateVariance(result, variance) case AnnotatedType(attribs, tp) => validateVariance(tp, variance) } @@ -678,7 +680,7 @@ abstract class RefChecks extends InfoTransform { unit.deprecationWarning( tree.pos, symbol.toString + " overrides concrete, non-deprecated symbol(s):" + - concrOvers.map(.fullNameString).mkString(" ", ", ", "")) + concrOvers.map(_.fullNameString).mkString(" ", ", ", "")) } } @@ -721,7 +723,7 @@ abstract class RefChecks extends InfoTransform { } traverse tree.tpe case TypeApply(fn, args) => - checkBounds(NoPrefix, NoSymbol, fn.tpe.typeParams, args map (.tpe)) + checkBounds(NoPrefix, NoSymbol, fn.tpe.typeParams, args map (_.tpe)) if (sym.isSourceMethod && sym.hasFlag(CASE)) result = toConstructor(tree.pos, tree.tpe) case Apply( diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala index a623a67fd4..8fc956715b 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala @@ -40,7 +40,7 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT private var accDefs: List[(Symbol, ListBuffer[Tree])] = List() private def accDefBuf(clazz: Symbol) = - accDefs.dropWhile(._1.!=(clazz)).head._2 + accDefs.dropWhile(_._1 != clazz).head._2 private def transformArgs(args: List[Tree], formals: List[Type]) = { if (!formals.isEmpty && formals.last.symbol == definitions.ByNameParamClass) @@ -106,7 +106,7 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT if (tree.isTerm && mix == nme.EMPTY.toTypeName && (clazz.isTrait || clazz != currentOwner.enclClass || !validCurrentOwner)) { val supername = nme.superName(sym.name) - var superAcc = clazz.info.decl(supername).suchThat(.alias.==(sym)) + var superAcc = clazz.info.decl(supername).suchThat(_.alias == sym) if (superAcc == NoSymbol) { if (settings.debug.value) log("add super acc " + sym + sym.locationString + " to `" + clazz);//debug superAcc = diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala index d91426867d..5ccad3b5f0 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala @@ -26,7 +26,7 @@ import scala.collection.mutable.ListBuffer * * */ -trait SyntheticMethods requires Analyzer { +trait SyntheticMethods { self: Analyzer => import global._ // the global environment import definitions._ // standard classes and methods import typer.{typed} // methods to type trees @@ -80,7 +80,7 @@ trait SyntheticMethods requires Analyzer { } def productElementMethod(accs: List[Symbol]): Tree = { - //val retTpe = lub(accs map (.tpe.resultType)) + //val retTpe = lub(accs map (_.tpe.resultType)) val method = syntheticMethod(nme.productElement, FINAL, MethodType(List(IntClass.tpe), AnyClass.tpe/*retTpe*/)) typed(DefDef(method, vparamss => Match(Ident(vparamss.head.head), { (for ((sym,i) <- accs.zipWithIndex) yield { diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 3c6a56d8af..6122ef4615 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -22,7 +22,7 @@ import util.HashSet * @author Martin Odersky * @version 1.0 */ -trait Typers requires Analyzer { +trait Typers { self: Analyzer => import global._ import definitions._ import posAssigner.atPos @@ -284,9 +284,9 @@ trait Typers requires Analyzer { def checkParamsConvertible(pos: Position, tpe: Type): unit = tpe match { case MethodType(formals, restpe) => - if (formals.exists(.symbol.==(ByNameParamClass)) && formals.length != 1) + if (formals.exists(_.symbol == ByNameParamClass) && formals.length != 1) error(pos, "methods with `=>'-parameter can be converted to function values only if they take no other parameters") - if (formals exists (.symbol.==(RepeatedParamClass))) + if (formals exists (_.symbol == RepeatedParamClass)) error(pos, "methods with `*'-parameters cannot be converted to function values"); if (restpe.isDependent) error(pos, "method with dependent type "+tpe+" cannot be converted to function value"); @@ -306,7 +306,7 @@ trait Typers requires Analyzer { object checkNoEscaping extends TypeMap { private var owner: Symbol = _ private var scope: Scope = _ - private var badSymbol: Symbol = _ + private var hiddenSymbols: List[Symbol] = _ /** Check that type tree does not refer to private * components unless itself is wrapped in something private @@ -333,68 +333,60 @@ trait Typers requires Analyzer { def check[T <: Tree](owner: Symbol, scope: Scope, pt: Type, tree: T): T = { this.owner = owner this.scope = scope - badSymbol = NoSymbol + hiddenSymbols = List() apply(tree.tpe) - if (badSymbol == NoSymbol) tree - else if (badSymbol.isErroneous) setError(tree) - else if (isFullyDefined(pt)) tree setType pt - else if (tree.tpe.symbol.isAnonymousClass) + if (hiddenSymbols.isEmpty) tree + else if (hiddenSymbols exists (_.isErroneous)) setError(tree) + else if (isFullyDefined(pt)) tree setType pt //todo: eliminate + else if (tree.tpe.symbol.isAnonymousClass) // todo: eliminate check(owner, scope, pt, tree setType anonymousClassRefinement(tree.tpe.symbol)) - else { - val tp1 = try { - heal(tree.tpe) - } catch { - case ex: MalformedType => - tree.tpe - // revert to `tree.tpe', because the healing widening operation would introduce - // a malformed type - } - if (tp1 eq tree.tpe) { - error(tree.pos, - (if (badSymbol hasFlag PRIVATE) "private " else "") + badSymbol + - " escapes its defining scope as part of type "+tree.tpe) - setError(tree) - } else - check(owner, scope, pt, tree setType tp1) + else if (owner == NoSymbol) { // locals + val (tparams, tp1) = existentialTransform(hiddenSymbols.reverse, tree.tpe) +// Console.println("original type: "+tree.tpe) +// Console.println("exist params : "+tparams) +// Console.println("replaced type: "+tp1) + tree setType existentialAbstraction(tparams, tp1) +// Console.println("abstracted type: "+tree.tpe) +// tree + } else { // privates + val badSymbol = hiddenSymbols.head + error(tree.pos, + (if (badSymbol hasFlag PRIVATE) "private " else "") + badSymbol + + " escapes its defining scope as part of type "+tree.tpe) + setError(tree) } } - object heal extends TypeMap { - def apply(tp: Type): Type = tp match { - case SingleType(pre, sym) => - if ((variance == 1) && (pre contains badSymbol)) { - val tp1 = tp.widen - if (tp1 contains badSymbol) tp else tp1 - } else tp - case _ => - mapOver(tp) - } - } + def addHidden(sym: Symbol) = + if (!(hiddenSymbols contains sym)) hiddenSymbols = sym :: hiddenSymbols override def apply(t: Type): Type = { def checkNoEscape(sym: Symbol): unit = { if (sym.hasFlag(PRIVATE)) { var o = owner - var leaking = true while (o != NoSymbol && o != sym.owner && !o.isLocal && !o.hasFlag(PRIVATE) && !o.privateWithin.ownerChain.contains(sym.owner)) o = o.owner - if (o == sym.owner) badSymbol = sym + if (o == sym.owner) addHidden(sym) } else if (sym.owner.isTerm && !sym.isTypeParameterOrSkolem) { var e = scope.lookupEntry(sym.name) - while ((e ne null) && e.owner == scope && badSymbol == NoSymbol) { - if (e.sym == sym) badSymbol = e.sym - e = scope.lookupNextEntry(e) + var found = false + while (!found && (e ne null) && e.owner == scope) { + if (e.sym == sym) { + found = true + addHidden(sym) + } else { + e = scope.lookupNextEntry(e) + } } } } - if (badSymbol == NoSymbol) - t match { - case TypeRef(_, sym, _) => checkNoEscape(sym) - case SingleType(_, sym) => checkNoEscape(sym) - case _ => - } + t match { + case TypeRef(_, sym, _) => checkNoEscape(sym) + case SingleType(_, sym) => checkNoEscape(sym) + case _ => + } mapOver(t) } } @@ -643,7 +635,7 @@ trait Typers requires Analyzer { case _ => TypeTree(tree.tpe) setOriginal(tree) } } else if ((mode & (PATTERNmode | FUNmode)) == (PATTERNmode | FUNmode)) { // (5) - val constr = tree.symbol.filter(.isCaseFactory) + val constr = tree.symbol.filter(_.isCaseFactory) if (constr != NoSymbol) { val clazz = constr.tpe.finalResultType.symbol assert(clazz hasFlag CASE, tree) @@ -803,12 +795,12 @@ trait Typers requires Analyzer { val supertparams = if (supertpt.hasSymbol) supertpt.symbol.typeParams else List() var supertpe = supertpt.tpe if (!supertparams.isEmpty) - supertpe = PolyType(supertparams, appliedType(supertpe, supertparams map (.tpe))) + supertpe = PolyType(supertparams, appliedType(supertpe, supertparams map (_.tpe))) // A method to replace a super reference by a New in a supercall def transformSuperCall(scall: Tree): Tree = (scall: @unchecked) match { case Apply(fn, args) => - copy.Apply(scall, transformSuperCall(fn), args map (.duplicate)) + copy.Apply(scall, transformSuperCall(fn), args map (_.duplicate)) case Select(Super(_, _), nme.CONSTRUCTOR) => copy.Select( scall, @@ -819,7 +811,7 @@ trait Typers requires Analyzer { treeInfo.firstConstructor(templ.body) match { case constr @ DefDef(_, _, _, vparamss, _, cbody @ Block(cstats, cunit)) => // Convert constructor body to block in environment and typecheck it - val cstats1: List[Tree] = cstats map (.duplicate) + val cstats1: List[Tree] = cstats map (_.duplicate) val scall = if (cstats.isEmpty) EmptyTree else cstats.last val cbody1 = scall match { case Apply(_, _) => @@ -834,7 +826,7 @@ trait Typers requires Analyzer { val cbody2 = newTyper(makeNewScope(outercontext, constr, outercontext.owner)) .typePrimaryConstrBody( - cbody1, supertparams, clazz.unsafeTypeParams, vparamss map (.map(.duplicate))) + cbody1, supertparams, clazz.unsafeTypeParams, vparamss map (_.map(_.duplicate))) scall match { case Apply(_, _) => @@ -927,7 +919,7 @@ trait Typers requires Analyzer { if (classinfo.expansiveRefs(tparam) contains tparam) { error(tparam.pos, "class graph is not finitary because type parameter "+tparam.name+" is expansively recursive") val newinfo = ClassInfoType( - classinfo.parents map (.instantiateTypeParams(List(tparam), List(AnyRefClass.tpe))), + classinfo.parents map (_.instantiateTypeParams(List(tparam), List(AnyRefClass.tpe))), classinfo.decls, clazz) clazz.setInfo { @@ -1117,7 +1109,7 @@ trait Typers requires Analyzer { List.map2(superParamAccessors, superArgs) { (superAcc, superArg) => superArg match { case Ident(name) => - if (vparamss.exists(.exists(vp => vp.symbol == superArg.symbol))) { + if (vparamss.exists(_.exists(_.symbol == superArg.symbol))) { var alias = superAcc.initialize.alias if (alias == NoSymbol) alias = superAcc.getter(superAcc.owner) @@ -1125,7 +1117,7 @@ trait Typers requires Analyzer { superClazz.info.nonPrivateMember(alias.name) != alias) alias = NoSymbol if (alias != NoSymbol) { - var ownAcc = clazz.info.decl(name).suchThat(.hasFlag(PARAMACCESSOR)) + var ownAcc = clazz.info.decl(name).suchThat(_.hasFlag(PARAMACCESSOR)) if ((ownAcc hasFlag ACCESSOR) && !(ownAcc hasFlag DEFERRED)) ownAcc = ownAcc.accessed if (!ownAcc.isVariable && !alias.accessed.isVariable) { @@ -1320,7 +1312,7 @@ trait Typers requires Analyzer { && // see bug901 for a reason why next conditions are neeed (pt.normalize.typeArgs.length - 1 == fun.vparams.length || - fun.vparams.exists(.tpt.isEmpty))) + fun.vparams.exists(_.tpt.isEmpty))) (pt.symbol, pt.normalize.typeArgs.init, pt.normalize.typeArgs.last) else (FunctionClass(fun.vparams.length), fun.vparams map (x => NoType), WildcardType) @@ -1349,7 +1341,7 @@ trait Typers requires Analyzer { checkNoEscaping.locals(context.scope, WildcardType, vparam.tpt); () } val body = checkNoEscaping.locals(context.scope, respt, typed(fun.body, respt)) - val formals = vparamSyms map (.tpe) + val formals = vparamSyms map (_.tpe) val restpe = body.tpe.deconst val funtpe = typeRef(clazz.tpe.prefix, clazz, formals ::: List(restpe)) val fun1 = copy.Function(fun, vparams, checkNoEscaping.locals(context.scope, restpe, body)) @@ -1493,13 +1485,13 @@ trait Typers requires Analyzer { context.undetparams = List() val args1 = typedArgs(args, argMode(fun, mode)) context.undetparams = undetparams - inferMethodAlternative(fun, context.undetparams, args1 map (.tpe.deconst), pt) + inferMethodAlternative(fun, context.undetparams, args1 map (_.tpe.deconst), pt) doTypedApply(tree, adapt(fun, funMode(mode), WildcardType), args1, mode, pt) case mt @ MethodType(formals0, _) => val formals = formalTypes(formals0, args.length) var args1 = actualArgs(tree.pos, args, formals.length) if (args1.length != args.length) { - silent(.doTypedApply(tree, fun, args1, mode, pt)) match { + silent(_.doTypedApply(tree, fun, args1, mode, pt)) match { case t: Tree => t case ex => errorTree(tree, "wrong number of arguments for "+treeSymTypeMsg(fun)) } @@ -1558,9 +1550,9 @@ trait Typers requires Analyzer { arg1 } val args2 = List.map2(args1, formals)(typedArgToPoly) - if (args2 exists (.tpe.isError)) setError(tree) + if (args2 exists (_.tpe.isError)) setError(tree) else { - if (settings.debug.value) log("infer method inst "+fun+", tparams = "+tparams+", args = "+args2.map(.tpe)+", pt = "+pt+", lobounds = "+tparams.map(.tpe.bounds.lo)+", parambounds = "+tparams.map(.info));//debug + if (settings.debug.value) log("infer method inst "+fun+", tparams = "+tparams+", args = "+args2.map(_.tpe)+", pt = "+pt+", lobounds = "+tparams.map(_.tpe.bounds.lo)+", parambounds = "+tparams.map(_.info));//debug val undetparams = inferMethodInstance(fun, tparams, args2, pt) val result = doTypedApply(tree, fun, args2, mode, pt) context.undetparams = undetparams @@ -1668,7 +1660,7 @@ trait Typers requires Analyzer { val attrScope = annType.decls .filter(sym => sym.isMethod && !sym.isConstructor && sym.hasFlag(JAVA)) val names = new collection.mutable.HashSet[Symbol] - names ++= attrScope.elements.filter(.isMethod) + names ++= attrScope.elements.filter(_.isMethod) if (args.length == 1) { names.retain(sym => sym.name != nme.value) } @@ -1702,6 +1694,38 @@ trait Typers requires Analyzer { } } + /** Given a set `rawSyms' of term- and type-symbols, and a type `tp'. + * produce a set of fresh type parameters and a type so that it can be + * abstracted to an existential type. + * Every type symbol `T' in `rawSyms' is mapped to a clone. + * Every term symbol `x' of type `T' in `rawSyms' is mapped to a type parameter + * + * type x.type <: T with + * + * The name of the type parameter is `x.type', to produce nice diagnostics. + * The parent ensures that the type parameter is still seen as a stable type. + * The new symbols are substituted for the old ones in all type parameter infos + * and in the returned type itself. + */ + protected def existentialTransform(rawSyms: List[Symbol], tp: Type) = { + val typeParams = rawSyms map { sym => + if (sym.isType) sym.cloneSymbol + else sym.owner.newAbstractType(sym.pos, newTermName(sym.name+".Type"))//todo: change to .type + .setInfo(mkTypeBounds(AllClass.tpe, sym.tpe)) + } + val typeParamTypes = typeParams map (_.tpe) + for (tparam <- typeParams) tparam.setInfo(tparam.info.subst(rawSyms, typeParamTypes)) + (typeParams, tp.subst(rawSyms, typeParamTypes)) + } + + protected def typedExistentialTypeTree(tree: ExistentialTypeTree): Tree = { + namer.enterSyms(tree.whereClauses) + val whereClauses1 = typedStats(tree.whereClauses, NoSymbol) + val tpt1 = typedType(tree.tpt) + val (typeParams, tpe) = existentialTransform(tree.whereClauses map (_.symbol), tpt1.tpe) + copy.ExistentialTypeTree(tree, tpt1, whereClauses1).setType(ExistentialType(typeParams, tpe)) + } + /** * @param tree ... * @param mode ... @@ -1854,7 +1878,7 @@ trait Typers requires Analyzer { context.undetparams = cloneSymbols(tpt1.symbol.typeParams) tpt1 = TypeTree() .setOriginal(tpt1) /* .setPos(tpt1.pos) */ - .setType(appliedType(tpt1.tpe, context.undetparams map (.tpe))) + .setType(appliedType(tpt1.tpe, context.undetparams map (_.tpe))) } if (tpt1.tpe.symbol hasFlag ABSTRACT) error(tree.pos, tpt1.tpe.symbol + " is abstract; cannot be instantiated") @@ -1915,7 +1939,7 @@ trait Typers requires Analyzer { def typedTypeApply(fun: Tree, args: List[Tree]): Tree = fun.tpe match { case OverloadedType(pre, alts) => - inferPolyAlternatives(fun, args map (.tpe)) + inferPolyAlternatives(fun, args map (_.tpe)) val tparams = fun.symbol.typeParams //@M TODO: fun.symbol.info.typeParams ? (as in typedAppliedTypeTree) assert(args.length == tparams.length) //@M: in case TypeApply we can't check the kind-arities // of the type arguments as we don't know which alternative to choose... here we do @@ -1926,7 +1950,7 @@ trait Typers requires Analyzer { typedTypeApply(fun, args1) case PolyType(tparams, restpe) if (tparams.length != 0) => if (tparams.length == args.length) { - val targs = args map (.tpe) + val targs = args map (_.tpe) checkBounds(tree.pos, NoPrefix, NoSymbol, tparams, targs, "") if (fun.symbol == Predef_classOf) { if (!targs.head.symbol.isClass || targs.head.symbol.isRefinementClass) @@ -1972,7 +1996,7 @@ trait Typers requires Analyzer { * @return ... */ def tryTypedApply(fun: Tree, args: List[Tree]): Tree = - silent(.doTypedApply(tree, fun, args, mode, pt)) match { + silent(_.doTypedApply(tree, fun, args, mode, pt)) match { case t: Tree => t case ex: TypeError => @@ -2013,7 +2037,7 @@ trait Typers requires Analyzer { typed1(tree, mode & ~PATTERNmode | EXPRmode, pt) } else { val funpt = if ((mode & PATTERNmode) != 0) pt else WildcardType - silent(.typed(fun, funMode(mode), funpt)) match { + silent(_.typed(fun, funMode(mode), funpt)) match { case fun1: Tree => val fun2 = if (stableApplication) stabilizeFun(fun1, mode, pt) else fun1 if (util.Statistics.enabled) appcnt = appcnt + 1 @@ -2087,7 +2111,7 @@ trait Typers requires Analyzer { mkAssign(qual) } if (settings.debug.value) log("retry assign: "+tree1) - silent(.typed1(tree1, mode, pt)) match { + silent(_.typed1(tree1, mode, pt)) match { case t: Tree => t case _ => @@ -2114,7 +2138,7 @@ trait Typers requires Analyzer { val ps = clazz.info.parents filter (p => p.symbol.name == mix) if (ps.isEmpty) { if (settings.debug.value) - Console.println(clazz.info.parents map (.symbol.name))//debug + Console.println(clazz.info.parents map (_.symbol.name))//debug error(tree.pos, mix+" does not name a parent class of "+clazz) ErrorType } else if (ps.tail.isEmpty) { @@ -2360,10 +2384,10 @@ trait Typers requires Analyzer { def typedCompoundTypeTree(templ: Template) = { val parents1 = List.mapConserve(templ.parents)(typedType) - if (parents1 exists (.tpe.isError)) tree setType ErrorType + if (parents1 exists (_.tpe.isError)) tree setType ErrorType else { val decls = newDecls(tree.asInstanceOf[CompoundTypeTree]) - val self = refinedType(parents1 map (.tpe), context.enclClass.owner, decls) + val self = refinedType(parents1 map (_.tpe), context.enclClass.owner, decls) newTyper(context.make(templ, self.symbol, decls)).typedRefinement(templ.body) tree setType self } @@ -2381,7 +2405,7 @@ trait Typers requires Analyzer { else map2Conserve(args, tparams) { (arg, tparam) => typedHigherKindedType(arg, parameterizedType(tparam.typeParams, AnyClass.tpe)) //@M! the polytype denotes the expected kind } - val argtypes = args1 map (.tpe) + val argtypes = args1 map (_.tpe) val owntype = if (tpt1.symbol.isClass || tpt1.symbol.isTypeMember) // @M! added the latter condition appliedType(tpt1.tpe, argtypes) else tpt1.tpe.instantiateTypeParams(tparams, argtypes) @@ -2491,7 +2515,7 @@ trait Typers requires Analyzer { } else { val selector1 = checkDead(typed(selector)) val cases1 = typedCases(tree, cases, selector1.tpe.widen, pt) - copy.Match(tree, selector1, cases1) setType ptOrLub(cases1 map (.tpe)) + copy.Match(tree, selector1, cases1) setType ptOrLub(cases1 map (_.tpe)) } case Return(expr) => @@ -2503,7 +2527,7 @@ trait Typers requires Analyzer { val finalizer1 = if (finalizer.isEmpty) finalizer else typed(finalizer, UnitClass.tpe) copy.Try(tree, block1, catches1, finalizer1) - .setType(ptOrLub(block1.tpe :: (catches1 map (.tpe)))) + .setType(ptOrLub(block1.tpe :: (catches1 map (_.tpe)))) case Throw(expr) => val expr1 = typed(expr, ThrowableClass.tpe) @@ -2627,6 +2651,9 @@ trait Typers requires Analyzer { case WildcardTypeTree(lo, hi) => tree setType mkTypeBounds(typedType(lo).tpe, typedType(hi).tpe) + case etpt @ ExistentialTypeTree(_, _) => + newTyper(makeNewScope(context, tree, context.owner)).typedExistentialTypeTree(etpt) + case TypeTree() => // we should get here only when something before failed // and we try again (@see tryTypedApply). In that case we can assign @@ -2719,19 +2746,19 @@ trait Typers requires Analyzer { /** Types a (fully parameterized) type tree */ def typedType(tree: Tree): Tree = - withNoGlobalVariance{ typed(tree, TYPEmode, WildcardType) } + typed(tree, TYPEmode, WildcardType) /** Types a higher-kinded type tree -- pt denotes the expected kind*/ def typedHigherKindedType(tree: Tree, pt: Type): Tree = if(pt.typeParams.isEmpty) typedType(tree) // kind is known and it's * - else withNoGlobalVariance{ typed(tree, HKmode, pt) } + else typed(tree, HKmode, pt) def typedHigherKindedType(tree: Tree): Tree = - withNoGlobalVariance{ typed(tree, HKmode, WildcardType) } + typed(tree, HKmode, WildcardType) /** Types a type constructor tree used in a new or supertype */ def typedTypeConstructor(tree: Tree): Tree = { - val result = withNoGlobalVariance{ typed(tree, TYPEmode | FUNmode, WildcardType) } + val result = typed(tree, TYPEmode | FUNmode, WildcardType) if (!phase.erasedTypes && result.tpe.isInstanceOf[TypeRef] && !result.tpe.prefix.isStable) error(tree.pos, result.tpe.prefix+" is not a legal prefix for a constructor") result setType(result.tpe) // @M: normalization is done during erasure @@ -2766,7 +2793,7 @@ trait Typers requires Analyzer { private def containsError(tp: Type): boolean = tp match { case PolyType(tparams, restpe) => containsError(restpe) - case MethodType(formals, restpe) => (formals exists (.isError)) || containsError(restpe) + case MethodType(formals, restpe) => (formals exists (_.isError)) || containsError(restpe) case _ => tp.isError } @@ -2918,7 +2945,7 @@ trait Typers requires Analyzer { def implicitsOfClass(tp: Type): List[ImplicitInfo] = tp match { case TypeRef(pre, clazz, _) => - clazz.initialize.linkedClassOfClass.info.members.toList.filter(.hasFlag(IMPLICIT)) map + clazz.initialize.linkedClassOfClass.info.members.toList.filter(_.hasFlag(IMPLICIT)) map (sym => new ImplicitInfo(sym.name, pre.memberType(clazz.linkedModuleOfClass), sym)) case _ => List() diff --git a/src/compiler/scala/tools/nsc/typechecker/Variances.scala b/src/compiler/scala/tools/nsc/typechecker/Variances.scala index 582cd028c5..41ca733914 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Variances.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Variances.scala @@ -79,6 +79,8 @@ trait Variances { flip(varianceInTypes(formals)(tparam)) & varianceInType(restpe)(tparam) case PolyType(tparams, restpe) => flip(varianceInSyms(tparams)(tparam)) & varianceInType(restpe)(tparam) + case ExistentialType(tparams, restpe) => + varianceInSyms(tparams)(tparam) & varianceInType(restpe)(tparam) case AnnotatedType(attribs, tp) => varianceInType(tp)(tparam) } diff --git a/src/library/scala/List.scala b/src/library/scala/List.scala index 386911b18e..1b1299b25a 100644 --- a/src/library/scala/List.scala +++ b/src/library/scala/List.scala @@ -711,6 +711,10 @@ sealed abstract class List[+A] extends Seq[A] { /** Returns all the elements of this list that satisfy the * predicate p. The order of the elements is preserved. + * It is guarenteed that the receiver list itself is returned iff all its + * elements satisfy the predicate `p'. Hence the following equality is valid: + * + * (xs filter p) eq xs == xs forall p * * @param p the predicate used to filter the list. * @return the elements of this list satisfying p. diff --git a/src/library/scala/Seq.scala b/src/library/scala/Seq.scala index c44c8fa552..f46517c9e4 100644 --- a/src/library/scala/Seq.scala +++ b/src/library/scala/Seq.scala @@ -268,7 +268,7 @@ trait Seq[+A] extends AnyRef with PartialFunction[Int, A] with Collection[A] { * @return true iff there is an element of this sequence * which is equal (w.r.t. ==) to elem. */ - def contains(elem: Any): Boolean = exists (.==(elem)) + def contains(elem: Any): Boolean = exists (_ == elem) /** Returns a subsequence starting from index from * consisting of len elements. diff --git a/src/library/scala/Symbol.scala b/src/library/scala/Symbol.scala index 6110fa07dd..92a4e838f0 100644 --- a/src/library/scala/Symbol.scala +++ b/src/library/scala/Symbol.scala @@ -48,7 +48,7 @@ final case class Symbol(name: String) { * @return the unique reference to this symbol. */ def intern: Symbol = internedSymbols.synchronized { - internedSymbols.get(this).map(.get).getOrElse(None) match { + internedSymbols.get(this).map(_.get).getOrElse(None) match { case Some(sym) => sym case _ => internedSymbols(this) = new ref.WeakReference(this); this diff --git a/src/library/scala/collection/Map.scala b/src/library/scala/collection/Map.scala index 3dfa5d999f..015bda5f21 100644 --- a/src/library/scala/collection/Map.scala +++ b/src/library/scala/collection/Map.scala @@ -113,7 +113,7 @@ trait Map[A, +B] extends PartialFunction[A, B] with Collection[(A, B)] { def keySet: Set[A] = new Set[A] { def size = Map.this.size def contains(key : A) = Map.this.contains(key) - def elements = Map.this.elements.map(._1) + def elements = Map.this.elements.map(_._1) } /** Creates an iterator for a contained values. diff --git a/src/library/scala/collection/SortedMap.scala b/src/library/scala/collection/SortedMap.scala index f645c9d9ba..d166ca3d7d 100644 --- a/src/library/scala/collection/SortedMap.scala +++ b/src/library/scala/collection/SortedMap.scala @@ -32,7 +32,7 @@ trait SortedMap[K,+E] extends Map[K,E] with Sorted[K,Tuple2[K,E]] { protected class DefaultKeySet extends SortedSet[K] { def size = SortedMap.this.size def contains(key : K) = SortedMap.this.contains(key) - def elements = SortedMap.this.elements.map(._1) + def elements = SortedMap.this.elements.map(_._1) def compare(k0 : K, k1 : K) = SortedMap.this.compare(k0, k1); override def rangeImpl(from : Option[K], until : Option[K]) : SortedSet[K] = { val map = SortedMap.this.rangeImpl(from,until); diff --git a/src/library/scala/collection/immutable/TreeSet.scala b/src/library/scala/collection/immutable/TreeSet.scala index 645308a658..4873426f38 100644 --- a/src/library/scala/collection/immutable/TreeSet.scala +++ b/src/library/scala/collection/immutable/TreeSet.scala @@ -83,9 +83,9 @@ class TreeSet[A <% Ordered[A]](val size: int, t: RedBlack[A]#Tree[Unit]) * * @return the new iterator */ - def elements: Iterator[A] = tree.elements.elements map (._1) + def elements: Iterator[A] = tree.elements.elements map (_._1) - def elementsSlow = tree.elementsSlow map (._1) + def elementsSlow = tree.elementsSlow map (_._1) override def foreach(f : A => Unit) : Unit = tree.visit[Unit](())((unit0,y,unit1) => Tuple2(true, f(y))) diff --git a/src/library/scala/collection/jcl/Map.scala b/src/library/scala/collection/jcl/Map.scala index 96dddd6add..40b2bcaf9c 100644 --- a/src/library/scala/collection/jcl/Map.scala +++ b/src/library/scala/collection/jcl/Map.scala @@ -22,7 +22,7 @@ trait Map[K,E] extends MutableIterable[Tuple2[K,E]] with scala.collection.mutabl /** The values of this map as a projection, which means removals from the returned collection will remove the element from this map. @returns a projection of this map's elements. */ - def valueSet : MutableIterable.Projection[E] = projection.map(._2); + def valueSet : MutableIterable.Projection[E] = projection.map(_._2); def put(key : K, elem : E) : Option[E]; def putAll(that : Iterable[Tuple2[K,E]]) : Unit = that.foreach(p => put(p._1, p._2)); @@ -41,7 +41,7 @@ trait Map[K,E] extends MutableIterable[Tuple2[K,E]] with scala.collection.mutabl case Some(e) if e == pair._2 => true; case _ => false; } - override def get(key : K) = elements.find(p => p._1 == key).map(._2); + override def get(key : K) = elements.find(p => p._1 == key).map(_._2); override def update(key : K, e : E) : Unit = put(key,e); override def +(pair : Tuple2[K,E]) : this.type = { put(pair._1,pair._2); this; @@ -80,7 +80,7 @@ trait Map[K,E] extends MutableIterable[Tuple2[K,E]] with scala.collection.mutabl protected class KeySet extends Set[K] { override def size = Map.this.size; override def add(k : K) = Map.this.put(k, default(k)) == None; - override def elements = Map.this.elements.map(._1); + override def elements = Map.this.elements.map(_._1); override def has(k : K) = Map.this.contains(k); } override def filterKeys(p : K => Boolean) : Map.Projection[K,E] = new Filter(p); diff --git a/src/library/scala/collection/jcl/Tests.scala b/src/library/scala/collection/jcl/Tests.scala index 39683323fa..a3007d8e1b 100644 --- a/src/library/scala/collection/jcl/Tests.scala +++ b/src/library/scala/collection/jcl/Tests.scala @@ -29,11 +29,11 @@ private[jcl] object Tests { rset + "bad"; Console.println(rset); Console.println(set); - val fset : SortedSet[String] = rset.projection.filter(.endsWith("d")); + val fset : SortedSet[String] = rset.projection.filter(_.endsWith("d")); Console.println(fset); fset += "cd"; Console.println(set); - //set.projection.map(.length).retain(x => x == 3); + //set.projection.map(_.length).retain(x => x == 3); Console.println(set); Console.println(rset); Console.println(fset); diff --git a/src/library/scala/collection/mutable/DoubleLinkedList.scala b/src/library/scala/collection/mutable/DoubleLinkedList.scala index 0d97a50176..d7a1ebf4f1 100644 --- a/src/library/scala/collection/mutable/DoubleLinkedList.scala +++ b/src/library/scala/collection/mutable/DoubleLinkedList.scala @@ -21,9 +21,8 @@ package scala.collection.mutable * @version 1.0, 08/07/2003 */ abstract class DoubleLinkedList[A, This >: Null <: DoubleLinkedList[A, This]] - requires This extends SingleLinkedList[A, This] -{ +{ self: This => var prev: This diff --git a/src/library/scala/collection/mutable/ObservableBuffer.scala b/src/library/scala/collection/mutable/ObservableBuffer.scala index 424c80ea86..63ceb12e65 100644 --- a/src/library/scala/collection/mutable/ObservableBuffer.scala +++ b/src/library/scala/collection/mutable/ObservableBuffer.scala @@ -22,11 +22,11 @@ package scala.collection.mutable * @author Matthias Zenger * @version 1.0, 08/07/2003 */ -trait ObservableBuffer[A, This <: ObservableBuffer[A, This]] requires This +trait ObservableBuffer[A, This <: ObservableBuffer[A, This]] extends Buffer[A] with Publisher[Message[(Location, A)] with Undoable, This] -{ +{ self: This => abstract override def +(element: A): Buffer[A] = { super.+(element) diff --git a/src/library/scala/collection/mutable/ObservableMap.scala b/src/library/scala/collection/mutable/ObservableMap.scala index 6841a3df5e..56843604fa 100644 --- a/src/library/scala/collection/mutable/ObservableMap.scala +++ b/src/library/scala/collection/mutable/ObservableMap.scala @@ -21,11 +21,11 @@ package scala.collection.mutable * @author Martin Odersky * @version 2.0, 31/12/2006 */ -trait ObservableMap[A, B, This <: ObservableMap[A, B, This]] requires This +trait ObservableMap[A, B, This <: ObservableMap[A, B, This]] extends Map[A, B] with Publisher[Message[(A, B)] with Undoable, This] -{ +{ self: This => abstract override def update(key: A, value: B): Unit = get(key) match { case None => diff --git a/src/library/scala/collection/mutable/ObservableSet.scala b/src/library/scala/collection/mutable/ObservableSet.scala index 46140275c9..b2e63b29b1 100644 --- a/src/library/scala/collection/mutable/ObservableSet.scala +++ b/src/library/scala/collection/mutable/ObservableSet.scala @@ -20,11 +20,11 @@ package scala.collection.mutable * @author Matthias Zenger * @version 1.0, 08/07/2003 */ -trait ObservableSet[A, This <: ObservableSet[A, This]] requires This +trait ObservableSet[A, This <: ObservableSet[A, This]] extends Set[A] with Publisher[Message[A] with Undoable, This] -{ +{ self: This => abstract override def +=(elem: A): Unit = if (!contains(elem)) { super.+=(elem) diff --git a/src/library/scala/collection/mutable/Publisher.scala b/src/library/scala/collection/mutable/Publisher.scala index 8d499e2e24..ddeb984442 100644 --- a/src/library/scala/collection/mutable/Publisher.scala +++ b/src/library/scala/collection/mutable/Publisher.scala @@ -22,7 +22,7 @@ package scala.collection.mutable * @author Matthias Zenger * @version 1.0, 08/07/2003 */ -trait Publisher[A, This <: Publisher[A, This]] requires This { +trait Publisher[A, This <: Publisher[A, This]] { self: This => private val filters = new HashMap[Subscriber[A, This], scala.collection.mutable.Set[A => Boolean]] with MultiMap[Subscriber[A, This], A => Boolean] diff --git a/src/library/scala/collection/mutable/SingleLinkedList.scala b/src/library/scala/collection/mutable/SingleLinkedList.scala index 80b4b6efe3..5ee6de582c 100644 --- a/src/library/scala/collection/mutable/SingleLinkedList.scala +++ b/src/library/scala/collection/mutable/SingleLinkedList.scala @@ -20,9 +20,8 @@ package scala.collection.mutable * @version 1.0, 08/07/2003 */ abstract class SingleLinkedList[A, This >: Null <: SingleLinkedList[A, This]] - requires This extends AnyRef with Seq[A] -{ +{ self: This => var elem: A diff --git a/src/library/scala/io/BytePickle.scala b/src/library/scala/io/BytePickle.scala index c41b231460..772b1246bc 100644 --- a/src/library/scala/io/BytePickle.scala +++ b/src/library/scala/io/BytePickle.scala @@ -275,7 +275,7 @@ object BytePickle { share(wrap((a:Array[byte]) => UTF8Codec.decode(a, 0, a.length), (s:String) => UTF8Codec.encode(s), bytearray)); def bytearray: SPU[Array[byte]] = { - wrap((l:List[byte]) => l.toArray, .toList, list(byte)) + wrap((l:List[byte]) => l.toArray, (_.toList), list(byte)) } def bool: SPU[boolean] = { diff --git a/src/library/scala/ref/Reference.scala b/src/library/scala/ref/Reference.scala index aac2e2a32a..65c49583ae 100644 --- a/src/library/scala/ref/Reference.scala +++ b/src/library/scala/ref/Reference.scala @@ -19,7 +19,7 @@ trait Reference[+T <: AnyRef] extends Function0[T] { def apply(): T /** return Some underlying if it hasn't been collected, otherwise None */ def get : Option[T] - override def toString = get.map(.toString).getOrElse("") + override def toString = get.map(_.toString).getOrElse("") def clear(): Unit def enqueue(): Boolean def isEnqueued(): Boolean diff --git a/src/library/scala/xml/parsing/ExternalSources.scala b/src/library/scala/xml/parsing/ExternalSources.scala index 90b7f406a4..699946be88 100644 --- a/src/library/scala/xml/parsing/ExternalSources.scala +++ b/src/library/scala/xml/parsing/ExternalSources.scala @@ -15,7 +15,7 @@ import compat.StringBuilder import scala.io.Source; import java.net.URL; -trait ExternalSources requires (ExternalSources with MarkupParser with MarkupHandler) { +trait ExternalSources { self: ExternalSources with MarkupParser with MarkupHandler => private def externalSourceFromURL(url:URL): Source = { import java.io.{BufferedReader, InputStreamReader}; diff --git a/src/library/scala/xml/parsing/MarkupParser.scala b/src/library/scala/xml/parsing/MarkupParser.scala index a1c34f7287..f3b0173288 100644 --- a/src/library/scala/xml/parsing/MarkupParser.scala +++ b/src/library/scala/xml/parsing/MarkupParser.scala @@ -28,7 +28,7 @@ import scala.xml.dtd._ * @author Burak Emir * @version 1.0 */ -trait MarkupParser requires (MarkupParser with MarkupHandler) extends AnyRef with TokenTests { +trait MarkupParser extends AnyRef with TokenTests { self: MarkupParser with MarkupHandler => val input: Source @@ -407,7 +407,7 @@ trait MarkupParser requires (MarkupParser with MarkupHandler) extends AnyRef wit * see [66] */ def xCharRef(ch: () => Char, nextch: () => Unit): String = { - Utility.parseCharRef(ch, nextch, &reportSyntaxError) + Utility.parseCharRef(ch, nextch, reportSyntaxError _) /* val hex = (ch() == 'x') && { nextch(); true }; val base = if (hex) 16 else 10; -- cgit v1.2.3