diff options
89 files changed, 569 insertions, 417 deletions
@@ -280,7 +280,7 @@ INITIALISATION <!-- Resolve maven dependencies --> <target name="init.maven.jars" depends="init.maven.tasks"> <artifact:dependencies pathId="dependency.classpath" filesetId="dependency.fileset"> - <dependency groupId="com.typesafe" artifactId="config" version="0.4.0"/> + <!--<dependency groupId="com.typesafe" artifactId="config" version="0.4.0"/>--> </artifact:dependencies> </target> @@ -1294,7 +1294,7 @@ QUICK BUILD (QUICK) <scalacfork destdir="${build-quick.dir}/classes/scalacheck" compilerpathref="quick.classpath" - params="${scalac.args.quick}" + params="${scalac.args.quick} -nowarn" srcdir="${src.dir}/scalacheck" jvmargs="${scalacfork.jvmargs}"> <include name="**/*.scala"/> @@ -1942,7 +1942,7 @@ BOOTSTRAPPING BUILD (STRAP) <scalacfork destdir="${build-strap.dir}/classes/scalacheck" compilerpathref="pack.classpath" - params="${scalac.args.quick}" + params="${scalac.args.quick} -nowarn" srcdir="${src.dir}/scalacheck" jvmargs="${scalacfork.jvmargs}"> <include name="**/*.scala"/> diff --git a/src/actors-migration/scala/actors/Pattern.scala b/src/actors-migration/scala/actors/Pattern.scala index 97dbd2cccd..26e9d1bb64 100644 --- a/src/actors-migration/scala/actors/Pattern.scala +++ b/src/actors-migration/scala/actors/Pattern.scala @@ -1,6 +1,7 @@ package scala.actors import scala.concurrent.util.Duration +import language.implicitConversions object pattern { diff --git a/src/actors-migration/scala/actors/StashingActor.scala b/src/actors-migration/scala/actors/StashingActor.scala index 37300f9d63..8f96e1b002 100644 --- a/src/actors-migration/scala/actors/StashingActor.scala +++ b/src/actors-migration/scala/actors/StashingActor.scala @@ -3,6 +3,7 @@ package scala.actors import scala.collection._ import scala.concurrent.util.Duration import java.util.concurrent.TimeUnit +import language.implicitConversions object StashingActor extends Combinators { implicit def mkBody[A](body: => A) = new InternalActor.Body[A] { diff --git a/src/actors-migration/scala/actors/Timeout.scala b/src/actors-migration/scala/actors/Timeout.scala index 0d9532a14b..7e400ab140 100644 --- a/src/actors-migration/scala/actors/Timeout.scala +++ b/src/actors-migration/scala/actors/Timeout.scala @@ -10,6 +10,7 @@ package scala.actors import scala.concurrent.util.Duration import java.util.concurrent.TimeUnit +import language.implicitConversions case class Timeout(duration: Duration) { def this(timeout: Long) = this(Duration(timeout, TimeUnit.MILLISECONDS)) diff --git a/src/actors/scala/actors/AbstractActor.scala b/src/actors/scala/actors/AbstractActor.scala index 3817f9cda3..dec91859bb 100644 --- a/src/actors/scala/actors/AbstractActor.scala +++ b/src/actors/scala/actors/AbstractActor.scala @@ -6,9 +6,10 @@ ** |/ ** \* */ - package scala.actors +import language.higherKinds + /** * @author Philipp Haller * diff --git a/src/actors/scala/actors/Actor.scala b/src/actors/scala/actors/Actor.scala index bc9bbc6ef0..0b1e7fb1e9 100644 --- a/src/actors/scala/actors/Actor.scala +++ b/src/actors/scala/actors/Actor.scala @@ -1,5 +1,3 @@ - - /* __ *\ ** ________ ___ / / ___ Scala API ** ** / __/ __// _ | / / / _ | (c) 2005-2011, LAMP/EPFL ** @@ -12,6 +10,7 @@ package scala.actors import scala.util.control.ControlThrowable import java.util.{Timer, TimerTask} +import language.implicitConversions /** * Provides functions for the definition of actors, as well as actor diff --git a/src/actors/scala/actors/CanReply.scala b/src/actors/scala/actors/CanReply.scala index 5053f43e94..9bf0022247 100644 --- a/src/actors/scala/actors/CanReply.scala +++ b/src/actors/scala/actors/CanReply.scala @@ -6,9 +6,10 @@ ** |/ ** \* */ - package scala.actors +import language.higherKinds + /** * Defines result-bearing message send operations. * diff --git a/src/actors/scala/actors/Combinators.scala b/src/actors/scala/actors/Combinators.scala index c1a9095614..dd704436fc 100644 --- a/src/actors/scala/actors/Combinators.scala +++ b/src/actors/scala/actors/Combinators.scala @@ -10,6 +10,8 @@ package scala.actors +import language.implicitConversions + private[actors] trait Combinators { /** diff --git a/src/actors/scala/actors/MQueue.scala b/src/actors/scala/actors/MQueue.scala index 4a148d2cb3..43074649fd 100644 --- a/src/actors/scala/actors/MQueue.scala +++ b/src/actors/scala/actors/MQueue.scala @@ -121,7 +121,7 @@ private[actors] class MQueue[Msg >: Null](protected val label: String) { * or `'''null'''` if `p` fails for all of them. */ def extractFirst(p: (Msg, OutputChannel[Any]) => Boolean): MQueueElement[Msg] = - removeInternal(0)(p) orNull + removeInternal(0)(p).orNull def extractFirst(pf: PartialFunction[Msg, Any]): MQueueElement[Msg] = { if (isEmpty) // early return diff --git a/src/actors/scala/actors/Reactor.scala b/src/actors/scala/actors/Reactor.scala index 7a8d738758..c962bb9d3d 100644 --- a/src/actors/scala/actors/Reactor.scala +++ b/src/actors/scala/actors/Reactor.scala @@ -12,6 +12,7 @@ package scala.actors import scala.actors.scheduler.{DelegatingScheduler, ExecutorScheduler, ForkJoinScheduler, ThreadPoolConfig} import java.util.concurrent.{ThreadPoolExecutor, TimeUnit, LinkedBlockingQueue} +import language.implicitConversions private[actors] object Reactor { diff --git a/src/build/maven/scala-library-pom.xml b/src/build/maven/scala-library-pom.xml index e8db512125..d1192b2dd8 100644 --- a/src/build/maven/scala-library-pom.xml +++ b/src/build/maven/scala-library-pom.xml @@ -31,11 +31,11 @@ <url>https://issues.scala-lang.org/</url> </issueManagement> <dependencies> - <dependency> + <!--<dependency> <groupId>com.typesafe</groupId> <artifactId>config</artifactId> <version>0.4.0</version> - </dependency> + </dependency>--> </dependencies> <distributionManagement> <repository> diff --git a/src/compiler/scala/tools/cmd/CommandLine.scala b/src/compiler/scala/tools/cmd/CommandLine.scala index d9a74a698c..ced3a97380 100644 --- a/src/compiler/scala/tools/cmd/CommandLine.scala +++ b/src/compiler/scala/tools/cmd/CommandLine.scala @@ -7,7 +7,6 @@ package scala.tools package cmd import scala.collection.mutable.ListBuffer -import language.postfixOps trait CommandLineConfig { def enforceArity: Boolean = true diff --git a/src/compiler/scala/tools/cmd/FromString.scala b/src/compiler/scala/tools/cmd/FromString.scala index 415940b3fd..d473796f39 100644 --- a/src/compiler/scala/tools/cmd/FromString.scala +++ b/src/compiler/scala/tools/cmd/FromString.scala @@ -43,7 +43,7 @@ object FromString { else cmd.runAndExit(println("'%s' is not an existing directory." format s)) } def ExistingDirRelativeTo(root: Directory) = new FromString[Directory]()(tagOfDirectory) { - private def resolve(s: String) = toDir(s) toAbsoluteWithRoot root toDirectory + private def resolve(s: String) = (toDir(s) toAbsoluteWithRoot root).toDirectory override def isDefinedAt(s: String) = resolve(s).isDirectory def apply(s: String): Directory = if (isDefinedAt(s)) resolve(s) diff --git a/src/compiler/scala/tools/cmd/package.scala b/src/compiler/scala/tools/cmd/package.scala index 5786b00fd1..8e74e6169e 100644 --- a/src/compiler/scala/tools/cmd/package.scala +++ b/src/compiler/scala/tools/cmd/package.scala @@ -8,6 +8,10 @@ package scala.tools package object cmd { def returning[T](x: T)(f: T => Unit): T = { f(x) ; x } + // make some language features in this package compile without warning + implicit def implicitConversions = language.implicitConversions + implicit def postfixOps = language.postfixOps + private[cmd] def debug(msg: String) = println(msg) def runAndExit(body: => Unit): Nothing = { diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala index 982267097b..c46b650949 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala @@ -73,6 +73,14 @@ abstract class GenICode extends SubComponent { ctx1 } + /** If the selector type has a member with the right name, + * it is the host class; otherwise the symbol's owner. + */ + def findHostClass(selector: Type, sym: Symbol) = selector member sym.name match { + case NoSymbol => log(s"Rejecting $selector as host class for $sym") ; sym.owner + case _ => selector.typeSymbol + } + /////////////////// Code generation /////////////////////// def gen(tree: Tree, ctx: Context): Context = tree match { @@ -949,13 +957,14 @@ abstract class GenICode extends SubComponent { */ fun match { case Select(qual, _) => - val qualSym = qual.tpe.typeSymbol + val qualSym = findHostClass(qual.tpe, sym) + if (qualSym == ArrayClass) cm setTargetTypeKind toTypeKind(qual.tpe) else cm setHostClass qualSym - debuglog( + log( if (qualSym == ArrayClass) "Stored target type kind " + toTypeKind(qual.tpe) + " for " + sym.fullName - else "Set more precise host class for " + sym.fullName + " host: " + qualSym + else s"Set more precise host class for ${sym.fullName} hostClass: $qualSym" ) case _ => } @@ -1005,13 +1014,14 @@ abstract class GenICode extends SubComponent { case Select(qualifier, selector) => val sym = tree.symbol generatedType = toTypeKind(sym.info) - val hostClass = qualifier.tpe.typeSymbol.orElse(sym.owner) + val hostClass = findHostClass(qualifier.tpe, sym) + log(s"Host class of $sym with qual $qualifier (${qualifier.tpe}) is $hostClass") if (sym.isModule) { genLoadModule(ctx, tree) } else if (sym.isStaticMember) { - ctx.bb.emit(LOAD_FIELD(sym, true) setHostClass hostClass, tree.pos) + ctx.bb.emit(LOAD_FIELD(sym, true) setHostClass hostClass, tree.pos) ctx } else { 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 7a5615ac26..962c47f443 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala @@ -470,6 +470,8 @@ abstract class TypeFlowAnalysis { val isOnWatchlist = mutable.Set.empty[Instruction] + val warnIfInlineFails = mutable.Set.empty[opcodes.CALL_METHOD] // cache for a given IMethod (ie cleared on Inliner.analyzeMethod). + /* Each time CallerCalleeInfo.isSafeToInline determines a concrete callee is unsafe to inline in the current caller, the fact is recorded in this TFA instance for the purpose of avoiding devoting processing to that callsite next time. The condition of "being unsafe to inline in the current caller" sticks across inlinings and TFA re-inits @@ -510,6 +512,7 @@ abstract class TypeFlowAnalysis { // initially populate the watchlist with all callsites standing a chance of being inlined isOnWatchlist.clear() relevantBBs.clear() + warnIfInlineFails.clear() /* TODO Do we want to perform inlining in non-finally exception handlers? * Seems counterproductive (the larger the method the less likely it will be JITed. * It's not that putting on radar only `linearizer linearizeAt (m, m.startBlock)` makes for much shorter inlining times (a minor speedup nonetheless) @@ -533,11 +536,11 @@ abstract class TypeFlowAnalysis { private def putOnRadar(blocks: Traversable[BasicBlock]) { for(bb <- blocks) { - val preCands = bb.toList collect { - case cm : opcodes.CALL_METHOD - if isPreCandidate(cm) /* && !isReceiverKnown(cm) */ - => cm + val calls = bb.toList collect { case cm : opcodes.CALL_METHOD => cm } + for(c <- calls; if(inliner.hasInline(c.method))) { + warnIfInlineFails += c } + val preCands = calls filter isPreCandidate isOnWatchlist ++= preCands } relevantBBs ++= blocks diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala index 025046f19e..e590a0b691 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala @@ -1159,7 +1159,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters { val linkedClass = moduleClass.companionClass val linkedModule = linkedClass.companionSymbol lazy val conflictingNames: Set[Name] = { - linkedClass.info.members collect { case sym if sym.name.isTermName => sym.name } toSet + (linkedClass.info.members collect { case sym if sym.name.isTermName => sym.name }).toSet } debuglog("Potentially conflicting names for forwarders: " + conflictingNames) @@ -1351,7 +1351,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters { val ps = c.symbol.info.parents val superInterfaces0: List[Symbol] = if(ps.isEmpty) Nil else c.symbol.mixinClasses; - val superInterfaces = superInterfaces0 ++ c.symbol.annotations.flatMap(ann => newParentForAttr(ann.symbol)) distinct + val superInterfaces = (superInterfaces0 ++ c.symbol.annotations.flatMap(ann => newParentForAttr(ann.symbol))).distinct if(superInterfaces.isEmpty) EMPTY_STRING_ARRAY else mkArray(minimizeInterfaces(superInterfaces) map javaName) @@ -3183,7 +3183,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters { hops ::= prev if (hops.contains(dest)) { // leave infinite-loops in place - return (dest, hops filterNot (dest eq)) + return (dest, hops filterNot (dest eq _)) } prev = dest; false diff --git a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala index 44acfed411..cce18d436f 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala @@ -129,11 +129,15 @@ abstract class Inliners extends SubComponent { override def apply(c: IClass) { queue += c } override def run() { + knownLacksInline.clear() + knownHasInline.clear() try { super.run() for(c <- queue) { inliner analyzeClass c } } finally { inliner.clearCaches() + knownLacksInline.clear() + knownHasInline.clear() } } } @@ -157,7 +161,21 @@ abstract class Inliners extends SubComponent { } } - def hasInline(sym: Symbol) = sym hasAnnotation ScalaInlineClass + val knownLacksInline = mutable.Set.empty[Symbol] // cache to avoid multiple inliner.hasInline() calls. + val knownHasInline = mutable.Set.empty[Symbol] // as above. Motivated by the need to warn on "inliner failures". + + def hasInline(sym: Symbol) = { + if (knownLacksInline(sym)) false + else if(knownHasInline(sym)) true + else { + val b = (sym hasAnnotation ScalaInlineClass) + if(b) { knownHasInline += sym } + else { knownLacksInline += sym } + + b + } + } + def hasNoInline(sym: Symbol) = sym hasAnnotation ScalaNoInlineClass /** @@ -536,6 +554,10 @@ abstract class Inliners extends SubComponent { } while (retry && count < MAX_INLINE_RETRY) + for(inlFail <- tfa.warnIfInlineFails) { + warn(inlFail.pos, "At the end of the day, could not inline @inline-marked method " + inlFail.method.originalName.decode) + } + m.normalize if (sizeBeforeInlining > 0) { val instrAfterInlining = m.code.instructionCount @@ -731,6 +753,7 @@ abstract class Inliners extends SubComponent { tfa.remainingCALLs.remove(instr) // this bookkpeeping is done here and not in MTFAGrowable.reinit due to (1st) convenience and (2nd) necessity. tfa.isOnWatchlist.remove(instr) // ditto + tfa.warnIfInlineFails.remove(instr) val targetPos = instr.pos log("Inlining " + inc.m + " in " + caller.m + " at pos: " + posToStr(targetPos)) diff --git a/src/compiler/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala b/src/compiler/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala index bae61f1a3b..c46c33c1ee 100644 --- a/src/compiler/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala +++ b/src/compiler/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala @@ -333,7 +333,7 @@ class DotDiagramGenerator(settings: doc.Settings) extends DiagramGenerator { else NodeSeq.Empty } catch { - case exc => + case exc: Exception => if (settings.docDiagramsDebug.value) { settings.printMsg("\n\n**********************************************************************") settings.printMsg("Encountered an error while generating page for " + template.qualifiedName) diff --git a/src/compiler/scala/tools/nsc/javac/JavaScanners.scala b/src/compiler/scala/tools/nsc/javac/JavaScanners.scala index a37fdc3ed1..58c2426602 100644 --- a/src/compiler/scala/tools/nsc/javac/JavaScanners.scala +++ b/src/compiler/scala/tools/nsc/javac/JavaScanners.scala @@ -139,7 +139,7 @@ trait JavaScanners extends ast.parser.ScannersCommon { kwOffset = offset arr } - final val tokenName = allKeywords map (_.swap) toMap + final val tokenName = allKeywords.map(_.swap).toMap //Token representation ----------------------------------------------------- diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala index e672f1914a..108c5ced6f 100644 --- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala +++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala @@ -58,23 +58,6 @@ abstract class CleanUp extends Transform with ast.TreeDSL { } private def mkTerm(prefix: String): TermName = unit.freshTermName(prefix) - /** Kludge to provide a safe fix for #4560: - * If we generate a reference in an implementation class, we - * watch out for embedded This(..) nodes that point to the interface. - * These must be wrong. We fix them by setting symbol and type to - * the enclosing implementation class instead. - */ - def safeREF(sym: Symbol) = { - def fix(tree: Tree): Unit = tree match { - case Select(qual @ This(_), name) if qual.symbol != currentClass => - qual.setSymbol(currentClass).setType(currentClass.tpe) - case _ => - } - val tree = REF(sym) - if (currentClass.isImplClass && sym.owner == currentClass) fix(tree) - tree - } - //private val classConstantMeth = new HashMap[String, Symbol] //private val symbolStaticFields = new HashMap[String, (Symbol, Tree, Tree)] @@ -164,7 +147,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL { val varDef = typedPos( VAL(varSym) === forInit ) newStaticMembers append transform(varDef) - val varInit = typedPos( safeREF(varSym) === forInit ) + val varInit = typedPos( REF(varSym) === forInit ) newStaticInits append transform(varInit) varSym @@ -200,7 +183,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL { addStaticVariableToClass(nme.reflParamsCacheName, arrayType(ClassClass.tpe), fromTypesToClassArrayLiteral(paramTypes), true) addStaticMethodToClass((_, forReceiverSym) => - gen.mkMethodCall(REF(forReceiverSym), Class_getMethod, Nil, List(LIT(method), safeREF(reflParamsCacheSym))) + gen.mkMethodCall(REF(forReceiverSym), Class_getMethod, Nil, List(LIT(method), REF(reflParamsCacheSym))) ) case MONO_CACHE => @@ -239,11 +222,11 @@ abstract class CleanUp extends Transform with ast.TreeDSL { addStaticMethodToClass((_, forReceiverSym) => BLOCK( IF (isCacheEmpty(forReceiverSym)) THEN BLOCK( - safeREF(reflMethodCacheSym) === ((REF(forReceiverSym) DOT Class_getMethod)(LIT(method), safeREF(reflParamsCacheSym))) , - safeREF(reflClassCacheSym) === gen.mkSoftRef(REF(forReceiverSym)), + REF(reflMethodCacheSym) === ((REF(forReceiverSym) DOT Class_getMethod)(LIT(method), REF(reflParamsCacheSym))) , + REF(reflClassCacheSym) === gen.mkSoftRef(REF(forReceiverSym)), UNIT ) ENDIF, - safeREF(reflMethodCacheSym) + REF(reflMethodCacheSym) ) ) @@ -277,22 +260,22 @@ abstract class CleanUp extends Transform with ast.TreeDSL { val reflPolyCacheSym: Symbol = ( addStaticVariableToClass(nme.reflPolyCacheName, SoftReferenceClass.tpe, mkNewPolyCache, false) ) - def getPolyCache = gen.mkCast(fn(safeREF(reflPolyCacheSym), nme.get), MethodCacheClass.tpe) + def getPolyCache = gen.mkCast(fn(REF(reflPolyCacheSym), nme.get), MethodCacheClass.tpe) addStaticMethodToClass((reflMethodSym, forReceiverSym) => { val methodSym = reflMethodSym.newVariable(mkTerm("method"), ad.pos) setInfo MethodClass.tpe BLOCK( - IF (getPolyCache OBJ_EQ NULL) THEN (safeREF(reflPolyCacheSym) === mkNewPolyCache) ENDIF, + IF (getPolyCache OBJ_EQ NULL) THEN (REF(reflPolyCacheSym) === mkNewPolyCache) ENDIF, VAL(methodSym) === ((getPolyCache DOT methodCache_find)(REF(forReceiverSym))) , IF (REF(methodSym) OBJ_!= NULL) . THEN (Return(REF(methodSym))) ELSE { - def methodSymRHS = ((REF(forReceiverSym) DOT Class_getMethod)(LIT(method), safeREF(reflParamsCacheSym))) + def methodSymRHS = ((REF(forReceiverSym) DOT Class_getMethod)(LIT(method), REF(reflParamsCacheSym))) def cacheRHS = ((getPolyCache DOT methodCache_add)(REF(forReceiverSym), REF(methodSym))) BLOCK( REF(methodSym) === (REF(ensureAccessibleMethod) APPLY (methodSymRHS)), - safeREF(reflPolyCacheSym) === gen.mkSoftRef(cacheRHS), + REF(reflPolyCacheSym) === gen.mkSoftRef(cacheRHS), Return(REF(methodSym)) ) } @@ -400,7 +383,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL { def genDefaultCall = { // reflective method call machinery val invokeName = MethodClass.tpe member nme.invoke_ // reflect.Method.invoke(...) - def cache = safeREF(reflectiveMethodCache(ad.symbol.name.toString, paramTypes)) // cache Symbol + def cache = REF(reflectiveMethodCache(ad.symbol.name.toString, paramTypes)) // cache Symbol def lookup = Apply(cache, List(qual1() GETCLASS)) // get Method object from cache def invokeArgs = ArrayValue(TypeTree(ObjectClass.tpe), params) // args for invocation def invocation = (lookup DOT invokeName)(qual1(), invokeArgs) // .invoke(qual1, ...) @@ -495,7 +478,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL { typedPos { val sym = currentOwner.newValue(mkTerm("qual"), ad.pos) setInfo qual0.tpe - qual = safeREF(sym) + qual = REF(sym) BLOCK( VAL(sym) === qual0, @@ -678,7 +661,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL { val rhs = gen.mkMethodCall(Symbol_apply, arg :: Nil) val staticFieldSym = getSymbolStaticField(tree.pos, symname, rhs, tree) // create a reference to a static field - val ntree = typedWithPos(tree.pos)(safeREF(staticFieldSym)) + val ntree = typedWithPos(tree.pos)(REF(staticFieldSym)) super.transform(ntree) // This transform replaces Array(Predef.wrapArray(Array(...)), <tag>) @@ -711,7 +694,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL { // create field definition and initialization val stfieldDef = theTyper.typedPos(pos)(VAL(stfieldSym) === rhs) - val stfieldInit = theTyper.typedPos(pos)(safeREF(stfieldSym) === rhs) + val stfieldInit = theTyper.typedPos(pos)(REF(stfieldSym) === rhs) // add field definition to new defs newStaticMembers append stfieldDef @@ -777,8 +760,8 @@ abstract class CleanUp extends Transform with ast.TreeDSL { val stfieldDef = localTyper.typedPos(tree.pos)(VAL(stfieldSym) === EmptyTree) val flattenedInit = fixedrhs match { - case Block(stats, expr) => Block(stats, safeREF(stfieldSym) === expr) - case rhs => safeREF(stfieldSym) === rhs + case Block(stats, expr) => Block(stats, REF(stfieldSym) === expr) + case rhs => REF(stfieldSym) === rhs } val stfieldInit = localTyper.typedPos(tree.pos)(flattenedInit) diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index ffcb682cf7..63f93aa000 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -798,6 +798,10 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { var specializingOn = specializedParams(sym) val unusedStvars = specializingOn filterNot specializedTypeVars(sym.info) + // I think the last condition should be !sym.isHidden, but that made the + // compiler start warning about Tuple1.scala and Tuple2.scala claiming + // their type parameters are used in non-specializable positions. Why is + // unusedStvars.nonEmpty for these classes??? if (unusedStvars.nonEmpty && currentRun.compiles(sym) && !sym.isSynthetic) { reporter.warning(sym.pos, "%s %s unused or used in non-specializable positions.".format( diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 805f60ba87..0fc298e886 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -552,7 +552,6 @@ trait Contexts { self: Analyzer => ( (ab.isTerm || ab == rootMirror.RootClass) || (accessWithin(ab) || accessWithinLinked(ab)) && ( !sym.hasLocalFlag - || sym.owner.isImplClass // allow private local accesses to impl classes || sym.isProtected && isSubThisType(pre, sym.owner) || pre =:= sym.owner.thisType ) diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index bcbcb96400..e096b75d6d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -1324,66 +1324,89 @@ trait Infer { } // if top-level abstract types can be checked using a classtag extractor, don't warn about them - def checkCheckable(tree: Tree, tp: Type, inPattern: Boolean, canRemedy: Boolean = false) = { - val kind = if (inPattern) "pattern " else "" + def checkCheckable(tree: Tree, typeToTest: Type, typeEnsured: Type, inPattern: Boolean, canRemedy: Boolean = false) = { + log(s"checkCheckable($tree, $typeToTest, $typeEnsured, inPattern = $inPattern, canRemedy = $canRemedy") - def patternWarning(tp0: Type, prefix: String) = { - context.unit.uncheckedWarning(tree.pos, prefix+tp0+" in type "+kind+tp+" is unchecked since it is eliminated by erasure") + sealed abstract class TypeConformance(check: (Type, Type) => Boolean) { + def apply(t1: Type, t2: Type): Boolean = check(t1, t2) && { + log(s"Skipping unchecked for statically verifiable condition $t1 ${this} $t2") + true + } } - def check(tp: Type, bound: List[Symbol]) { - def isLocalBinding(sym: Symbol) = - sym.isAbstractType && - ((bound contains sym) || - sym.name == tpnme.WILDCARD || { + // I tried to use varianceInType to track the variance implications + // but I could not make it work. + case object =:= extends TypeConformance(_ =:= _) + case object <:< extends TypeConformance(_ <:< _) + case object >:> extends TypeConformance((t1, t2) => t2 <:< t1) + case object =!= extends TypeConformance((t1, t2) => false) + + var bound: List[Symbol] = Nil + var warningMessages: List[String] = Nil + + def isLocalBinding(sym: Symbol) = ( + sym.isAbstractType && ( + (bound contains sym) + || (sym.name == tpnme.WILDCARD) + || { val e = context.scope.lookupEntry(sym.name) (e ne null) && e.sym == sym && !e.sym.isTypeParameterOrSkolem && e.owner == context.scope - }) - tp match { - case SingleType(pre, _) => - check(pre, bound) - case TypeRef(pre, sym, args) => - if (sym.isAbstractType) { - // we only use the extractor for top-level type tests, type arguments (see below) remain unchecked - if (!isLocalBinding(sym) && !canRemedy) patternWarning(tp, "abstract type ") - } else if (sym.isAliasType) { - check(tp.normalize, bound) - } else if (sym == NothingClass || sym == NullClass || sym == AnyValClass) { - TypePatternOrIsInstanceTestError(tree, tp) - } else { - for (arg <- args) { - if (sym == ArrayClass) check(arg, bound) - // avoid spurious warnings with higher-kinded types - else if (arg.typeArgs exists (_.typeSymbol.isTypeParameterOrSkolem)) () - // no way to suppress unchecked warnings on try/catch - else if (sym == NonLocalReturnControlClass) () - else arg match { - case TypeRef(_, sym, _) if isLocalBinding(sym) => - ; - case _ => - // Want to warn about type arguments, not type parameters. Otherwise we'll - // see warnings about "invisible" types, like: val List(x0) = x1 leading to "non - // variable type-argument A in type pattern List[A]..." - if (!arg.typeSymbol.isTypeParameterOrSkolem) - patternWarning(arg, "non variable type-argument ") - } - } - } - check(pre, bound) - case RefinedType(parents, decls) => - if (decls.isEmpty) for (p <- parents) check(p, bound) - else patternWarning(tp, "refinement ") - case ExistentialType(quantified, tp1) => - check(tp1, bound ::: quantified) - case ThisType(_) => - () - case NoPrefix => - () - case _ => - patternWarning(tp, "type ") - () + } + ) + ) + def check(tp0: Type, pt: Type, conformance: TypeConformance): Boolean = { + val tp = tp0.normalize + // Set the warning message to be issued when the top-level call fails. + def warn(what: String): Boolean = { + warningMessages ::= what + false + } + def checkArg(param: Symbol, arg: Type) = { + def conforms = ( + if (param.isCovariant) <:< + else if (param.isContravariant) >:> + else =:= + ) + val TypeRef(_, sym, args) = arg + + ( isLocalBinding(sym) + || arg.typeSymbol.isTypeParameterOrSkolem + || (sym.name == tpnme.WILDCARD) // avoid spurious warnings on HK types + || check(arg, param.tpe, conforms) + || warn("non-variable type argument " + arg) + ) } + + // Checking if pt (the expected type of the pattern, and the type + // we are guaranteed) conforms to tp (the type expressed in the pattern's + // type test.) If it does, then even if the type being checked for appears + // to be uncheckable, it is not a warning situation, because it is indeed + // checked: not at runtime, but statically. + conformance.apply(pt, tp) || (tp match { + case SingleType(pre, _) => check(pre, pt, =:=) + case ExistentialType(quantified, tp1) => bound :::= quantified ; check(tp1, pt, <:<) + case ThisType(_) | NoPrefix => true + case RefinedType(parents, decls) if decls.isEmpty => parents forall (p => check(p, pt, <:<)) + case RefinedType(_, _) => warn("refinement " + tp) + case TypeRef(_, ArrayClass, arg :: Nil) => check(arg, NoType, =!=) + case TypeRef(_, NonLocalReturnControlClass, _) => true // no way to suppress unchecked warnings on try/catch + // we only use the extractor for top-level type tests, type arguments remain unchecked + case TypeRef(_, sym, _) if sym.isAbstractType => isLocalBinding(sym) || canRemedy || warn("abstract type " + tp) + case TypeRef(_, _, Nil) => false // leaf node + case TypeRef(pre, sym, args) => forall2(sym.typeParams, args)(checkArg) && check(pre, pt.prefix, =:=) + case _ => warn("type " + tp) + }) + } + typeToTest match { + // Prohibit top-level type tests for these, but they are + // acceptable nested (e.g. case Foldable[Nothing] => ... ) + case TypeRef(_, NothingClass | NullClass | AnyValClass, _) => + TypePatternOrIsInstanceTestError(tree, typeToTest) + case _ => + def where = ( if (inPattern) "pattern " else "" ) + typeToTest + if (check(typeToTest, typeEnsured, =:=)) () + else warningMessages foreach (m => + context.unit.uncheckedWarning(tree.pos, s"$m in type $where is unchecked since it is eliminated by erasure")) } - check(tp, List()) } /** Type intersection of simple type tp1 with general type tp2. @@ -1420,7 +1443,7 @@ trait Infer { return ErrorType } - checkCheckable(tree0, pattp, inPattern = true, canRemedy) + checkCheckable(tree0, pattp, pt, inPattern = true, canRemedy) if (pattp <:< pt) () else { debuglog("free type params (1) = " + tpparams) diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala index 8b7c70c048..cf5c7265ad 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala @@ -412,8 +412,9 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL **/ // must treat Typed and Bind together -- we need to know the patBinder of the Bind pattern to get at the actual type case MaybeBoundTyped(subPatBinder, pt) => + val next = glb(List(patBinder.info.widen, pt)).normalize // a typed pattern never has any subtrees - noFurtherSubPats(TypeTestTreeMaker(subPatBinder, patBinder, pt, glb(List(patBinder.info.widen, pt)).normalize)(pos)) + noFurtherSubPats(TypeTestTreeMaker(subPatBinder, patBinder, pt, next)(pos)) /** A pattern binder x@p consists of a pattern variable x and a pattern p. The type of the variable x is the static type T of the pattern p. diff --git a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala index a378a95786..fe82af5b23 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala @@ -14,7 +14,7 @@ import util.returning abstract class TreeCheckers extends Analyzer { import global._ - private def classstr(x: AnyRef) = x.getClass.getName split """\\.|\\$""" last; + private def classstr(x: AnyRef) = (x.getClass.getName split """\\.|\\$""").last private def typestr(x: Type) = " (tpe = " + x + ")" private def treestr(t: Tree) = t + " [" + classstr(t) + "]" + typestr(t.tpe) private def ownerstr(s: Symbol) = "'" + s + "'" + s.locationString diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 51753baa4f..b1c3249e35 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1194,30 +1194,46 @@ trait Typers extends Modes with Adaptations with Tags { } val found = tree.tpe - val req = pt - if (!found.isErroneous && !req.isErroneous) { - if (!context.reportErrors && isPastTyper && req.skolemsExceptMethodTypeParams.nonEmpty) { - // Ignore type errors raised in later phases that are due to mismatching types with existential skolems - // We have lift crashing in 2.9 with an adapt failure in the pattern matcher. - // Here's my hypothsis why this happens. The pattern matcher defines a variable of type - // - // val x: T = expr - // - // where T is the type of expr, but T contains existential skolems ts. - // In that case, this value definition does not typecheck. - // The value definition - // - // val x: T forSome { ts } = expr - // - // would typecheck. Or one can simply leave out the type of the `val`: - // - // val x = expr - context.unit.warning(tree.pos, "recovering from existential Skolem type error in tree \n" + tree + "\nwith type " + tree.tpe + "\n expected type = " + pt + "\n context = " + context.tree) - adapt(tree, mode, deriveTypeWithWildcards(pt.skolemsExceptMethodTypeParams)(pt)) - } else { - // create an actual error - AdaptTypeError(tree, found, req) + if (!found.isErroneous && !pt.isErroneous) { + if (!context.reportErrors && isPastTyper) { + val (bound, req) = pt match { + case ExistentialType(qs, tpe) => (qs, tpe) + case _ => (Nil, pt) + } + val boundOrSkolems = bound ++ pt.skolemsExceptMethodTypeParams + if (boundOrSkolems.nonEmpty) { + // Ignore type errors raised in later phases that are due to mismatching types with existential skolems + // We have lift crashing in 2.9 with an adapt failure in the pattern matcher. + // Here's my hypothsis why this happens. The pattern matcher defines a variable of type + // + // val x: T = expr + // + // where T is the type of expr, but T contains existential skolems ts. + // In that case, this value definition does not typecheck. + // The value definition + // + // val x: T forSome { ts } = expr + // + // would typecheck. Or one can simply leave out the type of the `val`: + // + // val x = expr + // + // SI-6029 shows another case where we also fail (in uncurry), but this time the expected + // type is an existential type. + // + // The reason for both failures have to do with the way we (don't) transform + // skolem types along with the trees that contain them. We'd need a + // radically different approach to do it. But before investing a lot of time to + // to do this (I have already sunk 3 full days with in the end futile attempts + // to consistently transform skolems and fix 6029), I'd like to + // investigate ways to avoid skolems completely. + // + log("recovering from existential or skolem type error in tree \n" + tree + "\nwith type " + tree.tpe + "\n expected type = " + pt + "\n context = " + context.tree) + return adapt(tree, mode, deriveTypeWithWildcards(boundOrSkolems)(pt)) + } } + // create an actual error + AdaptTypeError(tree, found, pt) } setError(tree) } @@ -3672,7 +3688,8 @@ trait Typers extends Modes with Adaptations with Tags { typedClassOf(tree, args.head, true) else { if (!isPastTyper && fun.symbol == Any_isInstanceOf && !targs.isEmpty) - checkCheckable(tree, targs.head, inPattern = false) + checkCheckable(tree, targs.head, AnyClass.tpe, inPattern = false) + val resultpe = restpe.instantiateTypeParams(tparams, targs) //@M substitution in instantiateParams needs to be careful! //@M example: class Foo[a] { def foo[m[x]]: m[a] = error("") } (new Foo[Int]).foo[List] : List[Int] @@ -4530,7 +4547,7 @@ trait Typers extends Modes with Adaptations with Tags { assert(errorContainer == null, "Cannot set ambiguous error twice for identifier") errorContainer = tree } - + val fingerPrint: Long = name.fingerPrint var defSym: Symbol = tree.symbol // the directly found symbol diff --git a/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala b/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala index 017c8d24fd..211560e343 100644 --- a/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala +++ b/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala @@ -475,7 +475,7 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with val (prologue, rest) = (anfStats :+ anfExpr) span (s => !s.isInstanceOf[DefDef]) // find first case // println("rest: "+ rest) // val (defs, calls) = rest partition (_.isInstanceOf[DefDef]) - if (rest nonEmpty){ + if (rest.nonEmpty) { // the filter drops the ()'s emitted when transValue encountered a LabelDef val stats = prologue ++ (rest filter (_.isInstanceOf[DefDef])).reverse // ++ calls // println("REVERSED "+ (stats mkString ("{", "\n", "}"))) diff --git a/src/library/scala/collection/GenTraversableOnce.scala b/src/library/scala/collection/GenTraversableOnce.scala index 25edcfe19c..4e0f71ee8b 100644 --- a/src/library/scala/collection/GenTraversableOnce.scala +++ b/src/library/scala/collection/GenTraversableOnce.scala @@ -11,6 +11,7 @@ package scala.collection import scala.reflect.ClassTag import scala.collection.generic.CanBuildFrom import scala.annotation.unchecked.{ uncheckedVariance => uV } +import language.higherKinds /** A template trait for all traversable-once objects which may be * traversed in parallel. diff --git a/src/library/scala/collection/TraversableLike.scala b/src/library/scala/collection/TraversableLike.scala index 9356832afd..641dd095da 100644 --- a/src/library/scala/collection/TraversableLike.scala +++ b/src/library/scala/collection/TraversableLike.scala @@ -13,6 +13,7 @@ import mutable.{ Builder } import annotation.{tailrec, migration, bridge} import annotation.unchecked.{ uncheckedVariance => uV } import parallel.ParIterable +import language.higherKinds /** A template trait for traversable collections of type `Traversable[A]`. * diff --git a/src/library/scala/collection/concurrent/TrieMap.scala b/src/library/scala/collection/concurrent/TrieMap.scala index 2d8217551a..3d0aa6fd07 100644 --- a/src/library/scala/collection/concurrent/TrieMap.scala +++ b/src/library/scala/collection/concurrent/TrieMap.scala @@ -188,7 +188,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends if (sn.hc == hc && equal(sn.k, k, ct)) { if (GCAS(cn, cn.updatedAt(pos, new SNode(k, v, hc), gen), ct)) Some(sn.v) else null } else None - case otherv: V => + case otherv => if (sn.hc == hc && equal(sn.k, k, ct) && sn.v == otherv) { if (GCAS(cn, cn.updatedAt(pos, new SNode(k, v, hc), gen), ct)) Some(sn.v) else null } else None @@ -200,7 +200,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends val ncnode = rn.insertedAt(pos, flag, new SNode(k, v, hc), gen) if (GCAS(cn, ncnode, ct)) None else null case INode.KEY_PRESENT => None - case otherv: V => None + case otherv => None } case sn: TNode[K, V] => clean(parent, ct, lev - 5) @@ -224,9 +224,9 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends case Some(v0) => if (insertln()) Some(v0) else null case None => None } - case otherv: V => + case otherv => ln.get(k) match { - case Some(v0) if v0 == otherv => if (insertln()) Some(otherv) else null + case Some(v0) if v0 == otherv => if (insertln()) Some(otherv.asInstanceOf[V]) else null case _ => None } } diff --git a/src/library/scala/collection/parallel/ParIterableLike.scala b/src/library/scala/collection/parallel/ParIterableLike.scala index d4f1c2f39f..85758b29bc 100644 --- a/src/library/scala/collection/parallel/ParIterableLike.scala +++ b/src/library/scala/collection/parallel/ParIterableLike.scala @@ -30,7 +30,7 @@ import java.util.concurrent.atomic.AtomicBoolean import annotation.unchecked.uncheckedVariance import annotation.unchecked.uncheckedStable -import language.implicitConversions +import language.{ higherKinds, implicitConversions } /** A template trait for parallel collections of type `ParIterable[T]`. diff --git a/src/library/scala/reflect/base/Base.scala b/src/library/scala/reflect/base/Base.scala index 5df48307fe..53854f160d 100644 --- a/src/library/scala/reflect/base/Base.scala +++ b/src/library/scala/reflect/base/Base.scala @@ -52,7 +52,6 @@ class Base extends Universe { self => else if (isFreeTerm) "free term" else if (isTerm) "value" else "symbol" - // [Eugene++ to Martin] base names should expose `decode` override def toString() = s"$kindString $name" } implicit val SymbolTag = ClassTag[Symbol](classOf[Symbol]) @@ -204,20 +203,22 @@ class Base extends Universe { self => object nme extends TermNamesBase { type NameType = TermName - val EMPTY = newTermName("") - val ROOT = newTermName("<root>") - val EMPTY_PACKAGE_NAME = newTermName("<empty>") - val CONSTRUCTOR = newTermName("<init>") + val WILDCARD = newTermName("_") + val CONSTRUCTOR = newTermName("<init>") + val ROOTPKG = newTermName("_root_") + val EMPTY = newTermName("") + val EMPTY_PACKAGE_NAME = newTermName("<empty>") + val ROOT = newTermName("<root>") val NO_NAME = newTermName("<none>") - val WILDCARD = newTermName("_") } object tpnme extends TypeNamesBase { type NameType = TypeName - val EMPTY = nme.EMPTY.toTypeName - val ROOT = nme.ROOT.toTypeName - val EMPTY_PACKAGE_NAME = nme.EMPTY_PACKAGE_NAME.toTypeName - val WILDCARD = nme.WILDCARD.toTypeName + val WILDCARD = nme.WILDCARD.toTypeName + val EMPTY = nme.EMPTY.toTypeName + val WILDCARD_STAR = newTypeName("_*") + val EMPTY_PACKAGE_NAME = nme.EMPTY_PACKAGE_NAME.toTypeName + val ROOT = nme.ROOT.toTypeName } type FlagSet = Long diff --git a/src/library/scala/reflect/base/Names.scala b/src/library/scala/reflect/base/Names.scala index 280a6ce8a2..532b780e7e 100644 --- a/src/library/scala/reflect/base/Names.scala +++ b/src/library/scala/reflect/base/Names.scala @@ -1,6 +1,8 @@ package scala.reflect package base +import language.implicitConversions + /** A trait that manages names. * A name is a string in one of two name universes: terms and types. * The same string can be a name in both universes. diff --git a/src/library/scala/reflect/base/StandardNames.scala b/src/library/scala/reflect/base/StandardNames.scala index 8a3fbe9683..50399a4a1e 100644 --- a/src/library/scala/reflect/base/StandardNames.scala +++ b/src/library/scala/reflect/base/StandardNames.scala @@ -6,6 +6,11 @@ package scala.reflect package base +// Q: I have a pretty name. Where do I put it - into base.StandardNames or into api.StandardNames? +// A: Is it necessary to construct trees (like EMPTY or WILDCARD_STAR)? If yes, then it goes to base.StandardNames. +// Is it necessary to perform reflection (like ERROR or LOCAL_SUFFIX_STRING)? If yes, then it goes to api.StandardNames. +// Otherwise it goes nowhere - reflection API should stay minimalistic. + trait StandardNames { self: Universe => @@ -14,16 +19,16 @@ trait StandardNames { trait NamesBase { type NameType >: Null <: Name - val EMPTY: NameType - val ROOT: NameType - val EMPTY_PACKAGE_NAME: NameType val WILDCARD: NameType } - trait TypeNamesBase extends NamesBase - trait TermNamesBase extends NamesBase { val CONSTRUCTOR: TermName - val NO_NAME: NameType + val ROOTPKG: TermName + } + + trait TypeNamesBase extends NamesBase { + val EMPTY: NameType + val WILDCARD_STAR: NameType } } diff --git a/src/library/scala/runtime/Tuple2Zipped.scala b/src/library/scala/runtime/Tuple2Zipped.scala index 5ad364c8a5..dce7eef08d 100644 --- a/src/library/scala/runtime/Tuple2Zipped.scala +++ b/src/library/scala/runtime/Tuple2Zipped.scala @@ -10,6 +10,7 @@ package scala.runtime import scala.collection.{ TraversableLike, IterableLike } import scala.collection.generic.{ CanBuildFrom => CBF } +import language.{ higherKinds, implicitConversions } /** This interface is intended as a minimal interface, not complicated * by the requirement to resolve type constructors, for implicit search (which only diff --git a/src/library/scala/runtime/Tuple3Zipped.scala b/src/library/scala/runtime/Tuple3Zipped.scala index 4e9c542c58..f3ca08649d 100644 --- a/src/library/scala/runtime/Tuple3Zipped.scala +++ b/src/library/scala/runtime/Tuple3Zipped.scala @@ -10,6 +10,7 @@ package scala.runtime import scala.collection.{ TraversableLike, IterableLike } import scala.collection.generic.{ CanBuildFrom => CBF } +import language.{ higherKinds, implicitConversions } /** See comment on ZippedTraversable2. */ trait ZippedTraversable3[+El1, +El2, +El3] { diff --git a/src/library/scala/util/Try.scala b/src/library/scala/util/Try.scala index 9475a05d5a..f85bac0b84 100644 --- a/src/library/scala/util/Try.scala +++ b/src/library/scala/util/Try.scala @@ -8,11 +8,9 @@ package scala.util - - import collection.Seq import scala.util.control.NonFatal - +import language.implicitConversions /** * The `Try` type represents a computation that may either result in an exception, or return a @@ -208,7 +206,7 @@ final case class Success[+T](value: T) extends Try[T] { def flatMap[U](f: T => Try[U]): Try[U] = try f(value) catch { - case e => Failure(e) + case e: Throwable => Failure(e) } def flatten[U](implicit ev: T <:< Try[U]): Try[U] = value def foreach[U](f: T => U): Unit = f(value) diff --git a/src/library/scala/xml/dtd/ElementValidator.scala b/src/library/scala/xml/dtd/ElementValidator.scala index 111c1b5e78..f97da1c8a3 100644 --- a/src/library/scala/xml/dtd/ElementValidator.scala +++ b/src/library/scala/xml/dtd/ElementValidator.scala @@ -115,6 +115,7 @@ class ElementValidator() extends Function1[Node,Boolean] { (dfa delta q).getOrElse(e, throw ValidationException("element %s not allowed here" format e)) } } + case _ => false } /** applies various validations - accumulates error messages in exc diff --git a/src/partest/scala/tools/partest/DirectTest.scala b/src/partest/scala/tools/partest/DirectTest.scala index 5b4e1b4b25..323705b695 100644 --- a/src/partest/scala/tools/partest/DirectTest.scala +++ b/src/partest/scala/tools/partest/DirectTest.scala @@ -70,7 +70,7 @@ abstract class DirectTest extends App { /** Constructor/main body **/ try show() - catch { case t => println(t.getMessage) ; t.printStackTrace ; sys.exit(1) } + catch { case t: Exception => println(t.getMessage) ; t.printStackTrace ; sys.exit(1) } /** Debugger interest only below this line **/ protected def isDebug = (sys.props contains "partest.debug") || (sys.env contains "PARTEST_DEBUG") diff --git a/src/partest/scala/tools/partest/ScaladocModelTest.scala b/src/partest/scala/tools/partest/ScaladocModelTest.scala index ffc5e74cc0..7117d7c715 100644 --- a/src/partest/scala/tools/partest/ScaladocModelTest.scala +++ b/src/partest/scala/tools/partest/ScaladocModelTest.scala @@ -72,7 +72,7 @@ abstract class ScaladocModelTest extends DirectTest { testModel(universe.rootPackage) println("Done.") } catch { - case e => + case e: Exception => println(e) e.printStackTrace } @@ -102,7 +102,7 @@ abstract class ScaladocModelTest extends DirectTest { // finally, enable easy navigation inside the entities object access { - class TemplateAccess(tpl: DocTemplateEntity) { + implicit class TemplateAccess(tpl: DocTemplateEntity) { def _class(name: String): DocTemplateEntity = getTheFirst(_classes(name), tpl.qualifiedName + ".class(" + name + ")") def _classes(name: String): List[DocTemplateEntity] = tpl.templates.filter(_.name == name).collect({ case c: DocTemplateEntity with Class => c}) @@ -143,21 +143,21 @@ abstract class ScaladocModelTest extends DirectTest { def _aliasTypeTpls(name: String): List[DocTemplateEntity] = tpl.members.collect({ case dtpl: DocTemplateEntity with AliasType if dtpl.name == name => dtpl }) } - class PackageAccess(pack: Package) extends TemplateAccess(pack) { + trait WithMembers { + def members: List[MemberEntity] + def _member(name: String): MemberEntity = getTheFirst(_members(name), this.toString + ".member(" + name + ")") + def _members(name: String): List[MemberEntity] = members.filter(_.name == name) + } + implicit class PackageAccess(pack: Package) extends TemplateAccess(pack) { def _package(name: String): Package = getTheFirst(_packages(name), pack.qualifiedName + ".package(" + name + ")") def _packages(name: String): List[Package] = pack.packages.filter(_.name == name) } - - class MemberAccess(mbrs: WithMembers) { - def _member(name: String): MemberEntity = getTheFirst(_members(name), mbrs.toString + ".member(" + name + ")") - def _members(name: String): List[MemberEntity] = mbrs.members.filter(_.name == name) + implicit class DocTemplateEntityMembers(val underlying: DocTemplateEntity) extends WithMembers { + def members = underlying.members + } + implicit class ImplicitConversionMembers(val underlying: ImplicitConversion) extends WithMembers { + def members = underlying.members } - - type WithMembers = { def members: List[MemberEntity]; def toString: String } /* DocTemplates and ImplicitConversions */ - - implicit def templateAccess(tpl: DocTemplateEntity) = new TemplateAccess(tpl) - implicit def packageAccess(pack: Package) = new PackageAccess(pack) - implicit def membersAccess(mbrs: WithMembers) = new MemberAccess(mbrs) def getTheFirst[T](list: List[T], expl: String): T = list.length match { case 1 => list.head diff --git a/src/partest/scala/tools/partest/nest/RunnerManager.scala b/src/partest/scala/tools/partest/nest/RunnerManager.scala index dc15d4475b..5a7684dc61 100644 --- a/src/partest/scala/tools/partest/nest/RunnerManager.scala +++ b/src/partest/scala/tools/partest/nest/RunnerManager.scala @@ -82,7 +82,7 @@ class RunnerManager(kind: String, val fileManager: FileManager, params: TestRunP private def compareFiles(f1: File, f2: File): String = try fileManager.compareFiles(f1, f2) - catch { case t => t.toString } + catch { case t: Exception => t.toString } /** This does something about absolute paths and file separator * chars before diffing. @@ -779,11 +779,11 @@ class RunnerManager(kind: String, val fileManager: FileManager, params: TestRunP logStackTrace(logFile, t, "Possible compiler crash during test of: " + testFile + "\n") LogContext(logFile) } - catch { case t => LogContext(null) } + catch { case t: Throwable => LogContext(null) } } def run(): (Boolean, LogContext) = { - val result = try processSingleFile(testFile) catch { case t => (false, crashContext(t)) } + val result = try processSingleFile(testFile) catch { case t: Throwable => (false, crashContext(t)) } passed = Some(result._1) result } diff --git a/src/partest/scala/tools/partest/package.scala b/src/partest/scala/tools/partest/package.scala index 9b510eacd6..9f45b380eb 100644 --- a/src/partest/scala/tools/partest/package.scala +++ b/src/partest/scala/tools/partest/package.scala @@ -30,6 +30,9 @@ package object partest { implicit private[partest] def temporaryPath2File(x: Path): JFile = x.jfile implicit private[partest] def temporaryFile2Path(x: JFile): Path = Path(x) + implicit lazy val postfixOps = language.postfixOps + implicit lazy val implicitConversions = language.implicitConversions + def timed[T](body: => T): (T, Long) = { val t1 = System.currentTimeMillis val result = body @@ -60,7 +63,7 @@ package object partest { def allPropertiesString = { import collection.JavaConversions._ - System.getProperties.toList.sorted map { case (k, v) => "%s -> %s\n".format(k, v) } mkString + System.getProperties.toList.sorted map { case (k, v) => "%s -> %s\n".format(k, v) } mkString "" } def showAllJVMInfo() { diff --git a/src/reflect/scala/reflect/api/Names.scala b/src/reflect/scala/reflect/api/Names.scala index 222ee5024b..d6868c26ab 100644 --- a/src/reflect/scala/reflect/api/Names.scala +++ b/src/reflect/scala/reflect/api/Names.scala @@ -20,9 +20,6 @@ trait Names extends base.Names { */ abstract class NameApi extends NameBase { - // [Eugene++] this functionality should be in base - // this is because stuff will be reified in mangled state, and people will need a way to figure it out - /** Replaces all occurrences of \$op_names in this name by corresponding operator symbols. * Example: `foo_\$plus\$eq` becomes `foo_+=` */ diff --git a/src/reflect/scala/reflect/api/StandardNames.scala b/src/reflect/scala/reflect/api/StandardNames.scala index eb1ecda900..24d803a24a 100644 --- a/src/reflect/scala/reflect/api/StandardNames.scala +++ b/src/reflect/scala/reflect/api/StandardNames.scala @@ -5,6 +5,9 @@ package scala.reflect package api +// Q: I have a pretty name. Where do I put it - into base.StandardNames or into api.StandardNames? +// A: <see base.StandardNames> + trait StandardNames extends base.StandardNames { self: Universe => @@ -12,151 +15,16 @@ trait StandardNames extends base.StandardNames { val tpnme: TypeNamesApi trait NamesApi extends NamesBase { - val ANON_CLASS_NAME: NameType - val ANON_FUN_NAME: NameType + val ROOT: NameType val EMPTY: NameType val ERROR: NameType - val IMPORT: NameType - val MODULE_VAR_SUFFIX: NameType val PACKAGE: NameType - val ROOT: NameType - val SPECIALIZED_SUFFIX: NameType - - def flattenedName(segments: Name*): NameType } trait TermNamesApi extends NamesApi with TermNamesBase { - val EXPAND_SEPARATOR_STRING: String - val IMPL_CLASS_SUFFIX: String - val INTERPRETER_IMPORT_WRAPPER: String - val INTERPRETER_LINE_PREFIX: String - val INTERPRETER_VAR_PREFIX: String - val INTERPRETER_WRAPPER_SUFFIX: String - val LOCALDUMMY_PREFIX: String val LOCAL_SUFFIX_STRING: String - val MODULE_SUFFIX_NAME: TermName - val NAME_JOIN_NAME: TermName - val PROTECTED_PREFIX: String - val PROTECTED_SET_PREFIX: String - val SETTER_SUFFIX: TermName - val SINGLETON_SUFFIX: String - val SUPER_PREFIX_STRING: String - val TRAIT_SETTER_SEPARATOR_STRING: String - - val FAKE_LOCAL_THIS: TermName - val INITIALIZER: TermName - val LAZY_LOCAL: TermName - val UNIVERSE_BUILD: NameType - val UNIVERSE_BUILD_PREFIX: NameType - val UNIVERSE_PREFIX: NameType - val UNIVERSE_SHORT: NameType - val MIRROR_PREFIX: NameType - val MIRROR_SHORT: NameType - val MIRROR_UNTYPED: NameType - val REIFY_FREE_PREFIX: NameType - val REIFY_FREE_THIS_SUFFIX: NameType - val REIFY_FREE_VALUE_SUFFIX: NameType - val REIFY_SYMDEF_PREFIX: NameType - val MIXIN_CONSTRUCTOR: TermName - val MODULE_INSTANCE_FIELD: TermName - val OUTER: TermName - val OUTER_LOCAL: TermName - val OUTER_SYNTH: TermName - val SELECTOR_DUMMY: TermName - val SELF: TermName - val SPECIALIZED_INSTANCE: TermName - val STAR: TermName - val THIS: TermName - - val BITMAP_NORMAL: TermName - val BITMAP_TRANSIENT: TermName - val BITMAP_CHECKINIT: TermName - val BITMAP_CHECKINIT_TRANSIENT: TermName - - val ROOTPKG: TermName - - val ADD: TermName - val AND: TermName - val ASR: TermName - val DIV: TermName - val EQ: TermName - val EQL: TermName - val GE: TermName - val GT: TermName - val HASHHASH: TermName - val LE: TermName - val LSL: TermName - val LSR: TermName - val LT: TermName - val MINUS: TermName - val MOD: TermName - val MUL: TermName - val NE: TermName - val OR: TermName - val PLUS : TermName - val SUB: TermName - val XOR: TermName - val ZAND: TermName - val ZOR: TermName - - val UNARY_~ : TermName - val UNARY_+ : TermName - val UNARY_- : TermName - val UNARY_! : TermName - - val ??? : TermName - - def isConstructorName(name: Name): Boolean - def isExceptionResultName(name: Name): Boolean - def isImplClassName(name: Name): Boolean - def isLocalDummyName(name: Name): Boolean - def isLocalName(name: Name): Boolean - def isLoopHeaderLabel(name: Name): Boolean - def isModuleName(name: Name): Boolean - def isOpAssignmentName(name: Name): Boolean - def isProtectedAccessorName(name: Name): Boolean - def isReplWrapperName(name: Name): Boolean - def isSetterName(name: Name): Boolean - def isSingletonName(name: Name): Boolean - def isSuperAccessorName(name: Name): Boolean - def isTraitSetterName(name: Name): Boolean - - def defaultGetterName(name: Name, pos: Int): TermName - def defaultGetterToMethod(name: Name): TermName - def expandedName(name: TermName, base: Symbol, separator: String): TermName - def expandedSetterName(name: TermName, base: Symbol): TermName - def getterName(name: TermName): TermName - def getterToLocal(name: TermName): TermName - def getterToSetter(name: TermName): TermName - def localDummyName(clazz: Symbol): TermName - def localToGetter(name: TermName): TermName - def protName(name: Name): TermName - def protSetterName(name: Name): TermName - def setterToGetter(name: TermName): TermName - def superName(name: Name): TermName - - def dropLocalSuffix(name: Name): Name - def originalName(name: Name): Name - def stripModuleSuffix(name: Name): Name - def unspecializedName(name: Name): Name - def segments(name: String, assumeTerm: Boolean): List[Name] - def splitSpecializedName(name: Name): (Name, String, String) } trait TypeNamesApi extends NamesApi with TypeNamesBase { - val BYNAME_PARAM_CLASS_NAME: TypeName - val EQUALS_PATTERN_NAME: TypeName - val JAVA_REPEATED_PARAM_CLASS_NAME: TypeName - val LOCAL_CHILD: TypeName - val REFINE_CLASS_NAME: TypeName - val REPEATED_PARAM_CLASS_NAME: TypeName - val WILDCARD_STAR: TypeName - val REIFY_TYPECREATOR_PREFIX: NameType - val REIFY_TREECREATOR_PREFIX: NameType - - def dropSingletonName(name: Name): TypeName - def implClassName(name: Name): TypeName - def interfaceName(implname: Name): TypeName - def singletonName(name: Name): TypeName } } diff --git a/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala b/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala index fa758edf05..19f70ba785 100644 --- a/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala +++ b/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala @@ -226,7 +226,7 @@ trait BaseTypeSeqs { override def map(g: Type => Type) = lateMap(g) override def lateMap(g: Type => Type) = orig.lateMap(x => g(f(x))) override def exists(p: Type => Boolean) = elems exists (x => p(f(x))) - override protected def maxDepthOfElems: Int = elems map (x => typeDepth(f(x))) max + override protected def maxDepthOfElems: Int = elems.map(x => typeDepth(f(x))).max override def toString = elems.mkString("MBTS(", ",", ")") } diff --git a/src/reflect/scala/reflect/internal/Printers.scala b/src/reflect/scala/reflect/internal/Printers.scala index c018ddc88e..18f9928124 100644 --- a/src/reflect/scala/reflect/internal/Printers.scala +++ b/src/reflect/scala/reflect/internal/Printers.scala @@ -649,19 +649,18 @@ trait Printers extends api.Printers { self: SymbolTable => } def show(name: Name): String = name match { - // base.StandardNames case tpnme.EMPTY => "tpnme.EMPTY" case tpnme.ROOT => "tpnme.ROOT" + case tpnme.PACKAGE => "tpnme.PACKAGE" case tpnme.EMPTY_PACKAGE_NAME => "tpnme.EMPTY_PACKAGE_NAME" case tpnme.WILDCARD => "tpnme.WILDCARD" - case nme.CONSTRUCTOR => "nme.CONSTRUCTOR" - case nme.NO_NAME => "nme.NO_NAME" - // api.StandardNames - case tpnme.ERROR => "tpnme.ERROR" - case nme.ERROR => "nme.ERROR" case nme.EMPTY => "nme.EMPTY" - case tpnme.PACKAGE => "tpnme.PACKAGE" + case nme.ROOT => "nme.ROOT" case nme.PACKAGE => "nme.PACKAGE" + case nme.EMPTY_PACKAGE_NAME => "nme.EMPTY_PACKAGE_NAME" + case nme.WILDCARD => "nme.WILDCARD" + case nme.CONSTRUCTOR => "nme.CONSTRUCTOR" + case nme.ROOTPKG => "nme.ROOTPKG" case _ => val prefix = if (name.isTermName) "newTermName(\"" else "newTypeName(\"" prefix + name.toString + "\")" diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 10d02376b1..b14306282b 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -78,6 +78,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => def asType: Type = tpe def asTypeIn(site: Type): Type = site.memberType(this) def asTypeConstructor: Type = typeConstructor + def setFlags(flags: FlagSet): this.type = setInternalFlags(flags) def setInternalFlags(flag: Long): this.type = { setFlag(flag); this } def setTypeSignature(tpe: Type): this.type = { setInfo(tpe); this } def getAnnotations: List[AnnotationInfo] = { initialize; annotations } @@ -162,8 +163,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => val passedIn = named.collect { case (argName, argType) if argName == paramName => argType }.headOption - if (passedIn isDefined) passedIn - else defaults.get(paramIndex).map(_.asInstanceOf[Type]) + + passedIn orElse defaults.get(paramIndex).map(_.asInstanceOf[Type]) } val rest1 = { diff --git a/src/reflect/scala/reflect/internal/TreeGen.scala b/src/reflect/scala/reflect/internal/TreeGen.scala index c3a6fce164..285700f9ff 100644 --- a/src/reflect/scala/reflect/internal/TreeGen.scala +++ b/src/reflect/scala/reflect/internal/TreeGen.scala @@ -143,6 +143,8 @@ abstract class TreeGen extends makro.TreeBuilder { /** Computes stable type for a tree if possible */ def stableTypeFor(tree: Tree): Option[Type] = tree match { + case This(_) if tree.symbol != null && !tree.symbol.isError => + Some(ThisType(tree.symbol)) case Ident(_) if tree.symbol.isStable => Some(singleType(tree.symbol.owner.thisType, tree.symbol)) case Select(qual, _) if ((tree.symbol ne null) && (qual.tpe ne null)) && // turned assert into guard for #4064 diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index 01679a777d..3a218c18f1 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -600,7 +600,7 @@ trait Types extends api.Types { self: SymbolTable => def decl(name: Name): Symbol = findDecl(name, 0) /** A list of all non-private members defined or declared in this type. */ - def nonPrivateDecls: List[Symbol] = decls filter (x => !x.isPrivate) toList + def nonPrivateDecls: List[Symbol] = decls.filterNot(_.isPrivate).toList /** The non-private defined or declared members with name `name` in this type; * an OverloadedSymbol if several exist, NoSymbol if none exist. @@ -1392,11 +1392,9 @@ trait Types extends api.Types { self: SymbolTable => final class UniqueThisType(sym: Symbol) extends ThisType(sym) with UniqueType { } object ThisType extends ThisTypeExtractor { - def apply(sym: Symbol): Type = { - if (!phase.erasedTypes) unique(new UniqueThisType(sym)) - else if (sym.isImplClass) sym.typeOfThis - else sym.tpe - } + def apply(sym: Symbol): Type = + if (phase.erasedTypes) sym.tpe + else unique(new UniqueThisType(sym)) } /** A class for singleton types of the form `<prefix>.<sym.name>.type`. @@ -2613,7 +2611,7 @@ trait Types extends api.Types { self: SymbolTable => case class PolyType(override val typeParams: List[Symbol], override val resultType: Type) extends Type with PolyTypeApi { //assert(!(typeParams contains NoSymbol), this) - assert(typeParams nonEmpty, this) // used to be a marker for nullary method type, illegal now (see @NullaryMethodType) + assert(typeParams.nonEmpty, this) // used to be a marker for nullary method type, illegal now (see @NullaryMethodType) override def paramSectionCount: Int = resultType.paramSectionCount override def paramss: List[List[Symbol]] = resultType.paramss @@ -3275,7 +3273,7 @@ trait Types extends api.Types { self: SymbolTable => // to never be resumed with the current implementation assert(!suspended, this) TypeVar.trace("clone", originLocation)( - TypeVar(origin, constr cloneInternal, typeArgs, params) // @M TODO: clone args/params? + TypeVar(origin, constr.cloneInternal, typeArgs, params) // @M TODO: clone args/params? ) } } @@ -3637,7 +3635,7 @@ trait Types extends api.Types { self: SymbolTable => */ object GenPolyType { def apply(tparams: List[Symbol], tpe: Type): Type = ( - if (tparams nonEmpty) typeFun(tparams, tpe) + if (tparams.nonEmpty) typeFun(tparams, tpe) else tpe // it's okay to be forgiving here ) def unapply(tpe: Type): Option[(List[Symbol], Type)] = tpe match { @@ -4652,14 +4650,14 @@ trait Types extends api.Types { self: SymbolTable => // dependent method types object IsDependentCollector extends TypeCollector(false) { def traverse(tp: Type) { - if(tp isImmediatelyDependent) result = true + if (tp.isImmediatelyDependent) result = true else if (!result) mapOver(tp) } } object ApproximateDependentMap extends TypeMap { def apply(tp: Type): Type = - if(tp isImmediatelyDependent) WildcardType + if (tp.isImmediatelyDependent) WildcardType else mapOver(tp) } @@ -6159,7 +6157,7 @@ trait Types extends api.Types { self: SymbolTable => } val sorted = btsMap.toList.sortWith((x, y) => x._1.typeSymbol isLess y._1.typeSymbol) - val maxSeqLength = sorted map (_._2.size) max + val maxSeqLength = sorted.map(_._2.size).max val padded = sorted map (_._2.padTo(maxSeqLength, NoType)) val transposed = padded.transpose @@ -6265,7 +6263,7 @@ trait Types extends api.Types { self: SymbolTable => }).mkString("") println("Frontier(\n" + str + ")") - printLubMatrix(ts zip tsBts toMap, lubListDepth) + printLubMatrix((ts zip tsBts).toMap, lubListDepth) } loop(newtps) @@ -6275,7 +6273,7 @@ trait Types extends api.Types { self: SymbolTable => val initialBTSes = ts map (_.baseTypeSeq.toList) if (printLubs) - printLubMatrix(ts zip initialBTSes toMap, depth) + printLubMatrix((ts zip initialBTSes).toMap, depth) loop(initialBTSes) } @@ -6483,7 +6481,7 @@ trait Types extends api.Types { self: SymbolTable => map2(narrowts, syms)((t, sym) => t.memberInfo(sym).substThis(t.typeSymbol, lubThisType)) if (proto.isTerm) // possible problem: owner of info is still the old one, instead of new refinement class proto.cloneSymbol(lubRefined.typeSymbol).setInfoOwnerAdjusted(lub(symtypes, decr(depth))) - else if (symtypes.tail forall (symtypes.head =:=)) + else if (symtypes.tail forall (symtypes.head =:= _)) proto.cloneSymbol(lubRefined.typeSymbol).setInfoOwnerAdjusted(symtypes.head) else { def lubBounds(bnds: List[TypeBounds]): TypeBounds = @@ -6857,7 +6855,7 @@ trait Types extends api.Types { self: SymbolTable => tps map { case MethodType(params1, res) if (isSameTypes(params1 map (_.tpe), pts)) => res - case NullaryMethodType(res) if pts isEmpty => + case NullaryMethodType(res) if pts.isEmpty => res case _ => throw new NoCommonType(tps) diff --git a/src/reflect/scala/reflect/internal/util/Origins.scala b/src/reflect/scala/reflect/internal/util/Origins.scala index 0bd5ad55ca..3111730f76 100644 --- a/src/reflect/scala/reflect/internal/util/Origins.scala +++ b/src/reflect/scala/reflect/internal/util/Origins.scala @@ -96,7 +96,7 @@ object Origins { || (el.getClassName startsWith "java.lang.") ) private def findCutoff() = { - val cutoff = Thread.currentThread.getStackTrace dropWhile preCutoff head; + val cutoff = (Thread.currentThread.getStackTrace dropWhile preCutoff).head OriginId(cutoff.getClassName, cutoff.getMethodName) } diff --git a/src/reflect/scala/reflect/internal/util/SourceFile.scala b/src/reflect/scala/reflect/internal/util/SourceFile.scala index df4a3336c3..f24e44b351 100644 --- a/src/reflect/scala/reflect/internal/util/SourceFile.scala +++ b/src/reflect/scala/reflect/internal/util/SourceFile.scala @@ -41,7 +41,7 @@ abstract class SourceFile { (content drop offset) startsWith text def lineToString(index: Int): String = - content drop lineToOffset(index) takeWhile (c => !isLineBreakChar(c.toChar)) mkString + content drop lineToOffset(index) takeWhile (c => !isLineBreakChar(c.toChar)) mkString "" @tailrec final def skipWhitespace(offset: Int): Int = diff --git a/src/reflect/scala/reflect/internal/util/TableDef.scala b/src/reflect/scala/reflect/internal/util/TableDef.scala index d692a6d8f5..2e60ce3bcc 100644 --- a/src/reflect/scala/reflect/internal/util/TableDef.scala +++ b/src/reflect/scala/reflect/internal/util/TableDef.scala @@ -1,6 +1,7 @@ package scala.reflect.internal.util import TableDef._ +import language.postfixOps /** A class for representing tabular data in a way that preserves * its inner beauty. See Exceptional for an example usage. diff --git a/src/reflect/scala/reflect/makro/Universe.scala b/src/reflect/scala/reflect/makro/Universe.scala index a676f7f1de..d88e7e0bb8 100644 --- a/src/reflect/scala/reflect/makro/Universe.scala +++ b/src/reflect/scala/reflect/makro/Universe.scala @@ -24,8 +24,15 @@ abstract class Universe extends scala.reflect.api.Universe { */ trait SymbolContextApi extends SymbolApi with AttachableApi { this: Symbol => - // [Eugene++ to Martin] should we also add mutability methods here (similarly to what's done below for trees)? - // I'm talking about `setAnnotations` and friends + def setFlags(flags: FlagSet): this.type + + def setTypeSignature(tpe: Type): this.type + + def setAnnotations(annots: AnnotationInfo*): this.type + + def setName(name: Name): this.type + + def setPrivateWithin(sym: Symbol): this.type } // Tree extensions --------------------------------------------------------------- diff --git a/src/reflect/scala/reflect/runtime/ReflectionUtils.scala b/src/reflect/scala/reflect/runtime/ReflectionUtils.scala index 7839850529..f696aceb93 100644 --- a/src/reflect/scala/reflect/runtime/ReflectionUtils.scala +++ b/src/reflect/scala/reflect/runtime/ReflectionUtils.scala @@ -38,6 +38,8 @@ object ReflectionUtils { ) def show(cl: ClassLoader): String = { + import language.reflectiveCalls + def isAbstractFileClassLoader(clazz: Class[_]): Boolean = { if (clazz == null) return false if (clazz.getName == "scala.tools.nsc.interpreter.AbstractFileClassLoader") return true diff --git a/src/reflect/scala/tools/nsc/io/File.scala b/src/reflect/scala/tools/nsc/io/File.scala index eedf92ef98..1f3cac7ee1 100644 --- a/src/reflect/scala/tools/nsc/io/File.scala +++ b/src/reflect/scala/tools/nsc/io/File.scala @@ -120,13 +120,13 @@ class File(jfile: JFile)(implicit constructorCodec: Codec) extends Path(jfile) w def writeAll(strings: String*): Unit = { val out = bufferedWriter() try strings foreach (out write _) - finally out close + finally out.close() } def writeBytes(bytes: Array[Byte]): Unit = { val out = bufferedOutput() try out write bytes - finally out close + finally out.close() } def appendAll(strings: String*): Unit = { @@ -139,7 +139,7 @@ class File(jfile: JFile)(implicit constructorCodec: Codec) extends Path(jfile) w def printlnAll(strings: String*): Unit = { val out = printWriter() try strings foreach (out println _) - finally out close + finally out.close() } def safeSlurp(): Option[String] = diff --git a/src/reflect/scala/tools/nsc/io/Path.scala b/src/reflect/scala/tools/nsc/io/Path.scala index 984c96dfbb..74bd6cf16b 100644 --- a/src/reflect/scala/tools/nsc/io/Path.scala +++ b/src/reflect/scala/tools/nsc/io/Path.scala @@ -78,7 +78,7 @@ object Path { else new Path(jfile) /** Avoiding any shell/path issues by only using alphanumerics. */ - private[io] def randomPrefix = alphanumeric take 6 mkString + private[io] def randomPrefix = alphanumeric take 6 mkString "" private[io] def fail(msg: String) = throw FileOperationException(msg) } import Path._ diff --git a/src/reflect/scala/tools/nsc/io/Streamable.scala b/src/reflect/scala/tools/nsc/io/Streamable.scala index 03318674ee..4d872c0221 100644 --- a/src/reflect/scala/tools/nsc/io/Streamable.scala +++ b/src/reflect/scala/tools/nsc/io/Streamable.scala @@ -112,7 +112,7 @@ object Streamable { finally stream.close() def bytes(is: => InputStream): Array[Byte] = - new Bytes { def inputStream() = is } toByteArray + (new Bytes { def inputStream() = is }).toByteArray def slurp(is: => InputStream)(implicit codec: Codec): String = new Chars { def inputStream() = is } slurp codec diff --git a/src/reflect/scala/tools/nsc/io/VirtualDirectory.scala b/src/reflect/scala/tools/nsc/io/VirtualDirectory.scala index 0bcb2de43f..7272921054 100644 --- a/src/reflect/scala/tools/nsc/io/VirtualDirectory.scala +++ b/src/reflect/scala/tools/nsc/io/VirtualDirectory.scala @@ -48,7 +48,7 @@ extends AbstractFile { def iterator = files.values.toList.iterator override def lookupName(name: String, directory: Boolean): AbstractFile = - files get name filter (_.isDirectory == directory) orNull + (files get name filter (_.isDirectory == directory)).orNull override def fileNamed(name: String): AbstractFile = Option(lookupName(name, false)) getOrElse { diff --git a/src/scalap/scala/tools/scalap/Arguments.scala b/src/scalap/scala/tools/scalap/Arguments.scala index 37f6cd84ac..53f722994d 100644 --- a/src/scalap/scala/tools/scalap/Arguments.scala +++ b/src/scalap/scala/tools/scalap/Arguments.scala @@ -48,7 +48,7 @@ object Arguments { def parseBinding(str: String, separator: Char): (String, String) = (str indexOf separator) match { case -1 => argumentError("missing '" + separator + "' in binding '" + str + "'") ; Pair("", "") - case idx => Pair(str take idx trim, str drop (idx + 1) trim) + case idx => Pair((str take idx).trim, (str drop (idx + 1)).trim) } def parse(args: Array[String]): Arguments = { diff --git a/src/scalap/scala/tools/scalap/CodeWriter.scala b/src/scalap/scala/tools/scalap/CodeWriter.scala index d895ce3836..f5db183abb 100644 --- a/src/scalap/scala/tools/scalap/CodeWriter.scala +++ b/src/scalap/scala/tools/scalap/CodeWriter.scala @@ -58,7 +58,7 @@ class CodeWriter(writer: Writer) { try { writer.write(nl) } catch { - case e => sys.error("IO error") + case e: Exception => sys.error("IO error") } line = align align = true @@ -127,7 +127,7 @@ class CodeWriter(writer: Writer) { line = false this } catch { - case e => sys.error("IO error") + case e: Exception => sys.error("IO error") } override def toString(): String = writer.toString() diff --git a/src/scalap/scala/tools/scalap/Decode.scala b/src/scalap/scala/tools/scalap/Decode.scala index 4e12075541..26cea76893 100644 --- a/src/scalap/scala/tools/scalap/Decode.scala +++ b/src/scalap/scala/tools/scalap/Decode.scala @@ -49,7 +49,7 @@ object Decode { import classFile._ classFile annotation SCALA_SIG_ANNOTATION map { case Annotation(_, els) => - val bytesElem = els find (x => constant(x.elementNameIndex) == BYTES_VALUE) get + val bytesElem = els find (x => constant(x.elementNameIndex) == BYTES_VALUE) getOrElse null val _bytes = bytesElem.elementValue match { case ConstValueIndex(x) => constantWrapped(x) } val bytes = _bytes.asInstanceOf[StringBytesPair].bytes val length = ByteCodecs.decode(bytes) @@ -81,7 +81,7 @@ object Decode { xs.toList map (_.name dropRight 1) } - (ssig.symbols collect f).flatten toList + (ssig.symbols collect f).flatten.toList } } diff --git a/src/scalap/scala/tools/scalap/MetaParser.scala b/src/scalap/scala/tools/scalap/MetaParser.scala index ca9bd93f86..036738c5e9 100644 --- a/src/scalap/scala/tools/scalap/MetaParser.scala +++ b/src/scalap/scala/tools/scalap/MetaParser.scala @@ -61,7 +61,7 @@ class MetaParser(meta: String) { else None } catch { - case _ => None + case _: Exception => None } } else None; diff --git a/src/scalap/scala/tools/scalap/scalax/rules/package.scala b/src/scalap/scala/tools/scalap/scalax/rules/package.scala new file mode 100644 index 0000000000..324e87435e --- /dev/null +++ b/src/scalap/scala/tools/scalap/scalax/rules/package.scala @@ -0,0 +1,9 @@ +package scala.tools.scalap +package scalax + +package object rules { + implicit lazy val higherKinds = language.higherKinds + implicit lazy val postfixOps = language.postfixOps + implicit lazy val implicitConversions = language.implicitConversions + implicit lazy val reflectiveCalls = language.reflectiveCalls +} diff --git a/src/swing/scala/swing/Action.scala b/src/swing/scala/swing/Action.scala index 9deea0f3d4..a609329510 100644 --- a/src/swing/scala/swing/Action.scala +++ b/src/swing/scala/swing/Action.scala @@ -135,7 +135,7 @@ abstract class Action(title0: String) { def accelerator: Option[KeyStroke] = toOption(peer.getValue(javax.swing.Action.ACCELERATOR_KEY)) def accelerator_=(k: Option[KeyStroke]) { - peer.putValue(javax.swing.Action.ACCELERATOR_KEY, k orNull) + peer.putValue(javax.swing.Action.ACCELERATOR_KEY, k.orNull) } /** diff --git a/src/swing/scala/swing/ComboBox.scala b/src/swing/scala/swing/ComboBox.scala index 75f981064b..c7a457d082 100644 --- a/src/swing/scala/swing/ComboBox.scala +++ b/src/swing/scala/swing/ComboBox.scala @@ -6,8 +6,6 @@ ** |/ ** \* */ - - package scala.swing import event._ @@ -205,6 +203,6 @@ class ComboBox[A](items: Seq[A]) extends Component with Publisher { def prototypeDisplayValue: Option[A] = toOption[A](peer.getPrototypeDisplayValue) def prototypeDisplayValue_=(v: Option[A]) { - peer.setPrototypeDisplayValue(v map toAnyRef orNull) + peer.setPrototypeDisplayValue((v map toAnyRef).orNull) } } diff --git a/src/swing/scala/swing/GridBagPanel.scala b/src/swing/scala/swing/GridBagPanel.scala index d5b2472e38..dd4cbe3bcf 100644 --- a/src/swing/scala/swing/GridBagPanel.scala +++ b/src/swing/scala/swing/GridBagPanel.scala @@ -6,13 +6,10 @@ ** |/ ** \* */ - - package scala.swing import java.awt.{GridBagConstraints, GridBagLayout} - object GridBagPanel { object Fill extends Enumeration { val None = Value(GridBagConstraints.NONE) diff --git a/src/swing/scala/swing/RichWindow.scala b/src/swing/scala/swing/RichWindow.scala index 977aab300a..8eb58d56c9 100644 --- a/src/swing/scala/swing/RichWindow.scala +++ b/src/swing/scala/swing/RichWindow.scala @@ -145,7 +145,7 @@ object Dialog { initial: Int): Result.Value = { val r = JOptionPane.showOptionDialog(nullPeer(parent), message, title, optionType.id, messageType.id, Swing.wrapIcon(icon), - entries map toAnyRef toArray, entries(initial)) + (entries map toAnyRef).toArray, entries(initial)) Result(r) } @@ -157,7 +157,7 @@ object Dialog { entries: Seq[A] = Nil, initial: A): Option[A] = { val e = if (entries.isEmpty) null - else entries map toAnyRef toArray + else (entries map toAnyRef).toArray val r = JOptionPane.showInputDialog(nullPeer(parent), message, title, messageType.id, Swing.wrapIcon(icon), e, initial) diff --git a/src/swing/scala/swing/ScrollPane.scala b/src/swing/scala/swing/ScrollPane.scala index 5c18bb138a..966d5889e2 100644 --- a/src/swing/scala/swing/ScrollPane.scala +++ b/src/swing/scala/swing/ScrollPane.scala @@ -65,17 +65,17 @@ class ScrollPane extends Component with Container { def rowHeaderView: Option[Component] = Option(peer.getRowHeader.getView) map UIElement.cachedWrapper[Component] def rowHeaderView_=(c: Component) = peer.setRowHeaderView(c.peer) - def rowHeaderView_=(c: Option[Component]) = peer.setRowHeaderView(c map (_.peer) orNull) + def rowHeaderView_=(c: Option[Component]) = peer.setRowHeaderView(c.map(_.peer).orNull) def columnHeaderView: Option[Component] = Option(peer.getColumnHeader.getView) map UIElement.cachedWrapper[Component] def columnHeaderView_=(c: Component) = peer.setColumnHeaderView(c.peer) - def columnHeaderView_=(c: Option[Component]) = peer.setColumnHeaderView(c map (_.peer) orNull) + def columnHeaderView_=(c: Option[Component]) = peer.setColumnHeaderView(c.map(_.peer).orNull) def viewportView: Option[Component] = Option(peer.getViewport.getView) map UIElement.cachedWrapper[Component] def viewportView_=(c: Component) = peer.setViewportView(c.peer) - def viewportView_=(c: Option[Component]) = peer.setViewportView(c map (_.peer) orNull) + def viewportView_=(c: Option[Component]) = peer.setViewportView(c.map(_.peer).orNull) def verticalScrollBarPolicy = BarPolicy.wrap(peer.getVerticalScrollBarPolicy) def verticalScrollBarPolicy_=(p: BarPolicy.Value) = peer.setVerticalScrollBarPolicy(p.verticalPeer) diff --git a/src/swing/scala/swing/Swing.scala b/src/swing/scala/swing/Swing.scala index 519ccbaf33..05291f9aee 100644 --- a/src/swing/scala/swing/Swing.scala +++ b/src/swing/scala/swing/Swing.scala @@ -15,6 +15,7 @@ import javax.swing.event._ import javax.swing.border._ import javax.swing.{JComponent, Icon, BorderFactory, SwingUtilities} + /** * Helpers for this package. */ diff --git a/src/swing/scala/swing/UIElement.scala b/src/swing/scala/swing/UIElement.scala index 04e2217943..a83496fff0 100644 --- a/src/swing/scala/swing/UIElement.scala +++ b/src/swing/scala/swing/UIElement.scala @@ -37,7 +37,7 @@ object UIElement { case c: javax.swing.JComponent => c.getClientProperty(ClientKey) case _ => wrapperCache.get(c) } - try { w.asInstanceOf[C] } catch { case _ => null } + try { w.asInstanceOf[C] } catch { case _: Exception => null } } /** diff --git a/src/swing/scala/swing/Window.scala b/src/swing/scala/swing/Window.scala index 7991026a69..db911be0d7 100644 --- a/src/swing/scala/swing/Window.scala +++ b/src/swing/scala/swing/Window.scala @@ -51,7 +51,7 @@ abstract class Window extends UIElement with RootPanel with Publisher { outer => peer.getRootPane.setDefaultButton(b.peer) } def defaultButton_=(b: Option[Button]) { - peer.getRootPane.setDefaultButton(b map (_.peer) orNull) + peer.getRootPane.setDefaultButton(b.map(_.peer).orNull) } def dispose() { peer.dispose() } diff --git a/src/swing/scala/swing/package.scala b/src/swing/scala/swing/package.scala index d5095f021b..96530e2e94 100644 --- a/src/swing/scala/swing/package.scala +++ b/src/swing/scala/swing/package.scala @@ -14,6 +14,9 @@ package object swing { type Image = java.awt.Image type Font = java.awt.Font + implicit lazy val reflectiveCalls = language.reflectiveCalls + implicit lazy val implicitConversions = language.implicitConversions + private[swing] def ifNull[A](o: Object, a: A): A = if(o eq null) a else o.asInstanceOf[A] private[swing] def toOption[A](o: Object): Option[A] = if(o eq null) None else Some(o.asInstanceOf[A]) private[swing] def toAnyRef(x: Any): AnyRef = x.asInstanceOf[AnyRef] diff --git a/test/files/neg/t3234.check b/test/files/neg/t3234.check new file mode 100644 index 0000000000..477b021e5e --- /dev/null +++ b/test/files/neg/t3234.check @@ -0,0 +1,2 @@ +error: there were 1 inliner warnings; re-run with -Yinline-warnings for details +one error found diff --git a/test/files/pos/t3234.flags b/test/files/neg/t3234.flags index c9cefdc4b9..c9cefdc4b9 100644 --- a/test/files/pos/t3234.flags +++ b/test/files/neg/t3234.flags diff --git a/test/files/pos/t3234.scala b/test/files/neg/t3234.scala index 443d0467f0..443d0467f0 100644 --- a/test/files/pos/t3234.scala +++ b/test/files/neg/t3234.scala diff --git a/test/files/neg/unchecked.check b/test/files/neg/unchecked.check new file mode 100644 index 0000000000..34a11db1a0 --- /dev/null +++ b/test/files/neg/unchecked.check @@ -0,0 +1,19 @@ +unchecked.scala:18: error: non-variable type argument String in type pattern Iterable[String] is unchecked since it is eliminated by erasure + case xs: Iterable[String] => xs.head // unchecked + ^ +unchecked.scala:22: error: non-variable type argument Any in type pattern Set[Any] is unchecked since it is eliminated by erasure + case xs: Set[Any] => xs.head // unchecked + ^ +unchecked.scala:26: error: non-variable type argument Any in type pattern Map[Any,Any] is unchecked since it is eliminated by erasure + case xs: Map[Any, Any] => xs.head // unchecked + ^ +unchecked.scala:35: error: non-variable type argument List[Nothing] in type pattern Test.Contra[List[Nothing]] is unchecked since it is eliminated by erasure + case xs: Contra[List[Nothing]] => xs.head // unchecked + ^ +unchecked.scala:50: error: non-variable type argument String in type pattern Test.Exp[String] is unchecked since it is eliminated by erasure + case ArrayApply(x: Exp[Array[T]], _, j: Exp[String]) => x // unchecked + ^ +unchecked.scala:55: error: non-variable type argument Array[T] in type pattern Test.Exp[Array[T]] is unchecked since it is eliminated by erasure + case ArrayApply(x: Exp[Array[T]], _, _) => x // unchecked + ^ +6 errors found diff --git a/test/files/neg/unchecked.flags b/test/files/neg/unchecked.flags new file mode 100644 index 0000000000..464cc20ea6 --- /dev/null +++ b/test/files/neg/unchecked.flags @@ -0,0 +1 @@ +-Xfatal-warnings -unchecked
\ No newline at end of file diff --git a/test/files/neg/unchecked.scala b/test/files/neg/unchecked.scala new file mode 100644 index 0000000000..b50cdf9d7a --- /dev/null +++ b/test/files/neg/unchecked.scala @@ -0,0 +1,74 @@ +import language.existentials + +object Test { + class Def[T] + class Exp[T] + class Contra[-T] { def head[T1 <: T] : T1 = ??? } + class Cov[+T] { } + + case class ArrayApply[T](x: Exp[Array[T]], i: Exp[Int], j: Exp[_]) extends Def[T] + + val IntArrayApply = ArrayApply[Int](new Exp[Array[Int]], new Exp[Int], new Exp[Int]) + + def f(x: Any) = x match { + case xs: Iterable[Any] => xs.head // okay + case _ => 0 + } + def f2(x: Any) = x match { + case xs: Iterable[String] => xs.head // unchecked + case _ => 0 + } + def f3(x: Any) = x match { + case xs: Set[Any] => xs.head // unchecked + case _ => 0 + } + def f4(x: Any) = x match { + case xs: Map[Any, Any] => xs.head // unchecked + case _ => 0 + } + + def cf1(x: Any) = x match { + case xs: Contra[Nothing] => xs.head // okay + case _ => 0 + } + def cf2(x: Any) = x match { + case xs: Contra[List[Nothing]] => xs.head // unchecked + case _ => 0 + } + + def co1(x: List[Cov[List[Int]]]) = x match { + case _: Seq[Cov[Seq[Any]]] => true // okay + case _ => false + } + + def g[T](x: Def[T]) = x match { + case ArrayApply(x: Exp[Array[T]], i: Exp[Int], _) => x // okay + case _ => 0 + } + + def g2[T](x: Def[T]) = x match { + case ArrayApply(x: Exp[Array[T]], _, j: Exp[String]) => x // unchecked + case _ => 0 + } + + def g3[T](x: Any) = x match { + case ArrayApply(x: Exp[Array[T]], _, _) => x // unchecked + case _ => 0 + } + + def g4 = IntArrayApply match { + case ArrayApply(x: Exp[Array[Int]], _, _) => x // okay + case _ => () + } + def g5[T](x: ArrayApply[Int]) = x match { + case ArrayApply(x: Exp[Array[Int]], _, _) => x // okay + case _ => 0 + } + + // Nope + // + // def g5 = IntArrayApply match { + // case ArrayApply(x: Exp[Array[String]], _, _) => x // nope + // case _ => () + // } +} diff --git a/test/files/neg/unchecked2.check b/test/files/neg/unchecked2.check index 2c0be9ce00..e37865928e 100644 --- a/test/files/neg/unchecked2.check +++ b/test/files/neg/unchecked2.check @@ -1,19 +1,19 @@ -unchecked2.scala:2: error: non variable type-argument Int in type Option[Int] is unchecked since it is eliminated by erasure +unchecked2.scala:2: error: non-variable type argument Int in type Option[Int] is unchecked since it is eliminated by erasure Some(123).isInstanceOf[Option[Int]] ^ -unchecked2.scala:3: error: non variable type-argument String in type Option[String] is unchecked since it is eliminated by erasure +unchecked2.scala:3: error: non-variable type argument String in type Option[String] is unchecked since it is eliminated by erasure Some(123).isInstanceOf[Option[String]] ^ -unchecked2.scala:4: error: non variable type-argument List[String] in type Option[List[String]] is unchecked since it is eliminated by erasure +unchecked2.scala:4: error: non-variable type argument List[String] in type Option[List[String]] is unchecked since it is eliminated by erasure Some(123).isInstanceOf[Option[List[String]]] ^ -unchecked2.scala:5: error: non variable type-argument List[Int => String] in type Option[List[Int => String]] is unchecked since it is eliminated by erasure +unchecked2.scala:5: error: non-variable type argument List[Int => String] in type Option[List[Int => String]] is unchecked since it is eliminated by erasure Some(123).isInstanceOf[Option[List[Int => String]]] ^ -unchecked2.scala:6: error: non variable type-argument (String, Double) in type Option[(String, Double)] is unchecked since it is eliminated by erasure +unchecked2.scala:6: error: non-variable type argument (String, Double) in type Option[(String, Double)] is unchecked since it is eliminated by erasure Some(123).isInstanceOf[Option[(String, Double)]] ^ -unchecked2.scala:7: error: non variable type-argument String => Double in type Option[String => Double] is unchecked since it is eliminated by erasure +unchecked2.scala:7: error: non-variable type argument String => Double in type Option[String => Double] is unchecked since it is eliminated by erasure Some(123).isInstanceOf[Option[String => Double]] ^ 6 errors found diff --git a/test/files/pos/t5958.scala b/test/files/pos/t5958.scala new file mode 100644 index 0000000000..3b910f3633 --- /dev/null +++ b/test/files/pos/t5958.scala @@ -0,0 +1,15 @@ +class Test { + def newComponent(u: Universe): u.Component = ??? + + class Universe { self => + class Component + + newComponent(this): this.Component // error, but should be fine since this is a stable reference + newComponent(self): self.Component // error, but should be fine since this is a stable reference + newComponent(self): this.Component // error, but should be fine since this is a stable reference + newComponent(this): self.Component // error, but should be fine since this is a stable reference + + val u = this + newComponent(u): u.Component // ok + } +}
\ No newline at end of file diff --git a/test/files/pos/t6029.scala b/test/files/pos/t6029.scala new file mode 100644 index 0000000000..8f1bbb4ebf --- /dev/null +++ b/test/files/pos/t6029.scala @@ -0,0 +1,3 @@ +final case class V[A](x: A) extends AnyVal { + def flatMap[B](f: A => V[B]) = if (true) this else f(x) +} diff --git a/test/files/pos/unchecked-a.flags b/test/files/pos/unchecked-a.flags new file mode 100644 index 0000000000..779916d58f --- /dev/null +++ b/test/files/pos/unchecked-a.flags @@ -0,0 +1 @@ +-unchecked -Xfatal-warnings
\ No newline at end of file diff --git a/test/files/pos/unchecked-a.scala b/test/files/pos/unchecked-a.scala new file mode 100644 index 0000000000..deceb91c36 --- /dev/null +++ b/test/files/pos/unchecked-a.scala @@ -0,0 +1,15 @@ +trait Y +trait Z extends Y +class X[+A <: Y] + +object Test { + def f1(x: X[_ <: Y]) = x match { + case _: X[Any] => // looks a little funny; `Any` is outside the bounds for `A` + } + def f2(x: X[_ <: Y]) = x match { + case _: X[Y] => // looks better, let's allow this (too) + } + + // NonLocalReturnControl[_] warnings + def foo: Int = List(0).foldLeft(0){case _ => return 0} +} diff --git a/test/files/run/t4560.check b/test/files/run/t4560.check index fd3c81a4d7..f8cb0833ae 100644 --- a/test/files/run/t4560.check +++ b/test/files/run/t4560.check @@ -1,2 +1,6 @@ -5 -5 +'Test +Success 1 +'Test +Success 2 +'Test +Success 3 diff --git a/test/files/run/t4560.scala b/test/files/run/t4560.scala index 1392077e46..9979199067 100644 --- a/test/files/run/t4560.scala +++ b/test/files/run/t4560.scala @@ -1,39 +1,66 @@ -object Pimper { - implicit def pimp(i: Int) = new { - def test: String = i.toString - } -} +// SI-4560 (and SI-4601): Reflection caches are expected in the wrong classfiles +// with various differing constellations of self-types. This leads to runtime exceptions +// when the reflection caches are accessed. This tests both reflection cache accesses +// for structural type method invocations (`y.f()`) (SI-4560) and accesses to symbols which are +// handled similarly (SI-4601) -trait A +// TEST 1 +// self-type is other trait -trait B { - self: A => +trait Aa +trait Ab - def test { - import Pimper.pimp +trait B { + self: Aa with Ab => - println(5.test) + def y = new { def f() = println("Success 1") } + def fail() = { + println('Test) + y.f() } } +object Test1 extends Aa with Ab with B + +// TEST 2 +// self-type is class + class A2 trait B2 { self: A2 => - def test { - import Pimper.pimp + def y = new { def f() = println("Success 2") } + def fail() = { + println('Test) + y.f() + } +} + +object Test2 extends A2 with B2 + +// TEST 3 +// self-type is singleton type + +trait B3 { + this: Test3.type => - println(5.test) + def y = new { def f() = println("Success 3") } + def fail() = { + println('Test) + y.f() } } -object Test extends A with B { +object Test3 extends B3 { + def test { fail() } +} + +object Test { def main(args: Array[String]) { - test - Test2.test + Test1.fail() + Test2.fail() + Test3.fail() } } -object Test2 extends A2 with B2 - diff --git a/test/files/run/t4560b.check b/test/files/run/t4560b.check new file mode 100644 index 0000000000..7ee6e19b28 --- /dev/null +++ b/test/files/run/t4560b.check @@ -0,0 +1,2 @@ +23 +SUCCESS diff --git a/test/files/run/t4560b.scala b/test/files/run/t4560b.scala new file mode 100644 index 0000000000..97fe00ce37 --- /dev/null +++ b/test/files/run/t4560b.scala @@ -0,0 +1,28 @@ +object Outer { + class Tester + private[Outer] trait B4 { _: Tester => + protected val FREQ = 23 + def fail() = { + println(FREQ) + } + } + object C4 extends Tester with B4 +} + +object Outer2 { + abstract class A5 + private[Outer2] trait C5 { + def impl() { println("SUCCESS") } + } + trait B5 extends C5 { self: A5 => + def fail() { impl() } + } + object Test5 extends A5 with B5 with C5 +} + +object Test { + def main(args: Array[String]): Unit = { + Outer.C4.fail() + Outer2.Test5.fail() + } +} diff --git a/test/pending/run/t4560.scala b/test/pending/run/t4560.scala deleted file mode 100644 index fe62136319..0000000000 --- a/test/pending/run/t4560.scala +++ /dev/null @@ -1,9 +0,0 @@ -trait B { - this: Test.type => - - def y = new { def f() = () } - def fail() = y.f() -} -object Test extends B { - def main(args: Array[String]): Unit = fail() -}
\ No newline at end of file |