diff options
-rw-r--r-- | bincompat-backward.whitelist.conf | 17 | ||||
-rw-r--r-- | bincompat-forward.whitelist.conf | 29 | ||||
-rw-r--r-- | src/compiler/scala/tools/reflect/quasiquotes/Holes.scala | 6 | ||||
-rw-r--r-- | src/library/scala/collection/Iterator.scala | 10 | ||||
-rw-r--r-- | src/reflect/scala/reflect/api/Internals.scala | 2 | ||||
-rw-r--r-- | src/reflect/scala/reflect/api/Mirror.scala | 18 | ||||
-rw-r--r-- | src/reflect/scala/reflect/api/StandardLiftables.scala | 1 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/Mirrors.scala | 2 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/ReificationSupport.scala | 22 | ||||
-rw-r--r-- | test/files/pos/t8411/Macros_1.scala | 10 | ||||
-rw-r--r-- | test/files/pos/t8411/Test_2.scala | 4 | ||||
-rw-r--r-- | test/files/run/mirror_symbolof_x.check | 13 | ||||
-rw-r--r-- | test/files/run/mirror_symbolof_x.scala | 43 | ||||
-rw-r--r-- | test/files/run/t8428.scala | 12 | ||||
-rw-r--r-- | test/files/scalacheck/quasiquotes/ErrorProps.scala | 31 | ||||
-rw-r--r-- | test/files/scalacheck/quasiquotes/LiftableProps.scala | 8 | ||||
-rw-r--r-- | test/files/scalacheck/quasiquotes/TypecheckedProps.scala | 5 | ||||
-rw-r--r-- | versions.properties | 16 |
18 files changed, 223 insertions, 26 deletions
diff --git a/bincompat-backward.whitelist.conf b/bincompat-backward.whitelist.conf index ae31c286f3..b799b17c21 100644 --- a/bincompat-backward.whitelist.conf +++ b/bincompat-backward.whitelist.conf @@ -102,6 +102,11 @@ filter { matchName="scala.collection.mutable.ArrayOps#ofDouble.unzip3" problemName=IncompatibleMethTypeProblem }, + // see SI-8200 + { + matchName="scala.reflect.api.StandardLiftables#StandardLiftableInstances.liftTree" + problemName=MissingMethodProblem + }, // see SI-8331 { matchName="scala.reflect.api.Internals#ReificationSupportApi#SyntacticTypeAppliedExtractor.unapply" @@ -127,6 +132,18 @@ filter { { matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticPartialFunction" problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.api.Mirror.symbolOf" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.api.Mirror.typeOf" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.api.Mirror.weakTypeOf" + problemName=MissingMethodProblem } ] } diff --git a/bincompat-forward.whitelist.conf b/bincompat-forward.whitelist.conf index 3eba1effc1..58bf98a173 100644 --- a/bincompat-forward.whitelist.conf +++ b/bincompat-forward.whitelist.conf @@ -102,7 +102,16 @@ filter { matchName="scala.collection.mutable.ArrayOps#ofDouble.unzip3" problemName=IncompatibleMethTypeProblem }, - // see SI-8331 + // see SI-8200 + { + matchName="scala.reflect.api.Liftables#Liftable.liftTree" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.api.StandardLiftables#StandardLiftableInstances.liftTree" + problemName=MissingMethodProblem + }, + // see SI-8331 { matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticSelectType" problemName=MissingMethodProblem @@ -139,6 +148,22 @@ filter { { matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticPartialFunction" problemName=MissingMethodProblem - } + }, + { + matchName="scala.collection.Iterator#ConcatIterator.this" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.api.Mirror.symbolOf" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.api.Mirror.typeOf" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.api.Mirror.weakTypeOf" + problemName=MissingMethodProblem + } ] } diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala b/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala index 8376fca4ad..55a28f9f20 100644 --- a/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala +++ b/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala @@ -78,8 +78,10 @@ trait Holes { self: Quasiquotes => val (strippedTpe, tpe): (Type, Type) = { val (strippedRank, strippedTpe) = stripIterable(unquotee.tpe, limit = Some(annotatedRank)) if (isBottomType(strippedTpe)) cantSplice() - else if (isNativeType(strippedTpe)) (strippedTpe, iterableTypeFromRank(annotatedRank, strippedTpe)) - else if (isLiftableType(strippedTpe)) (strippedTpe, iterableTypeFromRank(annotatedRank, treeType)) + else if (isNativeType(strippedTpe)) { + if (strippedRank != NoDot && !(strippedTpe <:< treeType) && !isLiftableType(strippedTpe)) cantSplice() + else (strippedTpe, iterableTypeFromRank(annotatedRank, strippedTpe)) + } else if (isLiftableType(strippedTpe)) (strippedTpe, iterableTypeFromRank(annotatedRank, treeType)) else cantSplice() } 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/src/reflect/scala/reflect/api/Internals.scala b/src/reflect/scala/reflect/api/Internals.scala index 9faba7efd7..7788dba63e 100644 --- a/src/reflect/scala/reflect/api/Internals.scala +++ b/src/reflect/scala/reflect/api/Internals.scala @@ -765,7 +765,7 @@ trait Internals { self: Universe => val SyntacticPartialFunction: SyntacticPartialFunctionExtractor trait SyntacticPartialFunctionExtractor { def apply(cases: List[Tree]): Match - def unapply(tree: Match): Option[List[CaseDef]] + def unapply(tree: Tree): Option[List[CaseDef]] } val SyntacticMatch: SyntacticMatchExtractor diff --git a/src/reflect/scala/reflect/api/Mirror.scala b/src/reflect/scala/reflect/api/Mirror.scala index da3afd89ff..318fdb369a 100644 --- a/src/reflect/scala/reflect/api/Mirror.scala +++ b/src/reflect/scala/reflect/api/Mirror.scala @@ -118,4 +118,22 @@ abstract class Mirror[U <: Universe with Singleton] { * @group Mirror */ def staticPackage(fullName: String): U#ModuleSymbol + + /** + * Shortcut for `implicitly[WeakTypeTag[T]].tpe` + * @group TypeTags + */ + def weakTypeOf[T: universe.WeakTypeTag]: U#Type = universe.weakTypeTag[T].in(this).tpe + + /** + * Shortcut for `implicitly[TypeTag[T]].tpe` + * @group TypeTags + */ + def typeOf[T: universe.TypeTag]: U#Type = universe.typeTag[T].in(this).tpe + + /** + * Type symbol of `x` as derived from a type tag. + * @group TypeTags + */ + def symbolOf[T: universe.WeakTypeTag]: U#TypeSymbol } diff --git a/src/reflect/scala/reflect/api/StandardLiftables.scala b/src/reflect/scala/reflect/api/StandardLiftables.scala index af11de46ce..66ac62cc9e 100644 --- a/src/reflect/scala/reflect/api/StandardLiftables.scala +++ b/src/reflect/scala/reflect/api/StandardLiftables.scala @@ -27,6 +27,7 @@ trait StandardLiftables { self: Universe => callScala(stdnme.Symbol)(Literal(Constant(v.name)) :: Nil) } + implicit def liftTree[T <: Tree]: Liftable[T] = Liftable { identity } implicit def liftName[T <: Name]: Liftable[T] = Liftable { name => Ident(name) } implicit def liftExpr[T <: Expr[_]]: Liftable[T] = Liftable { expr => expr.tree } implicit def liftType[T <: Type]: Liftable[T] = Liftable { tpe => TypeTree(tpe) } diff --git a/src/reflect/scala/reflect/internal/Mirrors.scala b/src/reflect/scala/reflect/internal/Mirrors.scala index 7065a8cd6d..4a35e024de 100644 --- a/src/reflect/scala/reflect/internal/Mirrors.scala +++ b/src/reflect/scala/reflect/internal/Mirrors.scala @@ -30,6 +30,8 @@ trait Mirrors extends api.Mirrors { val EmptyPackageClass: ClassSymbol val EmptyPackage: ModuleSymbol + def symbolOf[T: universe.WeakTypeTag]: universe.TypeSymbol = universe.weakTypeTag[T].in(this).tpe.typeSymbolDirect.asType + def findMemberFromRoot(fullName: Name): Symbol = { val segs = nme.segments(fullName.toString, fullName.isTermName) if (segs.isEmpty) NoSymbol diff --git a/src/reflect/scala/reflect/internal/ReificationSupport.scala b/src/reflect/scala/reflect/internal/ReificationSupport.scala index 9a130337b4..f9f93fbff0 100644 --- a/src/reflect/scala/reflect/internal/ReificationSupport.scala +++ b/src/reflect/scala/reflect/internal/ReificationSupport.scala @@ -6,7 +6,7 @@ import Flags._ import util._ trait ReificationSupport { self: SymbolTable => - import definitions.{TupleClass, FunctionClass, ScalaPackage, UnitClass} + import definitions._ import internal._ class ReificationSupportImpl extends ReificationSupportApi { @@ -852,9 +852,25 @@ trait ReificationSupport { self: SymbolTable => object SyntacticPartialFunction extends SyntacticPartialFunctionExtractor { def apply(cases: List[Tree]): Match = Match(EmptyTree, mkCases(cases)) - def unapply(tree: Match): Option[List[CaseDef]] = tree match { + def unapply(tree: Tree): Option[List[CaseDef]] = tree match { case Match(EmptyTree, cases) => Some(cases) - case _ => None + case Typed( + Block( + List(ClassDef(clsMods, tpnme.ANON_FUN_NAME, Nil, Template( + List(abspf: TypeTree, ser: TypeTree), noSelfType, List( + DefDef(_, nme.CONSTRUCTOR, _, _, _, _), + DefDef(_, nme.applyOrElse, _, _, _, + Match(_, cases :+ + CaseDef(Bind(nme.DEFAULT_CASE, Ident(nme.WILDCARD)), _, _))), + DefDef(_, nme.isDefinedAt, _, _, _, _))))), + Apply(Select(New(Ident(tpnme.ANON_FUN_NAME)), termNames.CONSTRUCTOR), List())), + pf: TypeTree) + if pf.tpe != null && pf.tpe.typeSymbol.eq(PartialFunctionClass) && + abspf.tpe != null && abspf.tpe.typeSymbol.eq(AbstractPartialFunctionClass) && + ser.tpe != null && ser.tpe.typeSymbol.eq(SerializableClass) && + clsMods.hasFlag(FINAL) && clsMods.hasFlag(SYNTHETIC) => + Some(cases) + case _ => None } } diff --git a/test/files/pos/t8411/Macros_1.scala b/test/files/pos/t8411/Macros_1.scala new file mode 100644 index 0000000000..c5319c559c --- /dev/null +++ b/test/files/pos/t8411/Macros_1.scala @@ -0,0 +1,10 @@ +import scala.language.experimental.macros +import scala.reflect.macros.blackbox.Context + +object Macros { + def defaultZeroCase(pf: PartialFunction[Int, Int]): PartialFunction[Int, Int] = macro impl + def impl(c: Context)(pf: c.Tree) = { import c.universe._ + val q"{ case ..$cases }" = pf + q"{ case ..$cases case _ => 0 }" + } +} diff --git a/test/files/pos/t8411/Test_2.scala b/test/files/pos/t8411/Test_2.scala new file mode 100644 index 0000000000..a0ad30f0f5 --- /dev/null +++ b/test/files/pos/t8411/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + val pf = Macros.defaultZeroCase { case 1 => 2 } + assert(pf(2) == 0) +} diff --git a/test/files/run/mirror_symbolof_x.check b/test/files/run/mirror_symbolof_x.check new file mode 100644 index 0000000000..cc9cad7a13 --- /dev/null +++ b/test/files/run/mirror_symbolof_x.check @@ -0,0 +1,13 @@ +class Int +object C +type T +type Id +class Nothing +class Null +class Int +object C +type T +type Id +class Nothing +class Null +exception: class C not found. diff --git a/test/files/run/mirror_symbolof_x.scala b/test/files/run/mirror_symbolof_x.scala new file mode 100644 index 0000000000..8fec301f56 --- /dev/null +++ b/test/files/run/mirror_symbolof_x.scala @@ -0,0 +1,43 @@ +import scala.reflect.runtime.universe._ +import scala.reflect.runtime.{universe => ru} +import scala.reflect.runtime.{currentMirror => cm} +import scala.reflect.api.Mirror + +class C +object C + +object Test extends App { + object test1 { + val m = cm + type T = Int + type Id[X] = X + println(m.symbolOf[Int]: ru.TypeSymbol) + println(m.symbolOf[C.type]: ru.TypeSymbol) + println(m.symbolOf[T]: ru.TypeSymbol) + println(m.symbolOf[Id[_]]: ru.TypeSymbol) + println(m.symbolOf[Nothing]: ru.TypeSymbol) + println(m.symbolOf[Null]: ru.TypeSymbol) + } + + object test2 { + val m: Mirror[ru.type] = cm + type T = Int + type Id[X] = X + println(m.symbolOf[Int]: ru.TypeSymbol) + println(m.symbolOf[C.type]: ru.TypeSymbol) + println(m.symbolOf[T]: ru.TypeSymbol) + println(m.symbolOf[Id[_]]: ru.TypeSymbol) + println(m.symbolOf[Nothing]: ru.TypeSymbol) + println(m.symbolOf[Null]: ru.TypeSymbol) + } + + object test3 { + val m = ru.runtimeMirror(classOf[Int].getClass.getClassLoader) + try println(m.symbolOf[C]) + catch { case ex: ScalaReflectionException => println(s"exception: ${ex.getMessage}") } + } + + test1 + test2 + test3 +} 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/test/files/scalacheck/quasiquotes/ErrorProps.scala b/test/files/scalacheck/quasiquotes/ErrorProps.scala index 3d9b27de77..9137fe17d8 100644 --- a/test/files/scalacheck/quasiquotes/ErrorProps.scala +++ b/test/files/scalacheck/quasiquotes/ErrorProps.scala @@ -9,9 +9,10 @@ object ErrorProps extends QuasiquoteProperties("errors") { """) property("can't unquote with given rank") = fails( - "Can't unquote List[reflect.runtime.universe.Ident], consider using ..", + "Can't unquote List[StringBuilder], consider using .. or providing an implicit instance of Liftable[List[StringBuilder]]", """ - val xs = List(q"x", q"x") + import java.lang.StringBuilder + val xs: List[StringBuilder] = Nil q"$xs" """) @@ -71,9 +72,10 @@ object ErrorProps extends QuasiquoteProperties("errors") { """) property("use ... rank or provide liftable") = fails( - "Can't unquote List[List[reflect.runtime.universe.Ident]], consider using ...", + "Can't unquote List[List[StringBuilder]], consider using ... or providing an implicit instance of Liftable[List[List[StringBuilder]]]", """ - val xs = List(List(q"x", q"x")) + import java.lang.StringBuilder + val xs: List[List[StringBuilder]] = Nil q"$xs" """) @@ -172,6 +174,27 @@ object ErrorProps extends QuasiquoteProperties("errors") { tq"_" """) + property("SI-8420: don't crash on splicing of non-unliftable native type (1)") = fails( + "Can't unquote List[reflect.runtime.universe.Symbol] with .., consider omitting the dots or providing an implicit instance of Liftable[reflect.runtime.universe.Symbol]", + """ + val l: List[Symbol] = Nil + q"f(..$l)" + """) + + property("SI-8420: don't crash on splicing of non-unliftable native type (2)") = fails( + "Can't unquote List[reflect.runtime.universe.FlagSet] with .., consider omitting the dots or providing an implicit instance of Liftable[reflect.runtime.universe.FlagSet]", + """ + val l: List[FlagSet] = Nil + q"f(..$l)" + """) + + property("SI-8420: don't crash on splicing of non-unliftable native type (3)") = fails( + "Can't unquote List[reflect.runtime.universe.Modifiers] with .., consider omitting the dots or providing an implicit instance of Liftable[reflect.runtime.universe.Modifiers]", + """ + val l: List[Modifiers] = Nil + q"f(..$l)" + """) + // // Make sure a nice error is reported in this case // { import Flag._; val mods = NoMods; q"lazy $mods val x: Int" } } diff --git a/test/files/scalacheck/quasiquotes/LiftableProps.scala b/test/files/scalacheck/quasiquotes/LiftableProps.scala index 5d0eeb53c6..29fdea5c89 100644 --- a/test/files/scalacheck/quasiquotes/LiftableProps.scala +++ b/test/files/scalacheck/quasiquotes/LiftableProps.scala @@ -88,9 +88,10 @@ object LiftableProps extends QuasiquoteProperties("liftable") { assert(q"$const" ≈ q"0") } + val immutable = q"$scalapkg.collection.immutable" + property("lift list variants") = test { val lst = List(1, 2) - val immutable = q"$scalapkg.collection.immutable" assert(q"$lst" ≈ q"$immutable.List(1, 2)") assert(q"f(..$lst)" ≈ q"f(1, 2)") val llst = List(List(1), List(2)) @@ -98,6 +99,11 @@ object LiftableProps extends QuasiquoteProperties("liftable") { assert(q"f(...$llst)" ≈ q"f(1)(2)") } + property("lift list of tree") = test { + val lst = List(q"a", q"b") + assert(q"$lst" ≈ q"$immutable.List(a, b)") + } + property("lift tuple") = test { assert(q"${(1, 2)}" ≈ q"(1, 2)") assert(q"${(1, 2, 3)}" ≈ q"(1, 2, 3)") diff --git a/test/files/scalacheck/quasiquotes/TypecheckedProps.scala b/test/files/scalacheck/quasiquotes/TypecheckedProps.scala index 7c4cb0306e..fb2eb69321 100644 --- a/test/files/scalacheck/quasiquotes/TypecheckedProps.scala +++ b/test/files/scalacheck/quasiquotes/TypecheckedProps.scala @@ -152,4 +152,9 @@ object TypecheckedProps extends QuasiquoteProperties("typechecked") { assert(name == defName) assert(rhs ≈ defRhs) } + + property("partial function") = test { + val q"{ case ..$cases }: $ascr" = typecheck(q"{ case 1 => () }: PartialFunction[Int, Unit]") + assert(cases ≈ q"{ case 1 => () }".cases) + } } diff --git a/versions.properties b/versions.properties index 0ed771ac3e..d92553d68d 100644 --- a/versions.properties +++ b/versions.properties @@ -1,17 +1,17 @@ -#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 |