diff options
23 files changed, 271 insertions, 70 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala index 1332d01dbd..b650cdfa09 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala @@ -46,8 +46,10 @@ abstract class GenICode extends SubComponent { var unit: CompilationUnit = NoCompilationUnit override def run() { - scalaPrimitives.init() - classes.clear() + if (!settings.isBCodeActive) { + scalaPrimitives.init() + classes.clear() + } super.run() } @@ -1007,8 +1009,15 @@ abstract class GenICode extends SubComponent { } // emit conversion - if (generatedType != expectedType) - adapt(generatedType, expectedType, resCtx, tree.pos) + if (generatedType != expectedType) { + tree match { + case Literal(Constant(null)) if generatedType == NullReference => + // literal null on the stack (as opposed to a boxed null, see SI-8233), + // we can bypass `adapt` which would otherwise emitt a redundant [DROP, CONSTANT(null)] + case _ => + adapt(generatedType, expectedType, resCtx, tree.pos) + } + } resCtx } @@ -1058,6 +1067,9 @@ abstract class GenICode extends SubComponent { case (NothingReference, _) => ctx.bb.emit(THROW(ThrowableClass)) ctx.bb.enterIgnoreMode() + case (NullReference, REFERENCE(_)) => + // SI-8223 we can't assume that the stack contains a `null`, it might contain a Null$ + ctx.bb.emit(Seq(DROP(from), CONSTANT(Constant(null)))) case _ if from isAssignabledTo to => () case (_, UNIT) => diff --git a/src/compiler/scala/tools/nsc/backend/icode/Members.scala b/src/compiler/scala/tools/nsc/backend/icode/Members.scala index 267fa15312..64146585e5 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/Members.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/Members.scala @@ -21,7 +21,7 @@ trait Members { import global._ - object NoCode extends Code(null, "NoCode") { + object NoCode extends Code(null, TermName("NoCode")) { override def blocksList: List[BasicBlock] = Nil } @@ -29,8 +29,8 @@ trait Members { * This class represents the intermediate code of a method or * other multi-block piece of code, like exception handlers. */ - class Code(method: IMethod, name: String) { - def this(method: IMethod) = this(method, method.symbol.decodedName.toString.intern) + class Code(method: IMethod, name: Name) { + def this(method: IMethod) = this(method, method.symbol.name) /** The set of all blocks */ val blocks = mutable.ListBuffer[BasicBlock]() @@ -82,7 +82,7 @@ trait Members { } /** This methods returns a string representation of the ICode */ - override def toString = "ICode '" + name + "'" + override def toString = "ICode '" + name.decoded + "'" /* Compute a unique new label */ def nextLabel: Int = { diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index a60310f900..ccfddab94a 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -92,11 +92,22 @@ abstract class Erasure extends AddInterfaces // more rigorous way up front rather than catching it after the fact, // but that will be more involved. private def dotCleanup(sig: String): String = { + // OPT 50% of time in generic signatures (~1% of compile time) was in this method, hence the imperative rewrite. var last: Char = '\u0000' - sig map { - case '.' if last != '>' => last = '.' ; '$' - case ch => last = ch ; ch + var i = 0 + val len = sig.length + val copy: Array[Char] = sig.toCharArray + var changed = false + while (i < sig.length) { + val ch = copy(i) + if (ch == '.' && last != '>') { + copy(i) = '$' + changed = true + } + last = ch + i += 1 } + if (changed) new String(copy) else sig } /** This object is only used for sanity testing when -check:genjvm is set. diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index e193cf3de2..e7ea686bc8 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -105,12 +105,11 @@ abstract class UnCurry extends InfoTransform */ def isByNameRef(tree: Tree) = ( tree.isTerm - && !byNameArgs(tree) && (tree.symbol ne null) && (isByName(tree.symbol)) + && !byNameArgs(tree) ) - // ------- Handling non-local returns ------------------------------------------------- /** The type of a non-local return expression with given argument type */ diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index 4d0eda2377..2043eb5d5d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -418,7 +418,7 @@ trait ContextErrors { case TypeRef(_, _, arg :: _) if arg.typeSymbol == TupleClass(funArity) && funArity > 1 => sm"""| |Note: The expected type requires a one-argument function accepting a $funArity-Tuple. - | Consider a pattern matching anoynmous function, `{ case $example => ... }`""" + | Consider a pattern matching anonymous function, `{ case $example => ... }`""" case _ => "" } case _ => "" diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index dd0923a696..997fd6fc65 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -595,6 +595,7 @@ trait Infer extends Checkable { } private[typechecker] def followApply(tp: Type): Type = tp match { + case _ if tp.isError => tp // SI-8228, `ErrorType nonPrivateMember nme.apply` returns an member with an erroneous type! case NullaryMethodType(restp) => val restp1 = followApply(restp) if (restp1 eq restp) tp else restp1 diff --git a/src/library/scala/collection/immutable/List.scala b/src/library/scala/collection/immutable/List.scala index 90aabc5a9a..c3728fa02a 100644 --- a/src/library/scala/collection/immutable/List.scala +++ b/src/library/scala/collection/immutable/List.scala @@ -325,36 +325,7 @@ sealed abstract class List[+A] extends AbstractSeq[A] // Create a proxy for Java serialization that allows us to avoid mutation // during de-serialization. This is the Serialization Proxy Pattern. - protected final def writeReplace(): AnyRef = new SerializationProxy(this) -} - -@SerialVersionUID(1L) -private class SerializationProxy[B](@transient private var orig: List[B]) extends Serializable { - - private def writeObject(out: ObjectOutputStream) { - var xs: List[B] = orig - while (!xs.isEmpty) { - out.writeObject(xs.head) - xs = xs.tail - } - out.writeObject(ListSerializeEnd) - } - - // Java serialization calls this before readResolve during de-serialization. - // Read the whole list and store it in `orig`. - private def readObject(in: ObjectInputStream) { - val builder = List.newBuilder[B] - while (true) in.readObject match { - case ListSerializeEnd => - orig = builder.result() - return - case a => - builder += a.asInstanceOf[B] - } - } - - // Provide the result stored in `orig` for Java serialization - private def readResolve(): AnyRef = orig + protected final def writeReplace(): AnyRef = new List.SerializationProxy(this) } /** The empty list. @@ -385,8 +356,7 @@ case object Nil extends List[Nothing] { * @version 1.0, 15/07/2003 * @since 2.8 */ -final case class ::[B](private val hd: B, private[scala] var tl: List[B]) extends List[B] { - override def head : B = hd +final case class ::[B](override val head: B, private[scala] var tl: List[B]) extends List[B] { override def tail : List[B] = tl override def isEmpty: Boolean = false } @@ -405,6 +375,35 @@ object List extends SeqFactory[List] { override def empty[A]: List[A] = Nil override def apply[A](xs: A*): List[A] = xs.toList + + @SerialVersionUID(1L) + private class SerializationProxy[A](@transient private var orig: List[A]) extends Serializable { + + private def writeObject(out: ObjectOutputStream) { + var xs: List[A] = orig + while (!xs.isEmpty) { + out.writeObject(xs.head) + xs = xs.tail + } + out.writeObject(ListSerializeEnd) + } + + // Java serialization calls this before readResolve during de-serialization. + // Read the whole list and store it in `orig`. + private def readObject(in: ObjectInputStream) { + val builder = List.newBuilder[A] + while (true) in.readObject match { + case ListSerializeEnd => + orig = builder.result() + return + case a => + builder += a.asInstanceOf[A] + } + } + + // Provide the result stored in `orig` for Java serialization + private def readResolve(): AnyRef = orig + } } /** Only used for list serialization */ diff --git a/src/library/scala/collection/immutable/StringLike.scala b/src/library/scala/collection/immutable/StringLike.scala index 43d46cf4d0..8e1d950d00 100644 --- a/src/library/scala/collection/immutable/StringLike.scala +++ b/src/library/scala/collection/immutable/StringLike.scala @@ -131,6 +131,7 @@ self => * end characters, i.e. apply `.stripLineEnd` to all lines * returned by `linesWithSeparators`. */ + @deprecated("Use `lines` instead.","2.11.0") def linesIterator: Iterator[String] = linesWithSeparators map (line => new WrappedString(line).stripLineEnd) diff --git a/src/library/scala/concurrent/ExecutionContext.scala b/src/library/scala/concurrent/ExecutionContext.scala index d3c5a6b019..a55432fd71 100644 --- a/src/library/scala/concurrent/ExecutionContext.scala +++ b/src/library/scala/concurrent/ExecutionContext.scala @@ -14,9 +14,45 @@ import scala.annotation.implicitNotFound import scala.util.Try /** - * An `ExecutionContext` is an abstraction over an entity that can execute program logic. + * An `ExecutionContext` can execute program logic, typically but not + * necessarily on a thread pool. + * + * APIs such as `Future.onComplete` require you to provide a callback + * and an implicit `ExecutionContext`. The implicit `ExecutionContext` + * will be used to execute the callback. + * + * It is possible to simply import + * `scala.concurrent.ExecutionContext.Implicits.global` to obtain an + * implicit `ExecutionContext`. This global context is a reasonable + * default thread pool. + * + * However, application developers should carefully consider where they + * want to set policy; ideally, one place per application (or per + * logically-related section of code) will make a decision about + * which `ExecutionContext` to use. That is, you might want to avoid + * hardcoding `scala.concurrent.ExecutionContext.Implicits.global` all + * over the place in your code. + * One approach is to add `(implicit ec: ExecutionContext)` + * to methods which need an `ExecutionContext`. Then import a specific + * context in one place for the entire application or module, + * passing it implicitly to individual methods. + * + * A custom `ExecutionContext` may be appropriate to execute code + * which blocks on IO or performs long-running computations. + * `ExecutionContext.fromExecutorService` and `ExecutionContext.fromExecutor` + * are good ways to create a custom `ExecutionContext`. + * + * The intent of `ExecutionContext` is to lexically scope code execution. + * That is, each method, class, file, package, or application determines + * how to run its own code. This avoids issues such as running + * application callbacks on a thread pool belonging to a networking library. + * The size of a networking library's thread pool can be safely configured, + * knowing that only that library's network operations will be affected. + * Application callback execution can be configured separately. */ -@implicitNotFound("Cannot find an implicit ExecutionContext, either import scala.concurrent.ExecutionContext.Implicits.global or use a custom one") +@implicitNotFound("""Cannot find an implicit ExecutionContext. You might pass +an (implicit ec: ExecutionContext) parameter to your method +or import scala.concurrent.ExecutionContext.Implicits.global.""") trait ExecutionContext { /** Runs a block of code on this execution context. diff --git a/src/reflect/scala/reflect/internal/Names.scala b/src/reflect/scala/reflect/internal/Names.scala index 4075653674..73ce59feb2 100644 --- a/src/reflect/scala/reflect/internal/Names.scala +++ b/src/reflect/scala/reflect/internal/Names.scala @@ -345,6 +345,13 @@ trait Names extends api.Names { i += 1 i == prefix.length } + final def startsWith(prefix: String, start: Int): Boolean = { + var i = 0 + while (i < prefix.length && start + i < len && + chrs(index + start + i) == prefix.charAt(i)) + i += 1 + i == prefix.length + } /** Does this name end with suffix? */ final def endsWith(suffix: Name): Boolean = endsWith(suffix, len) @@ -357,6 +364,13 @@ trait Names extends api.Names { i += 1 i > suffix.length } + final def endsWith(suffix: String, end: Int): Boolean = { + var i = 1 + while (i <= suffix.length && i <= end && + chrs(index + end - i) == suffix.charAt(suffix.length - i)) + i += 1 + i > suffix.length + } final def containsName(subname: String): Boolean = containsName(newTermName(subname)) final def containsName(subname: Name): Boolean = { @@ -382,9 +396,9 @@ trait Names extends api.Names { final def startChar: Char = this charAt 0 final def endChar: Char = this charAt len - 1 final def startsWith(char: Char): Boolean = len > 0 && startChar == char - final def startsWith(name: String): Boolean = startsWith(newTermName(name)) + final def startsWith(name: String): Boolean = startsWith(name, 0) final def endsWith(char: Char): Boolean = len > 0 && endChar == char - final def endsWith(name: String): Boolean = endsWith(newTermName(name)) + final def endsWith(name: String): Boolean = endsWith(name, len) /** Rewrite the confusing failure indication via result == length to * the normal failure indication via result == -1. @@ -443,9 +457,10 @@ trait Names extends api.Names { } /** TODO - find some efficiency. */ - def append(ch: Char) = newName("" + this + ch) - def append(suffix: String) = newName("" + this + suffix) - def append(suffix: Name) = newName("" + this + suffix) + def append(ch: Char) = newName(toString + ch) + def append(suffix: String) = newName(toString + suffix) + def append(suffix: Name) = newName(toString + suffix) + def append(separator: Char, suffix: Name) = newName(toString + separator + suffix) def prepend(prefix: String) = newName("" + prefix + this) def decodedName: ThisNameType = newName(decode) @@ -463,7 +478,7 @@ trait Names extends api.Names { */ final class NameOps[T <: Name](name: T) { import NameTransformer._ - def stripSuffix(suffix: String): T = stripSuffix(suffix: TermName) + def stripSuffix(suffix: String): T = if (name endsWith suffix) dropRight(suffix.length) else name // OPT avoid creating a Name with `suffix` def stripSuffix(suffix: Name): T = if (name endsWith suffix) dropRight(suffix.length) else name def take(n: Int): T = name.subName(0, n).asInstanceOf[T] def drop(n: Int): T = name.subName(n, name.length).asInstanceOf[T] @@ -500,21 +515,21 @@ trait Names extends api.Names { /** TermName_S and TypeName_S have fields containing the string version of the name. * TermName_R and TypeName_R recreate it each time toString is called. */ - private class TermName_S(index0: Int, len0: Int, hash: Int, override val toString: String) extends TermName(index0, len0, hash) { + private final class TermName_S(index0: Int, len0: Int, hash: Int, override val toString: String) extends TermName(index0, len0, hash) { protected def createCompanionName(h: Int): TypeName = new TypeName_S(index, len, h, toString) override def newName(str: String): TermName = newTermNameCached(str) } - private class TypeName_S(index0: Int, len0: Int, hash: Int, override val toString: String) extends TypeName(index0, len0, hash) { + private final class TypeName_S(index0: Int, len0: Int, hash: Int, override val toString: String) extends TypeName(index0, len0, hash) { protected def createCompanionName(h: Int): TermName = new TermName_S(index, len, h, toString) override def newName(str: String): TypeName = newTypeNameCached(str) } - private class TermName_R(index0: Int, len0: Int, hash: Int) extends TermName(index0, len0, hash) { + private final class TermName_R(index0: Int, len0: Int, hash: Int) extends TermName(index0, len0, hash) { protected def createCompanionName(h: Int): TypeName = new TypeName_R(index, len, h) override def toString = new String(chrs, index, len) } - private class TypeName_R(index0: Int, len0: Int, hash: Int) extends TypeName(index0, len0, hash) { + private final class TypeName_R(index0: Int, len0: Int, hash: Int) extends TypeName(index0, len0, hash) { protected def createCompanionName(h: Int): TermName = new TermName_R(index, len, h) override def toString = new String(chrs, index, len) } diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 26914fecc1..b8cd1e86d3 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -1102,7 +1102,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => private def fullNameInternal(separator: Char): Name = ( if (isRoot || isRootPackage || this == NoSymbol) name else if (owner.isEffectiveRoot) name - else ((effectiveOwner.enclClass.fullNameAsName(separator) append separator): Name) append name + else effectiveOwner.enclClass.fullNameAsName(separator) append (separator, name) ) def fullNameAsName(separator: Char): Name = fullNameInternal(separator).dropLocal diff --git a/src/reflect/scala/reflect/internal/TreeGen.scala b/src/reflect/scala/reflect/internal/TreeGen.scala index 145b4a3f1f..29fdba2781 100644 --- a/src/reflect/scala/reflect/internal/TreeGen.scala +++ b/src/reflect/scala/reflect/internal/TreeGen.scala @@ -281,7 +281,7 @@ abstract class TreeGen extends macros.TreeBuilder { case tree :: Nil if flattenUnary => tree case _ => - Apply(scalaDot(TupleClass(elems.length).companionModule.name), elems) + Apply(scalaDot(TupleClass(elems.length).name.toTermName), elems) } def mkTupleType(elems: List[Tree], flattenUnary: Boolean = true): Tree = elems match { diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index 2acf901d0e..53c528a2bb 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -1988,12 +1988,39 @@ trait Types // too little information is known to determine its kind, and // it later turns out not to have kind *. See SI-4070. Only // logging it for now. - if (sym.typeParams.size != args.size) + val tparams = sym.typeParams + if (tparams.size != args.size) devWarning(s"$this.transform($tp), but tparams.isEmpty and args=$args") - - val GenPolyType(tparams, result) = asSeenFromOwner(tp) - assert((tparams eq Nil) || tparams == sym.typeParams, (tparams, sym.typeParams)) - result.instantiateTypeParams(sym.typeParams, args) + def asSeenFromInstantiated(tp: Type) = + asSeenFromOwner(tp).instantiateTypeParams(tparams, args) + // If we're called with a poly type, and we were to run the `asSeenFrom`, over the entire + // type, we can end up with new symbols for the type parameters (clones from TypeMap). + // The subsequent substitution of type arguments would fail. This problem showed up during + // the fix for SI-8046, however the solution taken there wasn't quite right, and led to + // SI-8170. + // + // Now, we detect the PolyType before both the ASF *and* the substitution, and just operate + // on the result type. + // + // TODO: Revisit this and explore the questions raised: + // + // AM: I like this better than the old code, but is there any way the tparams would need the ASF treatment as well? + // JZ: I think its largely irrelevant, as they are no longer referred to in the result type. + // In fact, you can get away with returning a type of kind * here and the sky doesn't fall: + // `case PolyType(`tparams`, result) => asSeenFromInstantiated(result)` + // But I thought it was better to retain the kind. + // AM: I've been experimenting with apply-type-args-then-ASF, but running into cycles. + // In general, it seems iffy the tparams can never occur in the result + // then we might as well represent the type as a no-arg typeref. + // AM: I've also been trying to track down uses of transform (pretty generic name for something that + // does not seem that widely applicable). + // It's kind of a helper for computing baseType (since it tries to propagate our type args to some + // other type, which has to be related to this type for that to make sense). + // + tp match { + case PolyType(`tparams`, result) => PolyType(tparams, asSeenFromInstantiated(result)) + case _ => asSeenFromInstantiated(tp) + } } // note: does not go through typeRef. There's no need to because diff --git a/test/files/jvm/t6941/Analyzed_1.scala b/test/files/jvm/t6941/Analyzed_1.scala index 549abd5e64..b6951f71ee 100644 --- a/test/files/jvm/t6941/Analyzed_1.scala +++ b/test/files/jvm/t6941/Analyzed_1.scala @@ -6,6 +6,6 @@ class SameBytecode { } def b(xs: List[Int]) = xs match { - case xs: ::[Int] => xs.hd$1 + case xs: ::[Int] => xs.head } }
\ No newline at end of file diff --git a/test/files/neg/missing-param-type-tuple.check b/test/files/neg/missing-param-type-tuple.check index bc46ba1023..3a4258ff8c 100644 --- a/test/files/neg/missing-param-type-tuple.check +++ b/test/files/neg/missing-param-type-tuple.check @@ -1,6 +1,6 @@ missing-param-type-tuple.scala:3: error: missing parameter type Note: The expected type requires a one-argument function accepting a 2-Tuple. - Consider a pattern matching anoynmous function, `{ case (a, b) => ... }` + Consider a pattern matching anonymous function, `{ case (a, b) => ... }` val x: ((Int, Int)) => Int = (a, b) => 0 ^ missing-param-type-tuple.scala:3: error: missing parameter type @@ -8,7 +8,7 @@ missing-param-type-tuple.scala:3: error: missing parameter type ^ missing-param-type-tuple.scala:5: error: missing parameter type Note: The expected type requires a one-argument function accepting a 3-Tuple. - Consider a pattern matching anoynmous function, `{ case (param1, ..., param3) => ... }` + Consider a pattern matching anonymous function, `{ case (param1, ..., param3) => ... }` val y: ((Int, Int, Int)) => Int = (a, b, !!) => 0 ^ missing-param-type-tuple.scala:5: error: missing parameter type @@ -19,7 +19,7 @@ missing-param-type-tuple.scala:5: error: missing parameter type ^ missing-param-type-tuple.scala:7: error: missing parameter type Note: The expected type requires a one-argument function accepting a 3-Tuple. - Consider a pattern matching anoynmous function, `{ case (param1, ..., param3) => ... }` + Consider a pattern matching anonymous function, `{ case (param1, ..., param3) => ... }` val z: ((Int, Int, Int)) => Int = (a, NotAVariablePatternName, c) => 0 ^ missing-param-type-tuple.scala:7: error: missing parameter type diff --git a/test/files/neg/t8228.check b/test/files/neg/t8228.check new file mode 100644 index 0000000000..02eff4b1b7 --- /dev/null +++ b/test/files/neg/t8228.check @@ -0,0 +1,4 @@ +t8228.scala:4: error: recursive value foo needs type + val foo = foo(null) + ^ +one error found diff --git a/test/files/neg/t8228.scala b/test/files/neg/t8228.scala new file mode 100644 index 0000000000..19d71aeab4 --- /dev/null +++ b/test/files/neg/t8228.scala @@ -0,0 +1,7 @@ +object X { + def bar = { + def foo(x: Any) = "" + val foo = foo(null) + foo(null) // cycle in isApplicableBasedOnArity + } +} diff --git a/test/files/pos/t8170.scala b/test/files/pos/t8170.scala new file mode 100644 index 0000000000..b65f4b8572 --- /dev/null +++ b/test/files/pos/t8170.scala @@ -0,0 +1,27 @@ +object O { + trait X + trait B extends A { + override type T[F1 <: X] = F1 + } + trait A { + type T[F <: X] + } +} + +object Test { + import O._ + val a: B = ??? + val b: a.T[X] = ??? + b.ensuring(x => true) // trigger an implicit search +} + + +/* +this = {AliasArgsTypeRef@3004}"Test#7680.a#14899.T#14823[O#7702.X#7793]" + sym = type T#14823 + info = namer: [F#14824 <: O#7703.X#7793]F#14824 +result = {AbstractNoArgsTypeRef@3237}"F#24451" +tp = {PolyType@3235}"[F#14824 <: O#7703.X#7793]F#14824" +tparams = + (0) = {AbstractTypeSymbol@3247}"type F#24451" +*/
\ No newline at end of file diff --git a/test/files/pos/t8170b.scala b/test/files/pos/t8170b.scala new file mode 100644 index 0000000000..53036f6c8a --- /dev/null +++ b/test/files/pos/t8170b.scala @@ -0,0 +1,25 @@ +import language._ + +object ScalaZeee { + trait HFold[M[_], U] { + type Apply[E, A <: U] <: U + } + trait GenericCons[M[_], H, +T <: GenericList[M]] extends GenericList[M] { + val tail: T + override type Folded[N[X] >: M[X], U, F <: HFold[N, U]] = F#Apply[H, tail.Folded[N, U, F]] + } + val KNil: GenericList[Nothing] = ??? + sealed trait GenericList[+M[_]] { + type Folded[N[X] >: M[X], U, F <: HFold[N, U]] <: U + } +} + +object TypelevelUsage { + import ScalaZeee._ + type T = GenericCons[Some, String, KNil.type] + val klist1: T = ??? + type T2 = klist1.Folded[Option, Int, HFold[Option, Int]] + val count2: T2 = ??? + + count2.ensuring(x => true).toChar // trigger an implicit search +} diff --git a/test/files/run/global-showdef.scala b/test/files/run/global-showdef.scala index c3ace590ed..1d4891fd1f 100644 --- a/test/files/run/global-showdef.scala +++ b/test/files/run/global-showdef.scala @@ -54,7 +54,7 @@ object Bippy { val run = new compiler.Run() run.compileSources(List(src)) } - output.linesIterator.toList + output.lines.toList } def showClass(name: String) = lines("-Yshow:typer", "-Xshow-class", name) def showObject(name: String) = lines("-Yshow:typer", "-Xshow-object", name) diff --git a/test/files/run/t8233-bcode.flags b/test/files/run/t8233-bcode.flags new file mode 100644 index 0000000000..c30091d3de --- /dev/null +++ b/test/files/run/t8233-bcode.flags @@ -0,0 +1 @@ +-Ybackend:GenBCode diff --git a/test/files/run/t8233-bcode.scala b/test/files/run/t8233-bcode.scala new file mode 100644 index 0000000000..fae1c2b702 --- /dev/null +++ b/test/files/run/t8233-bcode.scala @@ -0,0 +1,18 @@ +object Test { + def bar(s: String) = s; + val o: Option[Null] = None + def nullReference { + val a: Null = o.get + bar(a) // Was: VerifyError under GenICode + } + + def literal { + val a: Null = null + bar(a) + } + + def main(args: Array[String]) = { + try { nullReference } catch { case _: NoSuchElementException => } + literal + } +} diff --git a/test/files/run/t8233.scala b/test/files/run/t8233.scala new file mode 100644 index 0000000000..fae1c2b702 --- /dev/null +++ b/test/files/run/t8233.scala @@ -0,0 +1,18 @@ +object Test { + def bar(s: String) = s; + val o: Option[Null] = None + def nullReference { + val a: Null = o.get + bar(a) // Was: VerifyError under GenICode + } + + def literal { + val a: Null = null + bar(a) + } + + def main(args: Array[String]) = { + try { nullReference } catch { case _: NoSuchElementException => } + literal + } +} |