summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bincompat-forward.whitelist.conf6
-rw-r--r--src/compiler/scala/reflect/macros/contexts/Names.scala3
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala19
-rw-r--r--src/library/scala/collection/Iterator.scala10
-rw-r--r--test/files/neg/t8431.check27
-rw-r--r--test/files/neg/t8431.scala63
-rw-r--r--test/files/run/t8425.check1
-rw-r--r--test/files/run/t8425/Macros_1.scala12
-rw-r--r--test/files/run/t8425/Test_2.scala3
-rw-r--r--test/files/run/t8428.scala12
-rw-r--r--versions.properties18
11 files changed, 149 insertions, 25 deletions
diff --git a/bincompat-forward.whitelist.conf b/bincompat-forward.whitelist.conf
index 3eba1effc1..a4cbac4887 100644
--- a/bincompat-forward.whitelist.conf
+++ b/bincompat-forward.whitelist.conf
@@ -139,6 +139,10 @@ filter {
{
matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticPartialFunction"
problemName=MissingMethodProblem
- }
+ },
+ {
+ matchName="scala.collection.Iterator#ConcatIterator.this"
+ problemName=MissingMethodProblem
+ }
]
}
diff --git a/src/compiler/scala/reflect/macros/contexts/Names.scala b/src/compiler/scala/reflect/macros/contexts/Names.scala
index 299af40b94..5a5bb428b5 100644
--- a/src/compiler/scala/reflect/macros/contexts/Names.scala
+++ b/src/compiler/scala/reflect/macros/contexts/Names.scala
@@ -33,8 +33,9 @@ trait Names {
//
// TODO: hopefully SI-7823 will provide an ultimate answer to this problem.
// In the meanwhile I will also keep open the original issue: SI-6879 "c.freshName is broken".
+ val prefix = if (name.endsWith("$")) name else name + "$" // SI-8425
val sortOfUniqueSuffix = freshNameCreator.newName(nme.FRESH_SUFFIX)
- name + "$" + sortOfUniqueSuffix
+ prefix + sortOfUniqueSuffix
}
def freshName[NameType <: Name](name: NameType): NameType =
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index c8ac3622e2..1a38fcf3a4 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -82,7 +82,7 @@ trait Implicits {
// `implicitSearchContext.undetparams`, *not* in `context.undetparams`
// Here, we copy them up to parent context (analogously to the way the errors are copied above),
// and then filter out any which *were* inferred and are part of the substitutor in the implicit search result.
- context.undetparams = ((context.undetparams ++ implicitSearchContext.undetparams) filterNot result.subst.from.contains).distinct
+ context.undetparams = ((context.undetparams ++ result.undetparams) filterNot result.subst.from.contains).distinct
if (Statistics.canEnable) Statistics.stopTimer(implicitNanos, start)
if (Statistics.canEnable) Statistics.stopCounter(rawTypeImpl, rawTypeStart)
@@ -162,8 +162,9 @@ trait Implicits {
* @param tree The tree representing the implicit
* @param subst A substituter that represents the undetermined type parameters
* that were instantiated by the winning implicit.
+ * @param undetparams undeterminted type parameters
*/
- class SearchResult(val tree: Tree, val subst: TreeTypeSubstituter) {
+ class SearchResult(val tree: Tree, val subst: TreeTypeSubstituter, val undetparams: List[Symbol]) {
override def toString = "SearchResult(%s, %s)".format(tree,
if (subst.isEmpty) "" else subst)
@@ -173,16 +174,16 @@ trait Implicits {
final def isSuccess = !isFailure
}
- lazy val SearchFailure = new SearchResult(EmptyTree, EmptyTreeTypeSubstituter) {
+ lazy val SearchFailure = new SearchResult(EmptyTree, EmptyTreeTypeSubstituter, Nil) {
override def isFailure = true
}
- lazy val DivergentSearchFailure = new SearchResult(EmptyTree, EmptyTreeTypeSubstituter) {
+ lazy val DivergentSearchFailure = new SearchResult(EmptyTree, EmptyTreeTypeSubstituter, Nil) {
override def isFailure = true
override def isDivergent = true
}
- lazy val AmbiguousSearchFailure = new SearchResult(EmptyTree, EmptyTreeTypeSubstituter) {
+ lazy val AmbiguousSearchFailure = new SearchResult(EmptyTree, EmptyTreeTypeSubstituter, Nil) {
override def isFailure = true
override def isAmbiguousFailure = true
}
@@ -719,7 +720,7 @@ trait Implicits {
case Some(err) =>
fail("typing TypeApply reported errors for the implicit tree: " + err.errMsg)
case None =>
- val result = new SearchResult(unsuppressMacroExpansion(itree3), subst)
+ val result = new SearchResult(unsuppressMacroExpansion(itree3), subst, context.undetparams)
if (Statistics.canEnable) Statistics.incCounter(foundImplicits)
typingLog("success", s"inferred value of type $ptInstantiated is $result")
result
@@ -1126,7 +1127,7 @@ trait Implicits {
val tree1 = typedPos(pos.focus)(arg)
context.firstError match {
case Some(err) => processMacroExpansionError(err.errPos, err.errMsg)
- case None => new SearchResult(tree1, EmptyTreeTypeSubstituter)
+ case None => new SearchResult(tree1, EmptyTreeTypeSubstituter, Nil)
}
} catch {
case ex: TypeError =>
@@ -1196,7 +1197,7 @@ trait Implicits {
def findSubManifest(tp: Type) = findManifest(tp, if (full) FullManifestClass else OptManifestClass)
def mot(tp0: Type, from: List[Symbol], to: List[Type]): SearchResult = {
implicit def wrapResult(tree: Tree): SearchResult =
- if (tree == EmptyTree) SearchFailure else new SearchResult(tree, if (from.isEmpty) EmptyTreeTypeSubstituter else new TreeTypeSubstituter(from, to))
+ if (tree == EmptyTree) SearchFailure else new SearchResult(tree, if (from.isEmpty) EmptyTreeTypeSubstituter else new TreeTypeSubstituter(from, to), Nil)
val tp1 = tp0.dealias
tp1 match {
@@ -1284,7 +1285,7 @@ trait Implicits {
}
def wrapResult(tree: Tree): SearchResult =
- if (tree == EmptyTree) SearchFailure else new SearchResult(tree, EmptyTreeTypeSubstituter)
+ if (tree == EmptyTree) SearchFailure else new SearchResult(tree, EmptyTreeTypeSubstituter, Nil)
/** Materializes implicits of predefined types (currently, manifests and tags).
* Will be replaced by implicit macros once we fix them.
diff --git a/src/library/scala/collection/Iterator.scala b/src/library/scala/collection/Iterator.scala
index 01a0aa3b51..1b496383a3 100644
--- a/src/library/scala/collection/Iterator.scala
+++ b/src/library/scala/collection/Iterator.scala
@@ -165,11 +165,11 @@ object Iterator {
/** Avoid stack overflows when applying ++ to lots of iterators by
* flattening the unevaluated iterators out into a vector of closures.
*/
- private[scala] final class ConcatIterator[+A](initial: Vector[() => Iterator[A]]) extends Iterator[A] {
- // current set to null when all iterators are exhausted
- private[this] var current: Iterator[A] = Iterator.empty
+ private[scala] final class ConcatIterator[+A](private[this] var current: Iterator[A], initial: Vector[() => Iterator[A]]) extends Iterator[A] {
+ @deprecated def this(initial: Vector[() => Iterator[A]]) = this(Iterator.empty, initial) // for binary compatibility
private[this] var queue: Vector[() => Iterator[A]] = initial
// Advance current to the next non-empty iterator
+ // current is set to null when all iterators are exhausted
private[this] def advance(): Boolean = {
if (queue.isEmpty) {
current = null
@@ -185,7 +185,7 @@ object Iterator {
def next() = if (hasNext) current.next else Iterator.empty.next
override def ++[B >: A](that: => GenTraversableOnce[B]): Iterator[B] =
- new ConcatIterator(queue :+ (() => that.toIterator))
+ new ConcatIterator(current, queue :+ (() => that.toIterator))
}
private[scala] final class JoinIterator[+A](lhs: Iterator[A], that: => GenTraversableOnce[A]) extends Iterator[A] {
@@ -194,7 +194,7 @@ object Iterator {
def next = if (lhs.hasNext) lhs.next else rhs.next
override def ++[B >: A](that: => GenTraversableOnce[B]) =
- new ConcatIterator(Vector(() => this, () => that.toIterator))
+ new ConcatIterator(this, Vector(() => that.toIterator))
}
}
diff --git a/test/files/neg/t8431.check b/test/files/neg/t8431.check
new file mode 100644
index 0000000000..75351a8ae7
--- /dev/null
+++ b/test/files/neg/t8431.check
@@ -0,0 +1,27 @@
+t8431.scala:24: error: type mismatch;
+ found : CanBuildFrom[Invariant[Nothing]]
+ required: CanBuildFrom[Invariant[G]]
+ s.combined // fail
+ ^
+t8431.scala:24: error: value combined is not a member of Invariant[Nothing]
+ s.combined // fail
+ ^
+t8431.scala:35: error: type mismatch;
+ found : CanBuildFrom[Invariant[Nothing]]
+ required: CanBuildFrom[Invariant[G]]
+ s.combined // was okay!
+ ^
+t8431.scala:35: error: value combined is not a member of Invariant[Nothing]
+ s.combined // was okay!
+ ^
+t8431.scala:45: error: type mismatch;
+ found : CanBuildFrom[Invariant[Nothing]]
+ required: CanBuildFrom[Invariant[G]]
+ convert2(s).combined
+ ^
+t8431.scala:48: error: type mismatch;
+ found : CanBuildFrom[Invariant[Nothing]]
+ required: CanBuildFrom[Invariant[G]]
+ {val c1 = convert2(s); c1.combined}
+ ^
+6 errors found
diff --git a/test/files/neg/t8431.scala b/test/files/neg/t8431.scala
new file mode 100644
index 0000000000..032a1f394d
--- /dev/null
+++ b/test/files/neg/t8431.scala
@@ -0,0 +1,63 @@
+trait Covariant[+A]
+trait Invariant[A] extends Covariant[A @annotation.unchecked.uncheckedVariance]
+
+trait Combinable[G] {
+ def combined = 0
+}
+
+trait CanBuildFrom[+C]
+
+object C {
+ implicit def convert1[G, TRAVONCE[+e] <: Covariant[e]]
+ (xs: TRAVONCE[G]): Combinable[G] = ???
+
+ implicit def convert2[G, SET[e] <: Invariant[e]]
+ (xs: SET[_ <: G])
+ (implicit cbf: CanBuildFrom[SET[G]]): Combinable[G] = ???
+
+ implicit def cbf[A]: CanBuildFrom[Invariant[A]] = ???
+}
+// always failed
+class Test1 {
+ import C.{cbf, convert1, convert2}
+ val s: Invariant[Nothing] = ???
+ s.combined // fail
+}
+// didn't fail, now correctly fails
+class Test2 {
+ import C.{cbf, convert2, convert1}
+
+ val s: Invariant[Nothing] = ???
+
+ // Non-uniformity with Test1 was due to order of typechecking implicit candidates:
+ // the last candidate typechecked was the only one that could contribute undetermined type parameters
+ // to the enclosing context, due to mutation of `Context#undetparam` in `doTypedApply`.
+ s.combined // was okay!
+}
+
+
+class TestExplicit {
+ import C.{cbf, convert2}
+
+ val s: Invariant[Nothing] = ???
+
+ // Now the implicit Test fail uniformly as per this explicit conversion
+ convert2(s).combined
+
+ // Breaking this expression down doesn't make it work.
+ {val c1 = convert2(s); c1.combined}
+}
+
+// These ones work before and after; infering G=Null doesn't need to contribute an undetermined type param.
+class Test3 {
+ import C.{cbf, convert1, convert2}
+ val s: Invariant[Null] = ???
+ s.combined // okay
+}
+
+class Test4 {
+ import C.{cbf, convert2, convert1}
+
+ val s: Invariant[Null] = ???
+ s.combined // okay
+}
diff --git a/test/files/run/t8425.check b/test/files/run/t8425.check
new file mode 100644
index 0000000000..8379fa0a74
--- /dev/null
+++ b/test/files/run/t8425.check
@@ -0,0 +1 @@
+List(fresh$macro$1, $macro$2)
diff --git a/test/files/run/t8425/Macros_1.scala b/test/files/run/t8425/Macros_1.scala
new file mode 100644
index 0000000000..71a96518e8
--- /dev/null
+++ b/test/files/run/t8425/Macros_1.scala
@@ -0,0 +1,12 @@
+import scala.language.experimental.macros
+import scala.reflect.macros.blackbox.Context
+
+object Macros {
+ def foo: Unit = macro impl
+ def impl(c: Context) = {
+ import c.universe._
+ val test1 = c.freshName()
+ val test2 = c.freshName("$")
+ q"println(List($test1, $test2))"
+ }
+} \ No newline at end of file
diff --git a/test/files/run/t8425/Test_2.scala b/test/files/run/t8425/Test_2.scala
new file mode 100644
index 0000000000..acfddae942
--- /dev/null
+++ b/test/files/run/t8425/Test_2.scala
@@ -0,0 +1,3 @@
+object Test extends App {
+ Macros.foo
+} \ No newline at end of file
diff --git a/test/files/run/t8428.scala b/test/files/run/t8428.scala
new file mode 100644
index 0000000000..7da1207b7b
--- /dev/null
+++ b/test/files/run/t8428.scala
@@ -0,0 +1,12 @@
+object Test extends App {
+ val xs = List.tabulate(4)(List(_))
+ val i = xs.map(_.iterator).reduce { (a,b) =>
+ a.hasNext
+ a ++ b
+ }
+
+ val r1 = i.toList
+ val r2 = xs.flatten.toList
+
+ assert(r1 == r2, r1)
+}
diff --git a/versions.properties b/versions.properties
index 9042c4198b..d92553d68d 100644
--- a/versions.properties
+++ b/versions.properties
@@ -1,20 +1,20 @@
-#Fri, 28 Feb 2014 07:00:05 +0100
-starr.version=2.11.0-RC1
+#Wed, 19 Mar 2014 03:05:28 +0100
+starr.version=2.11.0-RC3
starr.use.released=1
# These are the versions of the modules that go with this release.
# These properties are used during PR validation and in dbuild builds.
-scala.binary.version=2.11.0-RC1
+scala.binary.version=2.11.0-RC3
# external modules shipped with distribution:
-scala-xml.version.number=1.0.0
-scala-parser-combinators.version.number=1.0.0
-scala-continuations-plugin.version.number=1.0.0
-scala-continuations-library.version.number=1.0.0
-scala-swing.version.number=1.0.0
+scala-xml.version.number=1.0.1
+scala-parser-combinators.version.number=1.0.1
+scala-continuations-plugin.version.number=1.0.1
+scala-continuations-library.version.number=1.0.1
+scala-swing.version.number=1.0.1
# these ship with distribution (and scala-library-all depends on them)
-akka-actor.version.number=2.3.0-RC4
+akka-actor.version.number=2.3.0
actors-migration.version.number=1.1.0
# external modules, used internally (not shipped)