summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala20
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/Members.scala8
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala17
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala3
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala1
-rw-r--r--src/library/scala/collection/immutable/List.scala63
-rw-r--r--src/library/scala/collection/immutable/StringLike.scala1
-rw-r--r--src/library/scala/concurrent/ExecutionContext.scala40
-rw-r--r--src/reflect/scala/reflect/internal/Names.scala35
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala2
-rw-r--r--src/reflect/scala/reflect/internal/TreeGen.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala37
-rw-r--r--test/files/jvm/t6941/Analyzed_1.scala2
-rw-r--r--test/files/neg/missing-param-type-tuple.check6
-rw-r--r--test/files/neg/t8228.check4
-rw-r--r--test/files/neg/t8228.scala7
-rw-r--r--test/files/pos/t8170.scala27
-rw-r--r--test/files/pos/t8170b.scala25
-rw-r--r--test/files/run/global-showdef.scala2
-rw-r--r--test/files/run/t8233-bcode.flags1
-rw-r--r--test/files/run/t8233-bcode.scala18
-rw-r--r--test/files/run/t8233.scala18
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
+ }
+}