diff options
37 files changed, 347 insertions, 176 deletions
@@ -134,7 +134,7 @@ codebase and re-compiles too many files, resulting in long build times (check [sbt#1104](https://github.com/sbt/sbt/issues/1104) for progress on that front). In the meantime you can: - Enable "ant mode" in which sbt only re-compiles source files that were modified. - Create a file `local.sbt` containing the line `(incOptions in ThisBuild) := (incOptions in ThisBuild).value.withNameHashing(false).withAntStyle(true)`. + Create a file `local.sbt` containing the line `antStyle := true`. Add an entry `local.sbt` to your `~/.gitignore`. - Use IntelliJ IDEA for incremental compiles (see [IDE Setup](#ide-setup) below) - its incremental compiler is a bit less conservative, but usually correct. diff --git a/src/compiler/scala/tools/nsc/Reporting.scala b/src/compiler/scala/tools/nsc/Reporting.scala index 01c583bea3..5635e678de 100644 --- a/src/compiler/scala/tools/nsc/Reporting.scala +++ b/src/compiler/scala/tools/nsc/Reporting.scala @@ -43,19 +43,19 @@ trait Reporting extends scala.reflect.internal.Reporting { self: ast.Positions w else sinceAndAmount += ((since, 1)) } val deprecationSummary = sinceAndAmount.size > 1 - sinceAndAmount.foreach { case (since, amount) => - val numWarnings = amount + sinceAndAmount.foreach { case (since, numWarnings) => val warningsSince = if (since.nonEmpty) s" (since $since)" else "" val warningVerb = if (numWarnings == 1) "was" else "were" val warningCount = countElementsAsString(numWarnings, s"$what warning") - val rerun = if (deprecationSummary) "" else s"; re-run with ${setting.name} for details" - reporter.warning(NoPosition, s"there $warningVerb $warningCount$warningsSince$rerun") + val rerun = if (deprecationSummary) "" else reporter.rerunWithDetails(setting, setting.name) + reporter.warning(NoPosition, s"there ${warningVerb} ${warningCount}${warningsSince}${rerun}") } if (deprecationSummary) { val numWarnings = warnings.size val warningVerb = if (numWarnings == 1) "was" else "were" val warningCount = countElementsAsString(numWarnings, s"$what warning") - reporter.warning(NoPosition, s"there $warningVerb $warningCount in total; re-run with ${setting.name} for details") + val rerun = reporter.rerunWithDetails(setting, setting.name) + reporter.warning(NoPosition, s"there ${warningVerb} ${warningCount} in total${rerun}") } } } diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index db8e203c1c..6678b565d5 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -343,7 +343,18 @@ abstract class Erasure extends AddInterfaces case MethodType(params, restpe) => val buf = new StringBuffer("(") - params foreach (p => buf append jsig(p.tpe)) + params foreach (p => { + val tp = p.attachments.get[TypeParamVarargsAttachment] match { + case Some(att) => + // For @varargs forwarders, a T* parameter has type Array[Object] in the forwarder + // instead of Array[T], as the latter would erase to Object (instead of Array[Object]). + // To make the generic signature correct ("[T", not "[Object"), an attachment on the + // parameter symbol stores the type T that was replaced by Object. + buf.append("["); att.typeParamRef + case _ => p.tpe + } + buf append jsig(tp) + }) buf append ")" buf append (if (restpe.typeSymbol == UnitClass || sym0.isConstructor) VOID_TAG.toString else jsig(restpe)) buf.toString @@ -1227,4 +1238,5 @@ abstract class Erasure extends AddInterfaces } private class TypeRefAttachment(val tpe: TypeRef) + class TypeParamVarargsAttachment(val typeParamRef: Type) } diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index 374e8430d8..3047b8f89a 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -744,72 +744,88 @@ abstract class UnCurry extends InfoTransform if (!dd.symbol.hasAnnotation(VarargsClass) || !enteringUncurry(mexists(dd.symbol.paramss)(sym => definitions.isRepeatedParamType(sym.tpe)))) return flatdd - def toArrayType(tp: Type): Type = { - val arg = elementType(SeqClass, tp) - // to prevent generation of an `Object` parameter from `Array[T]` parameter later - // as this would crash the Java compiler which expects an `Object[]` array for varargs - // e.g. def foo[T](a: Int, b: T*) - // becomes def foo[T](a: Int, b: Array[Object]) - // instead of def foo[T](a: Int, b: Array[T]) ===> def foo[T](a: Int, b: Object) - arrayType( - if (arg.typeSymbol.isTypeParameterOrSkolem) ObjectTpe - else arg - ) - } + val forwSym = currentClass.newMethod(dd.name.toTermName, dd.pos, VARARGS | SYNTHETIC | flatdd.symbol.flags) - val theTyper = typer.atOwner(dd, currentClass) - val flatparams = flatdd.symbol.paramss.head val isRepeated = enteringUncurry(dd.symbol.info.paramss.flatten.map(sym => definitions.isRepeatedParamType(sym.tpe))) - // create the type - val forwformals = map2(flatparams, isRepeated) { - case (p, true) => toArrayType(p.tpe) - case (p, false)=> p.tpe - } - val forwresult = dd.symbol.tpe_*.finalResultType - val forwformsyms = map2(forwformals, flatparams)((tp, oldparam) => - currentClass.newValueParameter(oldparam.name.toTermName, oldparam.pos).setInfo(tp) - ) - def mono = MethodType(forwformsyms, forwresult) - val forwtype = dd.symbol.tpe match { - case MethodType(_, _) => mono - case PolyType(tps, _) => PolyType(tps, mono) - } + val oldPs = flatdd.symbol.paramss.head + + // see comment in method toArrayType below + val arrayTypesMappedToObject = mutable.Map.empty[Symbol, Type] - // create the symbol - val forwsym = currentClass.newMethod(dd.name.toTermName, dd.pos, VARARGS | SYNTHETIC | flatdd.symbol.flags) setInfo forwtype - def forwParams = forwsym.info.paramss.flatten - - // create the tree - val forwtree = theTyper.typedPos(dd.pos) { - val locals = map3(forwParams, flatparams, isRepeated) { - case (_, fp, false) => null - case (argsym, fp, true) => - Block(Nil, - gen.mkCast( - gen.mkWrapArray(Ident(argsym), elementType(ArrayClass, argsym.tpe)), - seqType(elementType(SeqClass, fp.tpe)) - ) - ) + val forwTpe = { + val (oldTps, tps) = dd.symbol.tpe match { + case PolyType(oldTps, _) => + val newTps = oldTps.map(_.cloneSymbol(forwSym)) + (oldTps, newTps) + + case _ => (Nil, Nil) } - val seqargs = map2(locals, forwParams) { - case (null, argsym) => Ident(argsym) - case (l, _) => l + + def toArrayType(tp: Type, newParam: Symbol): Type = { + val arg = elementType(SeqClass, tp) + val elem = if (arg.typeSymbol.isTypeParameterOrSkolem && !(arg <:< AnyRefTpe)) { + // To prevent generation of an `Object` parameter from `Array[T]` parameter later + // as this would crash the Java compiler which expects an `Object[]` array for varargs + // e.g. def foo[T](a: Int, b: T*) + // becomes def foo[T](a: Int, b: Array[Object]) + // instead of def foo[T](a: Int, b: Array[T]) ===> def foo[T](a: Int, b: Object) + // + // In order for the forwarder method to type check we need to insert a cast: + // def foo'[T'](a: Int, b: Array[Object]) = foo[T'](a, wrapRefArray(b).asInstanceOf[Seq[T']]) + // The target element type for that cast (T') is stored in the `arrayTypesMappedToObject` map. + val originalArg = arg.substSym(oldTps, tps) + arrayTypesMappedToObject(newParam) = originalArg + // Store the type parameter that was replaced by Object to emit the correct generic signature + newParam.updateAttachment(new erasure.TypeParamVarargsAttachment(originalArg)) + ObjectTpe + } else + arg + arrayType(elem) } - val end = if (forwsym.isConstructor) List(UNIT) else Nil - DefDef(forwsym, BLOCK(Apply(gen.mkAttributedRef(flatdd.symbol), seqargs) :: end : _*)) + val ps = map2(oldPs, isRepeated)((oldParam, isRep) => { + val newParam = oldParam.cloneSymbol(forwSym) + val tp = if (isRep) toArrayType(oldParam.tpe, newParam) else oldParam.tpe + newParam.setInfo(tp) + }) + + val resTp = dd.symbol.tpe_*.finalResultType.substSym(oldPs, ps) + val mt = MethodType(ps, resTp) + val r = if (tps.isEmpty) mt else PolyType(tps, mt) + r.substSym(oldTps, tps) + } + + forwSym.setInfo(forwTpe) + val newPs = forwTpe.params + + val theTyper = typer.atOwner(dd, currentClass) + val forwTree = theTyper.typedPos(dd.pos) { + val seqArgs = map3(newPs, oldPs, isRepeated)((param, oldParam, isRep) => { + if (!isRep) Ident(param) + else { + val parTp = elementType(ArrayClass, param.tpe) + val wrap = gen.mkWrapArray(Ident(param), parTp) + arrayTypesMappedToObject.get(param) match { + case Some(tp) => gen.mkCast(wrap, seqType(tp)) + case _ => wrap + } + } + }) + + val forwCall = Apply(gen.mkAttributedRef(flatdd.symbol), seqArgs) + DefDef(forwSym, if (forwSym.isConstructor) Block(List(forwCall), UNIT) else forwCall) } // check if the method with that name and those arguments already exists in the template - currentClass.info.member(forwsym.name).alternatives.find(s => s != forwsym && s.tpe.matches(forwsym.tpe)) match { + currentClass.info.member(forwSym.name).alternatives.find(s => s != forwSym && s.tpe.matches(forwSym.tpe)) match { case Some(s) => reporter.error(dd.symbol.pos, "A method with a varargs annotation produces a forwarder method with the same signature " + s.tpe + " as an existing method.") case None => // enter symbol into scope - currentClass.info.decls enter forwsym - addNewMember(forwtree) + currentClass.info.decls enter forwSym + addNewMember(forwTree) } flatdd diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index ba104fb7a6..91cff54bc7 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -872,16 +872,32 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper case Block(_, tree1) => tree1.symbol case _ => tree.symbol } - def shouldEtaExpandToSam: Boolean = { - // SI-9536 don't adapt parameterless method types to a to SAM's, fall through to empty application - // instead for backwards compatiblity with 2.11. See comments of that ticket and SI-7187 - // for analogous trouble with non-SAM eta expansion. Suggestions there are: a) deprecate eta expansion to Function0, - // or b) switch the order of eta-expansion and empty application in this adaptation. - !mt.params.isEmpty && samOf(pt).exists - } - if (!meth.isConstructor && (isFunctionType(pt) || shouldEtaExpandToSam)) { // (4.2) + + def cantAdapt = + if (context.implicitsEnabled) MissingArgsForMethodTpeError(tree, meth) + else setError(tree) + + // constructors do not eta-expand + if (meth.isConstructor) cantAdapt + // (4.2) eta-expand method value when function or sam type is expected + else if (isFunctionType(pt) || (!mt.params.isEmpty && samOf(pt).exists)) { + // SI-9536 `!mt.params.isEmpty &&`: for backwards compatiblity with 2.11, + // we don't adapt a zero-arg method value to a SAM + // In 2.13, we won't do any eta-expansion for zero-arg method values, but we should deprecate first + debuglog(s"eta-expanding $tree: ${tree.tpe} to $pt") checkParamsConvertible(tree, tree.tpe) + + // SI-7187 eta-expansion of zero-arg method value is deprecated, switch order of (4.3) and (4.2) in 2.13 + def isExplicitEtaExpansion = original match { + case Typed(_, Function(Nil, EmptyTree)) => true // tree shape for `f _` + case _ => false + } + if (mt.params.isEmpty && !isExplicitEtaExpansion) { + currentRun.reporting.deprecationWarning(tree.pos, NoSymbol, + s"Eta-expansion of zero-argument method values is deprecated. Did you intend to write ${Apply(tree, Nil)}?", "2.12.0") + } + val tree0 = etaExpand(context.unit, tree, this) // #2624: need to infer type arguments for eta expansion of a polymorphic method @@ -895,12 +911,9 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper else typed(tree0, mode, pt) } - else if (!meth.isConstructor && mt.params.isEmpty) // (4.3) - adapt(typed(Apply(tree, Nil) setPos tree.pos), mode, pt, original) - else if (context.implicitsEnabled) - MissingArgsForMethodTpeError(tree, meth) - else - setError(tree) + // (4.3) apply to empty argument list -- TODO 2.13: move this one case up to avoid eta-expanding at arity 0 + else if (mt.params.isEmpty) adapt(typed(Apply(tree, Nil) setPos tree.pos), mode, pt, original) + else cantAdapt } def adaptType(): Tree = { @@ -4398,11 +4411,11 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper * (2) If $e$ is a parameterless method or call-by-name parameter of type `=>$T$`, `$e$ _` represents * the function of type `() => $T$`, which evaluates $e$ when it is applied to the empty parameterlist `()`. */ - def typedEta(methodValue: Tree): Tree = methodValue.tpe match { + def typedEta(methodValue: Tree, original: Tree): Tree = methodValue.tpe match { case tp@(MethodType(_, _) | PolyType(_, MethodType(_, _))) => // (1) val formals = tp.params if (isFunctionType(pt) || samMatchesFunctionBasedOnArity(samOf(pt), formals)) methodValue - else adapt(methodValue, mode, checkArity(methodValue)(functionTypeWildcard(formals.length))) + else adapt(methodValue, mode, checkArity(methodValue)(functionTypeWildcard(formals.length)), original) case TypeRef(_, ByNameParamClass, _) | NullaryMethodType(_) => // (2) val pos = methodValue.pos @@ -5106,7 +5119,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper case Typed(expr, Function(Nil, EmptyTree)) => typed1(suppressMacroExpansion(expr), mode, pt) match { case macroDef if treeInfo.isMacroApplication(macroDef) => MacroEtaError(macroDef) - case methodValue => typedEta(checkDead(methodValue)) + case methodValue => typedEta(checkDead(methodValue), tree) } case Typed(expr, tpt) => val tpt1 = typedType(tpt, mode) // type the ascribed type first diff --git a/src/reflect/scala/reflect/internal/Reporting.scala b/src/reflect/scala/reflect/internal/Reporting.scala index 27fda9a7d4..c1f0140479 100644 --- a/src/reflect/scala/reflect/internal/Reporting.scala +++ b/src/reflect/scala/reflect/internal/Reporting.scala @@ -7,6 +7,8 @@ package scala package reflect package internal +import settings.MutableSettings + /** Provides delegates to the reporter doing the actual work. * All forwarding methods should be marked final, * but some subclasses out of our reach still override them. @@ -105,6 +107,13 @@ abstract class Reporter { /** Finish reporting: print summaries, release resources. */ def finish(): Unit = () + + /** After reporting, offer advice on getting more details. */ + def rerunWithDetails(setting: MutableSettings#Setting, name: String): String = + setting.value match { + case b: Boolean if !b => s"; re-run with ${name} for details" + case _ => s"; re-run enabling ${name} for details, or try -help" + } } // TODO: move into superclass once partest cuts tie on Severity diff --git a/src/repl/scala/tools/nsc/MainGenericRunner.scala b/src/repl/scala/tools/nsc/MainGenericRunner.scala index 747b684293..a09e797e07 100644 --- a/src/repl/scala/tools/nsc/MainGenericRunner.scala +++ b/src/repl/scala/tools/nsc/MainGenericRunner.scala @@ -71,6 +71,11 @@ class MainGenericRunner { Right(false) case _ => // We start the repl when no arguments are given. + // If user is agnostic about both -feature and -deprecation, turn them on. + if (settings.deprecation.isDefault && settings.feature.isDefault) { + settings.deprecation.value = true + settings.feature.value = true + } Right(new interpreter.ILoop process settings) } diff --git a/src/repl/scala/tools/nsc/interpreter/ReplReporter.scala b/src/repl/scala/tools/nsc/interpreter/ReplReporter.scala index e6f5a4089e..3a0b69f41e 100644 --- a/src/repl/scala/tools/nsc/interpreter/ReplReporter.scala +++ b/src/repl/scala/tools/nsc/interpreter/ReplReporter.scala @@ -68,4 +68,7 @@ class ReplReporter(intp: IMain) extends ConsoleReporter(intp.settings, Console.i else super.displayPrompt() } + override def rerunWithDetails(setting: reflect.internal.settings.MutableSettings#Setting, name: String) = + s"; for details, enable `:setting $name' or `:replay $name'" + } diff --git a/src/scaladoc/scala/tools/nsc/doc/html/page/Entity.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/Entity.scala index 9dd2c2184d..54bf42bbd5 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/page/Entity.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/page/Entity.scala @@ -154,19 +154,7 @@ trait EntityPage extends HtmlPage { def search = <div id="search"> - <span id="doc-title"> - {universe.settings.doctitle.value} - <span id="doc-version"> - { - val version = universe.settings.docversion.value - - if (version.length > "XX.XX.XX-XXX".length) { - docletReporter.summaryWarning(s"doc-version ($version) was too long to be displayed in the webview, and will be left out. The max length is: XX.XX.XX-XXX") - "" - } else version - } - </span> - </span> + <span id="doc-title">{universe.settings.doctitle.value}<span id="doc-version">{universe.settings.docversion.value}</span></span> <span class="close-results"><span class="left"><</span> Back</span> <div id="textfilter"> <span class="input"> diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.css b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.css index d805ccc1ac..b153113e60 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.css +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.css @@ -167,6 +167,15 @@ textarea, input { outline: none; } color: #c2c2c2; font-weight: 100; font-size: 0.72em; + display: inline-block; + width: 12ex; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} + +#search > span#doc-title > span#doc-version:hover { + overflow: visible; } #search > span.toggle-sidebar:hover { diff --git a/test/files/jvm/interpreter.check b/test/files/jvm/interpreter.check index 9a2162a906..72d8d39fd0 100644 --- a/test/files/jvm/interpreter.check +++ b/test/files/jvm/interpreter.check @@ -93,7 +93,7 @@ scala> case class Bar(n: Int) defined class Bar scala> implicit def foo2bar(foo: Foo) = Bar(foo.n) -warning: there was one feature warning; re-run with -feature for details +warning: there was one feature warning; for details, enable `:setting -feature' or `:replay -feature' foo2bar: (foo: Foo)Bar scala> val bar: Bar = Foo(3) @@ -267,7 +267,7 @@ scala> xs map (x => x) res6: Array[_] = Array(1, 2) scala> xs map (x => (x, x)) -warning: there was one feature warning; re-run with -feature for details +warning: there was one feature warning; for details, enable `:setting -feature' or `:replay -feature' res7: Array[(_$1, _$1)] forSome { type _$1 } = Array((1,1), (2,2)) scala> diff --git a/test/files/jvm/t8786-sig.scala b/test/files/jvm/t8786-sig.scala new file mode 100644 index 0000000000..0745b650e6 --- /dev/null +++ b/test/files/jvm/t8786-sig.scala @@ -0,0 +1,116 @@ +class A[U] { + @annotation.varargs def m1[T] (a: T*): T = a.head + @annotation.varargs def m2[T <: AnyRef](a: T*): T = a.head + @annotation.varargs def m3[T <: AnyVal](a: T*): T = a.head + @annotation.varargs def m4[T <: Int] (a: T*): T = a.head + @annotation.varargs def m5[T <: String](a: T*): T = a.head + @annotation.varargs def m6 (a: String*): String = a.head + @annotation.varargs def m7 (a: Int*): Int = a.head + @annotation.varargs def m8 (a: U*): U = a.head + + def n1[T] (a: Array[T]): T = a(0) + def n2[T <: AnyRef](a: Array[T]): T = a(0) + def n3[T <: AnyVal](a: Array[T]): T = a(0) + def n4[T <: Int] (a: Array[T]): T = a(0) + def n5[T <: String](a: Array[T]): T = a(0) + def n6 (a: Array[String]): String = a(0) + def n7 (a: Array[Int]): Int = a(0) + def n8 (a: Array[U]): U = a(0) +} + +object Test extends App { + val a = classOf[A[_]] + + def sig (method: String, tp: Class[_]) = a.getDeclaredMethod(method, tp).toString + def genSig(method: String, tp: Class[_]) = a.getDeclaredMethod(method, tp).toGenericString + def bound (method: String, tp: Class[_]) = { + val m = a.getDeclaredMethod(method, tp) + m.getGenericParameterTypes.apply(0) match { + case _: Class[_] => "" + case gat: java.lang.reflect.GenericArrayType => + val compTp = gat.getGenericComponentType.asInstanceOf[java.lang.reflect.TypeVariable[_]] + compTp.getBounds.apply(0).toString + } + } + + def check(a: String, b: String) = { + assert(a == b, s"found: $a\nexpected: $b") + } + + val sq = classOf[Seq[_]] + val ob = classOf[Object] + val ao = classOf[Array[Object]] + val as = classOf[Array[String]] + val ai = classOf[Array[Int]] + + check(sig("m1", sq) , "public java.lang.Object A.m1(scala.collection.Seq)") + check(sig("m2", sq) , "public java.lang.Object A.m2(scala.collection.Seq)") + check(sig("m3", sq) , "public java.lang.Object A.m3(scala.collection.Seq)") + check(sig("m4", sq) , "public int A.m4(scala.collection.Seq)") + check(sig("m5", sq) , "public java.lang.String A.m5(scala.collection.Seq)") + check(sig("m6", sq) , "public java.lang.String A.m6(scala.collection.Seq)") + check(sig("m7", sq) , "public int A.m7(scala.collection.Seq)") + check(sig("m8", sq) , "public java.lang.Object A.m8(scala.collection.Seq)") + + check(genSig("m1", sq), "public <T> T A.m1(scala.collection.Seq<T>)") + check(genSig("m2", sq), "public <T> T A.m2(scala.collection.Seq<T>)") + check(genSig("m3", sq), "public <T> T A.m3(scala.collection.Seq<T>)") + // TODO: the signature for is wrong for T <: Int, SI-9846. The signature should be + // `public int A.m4(scala.collection.Seq<java.lang.Object>)`. This is testing the status quo. + check(genSig("m4", sq), "public <T> T A.m4(scala.collection.Seq<T>)") + check(genSig("m5", sq), "public <T> T A.m5(scala.collection.Seq<T>)") + check(genSig("m6", sq), "public java.lang.String A.m6(scala.collection.Seq<java.lang.String>)") + check(genSig("m7", sq), "public int A.m7(scala.collection.Seq<java.lang.Object>)") + check(genSig("m8", sq), "public U A.m8(scala.collection.Seq<U>)") + + + // varargs forwarder + + check(sig("m1", ao) , "public java.lang.Object A.m1(java.lang.Object[])") + check(sig("m2", ao) , "public java.lang.Object A.m2(java.lang.Object[])") + check(sig("m3", ao) , "public java.lang.Object A.m3(java.lang.Object[])") + check(sig("m4", ao) , "public int A.m4(java.lang.Object[])") + check(sig("m5", as) , "public java.lang.String A.m5(java.lang.String[])") + check(sig("m6", as) , "public java.lang.String A.m6(java.lang.String[])") + check(sig("m7", ai) , "public int A.m7(int[])") + check(sig("m8", ao) , "public java.lang.Object A.m8(java.lang.Object[])") + + check(genSig("m1", ao), "public <T> T A.m1(T...)") + check(genSig("m2", ao), "public <T> T A.m2(T...)") + check(genSig("m3", ao), "public <T> T A.m3(T...)") + // testing status quo: signature is wrong for T <: Int, SI-9846 + check(genSig("m4", ao), "public <T> T A.m4(T...)") + check(genSig("m5", as), "public <T> T A.m5(T...)") + check(genSig("m6", as), "public java.lang.String A.m6(java.lang.String...)") + check(genSig("m7", ai), "public int A.m7(int...)") + check(genSig("m8", ao), "public U A.m8(U...)") + + check(bound("m1", ao) , "class java.lang.Object") + check(bound("m2", ao) , "class java.lang.Object") + check(bound("m3", ao) , "class java.lang.Object") + check(bound("m4", ao) , "class java.lang.Object") + check(bound("m5", as) , "class java.lang.String") + check(bound("m6", as) , "") + check(bound("m7", ai) , "") + check(bound("m8", ao) , "class java.lang.Object") + + + check(sig("n1", ob) , "public java.lang.Object A.n1(java.lang.Object)") + check(sig("n2", ao) , "public java.lang.Object A.n2(java.lang.Object[])") + check(sig("n3", ob) , "public java.lang.Object A.n3(java.lang.Object)") + check(sig("n4", ob) , "public int A.n4(java.lang.Object)") + check(sig("n5", as) , "public java.lang.String A.n5(java.lang.String[])") + check(sig("n6", as) , "public java.lang.String A.n6(java.lang.String[])") + check(sig("n7", ai) , "public int A.n7(int[])") + check(sig("n8", ob) , "public java.lang.Object A.n8(java.lang.Object)") + + check(genSig("n1", ob), "public <T> T A.n1(java.lang.Object)") + check(genSig("n2", ao), "public <T> T A.n2(T[])") + check(genSig("n3", ob), "public <T> T A.n3(java.lang.Object)") + // testing status quo: signature is wrong for T <: Int, SI-9846 + check(genSig("n4", ob), "public <T> T A.n4(java.lang.Object)") + check(genSig("n5", as), "public <T> T A.n5(T[])") + check(genSig("n6", as), "public java.lang.String A.n6(java.lang.String[])") + check(genSig("n7", ai), "public int A.n7(int[])") + check(genSig("n8", ob), "public U A.n8(java.lang.Object)") +} diff --git a/test/files/jvm/t8786/A_1.scala b/test/files/jvm/t8786/A_1.scala new file mode 100644 index 0000000000..13c0ad191d --- /dev/null +++ b/test/files/jvm/t8786/A_1.scala @@ -0,0 +1,3 @@ +class A { + @annotation.varargs def foo[T](a: Int, b: T*): T = b.head +} diff --git a/test/files/jvm/t8786/B_2.java b/test/files/jvm/t8786/B_2.java new file mode 100644 index 0000000000..dc155a290f --- /dev/null +++ b/test/files/jvm/t8786/B_2.java @@ -0,0 +1,22 @@ +public class B_2 { + private static int res = 0; + + public static void m(char a[]) { res += 10; } + public static void m(String a) { res += 100; } + public static void m(Object a) { res += 1000; } + + public static <T> T foo(int a, T... b) { return b[0]; } + + public static <T> T bar(T b[]) { return b[0]; } + + public static void main(String[] args) { + m(foo(15, "a", "b", "c")); + if (res != 100) + throw new Error("bad: "+ res); + + A a = new A(); + m(a.foo(16, "a", "b", "c")); + if (res != 200) + throw new Error("bad: " + res); + } +} diff --git a/test/files/jvm/t8786/Test_2.scala b/test/files/jvm/t8786/Test_2.scala new file mode 100644 index 0000000000..76ccb4c3ed --- /dev/null +++ b/test/files/jvm/t8786/Test_2.scala @@ -0,0 +1,3 @@ +object Test extends App { + B_2.main(null) +} diff --git a/test/files/jvm/varargs/JavaClass.java b/test/files/jvm/varargs/JavaClass.java index 6928ee5adc..0cc3587c5e 100644 --- a/test/files/jvm/varargs/JavaClass.java +++ b/test/files/jvm/varargs/JavaClass.java @@ -1,16 +1,12 @@ - - - public class JavaClass { - public static <T> void varargz(int i, T... v) { - } - - public static void callSomeAnnotations() { - VaClass va = new VaClass(); - va.vs(4, "", "", ""); - va.vi(1, 2, 3, 4); - varargz(5, 1.0, 2.0, 3.0); - va.vt(16, "", "", ""); - System.out.println(va.vt1(16, "a", "b", "c")); - } -}
\ No newline at end of file + public static <T> void varargz(int i, T... v) { } + + public static void callSomeAnnotations() { + VaClass va = new VaClass(); + va.vs(4, "", "", ""); + va.vi(1, 2, 3, 4); + varargz(5, 1.0, 2.0, 3.0); + va.vt(16, "", "", ""); + System.out.println(va.vt1(16, "a", "b", "c")); + } +} diff --git a/test/files/jvm/varargs/VaClass.scala b/test/files/jvm/varargs/VaClass.scala index d83e63ace1..ee8c288a16 100644 --- a/test/files/jvm/varargs/VaClass.scala +++ b/test/files/jvm/varargs/VaClass.scala @@ -1,15 +1,8 @@ - - import annotation.varargs - - class VaClass { - @varargs def vs(a: Int, b: String*) = println(a + b.length) @varargs def vi(a: Int, b: Int*) = println(a + b.sum) @varargs def vt[T](a: Int, b: T*) = println(a + b.length) - - // TODO remove type bound after fixing SI-8786, see also https://github.com/scala/scala/pull/3961 - @varargs def vt1[T <: String](a: Int, b: T*): T = b.head + @varargs def vt1[T](a: Int, b: T*): T = b.head } diff --git a/test/files/jvm/varargs/varargs.scala b/test/files/jvm/varargs/varargs.scala index 6d2e707bdf..b09818f46f 100644 --- a/test/files/jvm/varargs/varargs.scala +++ b/test/files/jvm/varargs/varargs.scala @@ -1,21 +1,5 @@ - - - - - - object Test { def main(args: Array[String]) { JavaClass.callSomeAnnotations } } - - - - - - - - - - diff --git a/test/files/neg/t7187.check b/test/files/neg/t7187.check new file mode 100644 index 0000000000..a30803c746 --- /dev/null +++ b/test/files/neg/t7187.check @@ -0,0 +1,6 @@ +t7187.scala:3: warning: Eta-expansion of zero-argument method values is deprecated. Did you intend to write EtaExpandZeroArg.this.foo()? + val f: () => Any = foo + ^ +error: No warnings can be incurred under -Xfatal-warnings. +one warning found +one error found diff --git a/test/files/neg/t7187.flags b/test/files/neg/t7187.flags new file mode 100644 index 0000000000..c6bfaf1f64 --- /dev/null +++ b/test/files/neg/t7187.flags @@ -0,0 +1 @@ +-deprecation -Xfatal-warnings diff --git a/test/files/neg/t7187.scala b/test/files/neg/t7187.scala new file mode 100644 index 0000000000..45d33f06af --- /dev/null +++ b/test/files/neg/t7187.scala @@ -0,0 +1,6 @@ +class EtaExpandZeroArg { + def foo(): () => String = () => "" + val f: () => Any = foo + + // f() would evaluate to <function0> instead of "" +} diff --git a/test/files/pos/t9178.flags b/test/files/pos/t9178.flags deleted file mode 100644 index 7de3c0f3ee..0000000000 --- a/test/files/pos/t9178.flags +++ /dev/null @@ -1 +0,0 @@ --Xfatal-warnings -deprecation diff --git a/test/files/pos/t9178.scala b/test/files/pos/t9178.scala deleted file mode 100644 index f2cf20a778..0000000000 --- a/test/files/pos/t9178.scala +++ /dev/null @@ -1,13 +0,0 @@ -// eta expansion to Function0 is problematic (as shown here). -// Perhaps we should we deprecate it? See discussion in the comments of -// on SI-9178. -// -// This test encodes the status quo: no deprecation. -object Test { - def foo(): () => String = () => "" - val f: () => Any = foo - - def main(args: Array[String]): Unit = { - println(f()) // <function0> - } -} diff --git a/test/files/run/Course-2002-08.scala b/test/files/run/Course-2002-08.scala index 5e21edaba3..1d0e02262d 100644 --- a/test/files/run/Course-2002-08.scala +++ b/test/files/run/Course-2002-08.scala @@ -205,7 +205,7 @@ object M5 { val inputSig = input.getSignal; afterDelay(InverterDelay) {() => output.setSignal(!inputSig) }; } - input addAction invertAction + input addAction invertAction _ } def andGate(a1: Wire, a2: Wire, output: Wire): Unit = { @@ -214,8 +214,8 @@ object M5 { val a2Sig = a2.getSignal; afterDelay(AndGateDelay) {() => output.setSignal(a1Sig & a2Sig) }; } - a1 addAction andAction; - a2 addAction andAction; + a1 addAction andAction _ + a2 addAction andAction _ } def orGate(o1: Wire, o2: Wire, output: Wire): Unit = { @@ -224,8 +224,8 @@ object M5 { val o2Sig = o2.getSignal; afterDelay(OrGateDelay) {() => output.setSignal(o1Sig | o2Sig) }; } - o1 addAction orAction; - o2 addAction orAction; + o1 addAction orAction _ + o2 addAction orAction _ } def probe(name: String, wire: Wire): Unit = { @@ -479,7 +479,7 @@ abstract class BasicCircuitSimulator() extends Simulator() { val inputSig = input.getSignal; afterDelay(InverterDelay) {() => output.setSignal(!inputSig) }; } - input addAction invertAction + input addAction invertAction _ } def andGate(a1: Wire, a2: Wire, output: Wire) = { @@ -488,8 +488,8 @@ abstract class BasicCircuitSimulator() extends Simulator() { val a2Sig = a2.getSignal; afterDelay(AndGateDelay) {() => output.setSignal(a1Sig & a2Sig) }; } - a1 addAction andAction; - a2 addAction andAction + a1 addAction andAction _ + a2 addAction andAction _ } def orGate(a1: Wire, a2: Wire, output: Wire) = { @@ -498,8 +498,8 @@ abstract class BasicCircuitSimulator() extends Simulator() { val a2Sig = a2.getSignal; afterDelay(OrGateDelay) {() => output.setSignal(a1Sig | a2Sig) }; } - a1 addAction orAction; - a2 addAction orAction + a1 addAction orAction _ + a2 addAction orAction _ } def orGate2(a1: Wire, a2: Wire, output: Wire) = { diff --git a/test/files/run/constrained-types.check b/test/files/run/constrained-types.check index 5444cf2088..4acd9d16ae 100644 --- a/test/files/run/constrained-types.check +++ b/test/files/run/constrained-types.check @@ -69,11 +69,11 @@ scala> var four = "four" four: String = four scala> val four2 = m(four) // should have an existential bound -warning: there was one feature warning; re-run with -feature for details +warning: there was one feature warning; for details, enable `:setting -feature' or `:replay -feature' four2: String @Annot(x) forSome { val x: String } = four scala> val four3 = four2 // should have the same type as four2 -warning: there was one feature warning; re-run with -feature for details +warning: there was one feature warning; for details, enable `:setting -feature' or `:replay -feature' four3: String @Annot(x) forSome { val x: String } = four scala> val stuff = m("stuff") // should not crash @@ -96,7 +96,7 @@ scala> def m = { val y : String @Annot(x) = x y } // x should not escape the local scope with a narrow type -warning: there was one feature warning; re-run with -feature for details +warning: there was one feature warning; for details, enable `:setting -feature' or `:replay -feature' m: String @Annot(x) forSome { val x: String } scala> @@ -110,7 +110,7 @@ scala> def n(y: String) = { } m("stuff".stripMargin) } // x should be existentially bound -warning: there was one feature warning; re-run with -feature for details +warning: there was one feature warning; for details, enable `:setting -feature' or `:replay -feature' n: (y: String)String @Annot(x) forSome { val x: String } scala> diff --git a/test/files/run/iterator-from.scala b/test/files/run/iterator-from.scala index e7ba1aeb28..01006ffc21 100644 --- a/test/files/run/iterator-from.scala +++ b/test/files/run/iterator-from.scala @@ -1,5 +1,5 @@ /* This file tests iteratorFrom, keysIteratorFrom, and valueIteratorFrom on various sorted sets and maps - * filter: inliner warnings; re-run with + * filter: inliner warnings */ import scala.util.{Random => R} diff --git a/test/files/run/reflection-magicsymbols-repl.check b/test/files/run/reflection-magicsymbols-repl.check index dd26c08349..a33f41012e 100644 --- a/test/files/run/reflection-magicsymbols-repl.check +++ b/test/files/run/reflection-magicsymbols-repl.check @@ -19,7 +19,7 @@ scala> def test(n: Int): Unit = { val x = sig.asInstanceOf[MethodType].params.head println(x.info) } -warning: there was one feature warning; re-run with -feature for details +warning: there was one feature warning; for details, enable `:setting -feature' or `:replay -feature' test: (n: Int)Unit scala> for (i <- 1 to 8) test(i) diff --git a/test/files/run/repl-no-imports-no-predef-power.check b/test/files/run/repl-no-imports-no-predef-power.check index a76db3dbc2..08f614eb60 100644 --- a/test/files/run/repl-no-imports-no-predef-power.check +++ b/test/files/run/repl-no-imports-no-predef-power.check @@ -7,11 +7,11 @@ Try :help or completions for vals._ and power._ scala> // guarding against "error: reference to global is ambiguous" scala> global.emptyValDef // "it is imported twice in the same scope by ..." -warning: there was one deprecation warning (since 2.11.0); re-run with -deprecation for details +warning: there was one deprecation warning (since 2.11.0); for details, enable `:setting -deprecation' or `:replay -deprecation' res0: $r.global.noSelfType.type = private val _ = _ scala> val tp = ArrayClass[scala.util.Random] // magic with tags -warning: there was one feature warning; re-run with -feature for details +warning: there was one feature warning; for details, enable `:setting -feature' or `:replay -feature' tp: $r.global.Type = Array[scala.util.Random] scala> tp.memberType(Array_apply) // evidence diff --git a/test/files/run/repl-power.check b/test/files/run/repl-power.check index a76db3dbc2..08f614eb60 100644 --- a/test/files/run/repl-power.check +++ b/test/files/run/repl-power.check @@ -7,11 +7,11 @@ Try :help or completions for vals._ and power._ scala> // guarding against "error: reference to global is ambiguous" scala> global.emptyValDef // "it is imported twice in the same scope by ..." -warning: there was one deprecation warning (since 2.11.0); re-run with -deprecation for details +warning: there was one deprecation warning (since 2.11.0); for details, enable `:setting -deprecation' or `:replay -deprecation' res0: $r.global.noSelfType.type = private val _ = _ scala> val tp = ArrayClass[scala.util.Random] // magic with tags -warning: there was one feature warning; re-run with -feature for details +warning: there was one feature warning; for details, enable `:setting -feature' or `:replay -feature' tp: $r.global.Type = Array[scala.util.Random] scala> tp.memberType(Array_apply) // evidence diff --git a/test/files/run/runtime.scala b/test/files/run/runtime.scala index 89348b294d..468a80fc0c 100644 --- a/test/files/run/runtime.scala +++ b/test/files/run/runtime.scala @@ -73,7 +73,7 @@ object Test1Test { // {System.out.print(22); test1.bar}.System.out.println(); {Console.print(23); test1.bar.System}.out.println(); {Console.print(24); test1.bar.System.out}.println(); - {Console.print(25); test1.bar.System.out.println:(() => Unit)} apply (); + {Console.print(25); test1.bar.System.out.println _ : (() => Unit)} apply (); {Console.print(26); test1.bar.System.out.println()}; } diff --git a/test/files/run/synchronized.scala b/test/files/run/synchronized.scala index 6be0d64dd8..d777b85b2c 100644 --- a/test/files/run/synchronized.scala +++ b/test/files/run/synchronized.scala @@ -1,5 +1,5 @@ /* - * filter: inliner warnings; re-run with + * filter: inliner warnings; */ import java.lang.Thread.holdsLock import scala.collection.mutable.StringBuilder diff --git a/test/files/run/t4172.check b/test/files/run/t4172.check index 3141647dba..99e420678c 100644 --- a/test/files/run/t4172.check +++ b/test/files/run/t4172.check @@ -1,6 +1,6 @@ scala> val c = { class C { override def toString = "C" }; ((new C, new C { def f = 2 })) } -warning: there was one feature warning; re-run with -feature for details +warning: there was one feature warning; for details, enable `:setting -feature' or `:replay -feature' c: (C, C{def f: Int}) forSome { type C <: AnyRef } = (C,C) scala> :quit diff --git a/test/files/run/t4594-repl-settings.scala b/test/files/run/t4594-repl-settings.scala index 524ec28843..587bb2312b 100644 --- a/test/files/run/t4594-repl-settings.scala +++ b/test/files/run/t4594-repl-settings.scala @@ -9,7 +9,7 @@ object Test extends SessionTest { |depp: String | |scala> def a = depp - |warning: there was one deprecation warning (since Time began.); re-run with -deprecation for details + |warning: there was one deprecation warning (since Time began.); for details, enable `:setting -deprecation' or `:replay -deprecation' |a: String | |scala> :settings -deprecation diff --git a/test/files/run/t4710.check b/test/files/run/t4710.check index 5f90c68ed1..4a5d11f185 100644 --- a/test/files/run/t4710.check +++ b/test/files/run/t4710.check @@ -1,6 +1,6 @@ scala> def method : String = { implicit def f(s: Symbol) = "" ; 'symbol } -warning: there was one feature warning; re-run with -feature for details +warning: there was one feature warning; for details, enable `:setting -feature' or `:replay -feature' method: String scala> :quit diff --git a/test/files/run/t6329_repl.check b/test/files/run/t6329_repl.check index 86cd984e11..22882a3597 100644 --- a/test/files/run/t6329_repl.check +++ b/test/files/run/t6329_repl.check @@ -3,28 +3,28 @@ scala> import scala.reflect.classTag import scala.reflect.classTag scala> classManifest[scala.List[_]] -warning: there was one deprecation warning (since 2.10.0); re-run with -deprecation for details +warning: there was one deprecation warning (since 2.10.0); for details, enable `:setting -deprecation' or `:replay -deprecation' res0: scala.reflect.ClassTag[List[_]] = scala.collection.immutable.List[<?>] scala> classTag[scala.List[_]] res1: scala.reflect.ClassTag[List[_]] = scala.collection.immutable.List scala> classManifest[scala.collection.immutable.List[_]] -warning: there was one deprecation warning (since 2.10.0); re-run with -deprecation for details +warning: there was one deprecation warning (since 2.10.0); for details, enable `:setting -deprecation' or `:replay -deprecation' res2: scala.reflect.ClassTag[List[_]] = scala.collection.immutable.List[<?>] scala> classTag[scala.collection.immutable.List[_]] res3: scala.reflect.ClassTag[List[_]] = scala.collection.immutable.List scala> classManifest[Predef.Set[_]] -warning: there was one deprecation warning (since 2.10.0); re-run with -deprecation for details +warning: there was one deprecation warning (since 2.10.0); for details, enable `:setting -deprecation' or `:replay -deprecation' res4: scala.reflect.ClassTag[scala.collection.immutable.Set[_]] = scala.collection.immutable.Set[<?>] scala> classTag[Predef.Set[_]] res5: scala.reflect.ClassTag[scala.collection.immutable.Set[_]] = scala.collection.immutable.Set scala> classManifest[scala.collection.immutable.Set[_]] -warning: there was one deprecation warning (since 2.10.0); re-run with -deprecation for details +warning: there was one deprecation warning (since 2.10.0); for details, enable `:setting -deprecation' or `:replay -deprecation' res6: scala.reflect.ClassTag[scala.collection.immutable.Set[_]] = scala.collection.immutable.Set[<?>] scala> classTag[scala.collection.immutable.Set[_]] diff --git a/test/files/run/t6329_repl_bug.check b/test/files/run/t6329_repl_bug.check index 6476fa71fc..11decae9bd 100644 --- a/test/files/run/t6329_repl_bug.check +++ b/test/files/run/t6329_repl_bug.check @@ -6,7 +6,7 @@ scala> import scala.reflect.runtime._ import scala.reflect.runtime._ scala> classManifest[List[_]] -warning: there was one deprecation warning (since 2.10.0); re-run with -deprecation for details +warning: there was one deprecation warning (since 2.10.0); for details, enable `:setting -deprecation' or `:replay -deprecation' res0: scala.reflect.ClassTag[List[_]] = scala.collection.immutable.List[<?>] scala> scala.reflect.classTag[List[_]] diff --git a/test/files/run/t7319.check b/test/files/run/t7319.check index 31923e7119..1dcb84c804 100644 --- a/test/files/run/t7319.check +++ b/test/files/run/t7319.check @@ -3,15 +3,15 @@ scala> class M[A] defined class M scala> implicit def ma0[A](a: A): M[A] = null -warning: there was one feature warning; re-run with -feature for details +warning: there was one feature warning; for details, enable `:setting -feature' or `:replay -feature' ma0: [A](a: A)M[A] scala> implicit def ma1[A](a: A): M[A] = null -warning: there was one feature warning; re-run with -feature for details +warning: there was one feature warning; for details, enable `:setting -feature' or `:replay -feature' ma1: [A](a: A)M[A] scala> def convert[F[X <: F[X]]](builder: F[_ <: F[_]]) = 0 -warning: there was one feature warning; re-run with -feature for details +warning: there was one feature warning; for details, enable `:setting -feature' or `:replay -feature' convert: [F[X <: F[X]]](builder: F[_ <: F[_]])Int scala> convert(Some[Int](0)) |