diff options
47 files changed, 394 insertions, 134 deletions
@@ -13,15 +13,15 @@ If you need some help with your PR at any time, please feel free to @-mention an | username | talk to me about... | --------------------------------------------------------------------------------------------------|----------------------------------------------------------------|---------------------------------------------------| - <img src="https://avatars.githubusercontent.com/adriaanm" height="50px" title="Adriaan Moors"/> | [`@adriaanm`](https://github.com/adriaanm) | anything (type checker, pattern matcher, CI,...) | - <img src="https://avatars.githubusercontent.com/gkossakowski" height="50px" title="Grzegorz Kossakowski"/> | [`@gkossakowski`](https://github.com/gkossakowski) | infrastructure, incremental compilation, back-end | + <img src="https://avatars.githubusercontent.com/adriaanm" height="50px" title="Adriaan Moors"/> | [`@adriaanm`](https://github.com/adriaanm) | how we can help // type checker, pattern matcher, infrastructure | + <img src="https://avatars.githubusercontent.com/SethTisue" height="50px" title="Seth Tisue"/> | [`@SethTisue`](https://github.com/SethTisue) | back-end, library, improving the *welcome to Scala* experience | <img src="https://avatars.githubusercontent.com/retronym" height="50px" title="Jason Zaugg"/> | [`@retronym`](https://github.com/retronym) | Java 8 lambdas, tricky bug detective work | <img src="https://avatars.githubusercontent.com/Ichoran" height="50px" title="Rex Kerr"/> | [`@Ichoran`](https://github.com/Ichoran) | the collections library, performance | <img src="https://avatars.githubusercontent.com/lrytz" height="50px" title="Lukas Rytz"/> | [`@lrytz`](https://github.com/lrytz) | optimizer, named & default arguments | - <img src="https://avatars.githubusercontent.com/dickwall" height="50px" title="Dick Wall"/> | [`@dickwall`](https://github.com/dickwall) | process & documentation | <img src="https://avatars.githubusercontent.com/VladUreche" height="50px" title="Vlad Ureche"/> | [`@VladUreche`](https://github.com/VladUreche) | specialization & the scaladoc tool | <img src="https://avatars.githubusercontent.com/densh" height="50px" title="Denys Shabalin"/> | [`@densh`](https://github.com/densh) | quasiquotes, parser, string interpolators, macros in standard library | <img src="https://avatars.githubusercontent.com/xeno-by" height="50px" title="Eugene Burmako"/> | [`@xeno-by`](https://github.com/xeno-by) | macros and reflection | + <img src="https://avatars.githubusercontent.com/dickwall" height="50px" title="Dick Wall"/> | [`@dickwall`](https://github.com/dickwall) | process & community | PS: If you have some spare time to help out around here, we would be delighted to add your name to this list! @@ -29,8 +29,8 @@ PS: If you have some spare time to help out around here, we would be delighted t # Handy Links - [A wealth of documentation](http://docs.scala-lang.org) - [Scala CI](https://scala-ci.typesafe.com/) - - [Scala CI at EPFL](https://scala-webapps.epfl.ch/jenkins/) - [Download the latest nightly](http://www.scala-lang.org/files/archive/nightly/2.11.x/); + - [(Deprecated) Scala CI at EPFL](https://scala-webapps.epfl.ch/jenkins/) - Scala mailing lists: - [Compiler and standard library development](https://groups.google.com/group/scala-internals) - [Users of Scala](https://groups.google.com/group/scala-user) @@ -91,6 +91,12 @@ To help you plan your contributions, we communicate our plans on a regular basis Once you've gained some experience with the code base and the process, the logical next step is to offers reviews for others's contributions. The main goal of this whole process, in the end, is to ensure the health of the Scala project by improving the quality of the code base, the documentation, as well as this process itself. Thank you for doing your part! +## [Labels](https://github.com/scala/scala/labels) + - `reviewed` automatically added by scabot when a comment prefixed with LGTM is posted + - `welcome` reviewer / queue curator adds to welcome someone's first PR (for highlighting in the release notes) + - `release-notes` reviewer / queue curator adds to make sure this PR is highlighted in the release notes + - `on-hold` added when this PR should not yet be merged, even though CI is green + ### Tips & Tricks Once the `publish-core` task has completed on a commit, you can try it out in sbt as follows: @@ -313,7 +313,7 @@ TODO: <!-- scala-java8-compat, used by the experimental -target jvm-1.8 support. --> <if><isset property="scala-java8-compat.package"/><then> - <property name="scala-java8-compat.version" value="0.4.0"/> + <property name="scala-java8-compat.version" value="0.5.0"/> <property name="scala-java8-compat.binary.version" value="2.11"/> <artifact:dependencies pathId="scala-java8-compat.classpath" filesetId="scala-java8-compat.fileset"> <dependency groupId="org.scala-lang.modules" artifactId="scala-java8-compat_${scala-java8-compat.binary.version}" version="${scala-java8-compat.version}"> diff --git a/spec/05-classes-and-objects.md b/spec/05-classes-and-objects.md index a6908ba39f..28abe6c3bc 100644 --- a/spec/05-classes-and-objects.md +++ b/spec/05-classes-and-objects.md @@ -498,9 +498,7 @@ the validity and meaning of a modifier are as follows. The `private` modifier can be used with any definition or declaration in a template. Such members can be accessed only from within the directly enclosing template and its companion module or -[companion class](#object-definitions). They -are not inherited by subclasses and they may not override definitions -in parent classes. +[companion class](#object-definitions). The modifier can be _qualified_ with an identifier $C$ (e.g. `private[$C$]`) that must denote a class or package @@ -524,7 +522,8 @@ either class-private or object-private, but not if it is marked case the member is called _qualified private_. Class-private or object-private members may not be abstract, and may -not have `protected` or `override` modifiers. +not have `protected` or `override` modifiers. They are not inherited +by subclasses and they may not override definitions in parent classes. ### `protected` The `protected` modifier applies to class member definitions. diff --git a/spec/06-expressions.md b/spec/06-expressions.md index da9e21f267..85e288bf5f 100644 --- a/spec/06-expressions.md +++ b/spec/06-expressions.md @@ -512,7 +512,7 @@ In the latter case, the concrete self type of the expression is the compound type `$T$ with $x$.type`. The expression is evaluated by creating a fresh -object of type $T$ which is is initialized by evaluating $c$. The +object of type $T$ which is initialized by evaluating $c$. The type of the expression is $T$. A general instance creation expression is of the form diff --git a/spec/09-top-level-definitions.md b/spec/09-top-level-definitions.md index e3185d8b7d..b8a8dc7e0a 100644 --- a/spec/09-top-level-definitions.md +++ b/spec/09-top-level-definitions.md @@ -151,7 +151,7 @@ contain a class `B`, a compiler-time error would result. A _program_ is a top-level object that has a member method _main_ of type `(Array[String])Unit`. Programs can be -executed from a command shell. The program's command arguments are are +executed from a command shell. The program's command arguments are passed to the `main` method as a parameter of type `Array[String]`. diff --git a/src/compiler/scala/tools/nsc/ast/DocComments.scala b/src/compiler/scala/tools/nsc/ast/DocComments.scala index 02a199f7ac..6442ef2d54 100755 --- a/src/compiler/scala/tools/nsc/ast/DocComments.scala +++ b/src/compiler/scala/tools/nsc/ast/DocComments.scala @@ -76,9 +76,9 @@ trait DocComments { self: Global => superComment(sym) match { case None => - if (ownComment.indexOf("@inheritdoc") != -1) - reporter.warning(sym.pos, "The comment for " + sym + - " contains @inheritdoc, but no parent comment is available to inherit from.") + // SI-8210 - The warning would be false negative when this symbol is a setter + if (ownComment.indexOf("@inheritdoc") != -1 && ! sym.isSetter) + reporter.warning(sym.pos, s"The comment for ${sym} contains @inheritdoc, but no parent comment is available to inherit from.") ownComment.replaceAllLiterally("@inheritdoc", "<invalid inheritdoc annotation>") case Some(sc) => if (ownComment == "") sc diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala index 8ebe27e61b..40ba0c010b 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala @@ -33,7 +33,6 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { * Functionality to build the body of ASM MethodNode, except for `synchronized` and `try` expressions. */ abstract class PlainBodyBuilder(cunit: CompilationUnit) extends PlainSkelBuilder(cunit) { - import icodes.TestOp import icodes.opcodes.InvokeStyle @@ -1287,38 +1286,42 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { def genInvokeDynamicLambda(lambdaTarget: Symbol, arity: Int, functionalInterface: Symbol) { val isStaticMethod = lambdaTarget.hasFlag(Flags.STATIC) + def asmType(sym: Symbol) = classBTypeFromSymbol(sym).toASMType - val targetHandle = + val implMethodHandle = new asm.Handle(if (lambdaTarget.hasFlag(Flags.STATIC)) asm.Opcodes.H_INVOKESTATIC else asm.Opcodes.H_INVOKEVIRTUAL, classBTypeFromSymbol(lambdaTarget.owner).internalName, lambdaTarget.name.toString, asmMethodType(lambdaTarget).descriptor) - val receiver = if (isStaticMethod) None else Some(lambdaTarget.owner) + val receiver = if (isStaticMethod) Nil else lambdaTarget.owner :: Nil val (capturedParams, lambdaParams) = lambdaTarget.paramss.head.splitAt(lambdaTarget.paramss.head.length - arity) // Requires https://github.com/scala/scala-java8-compat on the runtime classpath - val returnUnit = lambdaTarget.info.resultType.typeSymbol == UnitClass - val functionalInterfaceDesc: String = classBTypeFromSymbol(functionalInterface).descriptor - val desc = (receiver.toList ::: capturedParams).map(sym => toTypeKind(sym.info)).mkString(("("), "", ")") + functionalInterfaceDesc + val invokedType = asm.Type.getMethodDescriptor(asmType(functionalInterface), (receiver ::: capturedParams).map(sym => toTypeKind(sym.info).toASMType): _*) - // TODO specialization val constrainedType = new MethodBType(lambdaParams.map(p => toTypeKind(p.tpe)), toTypeKind(lambdaTarget.tpe.resultType)).toASMType - val abstractMethod = functionalInterface.info.decls.find(_.isDeferred).getOrElse(functionalInterface.info.member(nme.apply)) - val methodName = abstractMethod.name.toString - val applyN = { - val mt = asmMethodType(abstractMethod) - mt.toASMType - } - - bc.jmethod.visitInvokeDynamicInsn(methodName, desc, lambdaMetaFactoryBootstrapHandle, - // boostrap args - applyN, targetHandle, constrainedType + val sam = functionalInterface.info.decls.find(_.isDeferred).getOrElse(functionalInterface.info.member(nme.apply)) + val samName = sam.name.toString + val samMethodType = asmMethodType(sam).toASMType + + val flags = 3 // TODO 2.12.x Replace with LambdaMetafactory.FLAG_SERIALIZABLE | LambdaMetafactory.FLAG_MARKERS + + val ScalaSerializable = classBTypeFromSymbol(definitions.SerializableClass).toASMType + bc.jmethod.visitInvokeDynamicInsn(samName, invokedType, lambdaMetaFactoryBootstrapHandle, + /* samMethodType = */ samMethodType, + /* implMethod = */ implMethodHandle, + /* instantiatedMethodType = */ constrainedType, + /* flags = */ flags.asInstanceOf[AnyRef], + /* markerInterfaceCount = */ 1.asInstanceOf[AnyRef], + /* markerInterfaces[0] = */ ScalaSerializable, + /* bridgeCount = */ 0.asInstanceOf[AnyRef] ) + indyLambdaHosts += this.claszSymbol } } - val lambdaMetaFactoryBootstrapHandle = + lazy val lambdaMetaFactoryBootstrapHandle = new asm.Handle(asm.Opcodes.H_INVOKESTATIC, - "java/lang/invoke/LambdaMetafactory", "metafactory", - "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;") + definitions.LambdaMetaFactory.fullName('/'), sn.AltMetafactory.toString, + "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;") } diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala index 18468f5ae3..6aa3a62295 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala @@ -682,6 +682,59 @@ abstract class BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { new java.lang.Long(id) ).visitEnd() } + + /** + * Add: + * private static java.util.Map $deserializeLambdaCache$ = null + * private static Object $deserializeLambda$(SerializedLambda l) { + * var cache = $deserializeLambdaCache$ + * if (cache eq null) { + * cache = new java.util.HashMap() + * $deserializeLambdaCache$ = cache + * } + * return scala.compat.java8.runtime.LambdaDeserializer.deserializeLambda(MethodHandles.lookup(), cache, l); + * } + */ + def addLambdaDeserialize(clazz: Symbol, jclass: asm.ClassVisitor): Unit = { + val cw = jclass + import scala.tools.asm.Opcodes._ + + // Need to force creation of BTypes for these as `getCommonSuperClass` is called on + // automatically computing the max stack size (`visitMaxs`) during method writing. + javaUtilHashMapReference + javaUtilMapReference + + cw.visitInnerClass("java/lang/invoke/MethodHandles$Lookup", "java/lang/invoke/MethodHandles", "Lookup", ACC_PUBLIC + ACC_FINAL + ACC_STATIC) + + { + val fv = cw.visitField(ACC_PRIVATE + ACC_STATIC + ACC_SYNTHETIC, "$deserializeLambdaCache$", "Ljava/util/Map;", null, null) + fv.visitEnd() + } + + { + val mv = cw.visitMethod(ACC_PRIVATE + ACC_STATIC + ACC_SYNTHETIC, "$deserializeLambda$", "(Ljava/lang/invoke/SerializedLambda;)Ljava/lang/Object;", null, null) + mv.visitCode() + mv.visitFieldInsn(GETSTATIC, clazz.javaBinaryName.encoded, "$deserializeLambdaCache$", "Ljava/util/Map;") + mv.visitVarInsn(ASTORE, 1) + mv.visitVarInsn(ALOAD, 1) + val l0 = new asm.Label() + mv.visitJumpInsn(IFNONNULL, l0) + mv.visitTypeInsn(NEW, "java/util/HashMap") + mv.visitInsn(DUP) + mv.visitMethodInsn(INVOKESPECIAL, "java/util/HashMap", "<init>", "()V", false) + mv.visitVarInsn(ASTORE, 1) + mv.visitVarInsn(ALOAD, 1) + mv.visitFieldInsn(PUTSTATIC, clazz.javaBinaryName.encoded, "$deserializeLambdaCache$", "Ljava/util/Map;") + mv.visitLabel(l0) + mv.visitFrame(asm.Opcodes.F_APPEND,1, Array("java/util/Map"), 0, null) + mv.visitMethodInsn(INVOKESTATIC, "java/lang/invoke/MethodHandles", "lookup", "()Ljava/lang/invoke/MethodHandles$Lookup;", false) + mv.visitVarInsn(ALOAD, 1) + mv.visitVarInsn(ALOAD, 0) + mv.visitMethodInsn(INVOKESTATIC, "scala/compat/java8/runtime/LambdaDeserializer", "deserializeLambda", "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/util/Map;Ljava/lang/invoke/SerializedLambda;)Ljava/lang/Object;", false) + mv.visitInsn(ARETURN) + mv.visitEnd() + } + } } // end of trait BCClassGen /* functionality for building plain and mirror classes */ diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala index 2a06c62e37..a2fd22d24c 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala @@ -68,6 +68,8 @@ abstract class BCodeSkelBuilder extends BCodeHelpers { var isCZStaticModule = false var isCZRemote = false + protected val indyLambdaHosts = collection.mutable.Set[Symbol]() + /* ---------------- idiomatic way to ask questions to typer ---------------- */ def paramTKs(app: Apply): List[BType] = { @@ -121,6 +123,16 @@ abstract class BCodeSkelBuilder extends BCodeHelpers { innerClassBufferASM ++= classBType.info.get.nestedClasses gen(cd.impl) + + + val shouldAddLambdaDeserialize = ( + settings.target.value == "jvm-1.8" + && settings.Ydelambdafy.value == "method" + && indyLambdaHosts.contains(claszSymbol)) + + if (shouldAddLambdaDeserialize) + addLambdaDeserialize(claszSymbol, cnode) + addInnerClassesASM(cnode, innerClassBufferASM.toList) cnode.visitAttribute(classBType.inlineInfoAttribute.get) diff --git a/src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala b/src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala index 492fe3ae79..00ca096e59 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala @@ -114,6 +114,8 @@ class CoreBTypes[BTFS <: BTypesFromSymbols[_ <: Global]](val bTypes: BTFS) { lazy val jioSerializableReference : ClassBType = classBTypeFromSymbol(JavaSerializableClass) // java/io/Serializable lazy val scalaSerializableReference : ClassBType = classBTypeFromSymbol(SerializableClass) // scala/Serializable lazy val classCastExceptionReference : ClassBType = classBTypeFromSymbol(ClassCastExceptionClass) // java/lang/ClassCastException + lazy val javaUtilMapReference : ClassBType = classBTypeFromSymbol(JavaUtilMap) // java/util/Map + lazy val javaUtilHashMapReference : ClassBType = classBTypeFromSymbol(JavaUtilHashMap) // java/util/HashMap lazy val srBooleanRef : ClassBType = classBTypeFromSymbol(requiredClass[scala.runtime.BooleanRef]) lazy val srByteRef : ClassBType = classBTypeFromSymbol(requiredClass[scala.runtime.ByteRef]) @@ -258,6 +260,8 @@ final class CoreBTypesProxy[BTFS <: BTypesFromSymbols[_ <: Global]](val bTypes: def jioSerializableReference : ClassBType = _coreBTypes.jioSerializableReference def scalaSerializableReference : ClassBType = _coreBTypes.scalaSerializableReference def classCastExceptionReference : ClassBType = _coreBTypes.classCastExceptionReference + def javaUtilMapReference : ClassBType = _coreBTypes.javaUtilMapReference + def javaUtilHashMapReference : ClassBType = _coreBTypes.javaUtilHashMapReference def srBooleanRef : ClassBType = _coreBTypes.srBooleanRef def srByteRef : ClassBType = _coreBTypes.srByteRef diff --git a/src/compiler/scala/tools/nsc/settings/Warnings.scala b/src/compiler/scala/tools/nsc/settings/Warnings.scala index 41ce0837cb..59cc13c64e 100644 --- a/src/compiler/scala/tools/nsc/settings/Warnings.scala +++ b/src/compiler/scala/tools/nsc/settings/Warnings.scala @@ -23,7 +23,7 @@ trait Warnings { val warnValueDiscard = BooleanSetting("-Ywarn-value-discard", "Warn when non-Unit expression results are unused.") val warnNumericWiden = BooleanSetting("-Ywarn-numeric-widen", "Warn when numerics are widened.") // SI-7712, SI-7707 warnUnused not quite ready for prime-time - val warnUnused = BooleanSetting("-Ywarn-unused", "Warn when local and private vals, vars, defs, and types are are unused.") + val warnUnused = BooleanSetting("-Ywarn-unused", "Warn when local and private vals, vars, defs, and types are unused.") // currently considered too noisy for general use val warnUnusedImport = BooleanSetting("-Ywarn-unused-import", "Warn when imports are unused.") diff --git a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala index 17fad78972..55ab73028e 100644 --- a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala +++ b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala @@ -146,6 +146,9 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre val isStatic = target.hasFlag(STATIC) def createBoxingBridgeMethod(functionParamTypes: List[Type], functionResultType: Type): Tree = { + // Note: we bail out of this method and return EmptyTree if we find there is no adaptation required. + // If we need to improve performance, we could check the types first before creating the + // method and parameter symbols. val methSym = oldClass.newMethod(target.name.append("$adapted").toTermName, target.pos, target.flags | FINAL | ARTIFACT) var neededAdaptation = false def boxedType(tpe: Type): Type = { diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index 9fdc3a9d72..a04625c9c5 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -814,11 +814,10 @@ abstract class Erasure extends AddInterfaces // specialized members have no type history before 'specialize', causing double def errors for curried defs override def exclude(sym: Symbol): Boolean = ( sym.isType - || sym.isPrivate || super.exclude(sym) || !sym.hasTypeAt(currentRun.refchecksPhase.id) ) - override def matches(lo: Symbol, high: Symbol) = true + override def matches(lo: Symbol, high: Symbol) = !high.isPrivate } def isErasureDoubleDef(pair: SymbolPair) = { import pair._ diff --git a/src/library/scala/collection/Iterator.scala b/src/library/scala/collection/Iterator.scala index 0783beac0f..c9037eb3e3 100644 --- a/src/library/scala/collection/Iterator.scala +++ b/src/library/scala/collection/Iterator.scala @@ -580,29 +580,21 @@ trait Iterator[+A] extends TraversableOnce[A] { def span(p: A => Boolean): (Iterator[A], Iterator[A]) = { val self = buffered - /* - * Giving a name to following iterator (as opposed to trailing) because - * anonymous class is represented as a structural type that trailing - * iterator is referring (the finish() method) and thus triggering - * handling of structural calls. It's not what's intended here. - */ + // Must be a named class to avoid structural call to finish from trailing iterator class Leading extends AbstractIterator[A] { - val lookahead = new mutable.Queue[A] - def advance() = { - self.hasNext && p(self.head) && { - lookahead += self.next - true - } + private val drained = new mutable.Queue[A] + private var finished = false + def finish(): Unit = { + require(!finished) + finished = true + while (selfish) drained += self.next } - def finish() = { - while (advance()) () - } - def hasNext = lookahead.nonEmpty || advance() + private def selfish = self.hasNext && p(self.head) + def hasNext = if (finished) drained.nonEmpty else selfish def next() = { - if (lookahead.isEmpty) - advance() - - lookahead.dequeue() + if (finished) drained.dequeue() + else if (selfish) self.next() + else empty.next() } } val leading = new Leading diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index 73ffb267a9..f3dd6a3280 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -369,6 +369,8 @@ trait Definitions extends api.StandardDefinitions { lazy val JavaEnumClass = requiredClass[java.lang.Enum[_]] lazy val RemoteInterfaceClass = requiredClass[java.rmi.Remote] lazy val RemoteExceptionClass = requiredClass[java.rmi.RemoteException] + lazy val JavaUtilMap = requiredClass[java.util.Map[_, _]] + lazy val JavaUtilHashMap = requiredClass[java.util.HashMap[_, _]] lazy val ByNameParamClass = specialPolyClass(tpnme.BYNAME_PARAM_CLASS_NAME, COVARIANT)(_ => AnyTpe) lazy val JavaRepeatedParamClass = specialPolyClass(tpnme.JAVA_REPEATED_PARAM_CLASS_NAME, COVARIANT)(tparam => arrayType(tparam.tpe)) @@ -514,6 +516,7 @@ trait Definitions extends api.StandardDefinitions { lazy val ScalaSignatureAnnotation = requiredClass[scala.reflect.ScalaSignature] lazy val ScalaLongSignatureAnnotation = requiredClass[scala.reflect.ScalaLongSignature] + lazy val LambdaMetaFactory = getClassIfDefined("java.lang.invoke.LambdaMetafactory") lazy val MethodHandle = getClassIfDefined("java.lang.invoke.MethodHandle") // Option classes diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala index c0562b0679..63e2ca0dbe 100644 --- a/src/reflect/scala/reflect/internal/StdNames.scala +++ b/src/reflect/scala/reflect/internal/StdNames.scala @@ -1167,6 +1167,8 @@ trait StdNames { final val Invoke: TermName = newTermName("invoke") final val InvokeExact: TermName = newTermName("invokeExact") + final val AltMetafactory: TermName = newTermName("altMetafactory") + val Boxed = immutable.Map[TypeName, TypeName]( tpnme.Boolean -> BoxedBoolean, tpnme.Byte -> BoxedByte, diff --git a/src/reflect/scala/reflect/internal/transform/PostErasure.scala b/src/reflect/scala/reflect/internal/transform/PostErasure.scala index 466c6133b2..dd4f044818 100644 --- a/src/reflect/scala/reflect/internal/transform/PostErasure.scala +++ b/src/reflect/scala/reflect/internal/transform/PostErasure.scala @@ -9,8 +9,7 @@ trait PostErasure { object elimErasedValueType extends TypeMap { def apply(tp: Type) = tp match { case ConstantType(Constant(tp: Type)) => ConstantType(Constant(apply(tp))) - case ErasedValueType(_, underlying) => - underlying + case ErasedValueType(_, underlying) => underlying case _ => mapOver(tp) } } diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala index 1c0aa7cf6d..ea213cadd9 100644 --- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala +++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala @@ -255,6 +255,8 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => definitions.JavaEnumClass definitions.RemoteInterfaceClass definitions.RemoteExceptionClass + definitions.JavaUtilMap + definitions.JavaUtilHashMap definitions.ByNameParamClass definitions.JavaRepeatedParamClass definitions.RepeatedParamClass @@ -310,6 +312,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => definitions.QuasiquoteClass_api_unapply definitions.ScalaSignatureAnnotation definitions.ScalaLongSignatureAnnotation + definitions.LambdaMetaFactory definitions.MethodHandle definitions.OptionClass definitions.OptionModule diff --git a/src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala b/src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala index 86155845b0..6cdd99c9ee 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala @@ -59,6 +59,7 @@ abstract class HtmlPage extends Page { thisPage => writeFile(site) { (w: Writer) => w.write(doctype.toString + "\n") w.write(xml.Xhtml.toXhtml(html)) + w.write('\n') } if (site.universe.settings.docRawOutput) diff --git a/test/files/instrumented/inline-in-constructors.flags b/test/files/instrumented/inline-in-constructors.flags index 068318e8ac..d1ebc4c940 100644 --- a/test/files/instrumented/inline-in-constructors.flags +++ b/test/files/instrumented/inline-in-constructors.flags @@ -1 +1 @@ --optimise -Ydelambdafy:inline +-optimise -Ydelambdafy:inline -Ybackend:GenASM diff --git a/test/files/jvm/constant-optimization/Foo_1.flags b/test/files/jvm/constant-optimization/Foo_1.flags index 86f52af447..67a1dbe8da 100644 --- a/test/files/jvm/constant-optimization/Foo_1.flags +++ b/test/files/jvm/constant-optimization/Foo_1.flags @@ -1 +1 @@ --Ynooptimise -Yconst-opt
\ No newline at end of file +-Ynooptimise -Yconst-opt -Ybackend:GenASM
\ No newline at end of file diff --git a/test/files/jvm/innerClassAttribute.check b/test/files/jvm/innerClassAttribute.check index bb532e4f36..41448f359b 100644 --- a/test/files/jvm/innerClassAttribute.check +++ b/test/files/jvm/innerClassAttribute.check @@ -14,27 +14,27 @@ A19 / null / null A19 / null / null A19 / null / null -- A20 -- -A20$$anonfun$6 / null / null / 17 +A20$$anonfun$4 / null / null / 17 fun1: attribute for itself and the two child closures `() => ()` and `() => () => 1` -A20$$anonfun$6 / null / null / 17 -A20$$anonfun$6$$anonfun$apply$1 / null / null / 17 -A20$$anonfun$6$$anonfun$apply$3 / null / null / 17 +A20$$anonfun$4 / null / null / 17 +A20$$anonfun$4$$anonfun$apply$1 / null / null / 17 +A20$$anonfun$4$$anonfun$apply$2 / null / null / 17 fun2 () => (): itself and the outer closure -A20$$anonfun$6 / null / null / 17 -A20$$anonfun$6$$anonfun$apply$1 / null / null / 17 +A20$$anonfun$4 / null / null / 17 +A20$$anonfun$4$$anonfun$apply$1 / null / null / 17 fun3 () => () => (): itself, the outer closure and its child closure -A20$$anonfun$6 / null / null / 17 -A20$$anonfun$6$$anonfun$apply$3 / null / null / 17 -A20$$anonfun$6$$anonfun$apply$3$$anonfun$apply$2 / null / null / 17 +A20$$anonfun$4 / null / null / 17 +A20$$anonfun$4$$anonfun$apply$2 / null / null / 17 +A20$$anonfun$4$$anonfun$apply$2$$anonfun$apply$3 / null / null / 17 fun4: () => 1: itself and the two outer closures -A20$$anonfun$6 / null / null / 17 -A20$$anonfun$6$$anonfun$apply$3 / null / null / 17 -A20$$anonfun$6$$anonfun$apply$3$$anonfun$apply$2 / null / null / 17 +A20$$anonfun$4 / null / null / 17 +A20$$anonfun$4$$anonfun$apply$2 / null / null / 17 +A20$$anonfun$4$$anonfun$apply$2$$anonfun$apply$3 / null / null / 17 enclosing: nested closures have outer class defined, but no outer method A20 / null / null -A20$$anonfun$6 / null / null -A20$$anonfun$6 / null / null -A20$$anonfun$6$$anonfun$apply$3 / null / null +A20$$anonfun$4 / null / null +A20$$anonfun$4 / null / null +A20$$anonfun$4$$anonfun$apply$2 / null / null #partest -Ydelambdafy:method -- A4 -- null / null / null diff --git a/test/files/jvm/innerClassAttribute/Classes_1.scala b/test/files/jvm/innerClassAttribute/Classes_1.scala index fb1f32aa3d..62c7d94d90 100644 --- a/test/files/jvm/innerClassAttribute/Classes_1.scala +++ b/test/files/jvm/innerClassAttribute/Classes_1.scala @@ -12,8 +12,8 @@ object A3 { } class A4 { - def f(l: List[Int]): List[Int] = { - l map (_ + 1) + def f(l: List[String]): List[String] = { + l map (_ + "1") } } @@ -114,21 +114,21 @@ class A18 { } class A19 { - ((x: Int) => x + 3) + ((x: String) => x + "3") val x = { - ((x: Int) => x + 1) + ((x: String) => x + "1") } { - ((x: Int) => x + 2) + ((x: String) => x + "2") } } class A20 { - () => { - {() => ()} - {() => () => 1} + (s: String) => { + {(s: String) => ()} + {(s: String) => (s: String) => 1} } } @@ -189,13 +189,13 @@ trait A24 extends A24Base { class SI_9105 { // the EnclosingMethod attributes depend on the delambdafy strategy (inline vs method) - // outerClass-inline enclMeth-inline outerClass-method enclMeth-method - val fun = () => { + // outerClass-inline enclMeth-inline outerClass-method enclMeth-method + val fun = (s: String) => { class A // closure null (*) SI_9105 null def m: Object = { class B; new B } // closure m$1 SI_9105 m$1 val f: Object = { class C; new C } // closure null (*) SI_9105 null } - def met = () => { + def met = (s: String) => { class D // closure null (*) SI_9105 met def m: Object = { class E; new E } // closure m$1 SI_9105 m$1 val f: Object = { class F; new F } // closure null (*) SI_9105 met @@ -210,17 +210,19 @@ class SI_9105 { // So using `null` looks more like the situation in the source code: C / F are nested classes of the anon-fun, and // there's no method in between. - def byName[T](op: => T) = 0 + def byName(op: => Any) = 0 val bnV = byName { class G // closure null (*) SI_9105 null def m: Object = { class H; new H } // closure m$1 SI_9105 m$1 val f: Object = { class I; new I } // closure null (*) SI_9105 null + "" } def bnM = byName { class J // closure null (*) SI_9105 bnM def m: Object = { class K; new K } // closure m$1 SI_9105 m$1 val f: Object = { class L; new L } // closure null (*) SI_9105 bnM + "" } } @@ -283,8 +285,8 @@ object NestedInValueClass { class A(val arg: String) extends AnyVal { // A has InnerClass entries for the two closures (and for A and A$). not for B / C def f = { - def g = List().map(x => (() => x)) // outer class A, no outer method (g is moved to the companion, doesn't exist in A) - g.map(x => (() => x)) // outer class A, outer method f + def g = List().map(x => ((s: String) => x)) // outer class A, no outer method (g is moved to the companion, doesn't exist in A) + g.map(x => ((s: String) => x)) // outer class A, outer method f } // statements and field declarations are not allowed in value classes } diff --git a/test/files/jvm/innerClassAttribute/Test.scala b/test/files/jvm/innerClassAttribute/Test.scala index bc9aa2376a..376b3c895b 100644 --- a/test/files/jvm/innerClassAttribute/Test.scala +++ b/test/files/jvm/innerClassAttribute/Test.scala @@ -5,11 +5,14 @@ import asm.{Opcodes => Flags} import scala.collection.JavaConverters._ object Test extends BytecodeTest { + // Helpful for debugging the test: + // println(new java.io.File(classpath.asURLs.head.toURI).list().sorted.mkString("\n")) + def assertSame(a: Any, b: Any) = { assert(a == b, s"\na: $a\nb: $b") } - val publicStatic = Flags.ACC_PUBLIC | Flags.ACC_STATIC + val publicStatic = Flags.ACC_PUBLIC | Flags.ACC_STATIC val publicAbstractInterface = Flags.ACC_PUBLIC | Flags.ACC_ABSTRACT | Flags.ACC_INTERFACE def innerClassNodes(className: String): List[InnerClassNode] = { @@ -266,10 +269,10 @@ object Test extends BytecodeTest { printInnerClassNodes("A20") - val fun1 = lambdaClass("A20$$anonfun$6", "A20$lambda$1") - val fun2 = lambdaClass("A20$$anonfun$6$$anonfun$apply$1", "A20$lambda$$$nestedInAnonfun$5$1") - val fun3 = lambdaClass("A20$$anonfun$6$$anonfun$apply$3", "A20$lambda$$$nestedInAnonfun$5$2") - val fun4 = lambdaClass("A20$$anonfun$6$$anonfun$apply$3$$anonfun$apply$2", "A20$lambda$$$nestedInAnonfun$7$1") + val fun1 = lambdaClass("A20$$anonfun$4", "A20$lambda$1") + val fun2 = lambdaClass("A20$$anonfun$4$$anonfun$apply$1", "A20$lambda$$$nestedInAnonfun$5$1") + val fun3 = lambdaClass("A20$$anonfun$4$$anonfun$apply$2", "A20$lambda$$$nestedInAnonfun$5$2") + val fun4 = lambdaClass("A20$$anonfun$4$$anonfun$apply$2$$anonfun$apply$3", "A20$lambda$$$nestedInAnonfun$7$1") println("fun1: attribute for itself and the two child closures `() => ()` and `() => () => 1`") printInnerClassNodes(fun1) @@ -339,9 +342,9 @@ object Test extends BytecodeTest { assertEnclosingMethod ("SI_9105$A$3" , "SI_9105", null , null) assertEnclosingMethod ("SI_9105$B$5" , "SI_9105", "m$1", "()Ljava/lang/Object;") assertEnclosingMethod ("SI_9105$C$1" , "SI_9105", null , null) - assertEnclosingMethod ("SI_9105$D$1" , "SI_9105", "met", "()Lscala/Function0;") + assertEnclosingMethod ("SI_9105$D$1" , "SI_9105", "met", "()Lscala/Function1;") assertEnclosingMethod ("SI_9105$E$1" , "SI_9105", "m$3", "()Ljava/lang/Object;") - assertEnclosingMethod ("SI_9105$F$1" , "SI_9105", "met", "()Lscala/Function0;") + assertEnclosingMethod ("SI_9105$F$1" , "SI_9105", "met", "()Lscala/Function1;") assertNoEnclosingMethod("SI_9105$lambda$$met$1") assertNoEnclosingMethod("SI_9105$lambda$1") assertNoEnclosingMethod("SI_9105") @@ -366,35 +369,35 @@ object Test extends BytecodeTest { assert(innerClassNodes("SI_9105").length == 12) // the 12 local classes } else { // comment in innerClassAttribute/Classes_1.scala explains the difference between A / C and D / F. - assertEnclosingMethod ("SI_9105$$anonfun$4$A$3" , "SI_9105$$anonfun$4" , null , null) - assertEnclosingMethod ("SI_9105$$anonfun$4$B$5" , "SI_9105$$anonfun$4" , "m$1" , "()Ljava/lang/Object;") - assertEnclosingMethod ("SI_9105$$anonfun$4$C$1" , "SI_9105$$anonfun$4" , null , null) + assertEnclosingMethod ("SI_9105$$anonfun$5$A$3" , "SI_9105$$anonfun$5" , null , null) + assertEnclosingMethod ("SI_9105$$anonfun$5$B$5" , "SI_9105$$anonfun$5" , "m$1" , "()Ljava/lang/Object;") + assertEnclosingMethod ("SI_9105$$anonfun$5$C$1" , "SI_9105$$anonfun$5" , null , null) assertEnclosingMethod ("SI_9105$$anonfun$met$1$D$1", "SI_9105$$anonfun$met$1", null , null) assertEnclosingMethod ("SI_9105$$anonfun$met$1$E$1", "SI_9105$$anonfun$met$1", "m$3" , "()Ljava/lang/Object;") assertEnclosingMethod ("SI_9105$$anonfun$met$1$F$1", "SI_9105$$anonfun$met$1", null , null) - assertEnclosingMethod ("SI_9105$$anonfun$4" , "SI_9105" , null , null) - assertEnclosingMethod ("SI_9105$$anonfun$met$1" , "SI_9105" , "met" , "()Lscala/Function0;") + assertEnclosingMethod ("SI_9105$$anonfun$5" , "SI_9105" , null , null) + assertEnclosingMethod ("SI_9105$$anonfun$met$1" , "SI_9105" , "met" , "()Lscala/Function1;") assertNoEnclosingMethod("SI_9105") - assertLocal(ownInnerClassNode("SI_9105$$anonfun$4$A$3"), "SI_9105$$anonfun$4$A$3" , "A$3") - assertLocal(ownInnerClassNode("SI_9105$$anonfun$4$B$5"), "SI_9105$$anonfun$4$B$5" , "B$5") - assertLocal(ownInnerClassNode("SI_9105$$anonfun$4$C$1"), "SI_9105$$anonfun$4$C$1" , "C$1") + assertLocal(ownInnerClassNode("SI_9105$$anonfun$5$A$3"), "SI_9105$$anonfun$5$A$3" , "A$3") + assertLocal(ownInnerClassNode("SI_9105$$anonfun$5$B$5"), "SI_9105$$anonfun$5$B$5" , "B$5") + assertLocal(ownInnerClassNode("SI_9105$$anonfun$5$C$1"), "SI_9105$$anonfun$5$C$1" , "C$1") assertLocal(ownInnerClassNode("SI_9105$$anonfun$met$1$D$1"), "SI_9105$$anonfun$met$1$D$1", "D$1") assertLocal(ownInnerClassNode("SI_9105$$anonfun$met$1$E$1"), "SI_9105$$anonfun$met$1$E$1", "E$1") assertLocal(ownInnerClassNode("SI_9105$$anonfun$met$1$F$1"), "SI_9105$$anonfun$met$1$F$1", "F$1") // by-name - assertEnclosingMethod("SI_9105$$anonfun$5$G$1", "SI_9105$$anonfun$5", null, null) - assertEnclosingMethod("SI_9105$$anonfun$5$H$1", "SI_9105$$anonfun$5", "m$2", "()Ljava/lang/Object;") - assertEnclosingMethod("SI_9105$$anonfun$5$I$1", "SI_9105$$anonfun$5", null, null) + assertEnclosingMethod("SI_9105$$anonfun$6$G$1", "SI_9105$$anonfun$6", null, null) + assertEnclosingMethod("SI_9105$$anonfun$6$H$1", "SI_9105$$anonfun$6", "m$2", "()Ljava/lang/Object;") + assertEnclosingMethod("SI_9105$$anonfun$6$I$1", "SI_9105$$anonfun$6", null, null) assertEnclosingMethod("SI_9105$$anonfun$bnM$1$J$1", "SI_9105$$anonfun$bnM$1", null, null) assertEnclosingMethod("SI_9105$$anonfun$bnM$1$K$2", "SI_9105$$anonfun$bnM$1", "m$4", "()Ljava/lang/Object;") assertEnclosingMethod("SI_9105$$anonfun$bnM$1$L$1", "SI_9105$$anonfun$bnM$1", null, null) - assertAnonymous(ownInnerClassNode("SI_9105$$anonfun$4"), "SI_9105$$anonfun$4") + assertAnonymous(ownInnerClassNode("SI_9105$$anonfun$5"), "SI_9105$$anonfun$5") assertAnonymous(ownInnerClassNode("SI_9105$$anonfun$met$1"), "SI_9105$$anonfun$met$1") - assert(innerClassNodes("SI_9105$$anonfun$4").length == 4) // itself and three of the local classes + assert(innerClassNodes("SI_9105$$anonfun$5").length == 4) // itself and three of the local classes assert(innerClassNodes("SI_9105$$anonfun$met$1").length == 4) // itself and three of the local classes assert(innerClassNodes("SI_9105").length == 4) // the four anon funs } @@ -474,7 +477,7 @@ object Test extends BytecodeTest { testInner("ImplClassesAreTopLevel$B2$1$class", b2) testInner("ImplClassesAreTopLevel$B3$1$class", b3) testInner("ImplClassesAreTopLevel$B4$class", b4) - + testInner("ImplClassesAreTopLevel$B1", b1) testInner("ImplClassesAreTopLevel$B2$1", b2) testInner("ImplClassesAreTopLevel$B3$1", b3) @@ -533,13 +536,13 @@ object Test extends BytecodeTest { "NestedInValueClass$A$lambda$$g$2$1", "NestedInValueClass$A$lambda$$f$extension$1", "NestedInValueClass$A$lambda$$$nestedInAnonfun$13$1", - "NestedInValueClass$A$lambda$$$nestedInAnonfun$15$1").foreach(assertNoEnclosingMethod) + "NestedInValueClass$A$lambda$$NestedInValueClass$A$$$nestedInAnonfun$15$1").foreach(assertNoEnclosingMethod) testInner("NestedInValueClass$A", a, am) testInner("NestedInValueClass$A$", a, am, b, c) testInner("NestedInValueClass$A$lambda$$g$2$1", am) testInner("NestedInValueClass$A$lambda$$f$extension$1", am) testInner("NestedInValueClass$A$lambda$$$nestedInAnonfun$13$1", am) - testInner("NestedInValueClass$A$lambda$$$nestedInAnonfun$15$1", am) + testInner("NestedInValueClass$A$lambda$$NestedInValueClass$A$$$nestedInAnonfun$15$1", am) } else { assertEnclosingMethod("NestedInValueClass$A$$anonfun$g$2$1" , "NestedInValueClass$A" , null, null) assertEnclosingMethod("NestedInValueClass$A$$anonfun$g$2$1$$anonfun$apply$4" , "NestedInValueClass$A$$anonfun$g$2$1" , null, null) diff --git a/test/files/jvm/javaReflection/Classes_1.scala b/test/files/jvm/javaReflection/Classes_1.scala index 11963e2770..e9cd4f756a 100644 --- a/test/files/jvm/javaReflection/Classes_1.scala +++ b/test/files/jvm/javaReflection/Classes_1.scala @@ -13,7 +13,7 @@ class A { trait C object D new T { } - (() => -1) + (() => "-1") def f = { class KB } } @@ -21,21 +21,21 @@ class A { new T { } // anonymous function, not a member - (() => 1) + (() => "1") def f = { class E trait F object G new T { } - (() => 2) + (() => "2") if (new Object().hashCode == 1) { class H trait I object J new T { } - (() => 3) + (() => "3") } else { () } @@ -46,7 +46,7 @@ class A { trait L object M new T { } - (() => 4) + (() => "4") } val x = { @@ -54,7 +54,7 @@ class A { trait O object P new T { } - (() => 5) + (() => "5") } def this(x: Int) { @@ -63,7 +63,7 @@ class A { trait R object S new T { } - (() => () => 5) + (() => () => "5") } } @@ -72,7 +72,7 @@ object AO { trait C object D new T { } - (() => 1) + (() => "1") } trait AT { @@ -80,5 +80,5 @@ trait AT { trait C object D new T { } - (() => 1) + (() => "1") } diff --git a/test/files/jvm/patmat_opt_ignore_underscore.flags b/test/files/jvm/patmat_opt_ignore_underscore.flags index 1182725e86..2cd4b38726 100644 --- a/test/files/jvm/patmat_opt_ignore_underscore.flags +++ b/test/files/jvm/patmat_opt_ignore_underscore.flags @@ -1 +1 @@ --optimize
\ No newline at end of file +-optimize -Ybackend:GenASM
\ No newline at end of file diff --git a/test/files/jvm/patmat_opt_no_nullcheck.flags b/test/files/jvm/patmat_opt_no_nullcheck.flags index 1182725e86..2cd4b38726 100644 --- a/test/files/jvm/patmat_opt_no_nullcheck.flags +++ b/test/files/jvm/patmat_opt_no_nullcheck.flags @@ -1 +1 @@ --optimize
\ No newline at end of file +-optimize -Ybackend:GenASM
\ No newline at end of file diff --git a/test/files/jvm/patmat_opt_primitive_typetest.flags b/test/files/jvm/patmat_opt_primitive_typetest.flags index 49d036a887..b9bb09167e 100644 --- a/test/files/jvm/patmat_opt_primitive_typetest.flags +++ b/test/files/jvm/patmat_opt_primitive_typetest.flags @@ -1 +1 @@ --optimize +-optimize -Ybackend:GenASM diff --git a/test/files/jvm/t7006/Foo_1.flags b/test/files/jvm/t7006/Foo_1.flags index 37b2116413..29a9d424f0 100644 --- a/test/files/jvm/t7006/Foo_1.flags +++ b/test/files/jvm/t7006/Foo_1.flags @@ -1 +1 @@ --optimise -Ydebug -Xfatal-warnings +-optimise -Ydebug -Xfatal-warnings -Ybackend:GenASM diff --git a/test/files/neg/t3234.flags b/test/files/neg/t3234.flags index cc3d9fb6f0..406231bd96 100644 --- a/test/files/neg/t3234.flags +++ b/test/files/neg/t3234.flags @@ -1 +1 @@ --Yinline -Yinline-warnings -Xfatal-warnings +-Yinline -Yinline-warnings -Xfatal-warnings -Ybackend:GenASM diff --git a/test/files/neg/t9286a.check b/test/files/neg/t9286a.check new file mode 100644 index 0000000000..2bc7c0cf15 --- /dev/null +++ b/test/files/neg/t9286a.check @@ -0,0 +1,7 @@ +t9286a.scala:6: error: name clash between defined and inherited member: +def foo(o: (String,)): Unit in class T and +private def foo(o: (Any,)): Unit at line 6 +have same type after erasure: (o: Tuple1)Unit + private def foo(o: Tuple1[Any]) = () + ^ +one error found diff --git a/test/files/neg/t9286a.scala b/test/files/neg/t9286a.scala new file mode 100644 index 0000000000..0375ac591f --- /dev/null +++ b/test/files/neg/t9286a.scala @@ -0,0 +1,13 @@ +class T { + def foo(o: Tuple1[String]) = () +} + +class U extends T { + private def foo(o: Tuple1[Any]) = () +} + +object Test { + def main(args: Array[String]): Unit = { + new U().foo(null) // IllegalAccessError: tried to access method U.foo(Lscala/Tuple1;)V from class Test$ + } +} diff --git a/test/files/neg/t9286b.check b/test/files/neg/t9286b.check new file mode 100644 index 0000000000..89a191bfee --- /dev/null +++ b/test/files/neg/t9286b.check @@ -0,0 +1,7 @@ +t9286b.scala:2: error: name clash between defined and inherited member: +def foo: Int in class C and +private def foo[A]: Int at line 2 +have same type after erasure: ()Int +class D extends C { private def foo[A] = 0 } + ^ +one error found diff --git a/test/files/neg/t9286b.scala b/test/files/neg/t9286b.scala new file mode 100644 index 0000000000..5c23075426 --- /dev/null +++ b/test/files/neg/t9286b.scala @@ -0,0 +1,5 @@ +class C { def foo = 0 } +class D extends C { private def foo[A] = 0 } + +class E { private def foo = 0 } +class F extends E { def foo[A] = 0 } // okay diff --git a/test/files/neg/t9286c.check b/test/files/neg/t9286c.check new file mode 100644 index 0000000000..785cb3f937 --- /dev/null +++ b/test/files/neg/t9286c.check @@ -0,0 +1,7 @@ +t9286c.scala:8: error: name clash between defined and inherited member: +def foo(m: M[_ >: String]): Int in trait T and +private def foo(m: M[_ >: Any]): Int at line 8 +have same type after erasure: (m: M)Int + def foo(m: M[_ >: Any]) = 0 // Expected: "same type after erasure" + ^ +one error found diff --git a/test/files/neg/t9286c.scala b/test/files/neg/t9286c.scala new file mode 100644 index 0000000000..3df08dcfe6 --- /dev/null +++ b/test/files/neg/t9286c.scala @@ -0,0 +1,14 @@ +class M[_] +trait T { + def foo(m: M[_ >: String]) = 42 +} + +object Test { + def t: T = new T { + def foo(m: M[_ >: Any]) = 0 // Expected: "same type after erasure" + } + def main(args: Array[String]): Unit = { + val m: M[String] = null + t.foo(m) // VeriyError: Duplicate method name&signature + } +} diff --git a/test/files/pos/t9321.scala b/test/files/pos/t9321.scala new file mode 100644 index 0000000000..ed3a816656 --- /dev/null +++ b/test/files/pos/t9321.scala @@ -0,0 +1,10 @@ +object p { + trait A { + private[p] val qualifiedPrivateMember = 1 + } + + def useQualifiedPrivate(b: Mix) = + b.qualifiedPrivateMember // allowed +} + +trait Mix extends p.A diff --git a/test/files/run/lambda-serialization-gc.scala b/test/files/run/lambda-serialization-gc.scala new file mode 100644 index 0000000000..8fa0b4b402 --- /dev/null +++ b/test/files/run/lambda-serialization-gc.scala @@ -0,0 +1,40 @@ +import java.io._ + +import java.net.URLClassLoader + +class C { + def serializeDeserialize[T <: AnyRef](obj: T) = { + val buffer = new ByteArrayOutputStream + val out = new ObjectOutputStream(buffer) + out.writeObject(obj) + val in = new ObjectInputStream(new ByteArrayInputStream(buffer.toByteArray)) + in.readObject.asInstanceOf[T] + } + + serializeDeserialize((c: String) => c.length) +} + +object Test { + def main(args: Array[String]): Unit = { + test() + } + + def test(): Unit = { + val loader = getClass.getClassLoader.asInstanceOf[URLClassLoader] + val loaderCClass = classOf[C] + def deserializedInThrowawayClassloader = { + val throwawayLoader: java.net.URLClassLoader = new java.net.URLClassLoader(loader.getURLs, ClassLoader.getSystemClassLoader) { + val maxMemory = Runtime.getRuntime.maxMemory() + val junk = new Array[Byte]((maxMemory / 2).toInt) + } + val clazz = throwawayLoader.loadClass("C") + assert(clazz != loaderCClass) + clazz.newInstance() + } + (1 to 4) foreach { i => + // This would OOM by the third iteration if we leaked `throwawayLoader` during + // deserialization. + deserializedInThrowawayClassloader + } + } +} diff --git a/test/files/run/lambda-serialization.scala b/test/files/run/lambda-serialization.scala new file mode 100644 index 0000000000..46b26d7c5e --- /dev/null +++ b/test/files/run/lambda-serialization.scala @@ -0,0 +1,35 @@ +import java.io.{ByteArrayInputStream, ObjectInputStream, ObjectOutputStream, ByteArrayOutputStream} + +object Test { + def main(args: Array[String]): Unit = { + roundTrip + } + + def roundTrip(): Unit = { + val c = new Capture("Capture") + val lambda = (p: Param) => ("a", p, c) + val reconstituted1 = serializeDeserialize(lambda).asInstanceOf[Object => Any] + val p = new Param + assert(reconstituted1.apply(p) == ("a", p, c)) + val reconstituted2 = serializeDeserialize(lambda).asInstanceOf[Object => Any] + assert(reconstituted1.getClass == reconstituted2.getClass) + + val reconstituted3 = serializeDeserialize(reconstituted1) + assert(reconstituted3.apply(p) == ("a", p, c)) + + val specializedLambda = (p: Int) => List(p, c).length + assert(serializeDeserialize(specializedLambda).apply(42) == 2) + assert(serializeDeserialize(serializeDeserialize(specializedLambda)).apply(42) == 2) + } + + def serializeDeserialize[T <: AnyRef](obj: T) = { + val buffer = new ByteArrayOutputStream + val out = new ObjectOutputStream(buffer) + out.writeObject(obj) + val in = new ObjectInputStream(new ByteArrayInputStream(buffer.toByteArray)) + in.readObject.asInstanceOf[T] + } +} + +case class Capture(s: String) extends Serializable +class Param diff --git a/test/files/run/private-inline.flags b/test/files/run/private-inline.flags index 00d3643fd4..c550fdce16 100644 --- a/test/files/run/private-inline.flags +++ b/test/files/run/private-inline.flags @@ -1 +1 @@ --optimise -Yinline-warnings +-optimise -Yinline-warnings -Ybackend:GenASM diff --git a/test/files/run/synchronized.check b/test/files/run/synchronized.check index 9add05ea0c..dd9f4ef424 100644 --- a/test/files/run/synchronized.check +++ b/test/files/run/synchronized.check @@ -1,8 +1,3 @@ -#partest !-Ybackend:GenBCode -warning: there were 14 inliner warnings; re-run with -Yinline-warnings for details -#partest -Ybackend:GenBCode -warning: there were 14 inliner warnings; re-run with -Yopt-warnings for details -#partest .|. c1.f1: OK .|. c1.fi: OK .|... c1.fv: OK diff --git a/test/files/run/synchronized.scala b/test/files/run/synchronized.scala index 1f0e32992b..077e9d02e8 100644 --- a/test/files/run/synchronized.scala +++ b/test/files/run/synchronized.scala @@ -1,3 +1,6 @@ +/* + * filter: inliner warnings; re-run with + */ import java.lang.Thread.holdsLock import scala.collection.mutable.StringBuilder diff --git a/test/files/run/t6102.check b/test/files/run/t6102.check index aa3e6cc9e2..07378f5ed4 100644 --- a/test/files/run/t6102.check +++ b/test/files/run/t6102.check @@ -28,5 +28,10 @@ [running phase constopt on t6102.scala] #partest [running phase dce on t6102.scala] +#partest !-Ybackend:GenBCode [running phase jvm on icode] +#partest -Ybackend:GenBCode +[running phase jvm on t6102.scala] +[running phase jvm on t6102.scala] +#partest hello diff --git a/test/files/run/t8601-closure-elim.flags b/test/files/run/t8601-closure-elim.flags index 2b5fd8a7b2..9158076b71 100644 --- a/test/files/run/t8601-closure-elim.flags +++ b/test/files/run/t8601-closure-elim.flags @@ -1 +1 @@ --optimize -Ydelambdafy:inline +-optimize -Ydelambdafy:inline -Ybackend:GenASM diff --git a/test/junit/scala/collection/IteratorTest.scala b/test/junit/scala/collection/IteratorTest.scala index d5389afd0c..1c1e50aed9 100644 --- a/test/junit/scala/collection/IteratorTest.scala +++ b/test/junit/scala/collection/IteratorTest.scala @@ -154,4 +154,14 @@ class IteratorTest { results += (Stream from 1).toIterator.drop(10).toStream.drop(10).toIterator.next() assertSameElements(List(1,1,21), results) } + // SI-9332 + @Test def spanExhaustsLeadingIterator(): Unit = { + def it = Iterator.iterate(0)(_ + 1).take(6) + val (x, y) = it.span(_ != 1) + val z = x.toList + assertEquals(1, z.size) + assertFalse(x.hasNext) + assertEquals(1, y.next) + assertFalse(x.hasNext) // was true, after advancing underlying iterator + } } diff --git a/test/scaladoc/run/SI-8210.check b/test/scaladoc/run/SI-8210.check new file mode 100644 index 0000000000..619c56180b --- /dev/null +++ b/test/scaladoc/run/SI-8210.check @@ -0,0 +1 @@ +Done. diff --git a/test/scaladoc/run/SI-8210.scala b/test/scaladoc/run/SI-8210.scala new file mode 100644 index 0000000000..3bd818473f --- /dev/null +++ b/test/scaladoc/run/SI-8210.scala @@ -0,0 +1,24 @@ +import scala.tools.nsc.doc.model._ +import scala.tools.partest.ScaladocModelTest + +object Test extends ScaladocModelTest { + override def code = """ +object Foo { + trait Config { + /** The bar obviously. */ + def bar: Int + } + class ConfigBuilder extends Config { + /** @inheritdoc + * + * The default value is 1234. + */ + var bar: Int = 1234 + } +} + """ + + def scaladocSettings = "" + + def testModel(root: Package) = () +} |