diff options
98 files changed, 767 insertions, 235 deletions
@@ -27,6 +27,7 @@ Erik Stenman <stenman@epfl.ch> Eugene Burmako <xeno.by@gmail.com> Eugene Burmako <xeno.by@gmail.com> <burmako@epfl.ch> Eugene Vigdorchik <eugenevigdorchik@epfl.ch> <eugene.vigdorchik@gmail.com> +François Garillot <francois@garillot.net> Geoff Reedy <geoff@programmer-monk.net> <gereedy@sandia.gov> Ilya Sergei <ilyas@epfl.ch> Ingo Maier <ingo.maier@epfl.ch> diff --git a/src/compiler/scala/reflect/macros/compiler/Resolvers.scala b/src/compiler/scala/reflect/macros/compiler/Resolvers.scala index 3025eb52a1..46c4e24817 100644 --- a/src/compiler/scala/reflect/macros/compiler/Resolvers.scala +++ b/src/compiler/scala/reflect/macros/compiler/Resolvers.scala @@ -57,7 +57,7 @@ trait Resolvers { val contextField = mkContextValDef(PARAMACCESSOR) val contextParam = mkContextValDef(PARAM | PARAMACCESSOR) val invokerCtor = DefDef(Modifiers(), nme.CONSTRUCTOR, Nil, List(List(contextParam)), TypeTree(), Block(List(pendingSuperCall), Literal(Constant(())))) - val invoker = atPos(bundleClass.pos)(ClassDef(NoMods, invokerName, Nil, Template(List(Ident(bundleClass)), emptyValDef, List(contextField, invokerCtor)))) + val invoker = atPos(bundleClass.pos)(ClassDef(NoMods, invokerName, Nil, Template(List(Ident(bundleClass)), noSelfType, List(contextField, invokerCtor)))) currentRun.compileLate(PackageDef(invokerPid, List(invoker))) } diff --git a/src/compiler/scala/reflect/reify/codegen/GenTrees.scala b/src/compiler/scala/reflect/reify/codegen/GenTrees.scala index 9de8451873..a09acc04b8 100644 --- a/src/compiler/scala/reflect/reify/codegen/GenTrees.scala +++ b/src/compiler/scala/reflect/reify/codegen/GenTrees.scala @@ -71,8 +71,8 @@ trait GenTrees { def reifyTreeSyntactically(tree: Tree) = tree match { case global.EmptyTree => reifyMirrorObject(EmptyTree) - case global.emptyValDef => - mirrorSelect(nme.emptyValDef) + case global.noSelfType => + mirrorSelect(nme.noSelfType) case global.pendingSuperCall => mirrorSelect(nme.pendingSuperCall) case Literal(const @ Constant(_)) => diff --git a/src/compiler/scala/reflect/reify/phases/Reshape.scala b/src/compiler/scala/reflect/reify/phases/Reshape.scala index 7610df67dc..fff6978653 100644 --- a/src/compiler/scala/reflect/reify/phases/Reshape.scala +++ b/src/compiler/scala/reflect/reify/phases/Reshape.scala @@ -169,7 +169,7 @@ trait Reshape { private def toPreTyperCompoundTypeTree(ctt: CompoundTypeTree): Tree = { val CompoundTypeTree(tmpl @ Template(parents, self, stats)) = ctt if (stats.nonEmpty) CannotReifyCompoundTypeTreeWithNonEmptyBody(ctt) - assert(self eq emptyValDef, self) + assert(self eq noSelfType, self) val att = tmpl.attachments.get[CompoundTypeTreeOriginalAttachment] val CompoundTypeTreeOriginalAttachment(parents1, stats1) = att.getOrElse(CompoundTypeTreeOriginalAttachment(parents, stats)) CompoundTypeTree(Template(parents1, self, stats1)) diff --git a/src/compiler/scala/reflect/reify/utils/Extractors.scala b/src/compiler/scala/reflect/reify/utils/Extractors.scala index 9af8f2de2a..d052127956 100644 --- a/src/compiler/scala/reflect/reify/utils/Extractors.scala +++ b/src/compiler/scala/reflect/reify/utils/Extractors.scala @@ -75,12 +75,12 @@ trait Extractors { newTypeName(global.currentUnit.fresh.newName(flavor.toString)), List(), Template(List(Ident(reifierBase)), - emptyValDef, + noSelfType, List( DefDef(NoMods, nme.CONSTRUCTOR, List(), List(List()), TypeTree(), Block(List(Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), List())), Literal(Constant(())))), DefDef(NoMods, reifierName, - List(TypeDef(Modifiers(PARAM), tparamu, List(), TypeBoundsTree(Ident(NothingClass), CompoundTypeTree(Template(List(Ident(reifierUniverse), Ident(SingletonClass)), emptyValDef, List()))))), + List(TypeDef(Modifiers(PARAM), tparamu, List(), TypeBoundsTree(Ident(NothingClass), CompoundTypeTree(Template(List(Ident(reifierUniverse), Ident(SingletonClass)), noSelfType, List()))))), List(List(ValDef(Modifiers(PARAM), nme.MIRROR_UNTYPED, AppliedTypeTree(Ident(MirrorClass), List(Ident(tparamu))), EmptyTree))), reifierTpt, reifierBody)))) Block(tpec, ApplyConstructor(Ident(tpec.name), List())) diff --git a/src/compiler/scala/tools/nsc/CompileServer.scala b/src/compiler/scala/tools/nsc/CompileServer.scala index c5366566d9..6f068e179c 100644 --- a/src/compiler/scala/tools/nsc/CompileServer.scala +++ b/src/compiler/scala/tools/nsc/CompileServer.scala @@ -85,7 +85,7 @@ class StandardCompileServer extends SocketServer { if (input == null || password != guessedPassword) return - val args = input.split("\0", -1).toList + val args = input.split("\u0000", -1).toList val newSettings = new FscSettings(fscError) val command = new OfflineCompilerCommand(args, newSettings) this.verbose = newSettings.verbose.value diff --git a/src/compiler/scala/tools/nsc/CompileSocket.scala b/src/compiler/scala/tools/nsc/CompileSocket.scala index 88d5c31b5d..c4f06b59ec 100644 --- a/src/compiler/scala/tools/nsc/CompileSocket.scala +++ b/src/compiler/scala/tools/nsc/CompileSocket.scala @@ -24,7 +24,7 @@ trait HasCompileSocket { sock.applyReaderAndWriter { (in, out) => out println (compileSocket getPassword sock.getPort()) - out println (args mkString "\0") + out println (args mkString "\u0000") def loop(): Boolean = in.readLine() match { case null => noErrors diff --git a/src/compiler/scala/tools/nsc/ast/Printers.scala b/src/compiler/scala/tools/nsc/ast/Printers.scala index 89652c5a20..c31b5e2c0e 100644 --- a/src/compiler/scala/tools/nsc/ast/Printers.scala +++ b/src/compiler/scala/tools/nsc/ast/Printers.scala @@ -20,7 +20,7 @@ trait Printers extends scala.reflect.internal.Printers { this: Global => printTree( if (tree.isDef && tree.symbol != NoSymbol && tree.symbol.isInitialized) { tree match { - case ClassDef(_, _, _, impl @ Template(ps, emptyValDef, body)) + case ClassDef(_, _, _, impl @ Template(ps, noSelfType, body)) if (tree.symbol.thisSym != tree.symbol) => ClassDef(tree.symbol, Template(ps, ValDef(tree.symbol.thisSym), body)) case ClassDef(_, _, _, impl) => ClassDef(tree.symbol, impl) diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala index 7122e864a4..28b127698f 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala @@ -261,7 +261,7 @@ abstract class TreeGen extends scala.reflect.internal.TreeGen with TreeDSL { */ def mkAnonymousNew(stats: List[Tree]): Tree = { val stats1 = if (stats.isEmpty) List(Literal(Constant(()))) else stats - mkNew(Nil, emptyValDef, stats1, NoPosition, NoPosition) + mkNew(Nil, noSelfType, stats1, NoPosition, NoPosition) } def mkSyntheticParam(pname: TermName) = diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala index 381ffb1ed9..bdff5e1344 100644 --- a/src/compiler/scala/tools/nsc/ast/Trees.scala +++ b/src/compiler/scala/tools/nsc/ast/Trees.scala @@ -70,7 +70,7 @@ trait Trees extends scala.reflect.internal.Trees { self: Global => ClassDef(sym, gen.mkTemplate(sym.info.parents map TypeTree, - if (sym.thisSym == sym || phase.erasedTypes) emptyValDef else ValDef(sym.thisSym), + if (sym.thisSym == sym || phase.erasedTypes) noSelfType else ValDef(sym.thisSym), constrMods, vparamss, body, superPos)) } diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index a894e38ab4..0ba4719d37 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -217,7 +217,7 @@ self => override def blockExpr(): Tree = skipBraces(EmptyTree) - override def templateBody(isPre: Boolean) = skipBraces((emptyValDef, EmptyTree.asList)) + override def templateBody(isPre: Boolean) = skipBraces((noSelfType, EmptyTree.asList)) } class UnitParser(override val unit: global.CompilationUnit, patches: List[BracePatch]) extends SourceFileParser(unit.source) { uself => @@ -429,7 +429,7 @@ self => // object Main def moduleName = newTermName(ScriptRunner scriptMain settings) - def moduleBody = Template(atInPos(scalaAnyRefConstr) :: Nil, emptyValDef, List(emptyInit, mainDef)) + def moduleBody = Template(atInPos(scalaAnyRefConstr) :: Nil, noSelfType, List(emptyInit, mainDef)) def moduleDef = ModuleDef(NoMods, moduleName, moduleBody) // package <empty> { ... } @@ -958,7 +958,7 @@ self => // it still gets a CompoundTypeTree. ts.toList match { case tp :: Nil if !hasRefinement => tp // single type, no refinement, already positioned - case tps => atPos(t.pos.startOrPoint)(CompoundTypeTree(Template(tps, emptyValDef, refinements))) + case tps => atPos(t.pos.startOrPoint)(CompoundTypeTree(Template(tps, noSelfType, refinements))) } } @@ -2257,9 +2257,10 @@ self => } if (contextBoundBuf ne null) { while (in.token == VIEWBOUND) { - contextBoundBuf += atPos(in.skipToken()) { - makeFunctionTypeTree(List(Ident(pname)), typ()) - } + val msg = "Use an implicit parameter instead.\nExample: Instead of `def f[A <% Int](a: A)` use `def f[A](a: A)(implicit ev: A => Int)`." + if (settings.future) + deprecationWarning(in.offset, s"View bounds are deprecated. $msg") + contextBoundBuf += atPos(in.skipToken())(makeFunctionTypeTree(List(Ident(pname)), typ())) } while (in.token == COLON) { contextBoundBuf += atPos(in.skipToken()) { @@ -2690,7 +2691,8 @@ self => classContextBounds = contextBoundBuf.toList val tstart = (in.offset :: classContextBounds.map(_.pos.startOrPoint)).min if (!classContextBounds.isEmpty && mods.isTrait) { - syntaxError("traits cannot have type parameters with context bounds `: ...' nor view bounds `<% ...'", skipIt = false) + val viewBoundsExist = if (settings.future) "" else " nor view bounds `<% ...'" + syntaxError(s"traits cannot have type parameters with context bounds `: ...'$viewBoundsExist", skipIt = false) classContextBounds = List() } val constrAnnots = if (!mods.isTrait) constructorAnnotations() else Nil @@ -2796,7 +2798,7 @@ self => if (in.token == LBRACE) { // @S: pre template body cannot stub like post body can! val (self, body) = templateBody(isPre = true) - if (in.token == WITH && (self eq emptyValDef)) { + if (in.token == WITH && (self eq noSelfType)) { val earlyDefs: List[Tree] = body.map(ensureEarlyDef).filter(_.nonEmpty) in.nextToken() val parents = templateParents() @@ -2883,7 +2885,7 @@ self => if (parenMeansSyntaxError) syntaxError(s"traits or objects may not have parameters", skipIt = true) else abort("unexpected opening parenthesis") } - (emptyValDef, List()) + (noSelfType, List()) } } @@ -2939,7 +2941,7 @@ self => * @param isPre specifies whether in early initializer (true) or not (false) */ def templateStatSeq(isPre : Boolean): (ValDef, List[Tree]) = checkNoEscapingPlaceholders { - var self: ValDef = emptyValDef + var self: ValDef = noSelfType var firstOpt: Option[Tree] = None if (isExprIntro) { in.flushDoc diff --git a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala index 239ecb4f8a..c34ff0ce97 100644 --- a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala +++ b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala @@ -118,7 +118,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners { def makeTemplate(parents: List[Tree], stats: List[Tree]) = Template( parents, - emptyValDef, + noSelfType, if (treeInfo.firstConstructor(stats) == EmptyTree) makeConstructor(List()) :: stats else stats) @@ -417,7 +417,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners { } val ts = buf.toList if (ts.tail.isEmpty) ts.head - else CompoundTypeTree(Template(ts, emptyValDef, List())) + else CompoundTypeTree(Template(ts, noSelfType, List())) } def formalParams(): List[ValDef] = { diff --git a/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala b/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala index a67c207820..16d432438a 100644 --- a/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala +++ b/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala @@ -18,11 +18,13 @@ abstract class AbstractReporter extends Reporter { def display(pos: Position, msg: String, severity: Severity): Unit def displayPrompt(): Unit - private val positions = new mutable.HashMap[Position, Severity] + private val positions = mutable.Map[Position, Severity]() withDefaultValue INFO + private val messages = mutable.Map[Position, List[String]]() withDefaultValue Nil override def reset() { super.reset() positions.clear() + messages.clear() } private def isVerbose = settings.verbose.value @@ -37,13 +39,14 @@ abstract class AbstractReporter extends Reporter { } } else { - val hidden = testAndLog(pos, severity) + val hidden = testAndLog(pos, severity, msg) if (severity == WARNING && noWarnings) () else { if (!hidden || isPromptSet) { severity.count += 1 display(pos, msg, severity) - } else if (settings.debug) { + } + else if (settings.debug) { severity.count += 1 display(pos, "[ suppressed ] " + msg, severity) } @@ -57,12 +60,20 @@ abstract class AbstractReporter extends Reporter { /** Logs a position and returns true if it was already logged. * @note Two positions are considered identical for logging if they have the same point. */ - private def testAndLog(pos: Position, severity: Severity): Boolean = + private def testAndLog(pos: Position, severity: Severity, msg: String): Boolean = pos != null && pos.isDefined && { val fpos = pos.focus - (positions get fpos) match { - case Some(level) if level >= severity => true - case _ => positions += (fpos -> severity) ; false + val suppress = positions(fpos) match { + case ERROR => true // already error at position + case highest if highest > severity => true // already message higher than present severity + case `severity` => messages(fpos) contains msg // already issued this exact message + case _ => false // good to go + } + + suppress || { + positions(fpos) = severity + messages(fpos) ::= msg + false } } } diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala index 6f27eb8660..8b739958ff 100644 --- a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala +++ b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala @@ -164,10 +164,17 @@ abstract class SymbolLoaders { if (settings.verbose) inform("[symloader] no class, picked up source file for " + src.path) enterToplevelsFromSource(owner, classRep.name, src) case (Some(bin), _) => - enterClassAndModule(owner, classRep.name, new ClassfileLoader(bin)) + enterClassAndModule(owner, classRep.name, newClassLoader(bin)) } } + /** Create a new loader from a binary classfile. + * This is intented as a hook allowing to support loading symbols from + * files other than .class files. + */ + protected def newClassLoader(bin: AbstractFile): SymbolLoader = + new ClassfileLoader(bin) + /** * A lazy type that completes itself by calling parameter doComplete. * Any linked modules/classes or module classes are also initialized. diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala index d9d08dde1e..2b7c6cca2c 100644 --- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala +++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala @@ -249,7 +249,7 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure => private def ifaceMemberDef(tree: Tree): Tree = createMemberDef(tree, true)(t => DefDef(t.symbol, EmptyTree)) private def ifaceTemplate(templ: Template): Template = - treeCopy.Template(templ, templ.parents, emptyValDef, templ.body map ifaceMemberDef) + treeCopy.Template(templ, templ.parents, noSelfType, templ.body map ifaceMemberDef) /** Transforms the member tree containing the implementation * into a member of the impl class. @@ -280,7 +280,7 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure => private def implTemplate(clazz: Symbol, templ: Template): Template = atPos(templ.pos) { val templ1 = ( - Template(templ.parents, emptyValDef, addMixinConstructorDef(clazz, templ.body map implMemberDef)) + Template(templ.parents, noSelfType, addMixinConstructorDef(clazz, templ.body map implMemberDef)) setSymbol clazz.newLocalDummy(templ.pos) ) templ1.changeOwner(templ.symbol.owner -> clazz, templ.symbol -> templ1.symbol) @@ -338,7 +338,7 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure => deriveDefDef(tree)(addMixinConstructorCalls(_, sym.owner)) // (3) case Template(parents, self, body) => val parents1 = sym.owner.info.parents map (t => TypeTree(t) setPos tree.pos) - treeCopy.Template(tree, parents1, emptyValDef, body) + treeCopy.Template(tree, parents1, noSelfType, body) case This(_) if sym.needsImplClass => val impl = implClass(sym) var owner = currentOwner diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index 31855bc1ad..2d005b26e3 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -88,7 +88,7 @@ abstract class Erasure extends AddInterfaces // more rigorous way up front rather than catching it after the fact, // but that will be more involved. private def dotCleanup(sig: String): String = { - var last: Char = '\0' + var last: Char = '\u0000' sig map { case '.' if last != '>' => last = '.' ; '$' case ch => last = ch ; ch @@ -1205,7 +1205,7 @@ abstract class Erasure extends AddInterfaces assert(!currentOwner.isImplClass) //Console.println("checking no dble defs " + tree)//DEBUG checkNoDoubleDefs(tree.symbol.owner) - treeCopy.Template(tree, parents, emptyValDef, addBridges(body, currentOwner)) + treeCopy.Template(tree, parents, noSelfType, addBridges(body, currentOwner)) case Match(selector, cases) => Match(Typed(selector, TypeTree(selector.tpe)), cases) diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index 5a440039d6..2d4269a3bc 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -1844,7 +1844,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { mbrs += ValDef(m).setType(NoType) } else if (m.isClass) { // mbrs += -// ClassDef(m, Template(m.info.parents map TypeTree, emptyValDef, List()) +// ClassDef(m, Template(m.info.parents map TypeTree, noSelfType, List()) // .setSymbol(m.newLocalDummy(m.pos))) // log("created synthetic class: " + m.fullName) } @@ -1866,7 +1866,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { for (((sym1, env), specCls) <- specializedClass if sym1 == tree.symbol) yield { debuglog("created synthetic class: " + specCls + " of " + sym1 + " in " + pp(env)) val parents = specCls.info.parents.map(TypeTree) - ClassDef(specCls, atPos(impl.pos)(Template(parents, emptyValDef, List())) + ClassDef(specCls, atPos(impl.pos)(Template(parents, noSelfType, List())) .setSymbol(specCls.newLocalDummy(sym1.pos))) setPos tree.pos } case _ => Nil diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index 1f4d5cbac2..dc8c26c926 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -145,18 +145,31 @@ trait ContextErrors { def errMsg = { val paramName = param.name val paramTp = param.tpe + def evOrParam = ( + if (paramName startsWith nme.EVIDENCE_PARAM_PREFIX) + "evidence parameter of type" + else + s"parameter $paramName:" + ) paramTp.typeSymbolDirect match { - case ImplicitNotFoundMsg(msg) => msg.format(paramName, paramTp) - case _ => - "could not find implicit value for "+ - (if (paramName startsWith nme.EVIDENCE_PARAM_PREFIX) "evidence parameter of type " - else "parameter "+paramName+": ")+paramTp + case ImplicitNotFoundMsg(msg) => msg.format(paramName, paramTp) + case _ => s"could not find implicit value for $evOrParam $paramTp" } } issueNormalTypeError(tree, errMsg) } def AdaptTypeError(tree: Tree, found: Type, req: Type) = { + // SI-3971 unwrapping to the outermost Apply helps prevent confusion with the + // error message point. + def callee = { + def unwrap(t: Tree): Tree = t match { + case Apply(app: Apply, _) => unwrap(app) + case _ => t + } + unwrap(tree) + } + // If the expected type is a refinement type, and the found type is a refinement or an anon // class, we can greatly improve the error message by retyping the tree to recover the actual // members present, then display along with the expected members. This is done here because @@ -181,7 +194,7 @@ trait ContextErrors { } assert(!foundType.isErroneous && !req.isErroneous, (foundType, req)) - issueNormalTypeError(tree, withAddendum(tree.pos)(typeErrorMsg(foundType, req))) + issueNormalTypeError(callee, withAddendum(callee.pos)(typeErrorMsg(foundType, req))) infer.explainTypes(foundType, req) } diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index cd2b9b3a97..315496e5f6 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -49,7 +49,7 @@ trait Contexts { self: Analyzer => private lazy val startContext = { NoContext.make( - Template(List(), emptyValDef, List()) setSymbol global.NoSymbol setType global.NoType, + Template(List(), noSelfType, List()) setSymbol global.NoSymbol setType global.NoType, rootMirror.RootClass, rootMirror.RootClass.info.decls) } @@ -615,7 +615,7 @@ trait Contexts { self: Analyzer => private def treeIdString = if (settings.uniqid.value) "#" + System.identityHashCode(tree).toString.takeRight(3) else "" private def treeString = tree match { case x: Import => "" + x - case Template(parents, `emptyValDef`, body) => + case Template(parents, `noSelfType`, body) => val pstr = if ((parents eq null) || parents.isEmpty) "Nil" else parents mkString " " val bstr = if (body eq null) "" else body.length + " stats" s"""Template($pstr, _, $bstr)""" diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index fbe8cd77fb..b30ae917d9 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -1405,13 +1405,15 @@ trait Implicits { case None => Some("Missing argument `msg` on implicitNotFound annotation.") }) + // http://dcsobral.blogspot.com/2010/01/string-interpolation-in-scala-with.html + private val Intersobralator = """\$\{\s*([^}\s]+)\s*\}""".r class Message(sym: Symbol, msg: String) { - // http://dcsobral.blogspot.com/2010/01/string-interpolation-in-scala-with.html - private def interpolate(text: String, vars: Map[String, String]) = { - """\$\{([^}]+)\}""".r.replaceAllIn(text, (_: Regex.Match) match { - case Regex.Groups(v) => java.util.regex.Matcher.quoteReplacement(vars.getOrElse(v, "")) // #3915: need to quote replacement string since it may include $'s (such as the interpreter's $iw) - })} + private def interpolate(text: String, vars: Map[String, String]) = + Intersobralator.replaceAllIn(text, (_: Regex.Match) match { + case Regex.Groups(v) => Regex quoteReplacement vars.getOrElse(v, "") + // #3915: need to quote replacement string since it may include $'s (such as the interpreter's $iw) + }) private lazy val typeParamNames: List[String] = sym.typeParams.map(_.decodedName) @@ -1420,17 +1422,16 @@ trait Implicits { interpolate(msg, Map((typeParamNames zip typeArgs): _*)) // TODO: give access to the name and type of the implicit argument, etc? def validate: Option[String] = { - // is there a shorter way to avoid the intermediate toList? - val refs = """\$\{([^}]+)\}""".r.findAllIn(msg).matchData.map(_ group 1).toSet + val refs = Intersobralator.findAllMatchIn(msg).map(_ group 1).toSet val decls = typeParamNames.toSet (refs &~ decls) match { case s if s.isEmpty => None - case unboundNames => + case unboundNames => val singular = unboundNames.size == 1 - Some("The type parameter"+( if(singular) " " else "s " )+ unboundNames.mkString(", ") + - " referenced in the message of the @implicitNotFound annotation "+( if(singular) "is" else "are" )+ - " not defined by "+ sym +".") + val ess = if (singular) "" else "s" + val bee = if (singular) "is" else "are" + Some(s"The type parameter$ess ${unboundNames mkString ", "} referenced in the message of the @implicitNotFound annotation $bee not defined by $sym.") } } } diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 347426d42a..12e8b0a3f9 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -841,7 +841,7 @@ trait Namers extends MethodSynthesis { // owner is the class with the self type def enterSelf(self: ValDef) { val ValDef(_, name, tpt, _) = self - if (self eq emptyValDef) + if (self eq noSelfType) return val hasName = name != nme.WILDCARD @@ -1272,9 +1272,7 @@ trait Namers extends MethodSynthesis { val defRhs = copyUntyped(vparam.rhs) val defaultTree = atPos(vparam.pos.focus) { - DefDef( - Modifiers(meth.flags & DefaultGetterFlags) | (SYNTHETIC | DEFAULTPARAM | oflag).toLong, - name, deftParams, defvParamss, defTpt, defRhs) + DefDef(Modifiers(paramFlagsToDefaultGetter(meth.flags)) | oflag, name, deftParams, defvParamss, defTpt, defRhs) } if (!isConstr) methOwner.resetFlag(INTERFACE) // there's a concrete member now diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 32e908e03b..d60e61df1b 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -121,20 +121,20 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans var checkedCombinations = Set[List[Type]]() // only one overloaded alternative is allowed to define default arguments - private def checkOverloadedRestrictions(clazz: Symbol): Unit = { + private def checkOverloadedRestrictions(clazz: Symbol, defaultClass: Symbol): Unit = { // Using the default getters (such as methodName$default$1) as a cheap way of // finding methods with default parameters. This way, we can limit the members to // those with the DEFAULTPARAM flag, and infer the methods. Looking for the methods // directly requires inspecting the parameter list of every one. That modification // shaved 95% off the time spent in this method. - val defaultGetters = clazz.info.findMembers(0L, DEFAULTPARAM) + val defaultGetters = defaultClass.info.findMembers(excludedFlags = PARAM, requiredFlags = DEFAULTPARAM) val defaultMethodNames = defaultGetters map (sym => nme.defaultGetterToMethod(sym.name)) defaultMethodNames.toList.distinct foreach { name => - val methods = clazz.info.findMember(name, 0L, METHOD, stableOnly = false).alternatives + val methods = clazz.info.findMember(name, 0L, requiredFlags = METHOD, stableOnly = false).alternatives def hasDefaultParam(tpe: Type): Boolean = tpe match { case MethodType(params, restpe) => (params exists (_.hasDefault)) || hasDefaultParam(restpe) - case _ => false + case _ => false } val haveDefaults = methods filter (sym => hasDefaultParam(sym.info) && !nme.isProtectedAccessorName(sym.name)) @@ -411,7 +411,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans overrideError("cannot be used here - classes can only override abstract types") } else if (other.isEffectivelyFinal) { // (1.2) overrideError("cannot override final member") - } else if (!other.isDeferred && !other.hasFlag(DEFAULTMETHOD) && !member.isAnyOverride && !member.isSynthetic) { // (*) + } else if (!other.isDeferredOrDefault && !other.hasFlag(DEFAULTMETHOD) && !member.isAnyOverride && !member.isSynthetic) { // (*) // (*) Synthetic exclusion for (at least) default getters, fixes SI-5178. We cannot assign the OVERRIDE flag to // the default getter: one default getter might sometimes override, sometimes not. Example in comment on ticket. if (isNeitherInClass && !(other.owner isSubClass member.owner)) @@ -596,7 +596,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans def checkNoAbstractMembers(): Unit = { // Avoid spurious duplicates: first gather any missing members. def memberList = clazz.info.nonPrivateMembersAdmitting(VBRIDGE) - val (missing, rest) = memberList partition (m => m.isDeferred && !ignoreDeferred(m)) + val (missing, rest) = memberList partition (m => m.isDeferredNotDefault && !ignoreDeferred(m)) // Group missing members by the name of the underlying symbol, // to consolidate getters and setters. val grouped = missing groupBy (sym => analyzer.underlyingSymbol(sym).name) @@ -1458,7 +1458,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans applyChecks(sym.annotations) // validate implicitNotFoundMessage analyzer.ImplicitNotFoundMsg.check(sym) foreach { warn => - unit.warning(tree.pos, "Invalid implicitNotFound message for %s%s:\n%s".format(sym, sym.locationString, warn)) + unit.warning(tree.pos, f"Invalid implicitNotFound message for ${sym}%s${sym.locationString}%s:%n$warn") } case tpt@TypeTree() => @@ -1638,7 +1638,9 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans case Template(parents, self, body) => localTyper = localTyper.atOwner(tree, currentOwner) validateBaseTypes(currentOwner) - checkOverloadedRestrictions(currentOwner) + checkOverloadedRestrictions(currentOwner, currentOwner) + // SI-7870 default getters for constructors live in the companion module + checkOverloadedRestrictions(currentOwner, currentOwner.companionModule) val bridges = addVarargBridges(currentOwner) checkAllOverrides(currentOwner) checkAnyValSubclass(currentOwner) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 157c6ba4de..2a2fd889ad 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -96,7 +96,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper private final val SYNTHETIC_PRIVATE = TRANS_FLAG private final val InterpolatorCodeRegex = """\$\{.*?\}""".r - private final val InterpolatorIdentRegex = """\$\w+""".r + private final val InterpolatorIdentRegex = """\$[$\w]+""".r // note that \w doesn't include $ abstract class Typer(context0: Context) extends TyperDiagnostics with Adaptation with Tag with PatternTyper with TyperContextErrors { import context0.unit @@ -3245,7 +3245,8 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper if (!tree.isErrorTyped) setError(tree) else tree // @H change to setError(treeCopy.Apply(tree, fun, args)) - case ExtractorType(unapply) if mode.inPatternMode => + // SI-7877 `isTerm` needed to exclude `class T[A] { def unapply(..) }; ... case T[X] =>` + case HasUnapply(unapply) if mode.inPatternMode && fun.isTerm => if (unapply == QuasiquoteClass_api_unapply) macroExpandUnapply(this, tree, fun, unapply, args, mode, pt) else doTypedUnapply(tree, fun0, fun, args, mode, pt) @@ -4177,6 +4178,9 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper case If(_, t, e) => treesInResult(t) ++ treesInResult(e) case Try(b, catches, _) => treesInResult(b) ++ catches case Typed(r, Function(Nil, EmptyTree)) => treesInResult(r) + case Select(qual, name) => treesInResult(qual) + case Apply(fun, args) => treesInResult(fun) ++ args.flatMap(treesInResult) + case TypeApply(fun, args) => treesInResult(fun) ++ args.flatMap(treesInResult) case _ => Nil }) def errorInResult(tree: Tree) = treesInResult(tree) exists (_.pos == typeError.errPos) @@ -4874,38 +4878,39 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper } // Warn about likely interpolated strings which are missing their interpolators - def warnMissingInterpolator(tree: Literal) = if (!isPastTyper) { - // Unfortunately implicit not found strings looks for all the world like - // missing interpolators. - def isArgToImplicitNotFound = context.enclosingApply.tree match { - case Apply(fn, _) => fn.symbol != null && fn.symbol.enclClass == ImplicitNotFoundClass - case _ => false - } - def warnAbout(s: String) = { - def names = InterpolatorIdentRegex findAllIn s map (n => TermName(n stripPrefix "$")) - def isSuspiciousExpr = (InterpolatorCodeRegex findFirstIn s).nonEmpty - //def isSuspiciousName = names exists (lookUp _ andThen (_.exists)) - def suspiciousName = names find (lookUp _ andThen (_.exists)) - def lookUp(n: TermName) = context.lookupSymbol(n, !_.alternatives.exists(symRequiresArg)).symbol - def symRequiresArg(s: Symbol) = ( - s.paramss.nonEmpty - && (s.paramss.head.headOption filterNot (_.isImplicit)).isDefined - ) - val suggest = "Did you forget the interpolator?" - if (isSuspiciousExpr) - unit.warning(tree.pos, s"That looks like an interpolated expression! $suggest") - else /* if (isSuspiciousName) */ suspiciousName foreach (n => - unit.warning(tree.pos, s"`$$$n` looks like an interpolated identifier! $suggest") + def warnMissingInterpolator(lit: Literal): Unit = if (!isPastTyper) { + // attempt to avoid warning about the special interpolated message string + // for implicitNotFound or any standard interpolation (with embedded $$). + def isRecognizablyNotForInterpolation = context.enclosingApply.tree match { + case Apply(Select(Apply(RefTree(_, nme.StringContext), _), _), _) => true + case Apply(Select(New(RefTree(_, tpnme.implicitNotFound)), _), _) => true + case _ => false + } + def requiresNoArgs(tp: Type): Boolean = tp match { + case PolyType(_, restpe) => requiresNoArgs(restpe) + case MethodType(Nil, restpe) => requiresNoArgs(restpe) // may be a curried method - can't tell yet + case MethodType(p :: _, _) => p.isImplicit // implicit method requires no args + case _ => true // catches all others including NullaryMethodType + } + def isPlausible(m: Symbol) = m.alternatives exists (m => requiresNoArgs(m.info)) + + def maybeWarn(s: String): Unit = { + def warn(message: String) = context.unit.warning(lit.pos, s"$message Did you forget the interpolator?") + def suspiciousSym(name: TermName) = context.lookupSymbol(name, _ => true).symbol + def suspiciousExpr = InterpolatorCodeRegex findFirstIn s + def suspiciousIdents = InterpolatorIdentRegex findAllIn s map (s => suspiciousSym(s drop 1)) + + // heuristics - no warning on e.g. a string with only "$asInstanceOf" + if (s contains ' ') ( + if (suspiciousExpr.nonEmpty) + warn("That looks like an interpolated expression!") // "${...}" + else + suspiciousIdents find isPlausible foreach (sym => warn(s"`$$${sym.name}` looks like an interpolated identifier!")) // "$id" ) } - tree.value match { - case Constant(s: String) => - val noWarn = ( - isArgToImplicitNotFound - || !(s contains ' ') // another heuristic - e.g. a string with only "$asInstanceOf" - ) - if (!noWarn) warnAbout(s) - case _ => + lit match { + case Literal(Constant(s: String)) if !isRecognizablyNotForInterpolation => maybeWarn(s) + case _ => } } diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala index af19e3cf80..ed96f66ab8 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala @@ -39,7 +39,7 @@ trait Unapplies extends ast.TreeDSL { */ def unapplyMember(tp: Type): Symbol = directUnapplyMember(tp) filter (sym => !hasMultipleNonImplicitParamLists(sym)) - object ExtractorType { + object HasUnapply { def unapply(tp: Type): Option[Symbol] = unapplyMember(tp).toOption } @@ -119,7 +119,7 @@ trait Unapplies extends ast.TreeDSL { ModuleDef( Modifiers(cdef.mods.flags & AccessFlags | SYNTHETIC, cdef.mods.privateWithin), cdef.name.toTermName, - gen.mkTemplate(parents, emptyValDef, NoMods, Nil, body, cdef.impl.pos.focus)) + gen.mkTemplate(parents, noSelfType, NoMods, Nil, body, cdef.impl.pos.focus)) } /** The apply method corresponding to a case class diff --git a/src/compiler/scala/tools/nsc/util/ClassPath.scala b/src/compiler/scala/tools/nsc/util/ClassPath.scala index 906a575d90..c63d7f6820 100644 --- a/src/compiler/scala/tools/nsc/util/ClassPath.scala +++ b/src/compiler/scala/tools/nsc/util/ClassPath.scala @@ -96,6 +96,12 @@ object ClassPath { */ def isValidName(name: String): Boolean = true + /** Filters for assessing validity of various entities. + */ + def validClassFile(name: String) = endsClass(name) && isValidName(name) + def validPackage(name: String) = (name != "META-INF") && (name != "") && (name.charAt(0) != '.') + def validSourceFile(name: String) = endsScala(name) || endsJava(name) + /** From the representation to its identifier. */ def toBinaryName(rep: T): String @@ -208,9 +214,9 @@ abstract class ClassPath[T] { /** Filters for assessing validity of various entities. */ - def validClassFile(name: String) = endsClass(name) && context.isValidName(name) - def validPackage(name: String) = (name != "META-INF") && (name != "") && (name.charAt(0) != '.') - def validSourceFile(name: String) = endsScala(name) || endsJava(name) + def validClassFile(name: String) = context.validClassFile(name) + def validPackage(name: String) = context.validPackage(name) + def validSourceFile(name: String) = context.validSourceFile(name) /** * Find a ClassRep given a class name of the form "package.subpackage.ClassName". diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala index 7114568d21..6a495cfcee 100644 --- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala +++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala @@ -227,7 +227,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => obj, gen.mkTemplate( List(TypeTree(ObjectTpe)), - emptyValDef, + noSelfType, NoMods, List(), List(methdef), diff --git a/src/library/scala/concurrent/Future.scala b/src/library/scala/concurrent/Future.scala index 4e3f3c6c81..b9f73c2872 100644 --- a/src/library/scala/concurrent/Future.scala +++ b/src/library/scala/concurrent/Future.scala @@ -96,11 +96,8 @@ trait Future[+T] extends Awaitable[T] { // of the Future trait. Note that this will // (modulo bugs) _never_ execute a callback // other than those below in this same file. - // As a nice side benefit, having this implicit - // here forces an ambiguity in those methods - // that also have an executor parameter, which - // keeps us from accidentally forgetting to use - // the executor parameter. + // + // See the documentation on `InternalCallbackExecutor` for more details. private def internalExecutor = Future.InternalCallbackExecutor /* Callbacks */ @@ -254,7 +251,7 @@ trait Future[+T] extends Awaitable[T] { case Success(v) => try f(v) match { // If possible, link DefaultPromises to avoid space leaks case dp: DefaultPromise[_] => dp.asInstanceOf[DefaultPromise[S]].linkRootOf(p) - case fut => fut onComplete p.complete + case fut => fut.onComplete(p.complete)(internalExecutor) } catch { case NonFatal(t) => p failure t } } p.future @@ -344,7 +341,7 @@ trait Future[+T] extends Awaitable[T] { def recoverWith[U >: T](pf: PartialFunction[Throwable, Future[U]])(implicit executor: ExecutionContext): Future[U] = { val p = Promise[U]() onComplete { - case Failure(t) => try pf.applyOrElse(t, (_: Throwable) => this) onComplete p.complete catch { case NonFatal(t) => p failure t } + case Failure(t) => try pf.applyOrElse(t, (_: Throwable) => this).onComplete(p.complete)(internalExecutor) catch { case NonFatal(t) => p failure t } case other => p complete other } p.future diff --git a/src/library/scala/io/AnsiColor.scala b/src/library/scala/io/AnsiColor.scala index 6b00eb283f..39e2e3b0ca 100644 --- a/src/library/scala/io/AnsiColor.scala +++ b/src/library/scala/io/AnsiColor.scala @@ -3,51 +3,51 @@ package io trait AnsiColor { /** Foreground color for ANSI black */ - final val BLACK = "\033[30m" + final val BLACK = "\u001b[30m" /** Foreground color for ANSI red */ - final val RED = "\033[31m" + final val RED = "\u001b[31m" /** Foreground color for ANSI green */ - final val GREEN = "\033[32m" + final val GREEN = "\u001b[32m" /** Foreground color for ANSI yellow */ - final val YELLOW = "\033[33m" + final val YELLOW = "\u001b[33m" /** Foreground color for ANSI blue */ - final val BLUE = "\033[34m" + final val BLUE = "\u001b[34m" /** Foreground color for ANSI magenta */ - final val MAGENTA = "\033[35m" + final val MAGENTA = "\u001b[35m" /** Foreground color for ANSI cyan */ - final val CYAN = "\033[36m" + final val CYAN = "\u001b[36m" /** Foreground color for ANSI white */ - final val WHITE = "\033[37m" + final val WHITE = "\u001b[37m" /** Background color for ANSI black */ - final val BLACK_B = "\033[40m" + final val BLACK_B = "\u001b[40m" /** Background color for ANSI red */ - final val RED_B = "\033[41m" + final val RED_B = "\u001b[41m" /** Background color for ANSI green */ - final val GREEN_B = "\033[42m" + final val GREEN_B = "\u001b[42m" /** Background color for ANSI yellow */ - final val YELLOW_B = "\033[43m" + final val YELLOW_B = "\u001b[43m" /** Background color for ANSI blue */ - final val BLUE_B = "\033[44m" + final val BLUE_B = "\u001b[44m" /** Background color for ANSI magenta */ - final val MAGENTA_B = "\033[45m" + final val MAGENTA_B = "\u001b[45m" /** Background color for ANSI cyan */ - final val CYAN_B = "\033[46m" + final val CYAN_B = "\u001b[46m" /** Background color for ANSI white */ - final val WHITE_B = "\033[47m" + final val WHITE_B = "\u001b[47m" /** Reset ANSI styles */ - final val RESET = "\033[0m" + final val RESET = "\u001b[0m" /** ANSI bold */ - final val BOLD = "\033[1m" + final val BOLD = "\u001b[1m" /** ANSI underlines */ - final val UNDERLINED = "\033[4m" + final val UNDERLINED = "\u001b[4m" /** ANSI blink */ - final val BLINK = "\033[5m" + final val BLINK = "\u001b[5m" /** ANSI reversed */ - final val REVERSED = "\033[7m" + final val REVERSED = "\u001b[7m" /** ANSI invisible */ - final val INVISIBLE = "\033[8m" + final val INVISIBLE = "\u001b[8m" } object AnsiColor extends AnsiColor { } diff --git a/src/reflect/scala/reflect/api/Printers.scala b/src/reflect/scala/reflect/api/Printers.scala index 81d30dec1e..6e2e2c3781 100644 --- a/src/reflect/scala/reflect/api/Printers.scala +++ b/src/reflect/scala/reflect/api/Printers.scala @@ -48,7 +48,7 @@ import java.io.{ PrintWriter, StringWriter } * res1: String = Block(List( * ClassDef(Modifiers(FINAL), newTypeName("C"), List(), Template( * List(Ident(newTypeName("AnyRef"))), - * emptyValDef, + * noSelfType, * List( * DefDef(Modifiers(), nme.CONSTRUCTOR, List(), List(List()), TypeTree(), * Block(List( @@ -72,7 +72,7 @@ import java.io.{ PrintWriter, StringWriter } * res2: String = Block[1](List( * ClassDef[2](Modifiers(FINAL), newTypeName("C"), List(), Template[3]( * List(Ident[4](newTypeName("AnyRef"))), - * emptyValDef, + * noSelfType, * List( * DefDef[2](Modifiers(), nme.CONSTRUCTOR, List(), List(List()), TypeTree[3](), * Block[1](List( diff --git a/src/reflect/scala/reflect/api/Trees.scala b/src/reflect/scala/reflect/api/Trees.scala index 7a627bc875..fa7d41f0fc 100644 --- a/src/reflect/scala/reflect/api/Trees.scala +++ b/src/reflect/scala/reflect/api/Trees.scala @@ -71,20 +71,13 @@ trait Trees { self: Universe => /** Is this tree one of the empty trees? * - * Empty trees are: the `EmptyTree` null object, `TypeTree` instances that don't carry a type - * and the special `emptyValDef` singleton. - * - * In the compiler the `isEmpty` check and the derived `orElse` method are mostly used - * as a check for a tree being a null object (`EmptyTree` for term trees and empty TypeTree for type trees). - * - * Unfortunately `emptyValDef` is also considered to be `isEmpty`, but this is deemed to be - * a conceptual mistake pending a fix in https://issues.scala-lang.org/browse/SI-6762. + * Empty trees are: the `EmptyTree` null object and `TypeTree` instances that don't carry a type. * * @see `canHaveAttrs` */ def isEmpty: Boolean - /** Is this tree one of the empty trees? + /** Is this tree not an empty tree? * * @see `isEmpty` */ @@ -92,7 +85,7 @@ trait Trees { self: Universe => /** Can this tree carry attributes (i.e. symbols, types or positions)? * Typically the answer is yes, except for the `EmptyTree` null object and - * two special singletons: `emptyValDef` and `pendingSuperCall`. + * two special singletons: `noSelfType` and `pendingSuperCall`. */ def canHaveAttrs: Boolean @@ -856,7 +849,7 @@ trait Trees { self: Universe => def parents: List[Tree] /** Self type of the template. - * Is equal to `emptyValDef` if the self type is not specified. + * Is equal to `noSelfType` if the self type is not specified. */ def self: ValDef @@ -2121,6 +2114,9 @@ trait Trees { self: Universe => * no definition of a self value of self type. * @group Trees */ + val noSelfType: ValDef + + @deprecated("Use `noSelfType` instead", "2.11.0") val emptyValDef: ValDef /** An empty superclass constructor call corresponding to: @@ -2635,7 +2631,7 @@ trait Trees { self: Universe => trees mapConserve (tree => transform(tree).asInstanceOf[TypeDef]) /** Transforms a `ValDef`. */ def transformValDef(tree: ValDef): ValDef = - if (tree eq emptyValDef) tree + if (tree eq noSelfType) tree else transform(tree).asInstanceOf[ValDef] /** Transforms a list of `ValDef` nodes. */ def transformValDefs(trees: List[ValDef]): List[ValDef] = diff --git a/src/reflect/scala/reflect/internal/BuildUtils.scala b/src/reflect/scala/reflect/internal/BuildUtils.scala index e5c7dc44af..25186ae95b 100644 --- a/src/reflect/scala/reflect/internal/BuildUtils.scala +++ b/src/reflect/scala/reflect/internal/BuildUtils.scala @@ -63,7 +63,7 @@ trait BuildUtils { self: SymbolTable => def setSymbol[T <: Tree](tree: T, sym: Symbol): T = { tree.setSymbol(sym); tree } def mkAnnotation(tree: Tree): Tree = tree match { - case SyntacticNew(Nil, SyntacticApplied(SyntacticTypeApplied(_, _), _) :: Nil, emptyValDef, Nil) => + case SyntacticNew(Nil, SyntacticApplied(SyntacticTypeApplied(_, _), _) :: Nil, noSelfType, Nil) => tree case _ => throw new IllegalArgumentException(s"Tree ${showRaw(tree)} isn't a correct representation of annotation." + @@ -364,7 +364,7 @@ trait BuildUtils { self: SymbolTable => def unapply(tree: Tree): Option[(List[Tree], List[Tree], ValDef, List[Tree])] = tree match { case SyntacticApplied(Select(New(SyntacticTypeApplied(ident, targs)), nme.CONSTRUCTOR), argss) => - Some((Nil, SyntacticApplied(SyntacticTypeApplied(ident, targs), argss) :: Nil, emptyValDef, Nil)) + Some((Nil, SyntacticApplied(SyntacticTypeApplied(ident, targs), argss) :: Nil, noSelfType, Nil)) case SyntacticBlock(SyntacticClassDef(_, tpnme.ANON_CLASS_NAME, Nil, _, ListOfNil, earlyDefs, parents, selfdef, body) :: Apply(Select(New(Ident(tpnme.ANON_CLASS_NAME)), nme.CONSTRUCTOR), Nil) :: Nil) => Some((earlyDefs, parents, selfdef, body)) diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index f8af4f155d..961e8e7264 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -658,8 +658,8 @@ trait Definitions extends api.StandardDefinitions { // These "direct" calls perform no dealiasing. They are most needed when // printing types when one wants to preserve the true nature of the type. - def isFunctionTypeDirect(tp: Type) = isFunctionSymbol(tp.typeSymbolDirect) - def isTupleTypeDirect(tp: Type) = isTupleSymbol(tp.typeSymbolDirect) + def isFunctionTypeDirect(tp: Type) = !tp.isHigherKinded && isFunctionSymbol(tp.typeSymbolDirect) + def isTupleTypeDirect(tp: Type) = !tp.isHigherKinded && isTupleSymbol(tp.typeSymbolDirect) // Note that these call .dealiasWiden and not .normalize, the latter of which // tends to change the course of events by forcing types. diff --git a/src/reflect/scala/reflect/internal/Flags.scala b/src/reflect/scala/reflect/internal/Flags.scala index c286ea53c6..dcdf6728ce 100644 --- a/src/reflect/scala/reflect/internal/Flags.scala +++ b/src/reflect/scala/reflect/internal/Flags.scala @@ -279,11 +279,13 @@ class Flags extends ModifierFlags { final val GetterFlags = ~(PRESUPER | MUTABLE) final val SetterFlags = ~(PRESUPER | MUTABLE | STABLE | CASEACCESSOR | IMPLICIT) - /** When a symbol for a default getter is created, it inherits these - * flags from the method with the default. Other flags applied at creation - * time are SYNTHETIC, DEFAULTPARAM, and possibly OVERRIDE, and maybe PRESUPER. + /** Since DEFAULTPARAM is overloaded with TRAIT, we need some additional + * means of determining what that bit means. Usually DEFAULTPARAM is coupled + * with PARAM, which suffices. Default getters get METHOD instead. + * This constant is the mask of flags which can survive from the parameter modifiers. + * See paramFlagsToDefaultGetter for the full logic. */ - final val DefaultGetterFlags = PRIVATE | PROTECTED | FINAL + final val DefaultGetterFlags = PRIVATE | PROTECTED | FINAL | PARAMACCESSOR /** When a symbol for a method parameter is created, only these flags survive * from Modifiers. Others which may be applied at creation time are: @@ -321,6 +323,9 @@ class Flags extends ModifierFlags { */ final val TopLevelPickledFlags = PickledFlags & ~(MODULE | METHOD | PACKAGE | PARAM | EXISTENTIAL) + def paramFlagsToDefaultGetter(paramFlags: Long): Long = + (paramFlags & DefaultGetterFlags) | SYNTHETIC | METHOD | DEFAULTPARAM + def getterFlags(fieldFlags: Long): Long = ACCESSOR + ( if ((fieldFlags & MUTABLE) != 0) fieldFlags & ~MUTABLE & ~PRESUPER else fieldFlags & ~PRESUPER | STABLE diff --git a/src/reflect/scala/reflect/internal/HasFlags.scala b/src/reflect/scala/reflect/internal/HasFlags.scala index 420b5fef81..4e12998ac7 100644 --- a/src/reflect/scala/reflect/internal/HasFlags.scala +++ b/src/reflect/scala/reflect/internal/HasFlags.scala @@ -81,7 +81,7 @@ trait HasFlags { // identically, testing for a single flag. def hasAbstractFlag = hasFlag(ABSTRACT) def hasAccessorFlag = hasFlag(ACCESSOR) - def hasDefault = hasAllFlags(DEFAULTPARAM | PARAM) + def hasDefault = hasFlag(DEFAULTPARAM) && hasFlag(METHOD | PARAM) // Second condition disambiguates with TRAIT def hasLocalFlag = hasFlag(LOCAL) def hasModuleFlag = hasFlag(MODULE) def hasPackageFlag = hasFlag(PACKAGE) @@ -116,6 +116,9 @@ trait HasFlags { def isSynthetic = hasFlag(SYNTHETIC) def isTrait = hasFlag(TRAIT) && !hasFlag(PARAM) + def isDeferredOrDefault = hasFlag(DEFERRED | DEFAULTMETHOD) + def isDeferredNotDefault = isDeferred && !hasFlag(DEFAULTMETHOD) + def flagBitsToString(bits: Long): String = { // Fast path for common case if (bits == 0L) "" else { diff --git a/src/reflect/scala/reflect/internal/Importers.scala b/src/reflect/scala/reflect/internal/Importers.scala index 9ddf156128..72c8ccfa62 100644 --- a/src/reflect/scala/reflect/internal/Importers.scala +++ b/src/reflect/scala/reflect/internal/Importers.scala @@ -308,8 +308,8 @@ trait Importers extends api.Importers { to: SymbolTable => new PackageDef(importRefTree(pid), stats map importTree) case from.ModuleDef(mods, name, impl) => new ModuleDef(importModifiers(mods), importName(name).toTermName, importTemplate(impl)) - case from.emptyValDef => - emptyValDef + case from.noSelfType => + noSelfType case from.pendingSuperCall => pendingSuperCall case from.ValDef(mods, name, tpt, rhs) => @@ -412,7 +412,7 @@ trait Importers extends api.Importers { to: SymbolTable => addFixup(recreatedTreeCompleter(their, my)) tryFixup() // we have to be careful with position import as some shared trees - // like EmptyTree, emptyValDef don't support position assignment + // like EmptyTree, noSelfType don't support position assignment if (their.pos != NoPosition) { my.setPos(importPosition(their.pos)) } diff --git a/src/reflect/scala/reflect/internal/Printers.scala b/src/reflect/scala/reflect/internal/Printers.scala index 206dff44e2..424e73dce8 100644 --- a/src/reflect/scala/reflect/internal/Printers.scala +++ b/src/reflect/scala/reflect/internal/Printers.scala @@ -549,8 +549,8 @@ trait Printers extends api.Printers { self: SymbolTable => print(")") case EmptyTree => print("EmptyTree") - case self.emptyValDef => - print("emptyValDef") + case self.noSelfType => + print("noSelfType") case self.pendingSuperCall => print("pendingSuperCall") case tree: Tree => diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala index f4eae5590a..4990596839 100644 --- a/src/reflect/scala/reflect/internal/StdNames.scala +++ b/src/reflect/scala/reflect/internal/StdNames.scala @@ -122,15 +122,16 @@ trait StdNames { final val Unit: NameType = "Unit" // some types whose companions we utilize - final val AnyRef: NameType = "AnyRef" - final val Array: NameType = "Array" - final val List: NameType = "List" - final val Seq: NameType = "Seq" - final val Symbol: NameType = "Symbol" - final val WeakTypeTag: NameType = "WeakTypeTag" - final val TypeTag : NameType = "TypeTag" - final val Expr: NameType = "Expr" - final val String: NameType = "String" + final val AnyRef: NameType = "AnyRef" + final val Array: NameType = "Array" + final val List: NameType = "List" + final val Seq: NameType = "Seq" + final val Symbol: NameType = "Symbol" + final val WeakTypeTag: NameType = "WeakTypeTag" + final val TypeTag : NameType = "TypeTag" + final val Expr: NameType = "Expr" + final val String: NameType = "String" + final val StringContext: NameType = "StringContext" // fictions we use as both types and terms final val ERROR: NameType = "<error>" @@ -237,6 +238,7 @@ trait StdNames { final val ClassManifest: NameType = "ClassManifest" final val Enum: NameType = "Enum" final val Group: NameType = "Group" + final val implicitNotFound: NameType = "implicitNotFound" final val Name: NameType = "Name" final val Tree: NameType = "Tree" final val TermName: NameType = "TermName" @@ -600,7 +602,6 @@ trait StdNames { val RootClass: NameType = "RootClass" val Select: NameType = "Select" val SelectFromTypeTree: NameType = "SelectFromTypeTree" - val StringContext: NameType = "StringContext" val SyntacticApplied: NameType = "SyntacticApplied" val SyntacticAssign: NameType = "SyntacticAssign" val SyntacticBlock: NameType = "SyntacticBlock" @@ -661,7 +662,7 @@ trait StdNames { val dollarScope: NameType = "$scope" val drop: NameType = "drop" val elem: NameType = "elem" - val emptyValDef: NameType = "emptyValDef" + val noSelfType: NameType = "noSelfType" val ensureAccessible : NameType = "ensureAccessible" val eq: NameType = "eq" val equalsNumChar : NameType = "equalsNumChar" diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index d58ea09386..14d742fc2c 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -571,7 +571,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => def isValue = false def isValueParameter = false def isVariable = false - override def hasDefault = false def isTermMacro = false /** Qualities of MethodSymbols, always false for TypeSymbols @@ -2601,7 +2600,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => override def companionSymbol: Symbol = companionClass override def moduleClass = if (isModule) referenced else NoSymbol - override def hasDefault = this hasFlag DEFAULTPARAM // overloaded with TRAIT override def isBridge = this hasFlag BRIDGE override def isEarlyInitialized = this hasFlag PRESUPER override def isMethod = this hasFlag METHOD diff --git a/src/reflect/scala/reflect/internal/TreeGen.scala b/src/reflect/scala/reflect/internal/TreeGen.scala index c8ae4df13d..9be1768289 100644 --- a/src/reflect/scala/reflect/internal/TreeGen.scala +++ b/src/reflect/scala/reflect/internal/TreeGen.scala @@ -376,7 +376,7 @@ abstract class TreeGen extends macros.TreeBuilder { DefDef(constrMods, nme.CONSTRUCTOR, List(), vparamss1, TypeTree(), Block(lvdefs ::: List(superCall), Literal(Constant()))))) } } - constr foreach (ensureNonOverlapping(_, parents ::: gvdefs, focus=false)) + constr foreach (ensureNonOverlapping(_, parents ::: gvdefs, focus = false)) // Field definitions for the class - remove defaults. val fieldDefs = vparamss.flatten map (vd => copyValDef(vd)(mods = vd.mods &~ DEFAULTPARAM, rhs = EmptyTree)) diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala index 9138a1c7bb..6ec542c103 100644 --- a/src/reflect/scala/reflect/internal/Trees.scala +++ b/src/reflect/scala/reflect/internal/Trees.scala @@ -1037,9 +1037,11 @@ trait Trees extends api.Trees { self: SymbolTable => } case object EmptyTree extends TermTree with CannotHaveAttrs { override def isEmpty = true; val asList = List(this) } - object emptyValDef extends ValDef(Modifiers(PRIVATE), nme.WILDCARD, TypeTree(NoType), EmptyTree) with CannotHaveAttrs + object noSelfType extends ValDef(Modifiers(PRIVATE), nme.WILDCARD, TypeTree(NoType), EmptyTree) with CannotHaveAttrs object pendingSuperCall extends Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), List()) with CannotHaveAttrs + @deprecated("Use `noSelfType` instead", "2.11.0") lazy val emptyValDef = noSelfType + def newValDef(sym: Symbol, rhs: Tree)( mods: Modifiers = Modifiers(sym.flags), name: TermName = sym.name.toTermName, @@ -1196,7 +1198,7 @@ trait Trees extends api.Trees { self: SymbolTable => traverse(annot); traverse(arg) case Template(parents, self, body) => traverseTrees(parents) - if (self ne emptyValDef) traverse(self) + if (self ne noSelfType) traverse(self) traverseStats(body, tree.symbol) case Block(stats, expr) => traverseTrees(stats); traverse(expr) diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index dd6917814e..77f4b1b70c 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -2553,7 +2553,7 @@ trait Types private var isdepmeth: ThreeValue = UNKNOWN override def isDependentMethodType: Boolean = { - if (isdepmeth == UNKNOWN) isdepmeth = fromBoolean(IsDependentCollector.collect(resultType)) + if (isdepmeth == UNKNOWN) isdepmeth = fromBoolean(IsDependentCollector.collect(resultType.dealias)) toBoolean(isdepmeth) } diff --git a/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala b/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala index be61c45041..d6310c8cec 100644 --- a/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala +++ b/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala @@ -841,7 +841,7 @@ private[internal] trait TypeMaps { object IsDependentCollector extends TypeCollector(false) { def traverse(tp: Type) { if (tp.isImmediatelyDependent) result = true - else if (!result) mapOver(tp) + else if (!result) mapOver(tp.dealias) } } diff --git a/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala index d5048dcfa3..2b7e2506d4 100644 --- a/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala @@ -41,8 +41,8 @@ trait ModelFactoryTypeSupport { private def appendType0(tpe: Type): Unit = tpe match { /* Type refs */ - case tp: TypeRef if definitions.isFunctionType(tp) => - val args = tp.normalize.typeArgs + case tp: TypeRef if definitions.isFunctionTypeDirect(tp) => + val args = tp.typeArgs nameBuffer append '(' appendTypes0(args.init, ", ") nameBuffer append ") ⇒ " @@ -53,8 +53,8 @@ trait ModelFactoryTypeSupport { case tp: TypeRef if definitions.isByNameParamType(tp) => nameBuffer append "⇒ " appendType0(tp.args.head) - case tp: TypeRef if definitions.isTupleType(tp) => - val args = tp.normalize.typeArgs + case tp: TypeRef if definitions.isTupleTypeDirect(tp) => + val args = tp.typeArgs nameBuffer append '(' appendTypes0(args, ", ") nameBuffer append ')' diff --git a/test/files/continuations-run/t5472.check b/test/files/continuations-run/t5472.check index 3192c746eb..2468b6b27d 100644 --- a/test/files/continuations-run/t5472.check +++ b/test/files/continuations-run/t5472.check @@ -6,6 +6,16 @@ t5472.scala:12: warning: expression case4(){ } is cps-transformed unexpectedly (location, accessors) <- new ContinuationizedParallelIterable(map) ^ +t5472.scala:12: warning: expression case5(){ + matchEnd3(false) +} is cps-transformed unexpectedly + (location, accessors) <- new ContinuationizedParallelIterable(map) + ^ +t5472.scala:12: warning: expression matchEnd3(x: Boolean){ + x +} is cps-transformed unexpectedly + (location, accessors) <- new ContinuationizedParallelIterable(map) + ^ t5472.scala:12: warning: expression matchEnd3(x: Int){ x } is cps-transformed unexpectedly diff --git a/test/files/neg/checksensible.check b/test/files/neg/checksensible.check index e5f1a38d96..ef3aee5ee4 100644 --- a/test/files/neg/checksensible.check +++ b/test/files/neg/checksensible.check @@ -28,6 +28,9 @@ checksensible.scala:27: warning: comparing values of types Int and Unit using `= checksensible.scala:29: warning: comparing values of types Int and String using `==' will always yield false 1 == "abc" ^ +checksensible.scala:29: warning: Int and String are unrelated: they will most likely never compare equal + 1 == "abc" + ^ checksensible.scala:33: warning: comparing values of types Some[Int] and Int using `==' will always yield false Some(1) == 1 // as above ^ @@ -61,12 +64,18 @@ checksensible.scala:51: warning: comparing values of types Int and Unit using `! checksensible.scala:52: warning: comparing values of types Int and Symbol using `!=' will always yield true (1 != 'sym) ^ +checksensible.scala:52: warning: Int and Symbol are unrelated: they will most likely always compare unequal + (1 != 'sym) + ^ checksensible.scala:58: warning: comparing a fresh object using `==' will always yield false ((x: Int) => x + 1) == null ^ checksensible.scala:59: warning: comparing a fresh object using `==' will always yield false Bep == ((_: Int) + 1) ^ +checksensible.scala:59: warning: Bep.type and Int => Int are unrelated: they will most likely never compare equal + Bep == ((_: Int) + 1) + ^ checksensible.scala:61: warning: comparing a fresh object using `==' will always yield false new Object == new Object ^ @@ -82,6 +91,9 @@ checksensible.scala:66: warning: comparing values of types Int and Null using `= checksensible.scala:71: warning: comparing values of types Bip and Bop using `==' will always yield false (x1 == x2) ^ +checksensible.scala:71: warning: Bip and Bop are unrelated: they will most likely never compare equal + (x1 == x2) + ^ checksensible.scala:81: warning: comparing values of types EqEqRefTest.this.C3 and EqEqRefTest.this.Z1 using `==' will always yield false c3 == z1 ^ @@ -94,9 +106,12 @@ checksensible.scala:83: warning: comparing values of types EqEqRefTest.this.Z1 a checksensible.scala:84: warning: comparing values of types EqEqRefTest.this.C3 and String using `!=' will always yield true c3 != "abc" ^ +checksensible.scala:84: warning: EqEqRefTest.this.C3 and String are unrelated: they will most likely always compare unequal + c3 != "abc" + ^ checksensible.scala:95: warning: comparing values of types Unit and Int using `!=' will always yield true while ((c = in.read) != -1) ^ error: No warnings can be incurred under -Xfatal-warnings. -33 warnings found +38 warnings found one error found diff --git a/test/files/neg/forgot-interpolator.check b/test/files/neg/forgot-interpolator.check index a96431841f..157cbb4802 100644 --- a/test/files/neg/forgot-interpolator.check +++ b/test/files/neg/forgot-interpolator.check @@ -1,24 +1,30 @@ forgot-interpolator.scala:4: warning: `$bippy` looks like an interpolated identifier! Did you forget the interpolator? - def f = "Put the $bippy in the $bippy!" // warn + def f = "Put the $bippy in the $bippy!" // warn 1 ^ forgot-interpolator.scala:14: warning: That looks like an interpolated expression! Did you forget the interpolator? - def f = """Put the ${println("bippy")} in the bippy!""" // warn + def f = """Put the ${println("bippy")} in the bippy!""" // warn 2 ^ forgot-interpolator.scala:30: warning: `$beppo` looks like an interpolated identifier! Did you forget the interpolator? - def f = "$beppo was a marx bros who saw dollars." // warn + def f = "$beppo was a marx bros who saw dollars." // warn 3 ^ forgot-interpolator.scala:34: warning: `$aleppo` looks like an interpolated identifier! Did you forget the interpolator? - def f = "$aleppo is a pepper and a city." // warn + def f = "$aleppo is a pepper and a city." // warn 4 ^ -forgot-interpolator.scala:40: warning: `$bar` looks like an interpolated identifier! Did you forget the interpolator? - def f = "$bar is private, shall we warn just in case?" // warn +forgot-interpolator.scala:42: warning: `$bar` looks like an interpolated identifier! Did you forget the interpolator? + def f = "$bar is private, shall we warn just in case?" // warn 5 ^ -forgot-interpolator.scala:45: warning: `$hippo` looks like an interpolated identifier! Did you forget the interpolator? - def h = "$hippo takes an implicit" // warn +forgot-interpolator.scala:47: warning: `$hippo` looks like an interpolated identifier! Did you forget the interpolator? + def h = "$hippo takes an implicit" // warn 6 ^ -forgot-interpolator.scala:37: warning: private method in class Bar is never used - private def bar = 8 - ^ +forgot-interpolator.scala:88: warning: `$groucho` looks like an interpolated identifier! Did you forget the interpolator? + def f2 = "I salute $groucho" // warn 7 + ^ +forgot-interpolator.scala:89: warning: `$dingo` looks like an interpolated identifier! Did you forget the interpolator? + def f3 = "I even salute $dingo" // warn 8 + ^ +forgot-interpolator.scala:90: warning: `$calico` looks like an interpolated identifier! Did you forget the interpolator? + def f4 = "I also salute $calico" // warn 9 + ^ error: No warnings can be incurred under -Xfatal-warnings. -7 warnings found +9 warnings found one error found diff --git a/test/files/neg/forgot-interpolator.scala b/test/files/neg/forgot-interpolator.scala index 5067f1dce9..34a7c7aef4 100644 --- a/test/files/neg/forgot-interpolator.scala +++ b/test/files/neg/forgot-interpolator.scala @@ -1,7 +1,7 @@ class A { val bippy = 123 - def f = "Put the $bippy in the $bippy!" // warn + def f = "Put the $bippy in the $bippy!" // warn 1 } class B { @@ -11,7 +11,7 @@ class B { } class C { - def f = """Put the ${println("bippy")} in the bippy!""" // warn + def f = """Put the ${println("bippy")} in the bippy!""" // warn 2 } package object test { @@ -27,21 +27,67 @@ package test { def beppo(i: Int) = 8 * i def beppo = 8 class Dah extends Doo { - def f = "$beppo was a marx bros who saw dollars." // warn + def f = "$beppo was a marx bros who saw dollars." // warn 3 } } class E { - def f = "$aleppo is a pepper and a city." // warn + def f = "$aleppo is a pepper and a city." // warn 4 + def k = s"Just an interpolation of $aleppo" // no warn } class Bar { private def bar = 8 + if (bar > 8) ??? // use it to avoid extra warning } class Baz extends Bar { - def f = "$bar is private, shall we warn just in case?" // warn + def f = "$bar is private, shall we warn just in case?" // warn 5 } class G { def g = "$greppo takes an arg" // no warn def z = "$zappos takes an arg too" // no warn - def h = "$hippo takes an implicit" // warn + def h = "$hippo takes an implicit" // warn 6 + } + class J { + def j = 8 + class J2 { + def j(i: Int) = 2 * i + def jj = "shadowed $j" // no warn + } + } + import annotation._ + @implicitNotFound("No Z in ${A}") // no warn + class Z[A] +} + + +package inf1 { + import scala.annotation.implicitNotFound + + @implicitNotFound(msg = "Cannot construct a collection of type ${To} with elements of type ${Elem} based on a collection of type ${From}.") // no warn + trait CannotBuildFrom[-From, -Elem, +To] +} + +package inf2 { + @scala.annotation.implicitNotFound(msg = "Cannot construct a collection of type ${To} with elements of type ${Elem} based on a collection of type ${From}.") // no warn + trait CannotBuildFrom[-From, -Elem, +To] +} + +package inf3 { + @scala.annotation.implicitNotFound("Cannot construct a collection of type ${To} with elements of type ${Elem} based on a collection of type ${From}.") // no warn + trait CannotBuildFrom[-From, -Elem, +To] +} + +package curry { + class A { + def bunko()(x: Int): Int = 5 + def groucho(): Int = 5 + def dingo()()()()()(): Int = 5 // kind of nuts this can be evaluated with just 'dingo', but okay + def calico[T1, T2]()()(): Int = 5 // even nutsier + def palomino[T1, T2]()(y: Int = 5)(): Int = 5 // even nutsier + + def f1 = "I was picked up by the $bunko squad" // no warn + def f2 = "I salute $groucho" // warn 7 + def f3 = "I even salute $dingo" // warn 8 + def f4 = "I also salute $calico" // warn 9 + def f5 = "I draw the line at $palomino" // no warn } } diff --git a/test/files/neg/newpat_unreachable.check b/test/files/neg/newpat_unreachable.check index a928e3853a..4463e2f1a4 100644 --- a/test/files/neg/newpat_unreachable.check +++ b/test/files/neg/newpat_unreachable.check @@ -13,6 +13,9 @@ If you intended to match against value d in class A, you must use backticks, lik newpat_unreachable.scala:9: warning: unreachable code due to variable pattern 'b' on line 6 case _ => println("matched neither") ^ +newpat_unreachable.scala:7: warning: unreachable code + case c => println("matched c") + ^ newpat_unreachable.scala:22: warning: patterns after a variable pattern cannot match (SLS 8.1.1) If you intended to match against parameter b of method g, you must use backticks, like: case `b` => case b => 1 @@ -24,6 +27,9 @@ If you intended to match against parameter c of method h, you must use backticks newpat_unreachable.scala:24: warning: unreachable code due to variable pattern 'b' on line 22 case _ => 3 ^ +newpat_unreachable.scala:23: warning: unreachable code + case c => 2 + ^ error: No warnings can be incurred under -Xfatal-warnings. -7 warnings found +9 warnings found one error found diff --git a/test/files/neg/package-ob-case.check b/test/files/neg/package-ob-case.check index 063a120db1..9b0ede1c6d 100644 --- a/test/files/neg/package-ob-case.check +++ b/test/files/neg/package-ob-case.check @@ -2,6 +2,9 @@ package-ob-case.scala:3: warning: it is not recommended to define classes/object If possible, define class X in package foo instead. case class X(z: Int) { } ^ +package-ob-case.scala:3: warning: class X should be placed directly in package foo instead of package object foo. Under some circumstances companion objects and case classes in package objects can fail to recompile. See https://issues.scala-lang.org/browse/SI-5954. + case class X(z: Int) { } + ^ error: No warnings can be incurred under -Xfatal-warnings. -one warning found +two warnings found one error found diff --git a/test/files/neg/pat_unreachable.check b/test/files/neg/pat_unreachable.check index b4c0e7e104..374ee4e9cf 100644 --- a/test/files/neg/pat_unreachable.check +++ b/test/files/neg/pat_unreachable.check @@ -9,6 +9,9 @@ If you intended to match against parameter c of method contrivedExample, you mus pat_unreachable.scala:24: warning: unreachable code due to variable pattern 'b' on line 22 case _ => println("matched neither") ^ +pat_unreachable.scala:23: warning: unreachable code + case c => println("matched c") + ^ error: No warnings can be incurred under -Xfatal-warnings. -three warnings found +four warnings found one error found diff --git a/test/files/neg/t2462b.check b/test/files/neg/t2462b.check index bc0d9aa469..b3b8007a93 100644 --- a/test/files/neg/t2462b.check +++ b/test/files/neg/t2462b.check @@ -6,9 +6,6 @@ t2462b.scala:9: warning: Invalid implicitNotFound message for trait Meh2 in pack The type parameter Elem referenced in the message of the @implicitNotFound annotation is not defined by trait Meh2. trait Meh2[-From, +To] ^ -t2462b.scala:12: error: overriding method x in class thankyoupartest of type => Int; - method x needs `override' modifier -class testmustfail extends thankyoupartest { def x = 43 } - ^ +error: No warnings can be incurred under -Xfatal-warnings. two warnings found one error found diff --git a/test/files/neg/t2462b.flags b/test/files/neg/t2462b.flags new file mode 100644 index 0000000000..85d8eb2ba2 --- /dev/null +++ b/test/files/neg/t2462b.flags @@ -0,0 +1 @@ +-Xfatal-warnings diff --git a/test/files/neg/t2462b.scala b/test/files/neg/t2462b.scala index 7a1389cc8e..576db4bd3f 100644 --- a/test/files/neg/t2462b.scala +++ b/test/files/neg/t2462b.scala @@ -7,6 +7,3 @@ trait Meh[-From, +To] @implicitNotFound(msg = "Cannot construct a collection of type ${To} ${Elem}.") trait Meh2[-From, +To] - -class thankyoupartest { def x = 42 } -class testmustfail extends thankyoupartest { def x = 43 } diff --git a/test/files/neg/t2462c.check b/test/files/neg/t2462c.check new file mode 100644 index 0000000000..edeead55d6 --- /dev/null +++ b/test/files/neg/t2462c.check @@ -0,0 +1,7 @@ +t2462c.scala:18: error: No C of X$Y + f[X$Y] + ^ +t2462c.scala:24: error: No C of Foo[Int] + f[Foo[Int]] + ^ +two errors found diff --git a/test/files/neg/t2462c.flags b/test/files/neg/t2462c.flags new file mode 100644 index 0000000000..85d8eb2ba2 --- /dev/null +++ b/test/files/neg/t2462c.flags @@ -0,0 +1 @@ +-Xfatal-warnings diff --git a/test/files/neg/t2462c.scala b/test/files/neg/t2462c.scala new file mode 100644 index 0000000000..acf04afba9 --- /dev/null +++ b/test/files/neg/t2462c.scala @@ -0,0 +1,25 @@ + +import annotation._ + +@implicitNotFound("No C of ${ A }") +class C[A] + +trait X$Y +/* using the $$ separator for expanded names is unwise +trait X$$Y +trait X$$$Y +trait X$$$$Y + */ + +trait Foo[A] + +class Test { + def f[A: C] = ??? + f[X$Y] +/* using the $$ separator for expanded names is unwise + f[X$$Y] + f[X$$$Y] + f[X$$$$Y] + */ + f[Foo[Int]] +} diff --git a/test/files/neg/t3971.check b/test/files/neg/t3971.check new file mode 100644 index 0000000000..8685119876 --- /dev/null +++ b/test/files/neg/t3971.check @@ -0,0 +1,21 @@ +t3971.scala:6: error: type mismatch; + found : Int + required: String + f(g("abc")("def")) // g returns Int, needs String + ^ +t3971.scala:7: error: type mismatch; + found : Int(5) + required: String + f(5) + ^ +t3971.scala:8: error: type mismatch; + found : Int + required: String + f(h("abc")) + ^ +t3971.scala:11: error: type mismatch; + found : Boolean + required: String + ({"ab".reverse; "ba".equals})(0): String + ^ +four errors found diff --git a/test/files/neg/t3971.scala b/test/files/neg/t3971.scala new file mode 100644 index 0000000000..35f64fde0c --- /dev/null +++ b/test/files/neg/t3971.scala @@ -0,0 +1,12 @@ +class A { + def f(x: String) = x + def g(x: String)(y: String): Int = x.length + y.length + def h(x: String) = x.length + + f(g("abc")("def")) // g returns Int, needs String + f(5) + f(h("abc")) + + // a perverse piece of code from a perverse coder + ({"ab".reverse; "ba".equals})(0): String +} diff --git a/test/files/neg/t5426.check b/test/files/neg/t5426.check index 98f3ddaaae..c042cdcec3 100644 --- a/test/files/neg/t5426.check +++ b/test/files/neg/t5426.check @@ -4,12 +4,18 @@ t5426.scala:2: warning: comparing values of types Some[Int] and Int using `==' w t5426.scala:3: warning: comparing values of types Int and Some[Int] using `==' will always yield false def f2 = 5 == Some(5) ^ +t5426.scala:3: warning: Int and Some[Int] are unrelated: they will most likely never compare equal + def f2 = 5 == Some(5) + ^ t5426.scala:8: warning: comparing values of types Int and Some[Int] using `==' will always yield false (x1 == x2) ^ +t5426.scala:8: warning: Int and Some[Int] are unrelated: they will most likely never compare equal + (x1 == x2) + ^ t5426.scala:9: warning: comparing values of types Some[Int] and Int using `==' will always yield false (x2 == x1) ^ error: No warnings can be incurred under -Xfatal-warnings. -four warnings found +6 warnings found one error found diff --git a/test/files/neg/t5663-badwarneq.check b/test/files/neg/t5663-badwarneq.check index 732e4f44d0..4b7795585b 100644 --- a/test/files/neg/t5663-badwarneq.check +++ b/test/files/neg/t5663-badwarneq.check @@ -25,6 +25,9 @@ t5663-badwarneq.scala:72: warning: ValueClass1 and Int are unrelated: they will t5663-badwarneq.scala:74: warning: comparing values of types Int and ValueClass1 using `==' will always yield false println(5 == new ValueClass1(5)) // bad ^ +t5663-badwarneq.scala:74: warning: Int and ValueClass1 are unrelated: they will never compare equal + println(5 == new ValueClass1(5)) // bad + ^ t5663-badwarneq.scala:78: warning: ValueClass2[String] and String are unrelated: they will never compare equal println(new ValueClass2("abc") == "abc") // bad ^ @@ -38,5 +41,5 @@ t5663-badwarneq.scala:82: warning: comparing values of types ValueClass3 and Int println(ValueClass3(5) == 5) // bad ^ error: No warnings can be incurred under -Xfatal-warnings. -13 warnings found +14 warnings found one error found diff --git a/test/files/neg/t6048.check b/test/files/neg/t6048.check index 5e11d24fde..f8eddf5471 100644 --- a/test/files/neg/t6048.check +++ b/test/files/neg/t6048.check @@ -10,6 +10,9 @@ t6048.scala:13: warning: patterns after a variable pattern cannot match (SLS 8.1 t6048.scala:14: warning: unreachable code due to variable pattern on line 13 case 5 if true => x // unreachable ^ +t6048.scala:14: warning: unreachable code + case 5 if true => x // unreachable + ^ error: No warnings can be incurred under -Xfatal-warnings. -four warnings found +5 warnings found one error found diff --git a/test/files/neg/t6120.check b/test/files/neg/t6120.check new file mode 100644 index 0000000000..a7d17e29cf --- /dev/null +++ b/test/files/neg/t6120.check @@ -0,0 +1,20 @@ +t6120.scala:5: warning: postfix operator bippy should be enabled +by making the implicit value scala.language.postfixOps visible. +This can be achieved by adding the import clause 'import scala.language.postfixOps' +or by setting the compiler option -language:postfixOps. +See the Scala docs for value scala.language.postfixOps for a discussion +why the feature should be explicitly enabled. + def f = null == null bippy + ^ +t6120.scala:5: warning: method bippy in class BooleanOps is deprecated: bobo + def f = null == null bippy + ^ +t6120.scala:5: warning: comparing values of types Null and Null using `==' will always yield true + def f = null == null bippy + ^ +t6120.scala:6: warning: method bippy in class BooleanOps is deprecated: bobo + def g = true.bippy + ^ +error: No warnings can be incurred under -Xfatal-warnings. +four warnings found +one error found diff --git a/test/files/neg/t6120.flags b/test/files/neg/t6120.flags new file mode 100644 index 0000000000..04d7c7d417 --- /dev/null +++ b/test/files/neg/t6120.flags @@ -0,0 +1 @@ +-feature -deprecation -Xfatal-warnings
\ No newline at end of file diff --git a/test/files/neg/t6120.scala b/test/files/neg/t6120.scala new file mode 100644 index 0000000000..425f09db47 --- /dev/null +++ b/test/files/neg/t6120.scala @@ -0,0 +1,7 @@ +class A { + implicit class BooleanOps(val b: Boolean) { + @deprecated("bobo", "2.11.0") def bippy() = 5 + } + def f = null == null bippy + def g = true.bippy +} diff --git a/test/files/neg/t7629-view-bounds-deprecation.check b/test/files/neg/t7629-view-bounds-deprecation.check new file mode 100644 index 0000000000..ed77c15c54 --- /dev/null +++ b/test/files/neg/t7629-view-bounds-deprecation.check @@ -0,0 +1,11 @@ +t7629-view-bounds-deprecation.scala:2: warning: View bounds are deprecated. Use an implicit parameter instead. +Example: Instead of `def f[A <% Int](a: A)` use `def f[A](a: A)(implicit ev: A => Int)`. + def f[A <% Int](a: A) = null + ^ +t7629-view-bounds-deprecation.scala:3: warning: View bounds are deprecated. Use an implicit parameter instead. +Example: Instead of `def f[A <% Int](a: A)` use `def f[A](a: A)(implicit ev: A => Int)`. + def g[C, B <: C, A <% B : Numeric](a: A) = null + ^ +error: No warnings can be incurred under -Xfatal-warnings. +two warnings found +one error found diff --git a/test/files/neg/t7629-view-bounds-deprecation.flags b/test/files/neg/t7629-view-bounds-deprecation.flags new file mode 100644 index 0000000000..43a25d4ccc --- /dev/null +++ b/test/files/neg/t7629-view-bounds-deprecation.flags @@ -0,0 +1 @@ +-deprecation -Xfatal-warnings -Xfuture diff --git a/test/files/neg/t7629-view-bounds-deprecation.scala b/test/files/neg/t7629-view-bounds-deprecation.scala new file mode 100644 index 0000000000..a6ede1fcc3 --- /dev/null +++ b/test/files/neg/t7629-view-bounds-deprecation.scala @@ -0,0 +1,4 @@ +object Test { + def f[A <% Int](a: A) = null + def g[C, B <: C, A <% B : Numeric](a: A) = null +} diff --git a/test/files/neg/t7721.check b/test/files/neg/t7721.check index e056b9a293..ade1ca3b20 100644 --- a/test/files/neg/t7721.check +++ b/test/files/neg/t7721.check @@ -7,6 +7,9 @@ t7721.scala:15: warning: abstract type pattern A.this.Foo is unchecked since it t7721.scala:19: warning: abstract type pattern A.this.Foo is unchecked since it is eliminated by erasure case x: Foo with Bar => x.bippy + x.barry ^ +t7721.scala:19: warning: abstract type pattern A.this.Bar is unchecked since it is eliminated by erasure + case x: Foo with Bar => x.bippy + x.barry + ^ t7721.scala:39: warning: abstract type pattern B.this.Foo is unchecked since it is eliminated by erasure case x: Foo with Concrete => x.bippy + x.dingo + x.conco ^ @@ -16,6 +19,9 @@ t7721.scala:43: warning: abstract type pattern B.this.Foo is unchecked since it t7721.scala:47: warning: abstract type pattern B.this.Foo is unchecked since it is eliminated by erasure case x: Foo with Bar with Concrete => x.bippy + x.barry + x.dingo + x.conco + x.bongo ^ +t7721.scala:47: warning: abstract type pattern B.this.Bar is unchecked since it is eliminated by erasure + case x: Foo with Bar with Concrete => x.bippy + x.barry + x.dingo + x.conco + x.bongo + ^ error: No warnings can be incurred under -Xfatal-warnings. -6 warnings found +8 warnings found one error found diff --git a/test/files/neg/t7756b.check b/test/files/neg/t7756b.check index 2817a7e230..e764783241 100644 --- a/test/files/neg/t7756b.check +++ b/test/files/neg/t7756b.check @@ -1,6 +1,9 @@ t7756b.scala:3: warning: comparing values of types Int and String using `==' will always yield false case _ => 0 == "" ^ +t7756b.scala:3: warning: Int and String are unrelated: they will most likely never compare equal + case _ => 0 == "" + ^ error: No warnings can be incurred under -Xfatal-warnings. -one warning found +two warnings found one error found diff --git a/test/files/neg/t7848-interp-warn.check b/test/files/neg/t7848-interp-warn.check index cbdc9f4c27..b7df6d8ce2 100644 --- a/test/files/neg/t7848-interp-warn.check +++ b/test/files/neg/t7848-interp-warn.check @@ -1,9 +1,12 @@ -t7848-interp-warn.scala:7: warning: `$foo` looks like an interpolated identifier! Did you forget the interpolator? +t7848-interp-warn.scala:8: warning: `$foo` looks like an interpolated identifier! Did you forget the interpolator? "An important $foo message!" ^ -t7848-interp-warn.scala:11: warning: That looks like an interpolated expression! Did you forget the interpolator? +t7848-interp-warn.scala:12: warning: That looks like an interpolated expression! Did you forget the interpolator? "A doubly important ${foo * 2} message!" ^ +t7848-interp-warn.scala:16: warning: `$bar` looks like an interpolated identifier! Did you forget the interpolator? + def j = s"Try using '${ "something like $bar" }' instead." // warn + ^ error: No warnings can be incurred under -Xfatal-warnings. -two warnings found +three warnings found one error found diff --git a/test/files/neg/t7848-interp-warn.scala b/test/files/neg/t7848-interp-warn.scala index bb3eeff60c..3887aff8de 100644 --- a/test/files/neg/t7848-interp-warn.scala +++ b/test/files/neg/t7848-interp-warn.scala @@ -2,6 +2,7 @@ package test object Test { + def bar = "bar" def f = { val foo = "bar" "An important $foo message!" @@ -10,4 +11,8 @@ object Test { val foo = "bar" "A doubly important ${foo * 2} message!" } + def h = s"Try using '$$bar' instead." // no warn + def i = s"Try using '${ "$bar" }' instead." // no warn on space test + def j = s"Try using '${ "something like $bar" }' instead." // warn + def k = f"Try using '$bar' instead." // no warn on other std interps } diff --git a/test/files/neg/t7870.check b/test/files/neg/t7870.check new file mode 100644 index 0000000000..d9db911ac1 --- /dev/null +++ b/test/files/neg/t7870.check @@ -0,0 +1,4 @@ +t7870.scala:1: error: in class C, multiple overloaded alternatives of constructor C define default arguments. +class C(a: Int = 0, b: Any) { + ^ +one error found diff --git a/test/files/neg/t7870.scala b/test/files/neg/t7870.scala new file mode 100644 index 0000000000..5d48d43b3a --- /dev/null +++ b/test/files/neg/t7870.scala @@ -0,0 +1,3 @@ +class C(a: Int = 0, b: Any) { + def this(a: Int = 0) = this(???, ???) +} diff --git a/test/files/neg/t7877.check b/test/files/neg/t7877.check new file mode 100644 index 0000000000..7f7f832463 --- /dev/null +++ b/test/files/neg/t7877.check @@ -0,0 +1,7 @@ +t7877.scala:6: error: not found: value Y + case Y() => () // not allowed + ^ +t7877.scala:7: error: OnNext[Any] does not take parameters + case OnNext[Any]() => () // should *not* be allowed, but was. + ^ +two errors found diff --git a/test/files/neg/t7877.scala b/test/files/neg/t7877.scala new file mode 100644 index 0000000000..52e167f3b8 --- /dev/null +++ b/test/files/neg/t7877.scala @@ -0,0 +1,13 @@ +class Test { + val X: OnNext[Any] = null + def Y: OnNext[Any] = null + (null: Any) match { + case X() => () // allowed + case Y() => () // not allowed + case OnNext[Any]() => () // should *not* be allowed, but was. + } +} + +class OnNext[+T] { + def unapply(x: Any) = false +} diff --git a/test/files/neg/unreachablechar.check b/test/files/neg/unreachablechar.check index 121f12a0c7..a621196c56 100644 --- a/test/files/neg/unreachablechar.check +++ b/test/files/neg/unreachablechar.check @@ -4,6 +4,9 @@ unreachablechar.scala:4: warning: patterns after a variable pattern cannot match unreachablechar.scala:5: warning: unreachable code due to variable pattern on line 4 case 'f' => println("not stuff?"); ^ +unreachablechar.scala:5: warning: unreachable code + case 'f' => println("not stuff?"); + ^ error: No warnings can be incurred under -Xfatal-warnings. -two warnings found +three warnings found one error found diff --git a/test/files/neg/warn-unused-privates.check b/test/files/neg/warn-unused-privates.check index 9c41a33e8f..d012869c93 100644 --- a/test/files/neg/warn-unused-privates.check +++ b/test/files/neg/warn-unused-privates.check @@ -16,6 +16,9 @@ warn-unused-privates.scala:35: warning: private val in class Boppy is never used warn-unused-privates.scala:42: warning: private var in trait Accessors is never used private var v1: Int = 0 // warn ^ +warn-unused-privates.scala:42: warning: private setter in trait Accessors is never used + private var v1: Int = 0 // warn + ^ warn-unused-privates.scala:43: warning: private setter in trait Accessors is never used private var v2: Int = 0 // warn, never set ^ @@ -59,5 +62,5 @@ warn-unused-privates.scala:102: warning: local type OtherThing is never used type OtherThing = String // warn ^ error: No warnings can be incurred under -Xfatal-warnings. -20 warnings found +21 warnings found one error found diff --git a/test/files/pos/t7815.scala b/test/files/pos/t7815.scala new file mode 100644 index 0000000000..12a434c5b0 --- /dev/null +++ b/test/files/pos/t7815.scala @@ -0,0 +1,30 @@ +import language.higherKinds + +trait Foo[A <: AnyRef] { + type Repr + def f(a: A): Repr + def g(a: A): Option[Repr] + + type M[X] + def m(a: A): M[a.type] + + type Id[X] = X + def n(a: A): Id[(Repr, M[a.type])] + +} + +object Foo { + type Aux[A <: AnyRef, B] = Foo[A] { type Repr = B; type M[X] = Int } + +} + +object Main extends App { + def mapWithFoo[A <: AnyRef, B](as: List[A])(implicit foo: Foo.Aux[A, B]) = { + // Should be Eta expandable because the result type of `f` is not + // dependant on the value, it is just `B`. + as map foo.f + as map foo.g + as map foo.m + as map foo.n + } +} diff --git a/test/files/run/future-flatmap-exec-count.check b/test/files/run/future-flatmap-exec-count.check new file mode 100644 index 0000000000..dd9dce64ed --- /dev/null +++ b/test/files/run/future-flatmap-exec-count.check @@ -0,0 +1,6 @@ +mapping +execute() +flatmapping +execute() +recovering +execute() diff --git a/test/files/run/future-flatmap-exec-count.scala b/test/files/run/future-flatmap-exec-count.scala new file mode 100644 index 0000000000..86c37be938 --- /dev/null +++ b/test/files/run/future-flatmap-exec-count.scala @@ -0,0 +1,61 @@ +import scala.concurrent._ +import java.util.concurrent.atomic.AtomicInteger + +object Test { + def main(args: Array[String]) { + test() + } + + def test() = { + def await(f: Future[Any]) = + Await.result(f, duration.Duration.Inf) + + val ec = new TestExecutionContext(ExecutionContext.Implicits.global) + + { + val p = Promise[Int]() + val fp = p.future + println("mapping") + val mapped = fp.map(x => x)(ec) + p.success(0) + await(mapped) + } + + { + println("flatmapping") + val p = Promise[Int]() + val fp = p.future + val flatMapped = fp.flatMap({ (x: Int) => + Future.successful(2 * x) + })(ec) + p.success(0) + await(flatMapped) + } + + { + println("recovering") + val recovered = Future.failed(new Throwable()).recoverWith { + case _ => Future.successful(2) + }(ec) + await(recovered) + } + } + + class TestExecutionContext(delegate: ExecutionContext) extends ExecutionContext { + def execute(runnable: Runnable): Unit = ??? + + def reportFailure(t: Throwable): Unit = ??? + + override def prepare(): ExecutionContext = { + val preparedDelegate = delegate.prepare() + return new ExecutionContext { + def execute(runnable: Runnable): Unit = { + println("execute()") + preparedDelegate.execute(runnable) + } + + def reportFailure(t: Throwable): Unit = ??? + } + } + } +} diff --git a/test/files/run/macro-reflective-mamd-normal-mi.check b/test/files/run/macro-reflective-mamd-normal-mi.check index ac4213d6e9..f77196b2db 100644 --- a/test/files/run/macro-reflective-mamd-normal-mi.check +++ b/test/files/run/macro-reflective-mamd-normal-mi.check @@ -1 +1,2 @@ -43
\ No newline at end of file +warning: there were 1 deprecation warning(s); re-run with -deprecation for details +43 diff --git a/test/files/run/private-inline.check b/test/files/run/private-inline.check index 3e44989521..e71aec2fcf 100644 --- a/test/files/run/private-inline.check +++ b/test/files/run/private-inline.check @@ -1,7 +1,13 @@ private-inline.scala:24: warning: Could not inline required method wrapper1 because callee contains exception handlers / finally clause, and is invoked with non-empty operand stack. def f1b() = identity(wrapper1(5)) ^ +private-inline.scala:24: warning: At the end of the day, could not inline @inline-marked method wrapper1 + def f1b() = identity(wrapper1(5)) + ^ private-inline.scala:29: warning: Could not inline required method wrapper2 because callee contains exception handlers / finally clause, and is invoked with non-empty operand stack. def f2b() = identity(wrapper2(5)) ^ +private-inline.scala:29: warning: At the end of the day, could not inline @inline-marked method wrapper2 + def f2b() = identity(wrapper2(5)) + ^ 20 diff --git a/test/files/run/repl-power.check b/test/files/run/repl-power.check index d6a0d8c931..c1992e89aa 100644 --- a/test/files/run/repl-power.check +++ b/test/files/run/repl-power.check @@ -11,7 +11,8 @@ scala> :power scala> // guarding against "error: reference to global is ambiguous" scala> global.emptyValDef // "it is imported twice in the same scope by ..." -res0: $r.global.emptyValDef.type = private val _ = _ +warning: there were 1 deprecation warning(s); re-run with -deprecation for details +res0: $r.global.noSelfType.type = private val _ = _ scala> val tp = ArrayClass[scala.util.Random] // magic with tags warning: there were 1 feature warning(s); re-run with -feature for details diff --git a/test/files/run/showraw_mods.check b/test/files/run/showraw_mods.check index 3ec868542d..4d34160422 100644 --- a/test/files/run/showraw_mods.check +++ b/test/files/run/showraw_mods.check @@ -1 +1 @@ -Block(List(ClassDef(Modifiers(ABSTRACT | DEFAULTPARAM/TRAIT), TypeName("C"), List(), Template(List(Ident(TypeName("AnyRef"))), emptyValDef, List(DefDef(Modifiers(), TermName("$init$"), List(), List(List()), TypeTree(), Block(List(), Literal(Constant(())))), ValDef(Modifiers(PRIVATE | LOCAL), TermName("x"), TypeTree(), Literal(Constant(2))), ValDef(Modifiers(MUTABLE), TermName("y"), TypeTree(), Select(This(TypeName("C")), TermName("x"))), ValDef(Modifiers(LAZY), TermName("z"), TypeTree(), Select(This(TypeName("C")), TermName("y"))))))), Literal(Constant(()))) +Block(List(ClassDef(Modifiers(ABSTRACT | DEFAULTPARAM/TRAIT), TypeName("C"), List(), Template(List(Ident(TypeName("AnyRef"))), noSelfType, List(DefDef(Modifiers(), TermName("$init$"), List(), List(List()), TypeTree(), Block(List(), Literal(Constant(())))), ValDef(Modifiers(PRIVATE | LOCAL), TermName("x"), TypeTree(), Literal(Constant(2))), ValDef(Modifiers(MUTABLE), TermName("y"), TypeTree(), Select(This(TypeName("C")), TermName("x"))), ValDef(Modifiers(LAZY), TermName("z"), TypeTree(), Select(This(TypeName("C")), TermName("y"))))))), Literal(Constant(()))) diff --git a/test/files/run/t2106.check b/test/files/run/t2106.check index b14e9d1c41..f8f625ff46 100644 --- a/test/files/run/t2106.check +++ b/test/files/run/t2106.check @@ -1,3 +1,6 @@ t2106.scala:7: warning: Could not inline required method foo because access level required by callee not matched by caller. def main(args: Array[String]): Unit = x.foo ^ +t2106.scala:7: warning: At the end of the day, could not inline @inline-marked method foo + def main(args: Array[String]): Unit = x.foo + ^ diff --git a/test/files/run/t6392b.check b/test/files/run/t6392b.check index 1ccfced1c6..c2cc103373 100644 --- a/test/files/run/t6392b.check +++ b/test/files/run/t6392b.check @@ -1 +1 @@ -ModuleDef(Modifiers(), TermName("C")#MOD, Template(List(Select(Ident(scala#PK), TypeName("AnyRef")#TPE)), emptyValDef, List(DefDef(Modifiers(), nme.CONSTRUCTOR#PCTOR, List(), List(List()), TypeTree(), Block(List(Apply(Select(Super(This(TypeName("C")), tpnme.EMPTY), nme.CONSTRUCTOR#PCTOR), List())), Literal(Constant(()))))))) +ModuleDef(Modifiers(), TermName("C")#MOD, Template(List(Select(Ident(scala#PK), TypeName("AnyRef")#TPE)), noSelfType, List(DefDef(Modifiers(), nme.CONSTRUCTOR#PCTOR, List(), List(List()), TypeTree(), Block(List(Apply(Select(Super(This(TypeName("C")), tpnme.EMPTY), nme.CONSTRUCTOR#PCTOR), List())), Literal(Constant(()))))))) diff --git a/test/files/run/t7331c.check b/test/files/run/t7331c.check index fd3ac1d9ef..b35d831f83 100644 --- a/test/files/run/t7331c.check +++ b/test/files/run/t7331c.check @@ -1,3 +1,3 @@ -ClassDef(Modifiers(), TypeName("C"), List(), Template(List(Select(Ident(scala), TypeName("AnyRef"))), emptyValDef, List(DefDef(Modifiers(), nme.CONSTRUCTOR, List(), List(List()), TypeTree(), Block(List(pendingSuperCall), Literal(Constant(()))))))) +ClassDef(Modifiers(), TypeName("C"), List(), Template(List(Select(Ident(scala), TypeName("AnyRef"))), noSelfType, List(DefDef(Modifiers(), nme.CONSTRUCTOR, List(), List(List()), TypeTree(), Block(List(pendingSuperCall), Literal(Constant(()))))))) source-<toolbox>,line-1,offset=6 NoPosition diff --git a/test/files/run/t7398.scala b/test/files/run/t7398.scala index dd59697b71..493c4dcf40 100644 --- a/test/files/run/t7398.scala +++ b/test/files/run/t7398.scala @@ -3,11 +3,9 @@ import scala.tools.partest._ object Test extends CompilerTest { import global._ - // This way we auto-pass on non-java8 since there's nothing to check - override lazy val units: List[CompilationUnit] = testUnderJavaAtLeast("1.8") { + override lazy val units: List[CompilationUnit] = { + // This test itself does not depend on JDK8. javaCompilationUnits(global)(defaultMethodSource) - } otherwise { - Nil } private def defaultMethodSource = """ diff --git a/test/files/run/t7825.scala b/test/files/run/t7825.scala new file mode 100644 index 0000000000..65ca06fdfc --- /dev/null +++ b/test/files/run/t7825.scala @@ -0,0 +1,34 @@ +import scala.tools.partest._ + +object Test extends CompilerTest { + import global._ + + override lazy val units: List[CompilationUnit] = { + // We can test this on JDK6. + javaCompilationUnits(global)(defaultMethodSource) ++ compilationUnits(global)(scalaExtendsDefault) + } + + private def defaultMethodSource = """ +public interface Iterator<E> { + boolean hasNext(); + E next(); + default void remove() { + throw new UnsupportedOperationException("remove"); + } +} + """ + + private def scalaExtendsDefault = """ +object Test { + object X extends Iterator[String] { + def hasNext = true + def next = "!" + } +} + """ + + // We're only checking we that the Scala compilation unit passes refchecks + // No further checks are needed here. + def check(source: String, unit: global.CompilationUnit): Unit = { + } +} diff --git a/test/files/run/t7876.scala b/test/files/run/t7876.scala new file mode 100644 index 0000000000..aeec8c8cce --- /dev/null +++ b/test/files/run/t7876.scala @@ -0,0 +1,26 @@ +import scala.tools.partest._ + +// Type constructors for FunctionN and TupleN should not be considered as function type / tuple types. +object Test extends DirectTest { + override def extraSettings: String = "-usejavacp" + + def code = "" + + def show() { + val global = newCompiler() + new global.Run() + import global._, definitions._ + val function0TC = FunctionClass(0).typeConstructor + val tuple1TC = TupleClass(1).typeConstructor + FunctionClass.seq.foreach { sym => + val tc = sym.typeConstructor + assert(!isFunctionType(tc), s"$tc") + assert(!isFunctionTypeDirect(tc), s"$tc (direct)") + } + TupleClass.seq.foreach { sym => + val tc = sym.typeConstructor + assert(!isTupleType(tc), s"$sym") + assert(!isTupleTypeDirect(tc), s"$tc (direct)") + } + } +} diff --git a/test/pending/t7629-view-bounds-removal.check b/test/pending/t7629-view-bounds-removal.check new file mode 100644 index 0000000000..dc52105eaf --- /dev/null +++ b/test/pending/t7629-view-bounds-removal.check @@ -0,0 +1,9 @@ +t7629-view-bounds-removal.scala:2: error: View bounds have been removed. Use an implicit parameter instead. +Example: Instead of `def f[A <% Int](a: A)` use `def f[A](a: A)(implicit ev: A => Int)`. + def f[A <% Int](a: A) = null + ^ +t7629-view-bounds-removal.scala:3: error: View bounds have been removed. Use an implicit parameter instead. +Example: Instead of `def f[A <% Int](a: A)` use `def f[A](a: A)(implicit ev: A => Int)`. + def g[C, B <: C, A <% B : Numeric](a: A) = null + ^ +two errors found diff --git a/test/pending/t7629-view-bounds-removal.flags b/test/pending/t7629-view-bounds-removal.flags new file mode 100644 index 0000000000..29f4ede37a --- /dev/null +++ b/test/pending/t7629-view-bounds-removal.flags @@ -0,0 +1 @@ +-Xfuture diff --git a/test/pending/t7629-view-bounds-removal.scala b/test/pending/t7629-view-bounds-removal.scala new file mode 100644 index 0000000000..a6ede1fcc3 --- /dev/null +++ b/test/pending/t7629-view-bounds-removal.scala @@ -0,0 +1,4 @@ +object Test { + def f[A <% Int](a: A) = null + def g[C, B <: C, A <% B : Numeric](a: A) = null +} diff --git a/test/scaladoc/run/SI-4676.scala b/test/scaladoc/run/SI-4676.scala index b83a59a472..99b3c5568a 100644 --- a/test/scaladoc/run/SI-4676.scala +++ b/test/scaladoc/run/SI-4676.scala @@ -21,6 +21,7 @@ object Test extends ScaladocModelTest { // check correct expansion of the use case signature val x = rootPackage._class("SI_4676")._method("x") - assert(x.valueParams(0)(0).resultType.name == "(String, String)", "parameter ss of method x has type (String, String") + val resultType = x.valueParams(0)(0).resultType.name + assert(resultType == "SS", s"parameter ss of method x has type $resultType, expected SS!") } }
\ No newline at end of file diff --git a/test/scaladoc/run/t7876.check b/test/scaladoc/run/t7876.check new file mode 100644 index 0000000000..619c56180b --- /dev/null +++ b/test/scaladoc/run/t7876.check @@ -0,0 +1 @@ +Done. diff --git a/test/scaladoc/run/t7876.scala b/test/scaladoc/run/t7876.scala new file mode 100644 index 0000000000..63c63f8a0c --- /dev/null +++ b/test/scaladoc/run/t7876.scala @@ -0,0 +1,19 @@ +import scala.tools.nsc.doc.model._ +import scala.tools.partest.ScaladocModelTest + +object Test extends ScaladocModelTest { + + override def code = """ + import language.higherKinds + trait T[M[_]] + class C extends T[Function0] + class D extends T[Tuple1] + """ + + def scaladocSettings = "" + + def testModel(rootPackage: Package) = { + import access._ + // did not crash + } +} diff --git a/test/scaladoc/run/t7876b.check b/test/scaladoc/run/t7876b.check new file mode 100644 index 0000000000..21aaf3b295 --- /dev/null +++ b/test/scaladoc/run/t7876b.check @@ -0,0 +1,3 @@ +foo: FInt +foo: TInt +Done. diff --git a/test/scaladoc/run/t7876b.scala b/test/scaladoc/run/t7876b.scala new file mode 100644 index 0000000000..4d5b8c22cf --- /dev/null +++ b/test/scaladoc/run/t7876b.scala @@ -0,0 +1,24 @@ +import scala.tools.nsc.doc.model._ +import scala.tools.partest.ScaladocModelTest + +// Don't dealias just to print a Function or Tuple type. +object Test extends ScaladocModelTest { + + override def code = """ + class Test { + type FInt = Function0[Int] + type TInt = Tuple1[Int] + def foo: FInt + def bar: TInt + } + """ + + def scaladocSettings = "" + + def testModel(rootPackage: Package) = { + import access._ + List("foo", "bar").foreach { name => + println("foo: " + rootPackage._class("Test")._method(name).resultType.name) + } + } +} |