summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/reflect/reify/Reifier.scala10
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala4
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala16
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala3
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala3
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/ScalacPatternExpanders.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala2
-rw-r--r--src/compiler/scala/tools/reflect/quasiquotes/Holes.scala114
-rw-r--r--src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala2
-rw-r--r--src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala10
-rw-r--r--src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala34
-rw-r--r--src/library/scala/Predef.scala23
-rw-r--r--src/reflect/scala/reflect/api/Printers.scala12
-rw-r--r--src/reflect/scala/reflect/api/Quasiquotes.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala3
-rw-r--r--src/reflect/scala/reflect/internal/Printers.scala184
-rw-r--r--src/reflect/scala/reflect/internal/ReificationSupport.scala8
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala2
-rw-r--r--src/reflect/scala/reflect/internal/TreeInfo.scala61
-rw-r--r--src/reflect/scala/reflect/internal/Trees.scala10
-rw-r--r--src/reflect/scala/reflect/internal/settings/MutableSettings.scala1
-rw-r--r--src/reflect/scala/reflect/internal/tpe/GlbLubs.scala69
-rw-r--r--src/reflect/scala/reflect/runtime/Settings.scala1
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/Settings.scala2
-rw-r--r--test/files/neg/logImplicits.check2
-rw-r--r--test/files/neg/predef-masking.scala2
-rw-r--r--test/files/neg/quasiquotes-syntax-error-position.check2
-rw-r--r--test/files/neg/t6675.flags2
-rw-r--r--test/files/neg/t6675b.flags2
-rw-r--r--test/files/neg/t7980.check (renamed from test/files/neg/si7980.check)2
-rw-r--r--test/files/neg/t7980.scala (renamed from test/files/neg/si7980.scala)0
-rw-r--r--test/files/neg/t8229.check4
-rw-r--r--test/files/neg/t8229.scala6
-rw-r--r--test/files/pos/t6675.flags2
-rw-r--r--test/files/pos/t7788.scala8
-rw-r--r--test/files/pos/t8224.scala12
-rw-r--r--test/files/pos/t8315.flags1
-rw-r--r--test/files/pos/t8315.scala12
-rw-r--r--test/files/pos/t8315b.flags1
-rw-r--r--test/files/pos/t8315b.scala11
-rw-r--r--test/files/run/macro-reify-chained1/Impls_Macros_1.scala (renamed from test/files/run/macro-reify-nested-b/Impls_Macros_1.scala)3
-rw-r--r--test/files/run/macro-reify-chained1/Test_2.scala9
-rw-r--r--test/files/run/macro-reify-chained2/Impls_Macros_1.scala47
-rw-r--r--test/files/run/macro-reify-chained2/Test_2.scala9
-rw-r--r--test/files/run/macro-reify-nested-a.flags1
-rw-r--r--test/files/run/macro-reify-nested-a1/Impls_Macros_1.scala (renamed from test/files/run/macro-reify-nested-a/Impls_Macros_1.scala)3
-rw-r--r--test/files/run/macro-reify-nested-a1/Test_2.scala (renamed from test/files/run/macro-reify-nested-a/Test_2.scala)5
-rw-r--r--test/files/run/macro-reify-nested-a2/Impls_Macros_1.scala47
-rw-r--r--test/files/run/macro-reify-nested-a2/Test_2.scala9
-rw-r--r--test/files/run/macro-reify-nested-b.flags1
-rw-r--r--test/files/run/macro-reify-nested-b1/Impls_Macros_1.scala47
-rw-r--r--test/files/run/macro-reify-nested-b1/Test_2.scala (renamed from test/files/run/macro-reify-nested-b/Test_2.scala)5
-rw-r--r--test/files/run/macro-reify-nested-b2/Impls_Macros_1.scala47
-rw-r--r--test/files/run/macro-reify-nested-b2/Test_2.scala9
-rw-r--r--test/files/run/t2251.flags1
-rw-r--r--test/files/run/t2251b.flags1
-rw-r--r--test/files/run/t4577.scala38
-rw-r--r--test/files/run/t6111.check1
-rw-r--r--test/files/run/t6111.scala2
-rw-r--r--test/files/run/t7185.check4
-rw-r--r--test/files/run/t8197.scala13
-rw-r--r--test/files/scalacheck/quasiquotes/DefinitionConstructionProps.scala100
-rw-r--r--test/files/scalacheck/quasiquotes/DefinitionDeconstructionProps.scala2
-rw-r--r--test/files/scalacheck/quasiquotes/ErrorProps.scala58
-rw-r--r--test/files/scalacheck/quasiquotes/LiftableProps.scala20
-rw-r--r--test/files/scalacheck/quasiquotes/PatternConstructionProps.scala16
-rw-r--r--test/files/scalacheck/quasiquotes/TermConstructionProps.scala56
-rw-r--r--test/files/scalacheck/quasiquotes/TypeConstructionProps.scala2
-rw-r--r--test/files/scalacheck/quasiquotes/TypecheckedProps.scala72
-rw-r--r--test/files/scalacheck/quasiquotes/UnliftableProps.scala4
-rw-r--r--test/junit/scala/reflect/internal/PrintersTest.scala2
-rw-r--r--test/scaladoc/run/diagrams-base.scala2
-rw-r--r--test/scaladoc/run/diagrams-filtering.scala2
76 files changed, 948 insertions, 345 deletions
diff --git a/src/compiler/scala/reflect/reify/Reifier.scala b/src/compiler/scala/reflect/reify/Reifier.scala
index 6b0a0ee8d7..b1cc797389 100644
--- a/src/compiler/scala/reflect/reify/Reifier.scala
+++ b/src/compiler/scala/reflect/reify/Reifier.scala
@@ -110,10 +110,18 @@ abstract class Reifier extends States
// todo. this is a common problem with non-trivial macros in our current macro system
// needs to be solved some day
// upd. a new hope: https://groups.google.com/forum/#!topic/scala-internals/TtCTPlj_qcQ
- val untyped = resetAttrs(result, leaveAlone = {
+ var importantSymbols = Set[Symbol](
+ NothingClass, AnyClass, SingletonClass, PredefModule, ScalaRunTimeModule, TypeCreatorClass, TreeCreatorClass, MirrorClass,
+ ApiUniverseClass, JavaUniverseClass, ReflectRuntimePackage, runDefinitions.ReflectRuntimeCurrentMirror)
+ importantSymbols ++= importantSymbols map (_.companionSymbol)
+ importantSymbols ++= importantSymbols map (_.moduleClass)
+ importantSymbols ++= importantSymbols map (_.linkedClassOfClass)
+ def isImportantSymbol(sym: Symbol): Boolean = sym != null && sym != NoSymbol && importantSymbols(sym)
+ val untyped = brutallyResetAttrs(result, leaveAlone = {
case ValDef(_, u, _, _) if u == nme.UNIVERSE_SHORT => true
case ValDef(_, m, _, _) if m == nme.MIRROR_SHORT => true
case tree if symtab.syms contains tree.symbol => true
+ case tree if isImportantSymbol(tree.symbol) => true
case _ => false
})
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index 03b76ed99e..6b14461cac 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -1798,10 +1798,8 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
private def writeICode() {
val printer = new icodes.TextPrinter(null, icodes.linearizer)
icodes.classes.values.foreach((cls) => {
- val suffix = if (cls.symbol.hasModuleFlag) "$.icode" else ".icode"
+ val suffix = s"${if (cls.symbol.hasModuleFlag) "$" else ""}_${phase}.icode"
val file = getFile(cls.symbol, suffix)
-// if (file.exists())
-// file = new File(file.getParentFile(), file.getName() + "1")
try {
val stream = new FileOutputStream(file)
printer.setWriter(new PrintWriter(stream, true))
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index d33ea5bb5c..9ca06427e8 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -194,8 +194,18 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
//
// def resetAllAttrs(x: Tree, leaveAlone: Tree => Boolean = null): Tree = new ResetAttrs(localOnly = false, leaveAlone).transform(x)
+ // upd. Unfortunately this didn't work out quite as we expected. The last two users of resetAllAttrs:
+ // reification and typedLabelDef broke in very weird ways when we replaced resetAllAttrs with resetLocalAttrs
+ // (see SI-8316 change from resetAllAttrs to resetLocalAttrs in reifiers broke Slick and
+ // SI-8318 NPE in mixin in scala-continuations for more information).
+ // Given that we're supposed to release 2.11.0-RC1 in less than a week, I'm temporarily reinstating resetAllAttrs
+ // until we have time to better understand what's going on. In order to dissuade people from using it,
+ // it now comes with a new, ridiculous name.
/** @see ResetAttrs */
- def resetAttrs(x: Tree, leaveAlone: Tree => Boolean = null): Tree = new ResetAttrs(leaveAlone).transform(x)
+ def brutallyResetAttrs(x: Tree, leaveAlone: Tree => Boolean = null): Tree = new ResetAttrs(brutally = true, leaveAlone).transform(x)
+
+ /** @see ResetAttrs */
+ def resetAttrs(x: Tree): Tree = new ResetAttrs(brutally = false, leaveAlone = null).transform(x)
/** A transformer which resets symbol and tpe fields of all nodes in a given tree,
* with special treatment of:
@@ -206,7 +216,7 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
*
* (bq:) This transformer has mutable state and should be discarded after use
*/
- private class ResetAttrs(leaveAlone: Tree => Boolean = null) {
+ private class ResetAttrs(brutally: Boolean, leaveAlone: Tree => Boolean) {
// this used to be based on -Ydebug, but the need for logging in this code is so situational
// that I've reverted to a hard-coded constant here.
val debug = false
@@ -299,7 +309,7 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
// if we move these trees into lexical contexts different from their original locations.
if (dupl.hasSymbol) {
val sym = dupl.symbol
- val vetoScope = !(locals contains sym)
+ val vetoScope = !brutally && !(locals contains sym)
val vetoThis = dupl.isInstanceOf[This] && sym.isPackageClass
if (!(vetoScope || vetoThis)) dupl.symbol = NoSymbol
}
diff --git a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala
index 0f317422ac..b39fee65bb 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala
@@ -95,8 +95,10 @@ abstract class DeadCodeElimination extends SubComponent {
localStores.clear()
clobbers.clear()
m.code.blocks.clear()
+ m.code.touched = true
accessedLocals = m.params.reverse
m.code.blocks ++= linearizer.linearize(m)
+ m.code.touched = true
collectRDef(m)
mark()
sweep(m)
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala
index 2a3c631a66..dc4969be43 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala
@@ -261,7 +261,8 @@ trait MatchApproximation extends TreeAndTypeAnalysis with ScalaLogic with MatchT
}
def nonNullTest(testedBinder: Symbol) = uniqueNonNullProp(binderToUniqueTree(testedBinder))
def equalsTest(pat: Tree, testedBinder: Symbol) = uniqueEqualityProp(binderToUniqueTree(testedBinder), unique(pat))
- def eqTest(pat: Tree, testedBinder: Symbol) = uniqueEqualityProp(binderToUniqueTree(testedBinder), unique(pat)) // TODO: eq, not ==
+ // rewrite eq test to type test against the singleton type `pat.tpe`; unrelated to == (uniqueEqualityProp), could be null
+ def eqTest(pat: Tree, testedBinder: Symbol) = uniqueTypeProp(binderToUniqueTree(testedBinder), uniqueTp(pat.tpe))
def tru = True
}
ttm.renderCondition(condStrategy)
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala
index a80f158949..5d8a9fecef 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala
@@ -447,8 +447,7 @@ trait MatchTreeMaking extends MatchCodeGen with Debugging {
// - Scala's arrays are invariant (so we don't drop type tests unsoundly)
if (extractorArgTypeTest) mkDefault
else expectedTp match {
- // TODO: [SPEC] the spec requires `eq` instead of `==` for singleton types - this implies sym.isStable
- case SingleType(_, sym) => and(mkEqualsTest(gen.mkAttributedQualifier(expectedTp)), mkTypeTest)
+ case SingleType(_, sym) => mkEqTest(gen.mkAttributedQualifier(expectedTp)) // SI-4577, SI-4897
case ThisType(sym) if sym.isModule => and(mkEqualsTest(CODE.REF(sym)), mkTypeTest) // must use == to support e.g. List() == Nil
case ConstantType(Constant(null)) if isAnyRef => mkEqTest(expTp(CODE.NULL))
case ConstantType(const) => mkEqualsTest(expTp(Literal(const)))
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/ScalacPatternExpanders.scala b/src/compiler/scala/tools/nsc/transform/patmat/ScalacPatternExpanders.scala
index 7858cb5586..d10eff1d8d 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/ScalacPatternExpanders.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/ScalacPatternExpanders.scala
@@ -139,8 +139,8 @@ trait ScalacPatternExpanders {
def acceptMessage = if (extractor.isErroneous) "" else s" to hold ${extractor.offeringString}"
val requiresTupling = isUnapply && patterns.totalArity == 1 && productArity > 1
- if (settings.lint && requiresTupling && effectivePatternArity(args) == 1)
- currentUnit.warning(sel.pos, s"${sel.symbol.owner} expects $productArity patterns$acceptMessage but crushing into $productArity-tuple to fit single pattern (SI-6675)")
+ if (requiresTupling && effectivePatternArity(args) == 1)
+ currentUnit.deprecationWarning(sel.pos, s"${sel.symbol.owner} expects $productArity patterns$acceptMessage but crushing into $productArity-tuple to fit single pattern (SI-6675)")
val normalizedExtractor = if (requiresTupling) tupleExtractor(extractor) else extractor
validateAligned(fn, Aligned(patterns, normalizedExtractor))
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index 2bb874a8aa..c8ac3622e2 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -807,7 +807,7 @@ trait Implicits {
private def isIneligible(info: ImplicitInfo) = (
info.isCyclicOrErroneous
- || isView && (info.sym eq Predef_conforms)
+ || isView && (info.sym eq Predef_conforms) // as an implicit conversion, Predef.$conforms is a no-op, so exclude it
|| (!context.macrosEnabled && info.sym.isTermMacro)
)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index 2d6c94349b..50744f2d72 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -1328,7 +1328,7 @@ trait Infer extends Checkable {
eligible
else
eligible filter (alt =>
- !alt.hasDefault && isApplicableBasedOnArity(alt.tpe, argtpes.length, varargsStar, tuplingAllowed = true)
+ !mexists(alt.info.paramss)(_.hasDefault) && isApplicableBasedOnArity(alt.tpe, argtpes.length, varargsStar, tuplingAllowed = true)
)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 8721450dc9..fa96d98bcc 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -2288,7 +2288,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
val sym2 = namer.enterInScope(
context.owner.newLabel(ldef.name, ldef.pos) setInfo MethodType(List(), restpe))
val LabelDef(_, _, rhs1) = resetAttrs(ldef)
- val rhs2 = typed(rhs1, restpe)
+ val rhs2 = typed(brutallyResetAttrs(rhs1), restpe)
ldef.params foreach (param => param setType param.symbol.tpe)
deriveLabelDef(ldef)(_ => rhs2) setSymbol sym2 setType restpe
}
diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala b/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala
index c2f1bf430d..8376fca4ad 100644
--- a/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala
+++ b/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala
@@ -5,17 +5,17 @@ import scala.collection.{immutable, mutable}
import scala.reflect.internal.Flags._
import scala.reflect.macros.TypecheckException
-class Cardinality private[Cardinality](val value: Int) extends AnyVal {
- def pred = { assert(value - 1 >= 0); new Cardinality(value - 1) }
- def succ = new Cardinality(value + 1)
+class Rank private[Rank](val value: Int) extends AnyVal {
+ def pred = { assert(value - 1 >= 0); new Rank(value - 1) }
+ def succ = new Rank(value + 1)
override def toString = if (value == 0) "no dots" else "." * (value + 1)
}
-object Cardinality {
- val NoDot = new Cardinality(0)
- val DotDot = new Cardinality(1)
- val DotDotDot = new Cardinality(2)
- object Dot { def unapply(card: Cardinality) = card != NoDot }
+object Rank {
+ val NoDot = new Rank(0)
+ val DotDot = new Rank(1)
+ val DotDotDot = new Rank(2)
+ object Dot { def unapply(rank: Rank) = rank != NoDot }
def parseDots(part: String) = {
if (part.endsWith("...")) (part.stripSuffix("..."), DotDotDot)
else if (part.endsWith("..")) (part.stripSuffix(".."), DotDot)
@@ -27,7 +27,7 @@ object Cardinality {
*/
trait Holes { self: Quasiquotes =>
import global._
- import Cardinality._
+ import Rank._
import definitions._
import universeTypes._
@@ -43,43 +43,43 @@ trait Holes { self: Quasiquotes =>
tpe <:< NothingClass.tpe || tpe <:< NullClass.tpe
private def extractIterableTParam(tpe: Type) =
IterableTParam.asSeenFrom(tpe, IterableClass)
- private def stripIterable(tpe: Type, limit: Option[Cardinality] = None): (Cardinality, Type) =
+ private def stripIterable(tpe: Type, limit: Option[Rank] = None): (Rank, Type) =
if (limit.map { _ == NoDot }.getOrElse { false }) (NoDot, tpe)
else if (tpe != null && !isIterableType(tpe)) (NoDot, tpe)
else if (isBottomType(tpe)) (NoDot, tpe)
else {
val targ = extractIterableTParam(tpe)
- val (card, innerTpe) = stripIterable(targ, limit.map { _.pred })
- (card.succ, innerTpe)
+ val (rank, innerTpe) = stripIterable(targ, limit.map { _.pred })
+ (rank.succ, innerTpe)
}
- private def iterableTypeFromCard(n: Cardinality, tpe: Type): Type = {
+ private def iterableTypeFromRank(n: Rank, tpe: Type): Type = {
if (n == NoDot) tpe
- else appliedType(IterableClass.toType, List(iterableTypeFromCard(n.pred, tpe)))
+ else appliedType(IterableClass.toType, List(iterableTypeFromRank(n.pred, tpe)))
}
- /** Hole encapsulates information about splices in quasiquotes.
- * It packs together a cardinality of a splice, pre-reified tree
- * representation (possibly preprocessed) and position.
+ /** Hole encapsulates information about unquotees in quasiquotes.
+ * It packs together a rank, pre-reified tree representation
+ * (possibly preprocessed) and position.
*/
abstract class Hole {
val tree: Tree
val pos: Position
- val cardinality: Cardinality
+ val rank: Rank
}
object Hole {
- def apply(card: Cardinality, tree: Tree): Hole =
- if (method != nme.unapply) new ApplyHole(card, tree)
- else new UnapplyHole(card, tree)
- def unapply(hole: Hole): Some[(Tree, Cardinality)] = Some((hole.tree, hole.cardinality))
+ def apply(rank: Rank, tree: Tree): Hole =
+ if (method != nme.unapply) new ApplyHole(rank, tree)
+ else new UnapplyHole(rank, tree)
+ def unapply(hole: Hole): Some[(Tree, Rank)] = Some((hole.tree, hole.rank))
}
- class ApplyHole(card: Cardinality, splicee: Tree) extends Hole {
+ class ApplyHole(annotatedRank: Rank, unquotee: Tree) extends Hole {
val (strippedTpe, tpe): (Type, Type) = {
- val (strippedCard, strippedTpe) = stripIterable(splicee.tpe, limit = Some(card))
+ val (strippedRank, strippedTpe) = stripIterable(unquotee.tpe, limit = Some(annotatedRank))
if (isBottomType(strippedTpe)) cantSplice()
- else if (isNativeType(strippedTpe)) (strippedTpe, iterableTypeFromCard(card, strippedTpe))
- else if (isLiftableType(strippedTpe)) (strippedTpe, iterableTypeFromCard(card, treeType))
+ else if (isNativeType(strippedTpe)) (strippedTpe, iterableTypeFromRank(annotatedRank, strippedTpe))
+ else if (isLiftableType(strippedTpe)) (strippedTpe, iterableTypeFromRank(annotatedRank, treeType))
else cantSplice()
}
@@ -88,28 +88,28 @@ trait Holes { self: Quasiquotes =>
if (isNativeType(itpe)) tree
else if (isLiftableType(itpe)) lifted(itpe)(tree)
else global.abort("unreachable")
- if (card == NoDot) inner(strippedTpe)(splicee)
- else iterated(card, splicee, splicee.tpe)
+ if (annotatedRank == NoDot) inner(strippedTpe)(unquotee)
+ else iterated(annotatedRank, unquotee, unquotee.tpe)
}
- val pos = splicee.pos
+ val pos = unquotee.pos
- val cardinality = stripIterable(tpe)._1
+ val rank = stripIterable(tpe)._1
private def cantSplice(): Nothing = {
- val (iterableCard, iterableType) = stripIterable(splicee.tpe)
- val holeCardMsg = if (card != NoDot) s" with $card" else ""
- val action = "splice " + splicee.tpe + holeCardMsg
- val suggestCard = card != iterableCard || card != NoDot
- val spliceeCardMsg = if (card != iterableCard && iterableCard != NoDot) s"using $iterableCard" else "omitting the dots"
- val cardSuggestion = if (suggestCard) spliceeCardMsg else ""
- val suggestLifting = (card == NoDot || iterableCard != NoDot) && !(iterableType <:< treeType) && !isLiftableType(iterableType)
- val liftedTpe = if (card != NoDot) iterableType else splicee.tpe
+ val (iterableRank, iterableType) = stripIterable(unquotee.tpe)
+ val holeRankMsg = if (annotatedRank != NoDot) s" with $annotatedRank" else ""
+ val action = "unquote " + unquotee.tpe + holeRankMsg
+ val suggestRank = annotatedRank != iterableRank || annotatedRank != NoDot
+ val unquoteeRankMsg = if (annotatedRank != iterableRank && iterableRank != NoDot) s"using $iterableRank" else "omitting the dots"
+ val rankSuggestion = if (suggestRank) unquoteeRankMsg else ""
+ val suggestLifting = (annotatedRank == NoDot || iterableRank != NoDot) && !(iterableType <:< treeType) && !isLiftableType(iterableType)
+ val liftedTpe = if (annotatedRank != NoDot) iterableType else unquotee.tpe
val liftSuggestion = if (suggestLifting) s"providing an implicit instance of Liftable[$liftedTpe]" else ""
val advice =
if (isBottomType(iterableType)) "bottom type values often indicate programmer mistake"
- else "consider " + List(cardSuggestion, liftSuggestion).filter(_ != "").mkString(" or ")
- c.abort(splicee.pos, s"Can't $action, $advice")
+ else "consider " + List(rankSuggestion, liftSuggestion).filter(_ != "").mkString(" or ")
+ c.abort(unquotee.pos, s"Can't $action, $advice")
}
private def lifted(tpe: Type)(tree: Tree): Tree = {
@@ -149,7 +149,7 @@ trait Holes { self: Quasiquotes =>
else None
}
- /** Map high-cardinality splice onto an expression that eveluates as a list of given cardinality.
+ /** Map high-rank unquotee onto an expression that eveluates as a list of given rank.
*
* All possible combinations of representations are given in the table below:
*
@@ -166,7 +166,7 @@ trait Holes { self: Quasiquotes =>
* x is not just an Iterable[T] but a List[T]. Similarly no mapping is performed if mapping function is
* known to be an identity.
*/
- private def iterated(card: Cardinality, tree: Tree, tpe: Type): Tree = (card, tpe) match {
+ private def iterated(rank: Rank, tree: Tree, tpe: Type): Tree = (rank, tpe) match {
case (DotDot, tpe @ IterableType(LiftedType(lift))) => mapF(toList(tree, tpe), lift)
case (DotDot, LiftedType(lift)) => toStats(lift(tree))
case (DotDotDot, tpe @ IterableType(inner)) => mapF(toList(tree, tpe), t => iterated(DotDot, t, inner))
@@ -175,7 +175,7 @@ trait Holes { self: Quasiquotes =>
}
}
- class UnapplyHole(val cardinality: Cardinality, pat: Tree) extends Hole {
+ class UnapplyHole(val rank: Rank, pat: Tree) extends Hole {
val (placeholderName, pos, tptopt) = pat match {
case Bind(pname, inner @ Bind(_, Typed(Ident(nme.WILDCARD), tpt))) => (pname, inner.pos, Some(tpt))
case Bind(pname, inner @ Typed(Ident(nme.WILDCARD), tpt)) => (pname, inner.pos, Some(tpt))
@@ -188,13 +188,13 @@ trait Holes { self: Quasiquotes =>
try c.typeCheck(TypeDef(NoMods, TypeName("T"), Nil, tpt))
catch { case TypecheckException(pos, msg) => c.abort(pos.asInstanceOf[c.Position], msg) }
val tpe = typedTpt.tpe
- val (iterableCard, _) = stripIterable(tpe)
- if (iterableCard.value < cardinality.value)
- c.abort(pat.pos, s"Can't extract $tpe with $cardinality, consider using $iterableCard")
- val (_, strippedTpe) = stripIterable(tpe, limit = Some(cardinality))
+ val (iterableRank, _) = stripIterable(tpe)
+ if (iterableRank.value < rank.value)
+ c.abort(pat.pos, s"Can't extract $tpe with $rank, consider using $iterableRank")
+ val (_, strippedTpe) = stripIterable(tpe, limit = Some(rank))
if (strippedTpe <:< treeType) treeNoUnlift
else
- unlifters.spawn(strippedTpe, cardinality).map {
+ unlifters.spawn(strippedTpe, rank).map {
Apply(_, treeNoUnlift :: Nil)
}.getOrElse {
c.abort(pat.pos, s"Can't find $unliftableType[$strippedTpe], consider providing it")
@@ -203,7 +203,7 @@ trait Holes { self: Quasiquotes =>
}
/** Full support for unliftable implies that it's possible to interleave
- * deconstruction with higher cardinality and unlifting of the values.
+ * deconstruction with higher rank and unlifting of the values.
* In particular extraction of List[Tree] as List[T: Unliftable] requires
* helper extractors that would do the job: UnliftListElementwise[T]. Similarly
* List[List[Tree]] needs UnliftListOfListsElementwise[T].
@@ -211,24 +211,24 @@ trait Holes { self: Quasiquotes =>
* See also "unlift list" tests in UnapplyProps.scala
*/
object unlifters {
- private var records = List.empty[(Type, Cardinality)]
+ private var records = List.empty[(Type, Rank)]
// Materialize unlift helper that does elementwise
- // unlifting for corresponding cardinality and type.
- def spawn(tpe: Type, card: Cardinality): Option[Tree] = {
+ // unlifting for corresponding rank and type.
+ def spawn(tpe: Type, rank: Rank): Option[Tree] = {
val unlifter = inferUnliftable(tpe)
if (unlifter == EmptyTree) None
- else if (card == NoDot) Some(unlifter)
+ else if (rank == NoDot) Some(unlifter)
else {
- val idx = records.indexWhere { p => p._1 =:= tpe && p._2 == card }
- val resIdx = if (idx != -1) idx else { records +:= (tpe, card); records.length - 1}
+ val idx = records.indexWhere { p => p._1 =:= tpe && p._2 == rank }
+ val resIdx = if (idx != -1) idx else { records +:= (tpe, rank); records.length - 1}
Some(Ident(TermName(nme.QUASIQUOTE_UNLIFT_HELPER + resIdx)))
}
}
// Returns a list of vals that will defined required unlifters
def preamble(): List[Tree] =
- records.zipWithIndex.map { case ((tpe, card), idx) =>
+ records.zipWithIndex.map { case ((tpe, rank), idx) =>
val name = TermName(nme.QUASIQUOTE_UNLIFT_HELPER + idx)
- val helperName = card match {
+ val helperName = rank match {
case DotDot => nme.UnliftListElementwise
case DotDotDot => nme.UnliftListOfListsElementwise
}
diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala b/src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala
index 301e7051df..3b93a8933d 100644
--- a/src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala
+++ b/src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala
@@ -123,7 +123,7 @@ trait Parsers { self: Quasiquotes =>
override def isStatSep(token: Int) = token == EOF || super.isStatSep(token)
override def expectedMsg(token: Int): String =
- if (isHole) expectedMsgTemplate(token2string(token), "splicee")
+ if (isHole) expectedMsgTemplate(token2string(token), "unquotee")
else super.expectedMsg(token)
// $mods def foo
diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala b/src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala
index e7730f878f..5986758c2b 100644
--- a/src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala
+++ b/src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala
@@ -12,7 +12,7 @@ import scala.collection.{immutable, mutable}
*/
trait Placeholders { self: Quasiquotes =>
import global._
- import Cardinality._
+ import Rank._
import universeTypes._
// Step 1: Transform Scala source with holes into vanilla Scala source
@@ -29,13 +29,13 @@ trait Placeholders { self: Quasiquotes =>
posMap += pos -> ((start, end))
}
- def appendHole(tree: Tree, cardinality: Cardinality) = {
+ def appendHole(tree: Tree, rank: Rank) = {
val placeholderName = c.freshName(TermName(nme.QUASIQUOTE_PREFIX + sessionSuffix))
sb.append(placeholderName)
val holeTree =
if (method != nme.unapply) tree
else Bind(placeholderName, tree)
- holeMap(placeholderName) = Hole(cardinality, holeTree)
+ holeMap(placeholderName) = Hole(rank, holeTree)
}
val iargs = method match {
@@ -47,9 +47,9 @@ trait Placeholders { self: Quasiquotes =>
}
foreach2(iargs, parts.init) { case (tree, (p, pos)) =>
- val (part, cardinality) = parseDots(p)
+ val (part, rank) = parseDots(p)
appendPart(part, pos)
- appendHole(tree, cardinality)
+ appendHole(tree, rank)
}
val (p, pos) = parts.last
appendPart(p, pos)
diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala
index 339937adc3..61fb22bc73 100644
--- a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala
+++ b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala
@@ -10,7 +10,7 @@ trait Reifiers { self: Quasiquotes =>
import global.build._
import global.treeInfo._
import global.definitions._
- import Cardinality._
+ import Rank._
import universeTypes._
abstract class Reifier(val isReifyingExpressions: Boolean) extends {
@@ -23,7 +23,7 @@ trait Reifiers { self: Quasiquotes =>
lazy val typer = throw new UnsupportedOperationException
def isReifyingPatterns: Boolean = !isReifyingExpressions
- def action = if (isReifyingExpressions) "splice" else "extract"
+ def action = if (isReifyingExpressions) "unquote" else "extract"
def holesHaveTypes = isReifyingExpressions
/** Map that stores freshly generated names linked to the corresponding names in the reified tree.
@@ -129,7 +129,7 @@ trait Reifiers { self: Quasiquotes =>
def reifyTreePlaceholder(tree: Tree): Tree = tree match {
case Placeholder(hole: ApplyHole) if hole.tpe <:< treeType => hole.tree
case Placeholder(Hole(tree, NoDot)) if isReifyingPatterns => tree
- case Placeholder(hole @ Hole(_, card @ Dot())) => c.abort(hole.pos, s"Can't $action with $card here")
+ case Placeholder(hole @ Hole(_, rank @ Dot())) => c.abort(hole.pos, s"Can't $action with $rank here")
case TuplePlaceholder(args) => reifyTuple(args)
case TupleTypePlaceholder(args) => reifyTupleType(args)
case FunctionTypePlaceholder(argtpes, restpe) => reifyFunctionType(argtpes, restpe)
@@ -236,7 +236,7 @@ trait Reifiers { self: Quasiquotes =>
case List(hole @ Placeholder(Hole(_, NoDot))) => reify(hole)
case List(Placeholder(_)) => reifyBuildCall(nme.SyntacticTuple, args)
// in a case we only have one element tuple without
- // any cardinality annotations this means that this is
+ // any rank annotations this means that this is
// just an expression wrapped in parentheses
case List(other) => reify(other)
case _ => reifyBuildCall(nme.SyntacticTuple, args)
@@ -295,8 +295,8 @@ trait Reifiers { self: Quasiquotes =>
*
* Example:
*
- * reifyMultiCardinalityList(lst) {
- * // first we define patterns that extract high-cardinality holeMap (currently ..)
+ * reifyHighRankList(lst) {
+ * // first we define patterns that extract high-rank holeMap (currently ..)
* case Placeholder(IterableType(_, _)) => tree
* } {
* // in the end we define how single elements are reified, typically with default reify call
@@ -306,10 +306,10 @@ trait Reifiers { self: Quasiquotes =>
* Sample execution of previous concrete list reifier:
*
* > val lst = List(foo, bar, qq$f3948f9s$1)
- * > reifyMultiCardinalityList(lst) { ... } { ... }
+ * > reifyHighRankList(lst) { ... } { ... }
* q"List($foo, $bar) ++ ${holeMap(qq$f3948f9s$1).tree}"
*/
- def reifyMultiCardinalityList(xs: List[Any])(fill: PartialFunction[Any, Tree])(fallback: Any => Tree): Tree
+ def reifyHighRankList(xs: List[Any])(fill: PartialFunction[Any, Tree])(fallback: Any => Tree): Tree
val fillListHole: PartialFunction[Any, Tree] = {
case Placeholder(Hole(tree, DotDot)) => tree
@@ -331,16 +331,16 @@ trait Reifiers { self: Quasiquotes =>
}
/** Reifies arbitrary list filling ..$x and ...$y holeMap when they are put
- * in the correct position. Fallbacks to regular reification for non-high cardinality
+ * in the correct position. Fallbacks to regular reification for zero rank
* elements.
*/
- override def reifyList(xs: List[Any]): Tree = reifyMultiCardinalityList(xs)(fillListHole.orElse(fillListOfListsHole))(reify)
+ override def reifyList(xs: List[Any]): Tree = reifyHighRankList(xs)(fillListHole.orElse(fillListOfListsHole))(reify)
- def reifyAnnotList(annots: List[Tree]): Tree = reifyMultiCardinalityList(annots) {
+ def reifyAnnotList(annots: List[Tree]): Tree = reifyHighRankList(annots) {
case AnnotPlaceholder(h @ Hole(_, DotDot)) => reifyAnnotation(h)
} {
case AnnotPlaceholder(h: ApplyHole) if h.tpe <:< treeType => reifyAnnotation(h)
- case AnnotPlaceholder(h: UnapplyHole) if h.cardinality == NoDot => reifyAnnotation(h)
+ case AnnotPlaceholder(h: UnapplyHole) if h.rank == NoDot => reifyAnnotation(h)
case other => reify(other)
}
@@ -372,7 +372,7 @@ trait Reifiers { self: Quasiquotes =>
}
class ApplyReifier extends Reifier(isReifyingExpressions = true) {
- def reifyMultiCardinalityList(xs: List[Any])(fill: PartialFunction[Any, Tree])(fallback: Any => Tree): Tree =
+ def reifyHighRankList(xs: List[Any])(fill: PartialFunction[Any, Tree])(fallback: Any => Tree): Tree =
if (xs.isEmpty) mkList(Nil)
else {
def reifyGroup(group: List[Any]): Tree = group match {
@@ -399,12 +399,12 @@ trait Reifiers { self: Quasiquotes =>
}
mods match {
case hole :: Nil =>
- if (flags.nonEmpty) c.abort(flags(0).pos, "Can't splice flags together with modifiers, consider merging flags into modifiers")
- if (annots.nonEmpty) c.abort(hole.pos, "Can't splice modifiers together with annotations, consider merging annotations into modifiers")
+ if (flags.nonEmpty) c.abort(flags(0).pos, "Can't unquote flags together with modifiers, consider merging flags into modifiers")
+ if (annots.nonEmpty) c.abort(hole.pos, "Can't unquote modifiers together with annotations, consider merging annotations into modifiers")
ensureNoExplicitFlags(m, hole.pos)
hole.tree
case _ :: hole :: Nil =>
- c.abort(hole.pos, "Can't splice multiple modifiers, consider merging them into a single modifiers instance")
+ c.abort(hole.pos, "Can't unquote multiple modifiers, consider merging them into a single modifiers instance")
case _ =>
val baseFlags = reifyFlags(m.flags)
val reifiedFlags = flags.foldLeft[Tree](baseFlags) { case (flag, hole) => Apply(Select(flag, nme.OR), List(hole.tree)) }
@@ -423,7 +423,7 @@ trait Reifiers { self: Quasiquotes =>
// pq"$lhs :: $rhs"
private def cons(lhs: Tree, rhs: Tree) = Apply(collectionCons, lhs :: rhs :: Nil)
- def reifyMultiCardinalityList(xs: List[Any])(fill: PartialFunction[Any, Tree])(fallback: Any => Tree): Tree = {
+ def reifyHighRankList(xs: List[Any])(fill: PartialFunction[Any, Tree])(fallback: Any => Tree): Tree = {
val grouped = group(xs) { (a, b) => !fill.isDefinedAt(a) && !fill.isDefinedAt(b) }
def appended(lst: List[Any], init: Tree) = lst.foldLeft(init) { (l, r) => append(l, fallback(r)) }
def prepended(lst: List[Any], init: Tree) = lst.foldRight(init) { (l, r) => cons(fallback(l), r) }
diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala
index 50577e710e..faeb1dcbe2 100644
--- a/src/library/scala/Predef.scala
+++ b/src/library/scala/Predef.scala
@@ -264,8 +264,16 @@ object Predef extends LowPriorityImplicits with DeprecatedPredef {
@inline def formatted(fmtstr: String): String = fmtstr format self
}
- implicit final class StringAdd[A](private val self: A) extends AnyVal {
- def +(other: String) = String.valueOf(self) + other
+ // TODO: remove, only needed for binary compatibility of 2.11.0-RC1 with 2.11.0-M8
+ // note that `private[scala]` becomes `public` in bytecode
+ private[scala] final class StringAdd[A](private val self: A) extends AnyVal {
+ def +(other: String): String = String.valueOf(self) + other
+ }
+ private[scala] def StringAdd(x: Any): Any = new StringAdd(x)
+
+ // SI-8229 retaining the pre 2.11 name for source compatibility in shadowing this implicit
+ implicit final class any2stringadd[A](private val self: A) extends AnyVal {
+ def +(other: String): String = String.valueOf(self) + other
}
implicit final class RichException(private val self: Throwable) extends AnyVal {
@@ -374,9 +382,13 @@ object Predef extends LowPriorityImplicits with DeprecatedPredef {
@implicitNotFound(msg = "Cannot prove that ${From} <:< ${To}.")
sealed abstract class <:<[-From, +To] extends (From => To) with Serializable
private[this] final val singleton_<:< = new <:<[Any,Any] { def apply(x: Any): Any = x }
- // not in the <:< companion object because it is also
- // intended to subsume identity (which is no longer implicit)
- implicit def conforms[A]: A <:< A = singleton_<:<.asInstanceOf[A <:< A]
+ // The dollar prefix is to dodge accidental shadowing of this method
+ // by a user-defined method of the same name (SI-7788).
+ // The collections rely on this method.
+ implicit def $conforms[A]: A <:< A = singleton_<:<.asInstanceOf[A <:< A]
+
+ @deprecated("Use `implicitly[T <:< U]` or `identity` instead.", "2.11.0")
+ def conforms[A]: A <:< A = $conforms[A]
/** An instance of `A =:= B` witnesses that the types `A` and `B` are equal.
*
@@ -410,7 +422,6 @@ private[scala] trait DeprecatedPredef {
@deprecated("Use `ArrowAssoc`", "2.11.0") def any2ArrowAssoc[A](x: A): ArrowAssoc[A] = new ArrowAssoc(x)
@deprecated("Use `Ensuring`", "2.11.0") def any2Ensuring[A](x: A): Ensuring[A] = new Ensuring(x)
@deprecated("Use `StringFormat`", "2.11.0") def any2stringfmt(x: Any): StringFormat[Any] = new StringFormat(x)
- @deprecated("Use String interpolation", "2.11.0") def any2stringadd(x: Any): StringAdd[Any] = new StringAdd(x)
@deprecated("Use `Throwable` directly", "2.11.0") def exceptionWrapper(exc: Throwable) = new RichException(exc)
@deprecated("Use `SeqCharSequence`", "2.11.0") def seqToCharSequence(xs: scala.collection.IndexedSeq[Char]): CharSequence = new SeqCharSequence(xs)
@deprecated("Use `ArrayCharSequence`", "2.11.0") def arrayToCharSequence(xs: Array[Char]): CharSequence = new ArrayCharSequence(xs)
diff --git a/src/reflect/scala/reflect/api/Printers.scala b/src/reflect/scala/reflect/api/Printers.scala
index b262fdce68..92ae6d8b44 100644
--- a/src/reflect/scala/reflect/api/Printers.scala
+++ b/src/reflect/scala/reflect/api/Printers.scala
@@ -209,20 +209,22 @@ trait Printers { self: Universe =>
* Renders the code of the passed tree, so that:
* 1) it can be later compiled by scalac retaining the same meaning,
* 2) it looks pretty.
- * At the moment we have handled #1 for unattributed trees and
- * later on plan to account for typical idiosyncrasies of the typechecker.
+ * #1 is available for unattributed trees and attributed trees
* #2 is more or less okay indentation-wise, but at the moment there's a lot of desugaring
- * left in place, and that's what we also plan to improve in the future.
+ * left in place, and that's what we plan to improve in the future.
+ * printTypes, printIds, printPositions options have the same meaning as for TreePrinter
+ * printRootPkg option is available only for attributed trees.
*
* @group Printers
*/
- def showCode(tree: Tree) = render(tree, newCodePrinter)
+ def showCode(tree: Tree, printTypes: BooleanFlag = None, printIds: BooleanFlag = None, printOwners: BooleanFlag = None, printPositions: BooleanFlag = None, printRootPkg: Boolean = false) =
+ render(tree, newCodePrinter(_, tree, printRootPkg), printTypes, printIds, printOwners, printKinds = None, printMirrors = None, printPositions)
/**
* Hook to define what `showCode(...)` means.
* @group Printers
*/
- protected def newCodePrinter(out: PrintWriter): TreePrinter
+ protected def newCodePrinter(out: PrintWriter, tree: Tree, printRootPkg: Boolean): TreePrinter
/** Renders internal structure of a reflection artifact as the
* visualization of a Scala syntax tree.
diff --git a/src/reflect/scala/reflect/api/Quasiquotes.scala b/src/reflect/scala/reflect/api/Quasiquotes.scala
index fcf8edcec7..c939eee164 100644
--- a/src/reflect/scala/reflect/api/Quasiquotes.scala
+++ b/src/reflect/scala/reflect/api/Quasiquotes.scala
@@ -7,7 +7,7 @@ trait Quasiquotes { self: Universe =>
// using the mechanism implemented in `scala.tools.reflect.FastTrack`
implicit class Quasiquote(ctx: StringContext) {
protected trait api {
- def apply[T](args: T*): Any = macro ???
+ def apply[T](args: T*): Tree = macro ???
def unapply(scrutinee: Any): Any = macro ???
}
object q extends api
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala
index 2567abe51d..e1d760a87a 100644
--- a/src/reflect/scala/reflect/internal/Definitions.scala
+++ b/src/reflect/scala/reflect/internal/Definitions.scala
@@ -1432,7 +1432,8 @@ trait Definitions extends api.StandardDefinitions {
TypeTagClass -> materializeTypeTag
)
lazy val TagSymbols = TagMaterializers.keySet
- lazy val Predef_conforms = getMemberMethod(PredefModule, nme.conforms)
+ lazy val Predef_conforms = (getMemberIfDefined(PredefModule, nme.conforms)
+ orElse getMemberMethod(PredefModule, "conforms": TermName)) // TODO: predicate on -Xsource:2.10 (for now, needed for transition from M8 -> RC1)
lazy val Predef_classOf = getMemberMethod(PredefModule, nme.classOf)
lazy val Predef_implicitly = getMemberMethod(PredefModule, nme.implicitly)
lazy val Predef_wrapRefArray = getMemberMethod(PredefModule, nme.wrapRefArray)
diff --git a/src/reflect/scala/reflect/internal/Printers.scala b/src/reflect/scala/reflect/internal/Printers.scala
index b1d76b6056..680c19e426 100644
--- a/src/reflect/scala/reflect/internal/Printers.scala
+++ b/src/reflect/scala/reflect/internal/Printers.scala
@@ -73,7 +73,14 @@ trait Printers extends api.Printers { self: SymbolTable =>
def indent() = indentMargin += indentStep
def undent() = indentMargin -= indentStep
- def printPosition(tree: Tree) = if (printPositions) print(tree.pos.show)
+ def printPosition(tree: Tree) =
+ if (printPositions) comment(print(tree.pos.show))
+
+ protected def printTypesInfo(tree: Tree) =
+ if (printTypes && tree.isTerm && tree.canHaveAttrs)
+ comment{
+ print("{", if (tree.tpe eq null) "<null>" else tree.tpe.toString, "}")
+ }
def println() = {
out.println()
@@ -124,12 +131,17 @@ trait Printers extends api.Printers { self: SymbolTable =>
print(symName(p, p.name)); printOpt(": ", TypeTree() setType p.tpe)
}
- protected def parenthesize(condition: Boolean = true)(body: => Unit) = {
- if (condition) print("(")
+ protected def parenthesize(condition: Boolean = true, open: String = "(", close: String = ")")(body: => Unit) = {
+ if (condition) print(open)
body
- if (condition) print(")")
+ if (condition) print(close)
}
+ protected val commentsRequired = false
+
+ protected def comment(body: => Unit) =
+ parenthesize(commentsRequired, "/*", "*/")(body)
+
protected def printImplicitInParamsList(vds: List[ValDef]) =
if (vds.nonEmpty) printFlags(vds.head.mods.flags & IMPLICIT, "")
@@ -275,13 +287,20 @@ trait Printers extends api.Printers { self: SymbolTable =>
print("(");
printValueParams
print(" => ", body, ")")
- if (printIds && tree.symbol != null) print("#" + tree.symbol.id)
- if (printOwners && tree.symbol != null) print("@" + tree.symbol.owner.id)
+ if (printIds && tree.symbol != null)
+ comment{
+ print("#" + tree.symbol.id)
+ }
+
+ if (printOwners && tree.symbol != null)
+ comment{
+ print("@" + tree.symbol.owner.id)
+ }
}
- protected def printSuper(tree: Super, resultName: => String) = {
+ protected def printSuper(tree: Super, resultName: => String, checkSymbol: Boolean = true) = {
val Super(This(qual), mix) = tree
- if (qual.nonEmpty || tree.symbol != NoSymbol) print(resultName + ".")
+ if (qual.nonEmpty || (checkSymbol && tree.symbol != NoSymbol)) print(resultName + ".")
print("super")
if (mix.nonEmpty) print(s"[$mix]")
}
@@ -292,6 +311,9 @@ trait Printers extends api.Printers { self: SymbolTable =>
print("this")
}
+ protected def printBlock(stats: List[Tree], expr: Tree) =
+ printColumn(stats ::: List(expr), "{", ";", "}")
+
def printTree(tree: Tree) = {
tree match {
case EmptyTree =>
@@ -351,7 +373,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
currentOwner = currentOwner1
case Block(stats, expr) =>
- printColumn(stats ::: List(expr), "{", ";", "}")
+ printBlock(stats, expr)
case Match(selector, cases) =>
val selectorType1 = selectorType
@@ -498,9 +520,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
case tree =>
xprintTree(this, tree)
}
- if (printTypes && tree.isTerm && tree.canHaveAttrs) {
- print("{", if (tree.tpe eq null) "<null>" else tree.tpe.toString, "}")
- }
+ printTypesInfo(tree)
}
def print(args: Any*): Unit = args foreach {
@@ -514,21 +534,8 @@ trait Printers extends api.Printers { self: SymbolTable =>
}
}
- // it's the printer for trees after parser and before typer phases
- class ParsedTreePrinter(out: PrintWriter) extends TreePrinter(out) {
- override def withTypes = this
- override def withIds = this
- override def withKinds = this
- override def withMirrors = this
- override def withPositions = this
-
- // TODO: add print parameters to typed trees printer
- printTypes = false
- printIds = false
- printKinds = false
- printMirrors = false
- printPositions = false
-
+ // it's the printer for AST-based code generation
+ class CodePrinter(out: PrintWriter, printRootPkg: Boolean) extends TreePrinter(out) {
protected val parentsStack = scala.collection.mutable.Stack[Tree]()
protected def currentTree = if (parentsStack.nonEmpty) Some(parentsStack.top) else None
@@ -558,6 +565,8 @@ trait Printers extends api.Printers { self: SymbolTable =>
qualIsIntLit && name.isOperatorName
}
+ override protected val commentsRequired = true
+
protected def needsParentheses(parent: Tree)(insideIf: Boolean = true, insideMatch: Boolean = true,
insideTry: Boolean = true, insideAnnotated: Boolean = true, insideBlock: Boolean = true, insideLabelDef: Boolean = true) = {
parent match {
@@ -582,10 +591,21 @@ trait Printers extends api.Printers { self: SymbolTable =>
case Select(qual, name) if name.isTermName => s"${resolveSelect(qual)}.${printedName(name)}"
case Select(qual, name) if name.isTypeName => s"${resolveSelect(qual)}#${blankForOperatorName(name)}%${printedName(name)}"
case Ident(name) => printedName(name)
- case _ => showCode(t)
+ case _ => render(t, new CodePrinter(_, printRootPkg))
}
}
+ protected def emptyTree(tree: Tree) = tree match {
+ case EmptyTree | build.SyntacticEmptyTypeTree() => true
+ case _ => false
+ }
+
+ protected def originalTypeTrees(trees: List[Tree]) =
+ trees.filter(!emptyTree(_)) map {
+ case tt: TypeTree => tt.original
+ case tree => tree
+ }
+
val defaultClasses = List(tpnme.AnyRef)
val defaultTraitsForCase = List(tpnme.Product, tpnme.Serializable)
protected def removeDefaultTypesFromList(trees: List[Tree])(classesToRemove: List[Name] = defaultClasses)(traitsToRemove: List[Name]) = {
@@ -602,9 +622,24 @@ trait Printers extends api.Printers { self: SymbolTable =>
removeDefaultTraitsFromList(removeDefaultClassesFromList(trees, classesToRemove), traitsToRemove)
}
- protected def removeDefaultClassesFromList(trees: List[Tree], classesToRemove: List[Name] = defaultClasses) = trees filter {
- case Select(Ident(sc), name) => !(classesToRemove.contains(name) && sc == nme.scala_)
- case _ => true
+ protected def removeDefaultClassesFromList(trees: List[Tree], classesToRemove: List[Name] = defaultClasses) =
+ originalTypeTrees(trees) filter {
+ case Select(Ident(sc), name) => !(classesToRemove.contains(name) && sc == nme.scala_)
+ case _ => true
+ }
+
+ protected def syntheticToRemove(tree: Tree) =
+ tree match {
+ case _: ValDef | _: TypeDef => false // don't remove ValDef and TypeDef
+ case md: MemberDef if md.mods.isSynthetic => true
+ case _ => false
+ }
+
+ override def printOpt(prefix: String, tree: Tree) =
+ if (!emptyTree(tree)) super.printOpt(prefix, tree)
+
+ override def printColumn(ts: List[Tree], start: String, sep: String, end: String) = {
+ super.printColumn(ts.filter(!syntheticToRemove(_)), start, sep, end)
}
def printFlags(mods: Modifiers, primaryCtorParam: Boolean = false): Unit = {
@@ -635,6 +670,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
def printParam(tree: Tree, primaryCtorParam: Boolean): Unit =
tree match {
case vd @ ValDef(mods, name, tp, rhs) =>
+ printPosition(tree)
printAnnotations(vd)
val mutableOrOverride = mods.isOverride || mods.isMutable
val hideCtorMods = mods.isParamAccessor && mods.isPrivateLocal && !mutableOrOverride
@@ -648,6 +684,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
printOpt(": ", tp);
printOpt(" = ", rhs)
case TypeDef(_, name, tparams, rhs) =>
+ printPosition(tree)
print(printedName(name))
printTypeParams(tparams);
print(rhs)
@@ -682,7 +719,17 @@ trait Printers extends api.Printers { self: SymbolTable =>
override def printTree(tree: Tree): Unit = {
parentsStack.push(tree)
+ try {
+ processTreePrinting(tree);
+ printTypesInfo(tree)
+ } finally parentsStack.pop()
+ }
+
+ def processTreePrinting(tree: Tree): Unit = {
tree match {
+ // don't remove synthetic ValDef/TypeDef
+ case _ if syntheticToRemove(tree) =>
+
case cl @ ClassDef(mods, name, tparams, impl) =>
if (mods.isJavaDefined) super.printTree(cl)
printAnnotations(cl)
@@ -733,12 +780,11 @@ trait Printers extends api.Printers { self: SymbolTable =>
printSeq(stats) {
print(_)
} {
- print(";");
+ println()
println()
};
case _ =>
- val separator = scala.util.Properties.lineSeparator
- printPackageDef(pd, separator)
+ printPackageDef(pd, scala.util.Properties.lineSeparator)
}
case md @ ModuleDef(mods, name, impl) =>
@@ -786,7 +832,8 @@ trait Printers extends api.Printers { self: SymbolTable =>
case imp @ Import(expr, _) =>
printImport(imp, resolveSelect(expr))
- case Template(parents, self, body) =>
+ case t @ Template(parents, self, tbody) =>
+ val body = treeInfo.untypecheckedTemplBody(t)
val printedParents =
currentParent map {
case _: CompoundTypeTree => parents
@@ -840,7 +887,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
case dd: DefDef => dd.name != nme.CONSTRUCTOR
case _ => true
}
- val modBody = left ::: right.drop(1)
+ val modBody = (left ::: right.drop(1))
val showBody = !(modBody.isEmpty && (self == noSelfType || self.isEmpty))
if (showBody) {
if (self.name != nme.WILDCARD) {
@@ -855,7 +902,8 @@ trait Printers extends api.Printers { self: SymbolTable =>
printColumn(modBody, "", ";", "}")
}
- case Block(stats, expr) => super.printTree(tree)
+ case bl @ Block(stats, expr) =>
+ printBlock(treeInfo.untypecheckedBlockBody(bl), expr)
case Match(selector, cases) =>
/* Insert braces if match is inner
@@ -900,12 +948,24 @@ trait Printers extends api.Printers { self: SymbolTable =>
printFunction(f)(printValueParams(vparams, inParentheses = printParentheses))
case Typed(expr, tp) =>
+ def printTp = print("(", tp, ")")
+
tp match {
+ case EmptyTree | build.SyntacticEmptyTypeTree() => printTp
+ // case for untypechecked trees
+ case Annotated(annot, arg) if (expr ne null) && (arg ne null) && expr.equalsStructure(arg) => printTp // remove double arg - 5: 5: @unchecked
+ case tt: TypeTree if tt.original.isInstanceOf[Annotated] => printTp
case Function(List(), EmptyTree) => print("(", expr, " _)") //func _
// parentheses required when (a match {}) : Type
case _ => print("((", expr, "): ", tp, ")")
}
+ // print only fun when targs are TypeTrees with empty original
+ case TypeApply(fun, targs) =>
+ if (targs.exists(emptyTree(_))) {
+ print(fun)
+ } else super.printTree(tree)
+
case Apply(fun, vargs) =>
tree match {
// processing methods ending on colons (x \: list)
@@ -918,20 +978,48 @@ trait Printers extends api.Printers { self: SymbolTable =>
case _ => super.printTree(tree)
}
+ case UnApply(fun, args) =>
+ fun match {
+ case treeInfo.Unapplied(body) =>
+ body match {
+ case Select(qual, name) if name == nme.unapply => print(qual)
+ case TypeApply(Select(qual, name), args) if name == nme.unapply || name == nme.unapplySeq =>
+ print(TypeApply(qual, args))
+ case _ => print(body)
+ }
+ case _ => print(fun)
+ }
+ printRow(args, "(", ", ", ")")
+
case st @ Super(This(qual), mix) =>
- printSuper(st, printedName(qual))
+ printSuper(st, printedName(qual), checkSymbol = false)
case th @ This(qual) =>
- printThis(th, printedName(qual))
+ if (tree.hasExistingSymbol && tree.symbol.isPackage) print(tree.symbol.fullName)
+ else printThis(th, printedName(qual))
+
+ // remove this prefix from constructor invocation in typechecked trees: this.this -> this
+ case Select(This(_), name @ nme.CONSTRUCTOR) => print(printedName(name))
case Select(qual: New, name) =>
print(qual)
- case Select(qualifier, name) => {
- val printParentheses = needsParentheses(qualifier)(insideAnnotated = false) || isIntLitWithDecodedOp(qualifier, name)
- if (printParentheses) print("(", resolveSelect(qualifier), ").", printedName(name))
- else print(resolveSelect(qualifier), ".", printedName(name))
- }
+ case Select(qual, name) =>
+ def checkRootPackage(tr: Tree): Boolean =
+ (currentParent match { //check that Select is not for package def name
+ case Some(_: PackageDef) => false
+ case _ => true
+ }) && (tr match { // check that Select contains package
+ case Select(q, _) => checkRootPackage(q)
+ case _: Ident | _: This => val sym = tr.symbol
+ tr.hasExistingSymbol && sym.isPackage && sym.name != nme.ROOTPKG
+ case _ => false
+ })
+
+ if (printRootPkg && checkRootPackage(tree)) print(s"${printedName(nme.ROOTPKG)}.")
+ val printParentheses = needsParentheses(qual)(insideAnnotated = false) || isIntLitWithDecodedOp(qual, name)
+ if (printParentheses) print("(", resolveSelect(qual), ").", printedName(name))
+ else print(resolveSelect(qual), ".", printedName(name))
case id @ Ident(name) =>
if (name.nonEmpty) {
@@ -971,6 +1059,9 @@ trait Printers extends api.Printers { self: SymbolTable =>
case SelectFromTypeTree(qualifier, selector) =>
print("(", qualifier, ")#", blankForOperatorName(selector), printedName(selector))
+ case tt: TypeTree =>
+ if (!emptyTree(tt)) print(tt.original)
+
case AppliedTypeTree(tp, args) =>
// it's possible to have (=> String) => String type but Function1[=> String, String] is not correct
val containsByNameTypeParam = args exists treeInfo.isByNameParamType
@@ -996,7 +1087,6 @@ trait Printers extends api.Printers { self: SymbolTable =>
case tree => super.printTree(tree)
}
- parentsStack.pop()
}
}
@@ -1004,7 +1094,9 @@ trait Printers extends api.Printers { self: SymbolTable =>
def xprintTree(treePrinter: TreePrinter, tree: Tree) =
treePrinter.print(tree.productPrefix+tree.productIterator.mkString("(", ", ", ")"))
- def newCodePrinter(writer: PrintWriter): TreePrinter = new ParsedTreePrinter(writer)
+ def newCodePrinter(writer: PrintWriter, tree: Tree, printRootPkg: Boolean): TreePrinter =
+ new CodePrinter(writer, printRootPkg)
+
def newTreePrinter(writer: PrintWriter): TreePrinter = new TreePrinter(writer)
def newTreePrinter(stream: OutputStream): TreePrinter = newTreePrinter(new PrintWriter(stream))
def newTreePrinter(): TreePrinter = newTreePrinter(new PrintWriter(ConsoleWriter))
diff --git a/src/reflect/scala/reflect/internal/ReificationSupport.scala b/src/reflect/scala/reflect/internal/ReificationSupport.scala
index 087d4186be..ea230a215b 100644
--- a/src/reflect/scala/reflect/internal/ReificationSupport.scala
+++ b/src/reflect/scala/reflect/internal/ReificationSupport.scala
@@ -237,7 +237,9 @@ trait ReificationSupport { self: SymbolTable =>
// undo gen.mkTemplate
protected object UnMkTemplate {
def unapply(templ: Template): Option[(List[Tree], ValDef, Modifiers, List[List[ValDef]], List[Tree], List[Tree])] = {
- val Template(parents, selfType, tbody) = templ
+ val Template(parents, selfType, _) = templ
+ val tbody = treeInfo.untypecheckedTemplBody(templ)
+
def result(ctorMods: Modifiers, vparamss: List[List[ValDef]], edefs: List[Tree], body: List[Tree]) =
Some((parents, selfType, ctorMods, vparamss, edefs, body))
def indexOfCtor(trees: List[Tree]) =
@@ -463,8 +465,8 @@ trait ReificationSupport { self: SymbolTable =>
else gen.mkBlock(stats)
def unapply(tree: Tree): Option[List[Tree]] = tree match {
- case self.Block(stats, SyntheticUnit()) => Some(stats)
- case self.Block(stats, expr) => Some(stats :+ expr)
+ case bl @ self.Block(stats, SyntheticUnit()) => Some(treeInfo.untypecheckedBlockBody(bl))
+ case bl @ self.Block(stats, expr) => Some(treeInfo.untypecheckedBlockBody(bl) :+ expr)
case EmptyTree => Some(Nil)
case _ if tree.isTerm => Some(tree :: Nil)
case _ => None
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index 0c28c4fba4..f3467ff9f4 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -671,7 +671,7 @@ trait StdNames {
val classOf: NameType = "classOf"
val clone_ : NameType = "clone"
val collection: NameType = "collection"
- val conforms: NameType = "conforms"
+ val conforms: NameType = "$conforms" // dollar prefix to avoid accidental shadowing
val copy: NameType = "copy"
val create: NameType = "create"
val currentMirror: NameType = "currentMirror"
diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala
index b7df2e82cb..7cf749c048 100644
--- a/src/reflect/scala/reflect/internal/TreeInfo.scala
+++ b/src/reflect/scala/reflect/internal/TreeInfo.scala
@@ -405,6 +405,67 @@ abstract class TreeInfo {
case _ => false
}
+ /** Does the tree have a structure similar to typechecked trees? */
+ private[internal] def detectTypecheckedTree(tree: Tree) =
+ tree.hasExistingSymbol || tree.exists {
+ case dd: DefDef => dd.mods.hasAccessorFlag || dd.mods.isSynthetic // for untypechecked trees
+ case md: MemberDef => md.hasExistingSymbol
+ case _ => false
+ }
+
+ /** Recover template body to parsed state */
+ private[internal] def untypecheckedTemplBody(templ: Template) =
+ untypecheckedTreeBody(templ, templ.body)
+
+ /** Recover block body to parsed state */
+ private[internal] def untypecheckedBlockBody(block: Block) =
+ untypecheckedTreeBody(block, block.stats)
+
+ /** Recover tree body to parsed state */
+ private[internal] def untypecheckedTreeBody(tree: Tree, tbody: List[Tree]) = {
+ def filterBody(body: List[Tree]) = body filter {
+ case _: ValDef | _: TypeDef => true
+ // keep valdef or getter for val/var
+ case dd: DefDef if dd.mods.hasAccessorFlag => !nme.isSetterName(dd.name) && !tbody.exists {
+ case vd: ValDef => dd.name == vd.name.dropLocal
+ case _ => false
+ }
+ case md: MemberDef => !md.mods.isSynthetic
+ case tree => true
+ }
+
+ def lazyValDefRhs(body: Tree) =
+ body match {
+ case Block(List(Assign(_, rhs)), _) => rhs
+ case _ => body
+ }
+
+ def recoverBody(body: List[Tree]) = body map {
+ case vd @ ValDef(vmods, vname, _, vrhs) if nme.isLocalName(vname) =>
+ tbody find {
+ case dd: DefDef => dd.name == vname.dropLocal
+ case _ => false
+ } map { dd =>
+ val DefDef(dmods, dname, _, _, _, drhs) = dd
+ // get access flags from DefDef
+ val vdMods = (vmods &~ Flags.AccessFlags) | (dmods & Flags.AccessFlags).flags
+ // for most cases lazy body should be taken from accessor DefDef
+ val vdRhs = if (vmods.isLazy) lazyValDefRhs(drhs) else vrhs
+ copyValDef(vd)(mods = vdMods, name = dname, rhs = vdRhs)
+ } getOrElse (vd)
+ // for abstract and some lazy val/vars
+ case dd @ DefDef(mods, name, _, _, tpt, rhs) if mods.hasAccessorFlag =>
+ // transform getter mods to field
+ val vdMods = (if (!mods.hasStableFlag) mods | Flags.MUTABLE else mods &~ Flags.STABLE) &~ Flags.ACCESSOR
+ ValDef(vdMods, name, tpt, rhs)
+ case tr => tr
+ }
+
+ if (detectTypecheckedTree(tree)) {
+ recoverBody(filterBody(tbody))
+ } else tbody
+ }
+
/** The first constructor definitions in `stats` */
def firstConstructor(stats: List[Tree]): Tree = stats find {
case x: DefDef => nme.isConstructorName(x.name)
diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala
index 7a6862a770..9dc4baee32 100644
--- a/src/reflect/scala/reflect/internal/Trees.scala
+++ b/src/reflect/scala/reflect/internal/Trees.scala
@@ -1685,10 +1685,12 @@ trait Trees extends api.Trees {
// this is necessary to avoid crashes like https://github.com/scalamacros/paradise/issues/1
// when someone tries to c.typecheck a naked MemberDef
- def wrappingIntoTerm(tree: Tree)(op: Tree => Tree): Tree = {
- op(build.SyntacticBlock(tree :: Nil)) match {
- case build.SyntacticBlock(tree :: Nil) => tree
- case tree => tree
+ def wrappingIntoTerm(tree0: Tree)(op: Tree => Tree): Tree = {
+ val neededWrapping = !tree0.isTerm
+ val tree1 = build.SyntacticBlock(tree0 :: Nil)
+ op(tree1) match {
+ case Block(tree2 :: Nil, Literal(Constant(()))) if neededWrapping => tree2
+ case tree2 => tree2
}
}
diff --git a/src/reflect/scala/reflect/internal/settings/MutableSettings.scala b/src/reflect/scala/reflect/internal/settings/MutableSettings.scala
index 048fe9ef37..a494c7f0d0 100644
--- a/src/reflect/scala/reflect/internal/settings/MutableSettings.scala
+++ b/src/reflect/scala/reflect/internal/settings/MutableSettings.scala
@@ -37,6 +37,7 @@ abstract class MutableSettings extends AbsSettings {
def XfullLubs: BooleanSetting
def XnoPatmatAnalysis: BooleanSetting
def Xprintpos: BooleanSetting
+ def strictInference: BooleanSetting
def Yposdebug: BooleanSetting
def Yrangepos: BooleanSetting
def Yshowsymowners: BooleanSetting
diff --git a/src/reflect/scala/reflect/internal/tpe/GlbLubs.scala b/src/reflect/scala/reflect/internal/tpe/GlbLubs.scala
index 1c4d05ae32..876685e24a 100644
--- a/src/reflect/scala/reflect/internal/tpe/GlbLubs.scala
+++ b/src/reflect/scala/reflect/internal/tpe/GlbLubs.scala
@@ -14,11 +14,11 @@ private[internal] trait GlbLubs {
import TypesStats._
private final val printLubs = scala.sys.props contains "scalac.debug.lub"
+ private final val strictInference = settings.strictInference
/** In case anyone wants to turn off lub verification without reverting anything. */
private final val verifyLubs = true
-
private def printLubMatrix(btsMap: Map[Type, List[Type]], depth: Depth) {
import util.TableDef
import TableDef.Column
@@ -63,6 +63,26 @@ private[internal] trait GlbLubs {
}
}
+ // only called when strictInference
+ private def willViolateRecursiveBounds(tp: Type, ts: List[Type], tsElimSub: List[Type]) = {
+ val typeSym = ts.head.typeSymbol // we're uniform, the `.head` is as good as any.
+ def fbounds = findRecursiveBounds(ts) map (_._2)
+ def isRecursive = typeSym.typeParams exists fbounds.contains
+
+ isRecursive && (transposeSafe(tsElimSub map (_.normalize.typeArgs)) match {
+ case Some(arggsTransposed) =>
+ val mergedTypeArgs = (tp match { case et: ExistentialType => et.underlying; case _ => tp}).typeArgs
+ exists3(typeSym.typeParams, mergedTypeArgs, arggsTransposed) {
+ (param, arg, lubbedArgs) =>
+ val isExistential = arg.typeSymbol.isExistentiallyBound
+ val isInFBound = fbounds contains param
+ val wasLubbed = !lubbedArgs.exists(_ =:= arg)
+ (!isExistential && isInFBound && wasLubbed)
+ }
+ case None => false
+ })
+ }
+
/** Given a matrix `tsBts` whose columns are basetype sequences (and the symbols `tsParams` that should be interpreted as type parameters in this matrix),
* compute its least sorted upwards closed upper bound relative to the following ordering <= between lists of types:
*
@@ -88,7 +108,8 @@ private[internal] trait GlbLubs {
case _ => tp
}
// pretypes is a tail-recursion-preserving accumulator.
- @tailrec def loop(pretypes: List[Type], tsBts: List[List[Type]]): List[Type] = {
+ @tailrec
+ def loop(pretypes: List[Type], tsBts: List[List[Type]]): List[Type] = {
lubListDepth = lubListDepth.incr
if (tsBts.isEmpty || (tsBts exists typeListIsEmpty)) pretypes.reverse
@@ -110,28 +131,19 @@ private[internal] trait GlbLubs {
// merging, strip targs that refer to bound tparams (when we're computing the lub of type
// constructors.) Also filter out all types that are a subtype of some other type.
if (isUniformFrontier) {
- val fbounds = findRecursiveBounds(ts0) map (_._2)
- val tcLubList = typeConstructorLubList(ts0)
- def isRecursive(tp: Type) = tp.typeSymbol.typeParams exists fbounds.contains
-
- val ts1 = ts0 map { t =>
- if (isRecursive(t)) {
- tcLubList map (t baseType _.typeSymbol) find (t => !isRecursive(t)) match {
- case Some(tp) => logResult(s"Breaking recursion in lublist, substituting weaker type.\n Was: $t\n Now")(tp)
- case _ => t
- }
- }
- else t
- }
val tails = tsBts map (_.tail)
- mergePrefixAndArgs(elimSub(ts1, depth) map elimHigherOrderTypeParam, Covariant, depth) match {
+ val ts1 = elimSub(ts0, depth) map elimHigherOrderTypeParam
+ mergePrefixAndArgs(ts1, Covariant, depth) match {
case NoType => loop(pretypes, tails)
- case tp => loop(tp :: pretypes, tails)
+ case tp if strictInference && willViolateRecursiveBounds(tp, ts0, ts1) =>
+ log(s"Breaking recursion in lublist, advancing frontier and discaring merged prefix/args from $tp")
+ loop(pretypes, tails)
+ case tp =>
+ loop(tp :: pretypes, tails)
}
- }
- else {
+ } else {
// frontier is not uniform yet, move it beyond the current minimal symbol;
- // lather, rinSe, repeat
+ // lather, rinse, repeat
val sym = minSym(ts0)
val newtps = tsBts map (ts => if (ts.head.typeSymbol == sym) ts.tail else ts)
if (printLubs) {
@@ -257,23 +269,6 @@ private[internal] trait GlbLubs {
private val _glbResults = new mutable.HashMap[(Depth, List[Type]), Type]
def glbResults = _glbResults
- /** Given a list of types, finds all the base classes they have in
- * common, then returns a list of type constructors derived directly
- * from the symbols (so any more specific type information is ignored.)
- * The list is filtered such that every type constructor in the list
- * expects the same number of type arguments, which is chosen based
- * on the deepest class among the common baseclasses.
- */
- def typeConstructorLubList(ts: List[Type]): List[Type] = {
- val bcs = ts.flatMap(_.baseClasses).distinct sortWith (_ isLess _)
- val tcons = bcs filter (clazz => ts forall (_.typeSymbol isSubClass clazz))
-
- tcons map (_.typeConstructor) match {
- case Nil => Nil
- case t :: ts => t :: ts.filter(_.typeParams.size == t.typeParams.size)
- }
- }
-
def lub(ts: List[Type]): Type = ts match {
case Nil => NothingTpe
case t :: Nil => t
diff --git a/src/reflect/scala/reflect/runtime/Settings.scala b/src/reflect/scala/reflect/runtime/Settings.scala
index d46846fc21..27d574b1de 100644
--- a/src/reflect/scala/reflect/runtime/Settings.scala
+++ b/src/reflect/scala/reflect/runtime/Settings.scala
@@ -33,6 +33,7 @@ private[reflect] class Settings extends MutableSettings {
val Xexperimental = new BooleanSetting(false)
val XfullLubs = new BooleanSetting(false)
val XnoPatmatAnalysis = new BooleanSetting(false)
+ val strictInference = new BooleanSetting(false)
val Xprintpos = new BooleanSetting(false)
val Yposdebug = new BooleanSetting(false)
val Yrangepos = new BooleanSetting(false)
diff --git a/src/scaladoc/scala/tools/nsc/doc/Settings.scala b/src/scaladoc/scala/tools/nsc/doc/Settings.scala
index 5ea1443a19..67529f4178 100644
--- a/src/scaladoc/scala/tools/nsc/doc/Settings.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/Settings.scala
@@ -298,7 +298,7 @@ class Settings(error: String => Unit, val printMsg: String => Unit = println(_))
/** Common conversion targets that affect any class in Scala */
val commonConversionTargets = Set(
"scala.Predef.StringFormat",
- "scala.Predef.StringAdd",
+ "scala.Predef.any2stringadd",
"scala.Predef.ArrowAssoc",
"scala.Predef.Ensuring",
"scala.collection.TraversableOnce.alternateImplicit")
diff --git a/test/files/neg/logImplicits.check b/test/files/neg/logImplicits.check
index 2265614962..270882b71a 100644
--- a/test/files/neg/logImplicits.check
+++ b/test/files/neg/logImplicits.check
@@ -10,7 +10,7 @@ logImplicits.scala:15: inferred view from String("abc") to Int = C.this.convert:
logImplicits.scala:19: applied implicit conversion from Int(1) to ?{def ->: ?} = implicit def ArrowAssoc[A](self: A): ArrowAssoc[A]
def f = (1 -> 2) + "c"
^
-logImplicits.scala:19: applied implicit conversion from (Int, Int) to ?{def +: ?} = implicit def StringAdd[A](self: A): StringAdd[A]
+logImplicits.scala:19: applied implicit conversion from (Int, Int) to ?{def +: ?} = implicit def any2stringadd[A](self: A): any2stringadd[A]
def f = (1 -> 2) + "c"
^
logImplicits.scala:22: error: class Un needs to be abstract, since method unimplemented is not defined
diff --git a/test/files/neg/predef-masking.scala b/test/files/neg/predef-masking.scala
index 6f4f4859d0..67b69aa169 100644
--- a/test/files/neg/predef-masking.scala
+++ b/test/files/neg/predef-masking.scala
@@ -1,5 +1,5 @@
// Testing predef masking
-import Predef.{ StringAdd => _, _ }
+import Predef.{ any2stringadd => _, _ }
object StringPlusConfusion {
// Would love to do something about this error message, but by the
diff --git a/test/files/neg/quasiquotes-syntax-error-position.check b/test/files/neg/quasiquotes-syntax-error-position.check
index 14fef16e01..fd55bd25b5 100644
--- a/test/files/neg/quasiquotes-syntax-error-position.check
+++ b/test/files/neg/quasiquotes-syntax-error-position.check
@@ -7,7 +7,7 @@ quasiquotes-syntax-error-position.scala:6: error: illegal start of simple expres
quasiquotes-syntax-error-position.scala:7: error: '}' expected but end of quote found.
q"class $t { def foo = $a"
^
-quasiquotes-syntax-error-position.scala:8: error: '.' expected but splicee found.
+quasiquotes-syntax-error-position.scala:8: error: '.' expected but unquotee found.
q"import $t $t"
^
quasiquotes-syntax-error-position.scala:9: error: '{' expected but end of quote found.
diff --git a/test/files/neg/t6675.flags b/test/files/neg/t6675.flags
index e93641e931..2843ea9efc 100644
--- a/test/files/neg/t6675.flags
+++ b/test/files/neg/t6675.flags
@@ -1 +1 @@
--Xlint -Xfatal-warnings \ No newline at end of file
+-deprecation -Xlint -Xfatal-warnings \ No newline at end of file
diff --git a/test/files/neg/t6675b.flags b/test/files/neg/t6675b.flags
index 1008b0a70c..2fcfa0cddb 100644
--- a/test/files/neg/t6675b.flags
+++ b/test/files/neg/t6675b.flags
@@ -1 +1 @@
--Xlint
+-deprecation -Xlint
diff --git a/test/files/neg/si7980.check b/test/files/neg/t7980.check
index b085cabf1d..031c23dbeb 100644
--- a/test/files/neg/si7980.check
+++ b/test/files/neg/t7980.check
@@ -1,4 +1,4 @@
-si7980.scala:7: error: Can't splice Nothing, bottom type values often indicate programmer mistake
+t7980.scala:7: error: Can't unquote Nothing, bottom type values often indicate programmer mistake
println(q"class ${Name(X)} { }")
^
one error found
diff --git a/test/files/neg/si7980.scala b/test/files/neg/t7980.scala
index b21907de54..b21907de54 100644
--- a/test/files/neg/si7980.scala
+++ b/test/files/neg/t7980.scala
diff --git a/test/files/neg/t8229.check b/test/files/neg/t8229.check
new file mode 100644
index 0000000000..cc504fa34e
--- /dev/null
+++ b/test/files/neg/t8229.check
@@ -0,0 +1,4 @@
+t8229.scala:5: error: value + is not a member of Object
+ o + ""
+ ^
+one error found
diff --git a/test/files/neg/t8229.scala b/test/files/neg/t8229.scala
new file mode 100644
index 0000000000..91966311e2
--- /dev/null
+++ b/test/files/neg/t8229.scala
@@ -0,0 +1,6 @@
+import Predef.{any2stringadd => _, _}
+
+object Test {
+ val o = new Object()
+ o + ""
+}
diff --git a/test/files/pos/t6675.flags b/test/files/pos/t6675.flags
index e8fb65d50c..d1b831ea87 100644
--- a/test/files/pos/t6675.flags
+++ b/test/files/pos/t6675.flags
@@ -1 +1 @@
--Xfatal-warnings \ No newline at end of file
+-deprecation -Xfatal-warnings \ No newline at end of file
diff --git a/test/files/pos/t7788.scala b/test/files/pos/t7788.scala
new file mode 100644
index 0000000000..81eada962b
--- /dev/null
+++ b/test/files/pos/t7788.scala
@@ -0,0 +1,8 @@
+class Test {
+ // Predef used to define a method `conforms` to produce the implicit evidence below
+ // all this does is ensure we don't rename Predef.$conforms back to conforms when $ goes out of fashion
+ // or that there is some other way of generating the implicit value that witnesses T => U for T <: U
+ def conforms(x: Int, y: Int) = x < y
+ def foo[A](implicit ev: Int => A) = ???
+ foo[Int]
+} \ No newline at end of file
diff --git a/test/files/pos/t8224.scala b/test/files/pos/t8224.scala
new file mode 100644
index 0000000000..2fae925df3
--- /dev/null
+++ b/test/files/pos/t8224.scala
@@ -0,0 +1,12 @@
+import language.higherKinds
+
+trait P [N1, +E1[X <: N1]]
+trait PIn[N2, +E2[X <: N2]] extends P[Int,Any]
+
+trait EI extends PIn[Int, Nothing]
+trait NI extends PIn[Int, Nothing]
+
+object Test {
+ val lub = if (true) ??? : EI else ??? : NI
+ val pin: PIn[Int,Nothing] = lub
+}
diff --git a/test/files/pos/t8315.flags b/test/files/pos/t8315.flags
new file mode 100644
index 0000000000..c926ad6493
--- /dev/null
+++ b/test/files/pos/t8315.flags
@@ -0,0 +1 @@
+-Yinline -Ydead-code
diff --git a/test/files/pos/t8315.scala b/test/files/pos/t8315.scala
new file mode 100644
index 0000000000..2f7742ed67
--- /dev/null
+++ b/test/files/pos/t8315.scala
@@ -0,0 +1,12 @@
+object Test {
+ def crash(as: Listt): Unit = {
+ map(as, (_: Any) => return)
+ }
+
+ final def map(x: Listt, f: Any => Any): Any = {
+ if (x eq Nill) "" else f("")
+ }
+}
+
+object Nill extends Listt
+class Listt
diff --git a/test/files/pos/t8315b.flags b/test/files/pos/t8315b.flags
new file mode 100644
index 0000000000..c926ad6493
--- /dev/null
+++ b/test/files/pos/t8315b.flags
@@ -0,0 +1 @@
+-Yinline -Ydead-code
diff --git a/test/files/pos/t8315b.scala b/test/files/pos/t8315b.scala
new file mode 100644
index 0000000000..d7a2bf565f
--- /dev/null
+++ b/test/files/pos/t8315b.scala
@@ -0,0 +1,11 @@
+object Test extends Object {
+ def crash: Unit = {
+ val key = ""
+ try map(new F(key))
+ catch { case _: Throwable => }
+ };
+ final def map(f: F): Any = f.apply("");
+};
+final class F(key: String) {
+ final def apply(a: Any): Any = throw new RuntimeException(key);
+}
diff --git a/test/files/run/macro-reify-nested-b/Impls_Macros_1.scala b/test/files/run/macro-reify-chained1/Impls_Macros_1.scala
index 3bea04cead..7f877b2729 100644
--- a/test/files/run/macro-reify-nested-b/Impls_Macros_1.scala
+++ b/test/files/run/macro-reify-chained1/Impls_Macros_1.scala
@@ -1,6 +1,7 @@
import scala.reflect.runtime.universe._
import scala.reflect.runtime.{universe => ru}
import scala.reflect.macros.blackbox.Context
+import scala.language.experimental.macros
case class Utils[C <: Context]( c:C ) {
import c.universe._
@@ -34,7 +35,7 @@ object QueryableMacros{
c.universe.reify{ Queryable.factory[S]( foo.splice )}
}
def map[T:c.WeakTypeTag, S:c.WeakTypeTag]
- (c: scala.reflect.macros.blackbox.Context)
+ (c: Context)
(projection: c.Expr[T => S]): c.Expr[Queryable[S]] = _helper[c.type,S]( c )( "_map", projection )
}
class Queryable[T]{
diff --git a/test/files/run/macro-reify-chained1/Test_2.scala b/test/files/run/macro-reify-chained1/Test_2.scala
new file mode 100644
index 0000000000..2adb07b035
--- /dev/null
+++ b/test/files/run/macro-reify-chained1/Test_2.scala
@@ -0,0 +1,9 @@
+object Test extends App{
+ val q : Queryable[Any] = new Queryable[Any]
+ q.map(x => x).map(x => x)
+
+ locally {
+ val q : Queryable[Any] = new Queryable[Any]
+ q.map(x => x).map(x => x)
+ }
+} \ No newline at end of file
diff --git a/test/files/run/macro-reify-chained2/Impls_Macros_1.scala b/test/files/run/macro-reify-chained2/Impls_Macros_1.scala
new file mode 100644
index 0000000000..965b191044
--- /dev/null
+++ b/test/files/run/macro-reify-chained2/Impls_Macros_1.scala
@@ -0,0 +1,47 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{universe => ru}
+import scala.reflect.macros.whitebox.Context
+import scala.language.experimental.macros
+
+case class Utils[C <: Context]( c:C ) {
+ import c.universe._
+ import c.{Tree=>_}
+ object removeDoubleReify extends c.universe.Transformer {
+ def apply( tree:Tree ) = transform(tree)
+ override def transform(tree: Tree): Tree = {
+ super.transform {
+ tree match {
+ case Apply(TypeApply(Select(_this, termname), _), reification::Nil )
+ if termname.toString == "factory" => c.unreifyTree(reification)
+ case Apply(Select(_this, termname), reification::Nil )
+ if termname.toString == "factory" => c.unreifyTree(reification)
+ case _ => tree
+ }
+ }
+ }
+ }
+}
+object QueryableMacros{
+ def _helper[C <: Context,S:c.WeakTypeTag]( c:C )( name:String, projection:c.Expr[_] ) = {
+ import c.universe._
+ import internal._
+ val element_type = implicitly[c.WeakTypeTag[S]].tpe
+ val foo = c.Expr[ru.Expr[Queryable[S]]](
+ c.reifyTree( gen.mkRuntimeUniverseRef, EmptyTree, c.typecheck(
+ Utils[c.type](c).removeDoubleReify(
+ Apply(Select(c.prefix.tree, TermName( name )), List( projection.tree ))
+ ).asInstanceOf[Tree]
+ )))
+ c.universe.reify{ Queryable.factory[S]( foo.splice )}
+ }
+ def map[T:c.WeakTypeTag, S:c.WeakTypeTag]
+ (c: Context)
+ (projection: c.Expr[T => S]): c.Expr[Queryable[S]] = _helper[c.type,S]( c )( "_map", projection )
+}
+class Queryable[T]{
+ def _map[S]( projection: T => S ) : Queryable[S] = ???
+ def map[S]( projection: T => S ) : Queryable[S] = macro QueryableMacros.map[T,S]
+}
+object Queryable{
+ def factory[S]( projection:ru.Expr[Queryable[S]] ) : Queryable[S] = null
+} \ No newline at end of file
diff --git a/test/files/run/macro-reify-chained2/Test_2.scala b/test/files/run/macro-reify-chained2/Test_2.scala
new file mode 100644
index 0000000000..2adb07b035
--- /dev/null
+++ b/test/files/run/macro-reify-chained2/Test_2.scala
@@ -0,0 +1,9 @@
+object Test extends App{
+ val q : Queryable[Any] = new Queryable[Any]
+ q.map(x => x).map(x => x)
+
+ locally {
+ val q : Queryable[Any] = new Queryable[Any]
+ q.map(x => x).map(x => x)
+ }
+} \ No newline at end of file
diff --git a/test/files/run/macro-reify-nested-a.flags b/test/files/run/macro-reify-nested-a.flags
deleted file mode 100644
index cd66464f2f..0000000000
--- a/test/files/run/macro-reify-nested-a.flags
+++ /dev/null
@@ -1 +0,0 @@
--language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-reify-nested-a/Impls_Macros_1.scala b/test/files/run/macro-reify-nested-a1/Impls_Macros_1.scala
index 3bea04cead..7f877b2729 100644
--- a/test/files/run/macro-reify-nested-a/Impls_Macros_1.scala
+++ b/test/files/run/macro-reify-nested-a1/Impls_Macros_1.scala
@@ -1,6 +1,7 @@
import scala.reflect.runtime.universe._
import scala.reflect.runtime.{universe => ru}
import scala.reflect.macros.blackbox.Context
+import scala.language.experimental.macros
case class Utils[C <: Context]( c:C ) {
import c.universe._
@@ -34,7 +35,7 @@ object QueryableMacros{
c.universe.reify{ Queryable.factory[S]( foo.splice )}
}
def map[T:c.WeakTypeTag, S:c.WeakTypeTag]
- (c: scala.reflect.macros.blackbox.Context)
+ (c: Context)
(projection: c.Expr[T => S]): c.Expr[Queryable[S]] = _helper[c.type,S]( c )( "_map", projection )
}
class Queryable[T]{
diff --git a/test/files/run/macro-reify-nested-a/Test_2.scala b/test/files/run/macro-reify-nested-a1/Test_2.scala
index fa0eb378af..b99c4c55e4 100644
--- a/test/files/run/macro-reify-nested-a/Test_2.scala
+++ b/test/files/run/macro-reify-nested-a1/Test_2.scala
@@ -1,4 +1,9 @@
object Test extends App{
val q : Queryable[Any] = new Queryable[Any]
q.map(e1 => q.map(e2=>e1))
+
+ locally {
+ val q : Queryable[Any] = new Queryable[Any]
+ q.map(e1 => q.map(e2=>e1))
+ }
} \ No newline at end of file
diff --git a/test/files/run/macro-reify-nested-a2/Impls_Macros_1.scala b/test/files/run/macro-reify-nested-a2/Impls_Macros_1.scala
new file mode 100644
index 0000000000..965b191044
--- /dev/null
+++ b/test/files/run/macro-reify-nested-a2/Impls_Macros_1.scala
@@ -0,0 +1,47 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{universe => ru}
+import scala.reflect.macros.whitebox.Context
+import scala.language.experimental.macros
+
+case class Utils[C <: Context]( c:C ) {
+ import c.universe._
+ import c.{Tree=>_}
+ object removeDoubleReify extends c.universe.Transformer {
+ def apply( tree:Tree ) = transform(tree)
+ override def transform(tree: Tree): Tree = {
+ super.transform {
+ tree match {
+ case Apply(TypeApply(Select(_this, termname), _), reification::Nil )
+ if termname.toString == "factory" => c.unreifyTree(reification)
+ case Apply(Select(_this, termname), reification::Nil )
+ if termname.toString == "factory" => c.unreifyTree(reification)
+ case _ => tree
+ }
+ }
+ }
+ }
+}
+object QueryableMacros{
+ def _helper[C <: Context,S:c.WeakTypeTag]( c:C )( name:String, projection:c.Expr[_] ) = {
+ import c.universe._
+ import internal._
+ val element_type = implicitly[c.WeakTypeTag[S]].tpe
+ val foo = c.Expr[ru.Expr[Queryable[S]]](
+ c.reifyTree( gen.mkRuntimeUniverseRef, EmptyTree, c.typecheck(
+ Utils[c.type](c).removeDoubleReify(
+ Apply(Select(c.prefix.tree, TermName( name )), List( projection.tree ))
+ ).asInstanceOf[Tree]
+ )))
+ c.universe.reify{ Queryable.factory[S]( foo.splice )}
+ }
+ def map[T:c.WeakTypeTag, S:c.WeakTypeTag]
+ (c: Context)
+ (projection: c.Expr[T => S]): c.Expr[Queryable[S]] = _helper[c.type,S]( c )( "_map", projection )
+}
+class Queryable[T]{
+ def _map[S]( projection: T => S ) : Queryable[S] = ???
+ def map[S]( projection: T => S ) : Queryable[S] = macro QueryableMacros.map[T,S]
+}
+object Queryable{
+ def factory[S]( projection:ru.Expr[Queryable[S]] ) : Queryable[S] = null
+} \ No newline at end of file
diff --git a/test/files/run/macro-reify-nested-a2/Test_2.scala b/test/files/run/macro-reify-nested-a2/Test_2.scala
new file mode 100644
index 0000000000..b99c4c55e4
--- /dev/null
+++ b/test/files/run/macro-reify-nested-a2/Test_2.scala
@@ -0,0 +1,9 @@
+object Test extends App{
+ val q : Queryable[Any] = new Queryable[Any]
+ q.map(e1 => q.map(e2=>e1))
+
+ locally {
+ val q : Queryable[Any] = new Queryable[Any]
+ q.map(e1 => q.map(e2=>e1))
+ }
+} \ No newline at end of file
diff --git a/test/files/run/macro-reify-nested-b.flags b/test/files/run/macro-reify-nested-b.flags
deleted file mode 100644
index cd66464f2f..0000000000
--- a/test/files/run/macro-reify-nested-b.flags
+++ /dev/null
@@ -1 +0,0 @@
--language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-reify-nested-b1/Impls_Macros_1.scala b/test/files/run/macro-reify-nested-b1/Impls_Macros_1.scala
new file mode 100644
index 0000000000..7f877b2729
--- /dev/null
+++ b/test/files/run/macro-reify-nested-b1/Impls_Macros_1.scala
@@ -0,0 +1,47 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{universe => ru}
+import scala.reflect.macros.blackbox.Context
+import scala.language.experimental.macros
+
+case class Utils[C <: Context]( c:C ) {
+ import c.universe._
+ import c.{Tree=>_}
+ object removeDoubleReify extends c.universe.Transformer {
+ def apply( tree:Tree ) = transform(tree)
+ override def transform(tree: Tree): Tree = {
+ super.transform {
+ tree match {
+ case Apply(TypeApply(Select(_this, termname), _), reification::Nil )
+ if termname.toString == "factory" => c.unreifyTree(reification)
+ case Apply(Select(_this, termname), reification::Nil )
+ if termname.toString == "factory" => c.unreifyTree(reification)
+ case _ => tree
+ }
+ }
+ }
+ }
+}
+object QueryableMacros{
+ def _helper[C <: Context,S:c.WeakTypeTag]( c:C )( name:String, projection:c.Expr[_] ) = {
+ import c.universe._
+ import internal._
+ val element_type = implicitly[c.WeakTypeTag[S]].tpe
+ val foo = c.Expr[ru.Expr[Queryable[S]]](
+ c.reifyTree( gen.mkRuntimeUniverseRef, EmptyTree, c.typecheck(
+ Utils[c.type](c).removeDoubleReify(
+ Apply(Select(c.prefix.tree, TermName( name )), List( projection.tree ))
+ ).asInstanceOf[Tree]
+ )))
+ c.universe.reify{ Queryable.factory[S]( foo.splice )}
+ }
+ def map[T:c.WeakTypeTag, S:c.WeakTypeTag]
+ (c: Context)
+ (projection: c.Expr[T => S]): c.Expr[Queryable[S]] = _helper[c.type,S]( c )( "_map", projection )
+}
+class Queryable[T]{
+ def _map[S]( projection: T => S ) : Queryable[S] = ???
+ def map[S]( projection: T => S ) : Queryable[S] = macro QueryableMacros.map[T,S]
+}
+object Queryable{
+ def factory[S]( projection:ru.Expr[Queryable[S]] ) : Queryable[S] = null
+} \ No newline at end of file
diff --git a/test/files/run/macro-reify-nested-b/Test_2.scala b/test/files/run/macro-reify-nested-b1/Test_2.scala
index fa13f57ffb..b199036349 100644
--- a/test/files/run/macro-reify-nested-b/Test_2.scala
+++ b/test/files/run/macro-reify-nested-b1/Test_2.scala
@@ -1,4 +1,9 @@
object Test extends App{
val q : Queryable[Any] = new Queryable[Any]
q.map(e1 => q.map(e2=>e1).map(e2=>e1))
+
+ locally {
+ val q : Queryable[Any] = new Queryable[Any]
+ q.map(e1 => q.map(e2=>e1).map(e2=>e1))
+ }
} \ No newline at end of file
diff --git a/test/files/run/macro-reify-nested-b2/Impls_Macros_1.scala b/test/files/run/macro-reify-nested-b2/Impls_Macros_1.scala
new file mode 100644
index 0000000000..965b191044
--- /dev/null
+++ b/test/files/run/macro-reify-nested-b2/Impls_Macros_1.scala
@@ -0,0 +1,47 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{universe => ru}
+import scala.reflect.macros.whitebox.Context
+import scala.language.experimental.macros
+
+case class Utils[C <: Context]( c:C ) {
+ import c.universe._
+ import c.{Tree=>_}
+ object removeDoubleReify extends c.universe.Transformer {
+ def apply( tree:Tree ) = transform(tree)
+ override def transform(tree: Tree): Tree = {
+ super.transform {
+ tree match {
+ case Apply(TypeApply(Select(_this, termname), _), reification::Nil )
+ if termname.toString == "factory" => c.unreifyTree(reification)
+ case Apply(Select(_this, termname), reification::Nil )
+ if termname.toString == "factory" => c.unreifyTree(reification)
+ case _ => tree
+ }
+ }
+ }
+ }
+}
+object QueryableMacros{
+ def _helper[C <: Context,S:c.WeakTypeTag]( c:C )( name:String, projection:c.Expr[_] ) = {
+ import c.universe._
+ import internal._
+ val element_type = implicitly[c.WeakTypeTag[S]].tpe
+ val foo = c.Expr[ru.Expr[Queryable[S]]](
+ c.reifyTree( gen.mkRuntimeUniverseRef, EmptyTree, c.typecheck(
+ Utils[c.type](c).removeDoubleReify(
+ Apply(Select(c.prefix.tree, TermName( name )), List( projection.tree ))
+ ).asInstanceOf[Tree]
+ )))
+ c.universe.reify{ Queryable.factory[S]( foo.splice )}
+ }
+ def map[T:c.WeakTypeTag, S:c.WeakTypeTag]
+ (c: Context)
+ (projection: c.Expr[T => S]): c.Expr[Queryable[S]] = _helper[c.type,S]( c )( "_map", projection )
+}
+class Queryable[T]{
+ def _map[S]( projection: T => S ) : Queryable[S] = ???
+ def map[S]( projection: T => S ) : Queryable[S] = macro QueryableMacros.map[T,S]
+}
+object Queryable{
+ def factory[S]( projection:ru.Expr[Queryable[S]] ) : Queryable[S] = null
+} \ No newline at end of file
diff --git a/test/files/run/macro-reify-nested-b2/Test_2.scala b/test/files/run/macro-reify-nested-b2/Test_2.scala
new file mode 100644
index 0000000000..b199036349
--- /dev/null
+++ b/test/files/run/macro-reify-nested-b2/Test_2.scala
@@ -0,0 +1,9 @@
+object Test extends App{
+ val q : Queryable[Any] = new Queryable[Any]
+ q.map(e1 => q.map(e2=>e1).map(e2=>e1))
+
+ locally {
+ val q : Queryable[Any] = new Queryable[Any]
+ q.map(e1 => q.map(e2=>e1).map(e2=>e1))
+ }
+} \ No newline at end of file
diff --git a/test/files/run/t2251.flags b/test/files/run/t2251.flags
new file mode 100644
index 0000000000..19243266d1
--- /dev/null
+++ b/test/files/run/t2251.flags
@@ -0,0 +1 @@
+-Xstrict-inference \ No newline at end of file
diff --git a/test/files/run/t2251b.flags b/test/files/run/t2251b.flags
new file mode 100644
index 0000000000..19243266d1
--- /dev/null
+++ b/test/files/run/t2251b.flags
@@ -0,0 +1 @@
+-Xstrict-inference \ No newline at end of file
diff --git a/test/files/run/t4577.scala b/test/files/run/t4577.scala
new file mode 100644
index 0000000000..b08100d3ea
--- /dev/null
+++ b/test/files/run/t4577.scala
@@ -0,0 +1,38 @@
+object Test {
+ val bippy = new Symbol("bippy")
+ val imposter = new Symbol("bippy")
+ val notBippy = new Symbol("not-bippy")
+ val syms = List(bippy, imposter, notBippy)
+
+ // the equals method should only be used for case `bippy`,
+ // for the singleton type pattern, case _: bippy.type, the spec mandates `bippy eq _` as the test
+ class Symbol(val name: String) {
+ override def equals(other: Any) = other match {
+ case x: Symbol => name == x.name
+ case _ => false
+ }
+ override def toString = name
+ }
+
+ // TODO: test bytecode equality for f and fDirect (and g and gDirect),
+ // for now the optimizer doesn't quite get from `f` to `fDirect`
+ def f(s: Symbol) = s match {
+ case _: bippy.type => true
+ case _ => false
+ }
+ def fDirect(s: Symbol) = bippy eq s
+
+ def g(s: Symbol) = s match {
+ case _: bippy.type => 1
+ case `bippy` => 2
+ case _ => 3
+ }
+ def gDirect(s: Symbol) = if (bippy eq s) 1 else if (bippy == s) 2 else 3
+
+ def main(args: Array[String]): Unit = {
+ // `syms map f` should be: true false false
+ assert(syms forall (s => f(s) == fDirect(s)))
+ // `syms map g` should be: 1 2 3
+ assert(syms forall (s => g(s) == gDirect(s)))
+ }
+} \ No newline at end of file
diff --git a/test/files/run/t6111.check b/test/files/run/t6111.check
index 7fd2e33526..1f23a87f73 100644
--- a/test/files/run/t6111.check
+++ b/test/files/run/t6111.check
@@ -1,2 +1,3 @@
+warning: there were 2 deprecation warning(s); re-run with -deprecation for details
(8,8)
(x,x)
diff --git a/test/files/run/t6111.scala b/test/files/run/t6111.scala
index 7cceea1d09..c0bcf17a07 100644
--- a/test/files/run/t6111.scala
+++ b/test/files/run/t6111.scala
@@ -1,3 +1,5 @@
+// SI-6675 DEPRECATED AUTO-TUPLING BECAUSE BAD IDEA -- MEAMAXIMACULPA
+// TODO: remove this test case in 2.12, when the deprecation will go into effect and this will no longer compile
// slightly overkill, but a good test case for implicit resolution in extractor calls,
// along with the real fix: an extractor pattern with 1 sub-pattern should type check for all extractors
// that return Option[T], whatever T (even if it's a tuple)
diff --git a/test/files/run/t7185.check b/test/files/run/t7185.check
index 2b4adf36b4..ebf85b731f 100644
--- a/test/files/run/t7185.check
+++ b/test/files/run/t7185.check
@@ -24,7 +24,9 @@ tree: reflect.runtime.universe.Apply =
scala> {val tb = reflect.runtime.currentMirror.mkToolBox(); tb.typecheck(tree): Any}
res0: Any =
{
- $read.O.apply()
+ {
+ $read.O.apply()
+ }
}
scala>
diff --git a/test/files/run/t8197.scala b/test/files/run/t8197.scala
new file mode 100644
index 0000000000..5ca67088de
--- /dev/null
+++ b/test/files/run/t8197.scala
@@ -0,0 +1,13 @@
+// NOTE: according to SI-4728, this shouldn't even compile...
+class A
+class B
+// default arguments do not participate in overload resolution
+class Foo(val x: A = null) {
+ def this(bla: B*) {
+ this(new A)
+ }
+}
+
+object Test extends App {
+ assert((new Foo).x != null)
+}
diff --git a/test/files/scalacheck/quasiquotes/DefinitionConstructionProps.scala b/test/files/scalacheck/quasiquotes/DefinitionConstructionProps.scala
index 7e846bfb24..fdb0d83277 100644
--- a/test/files/scalacheck/quasiquotes/DefinitionConstructionProps.scala
+++ b/test/files/scalacheck/quasiquotes/DefinitionConstructionProps.scala
@@ -50,24 +50,24 @@ trait ClassConstruction { self: QuasiquoteProperties =>
assertEqAst(q"class Foo extends ..$parents", "class Foo")
}
- property("splice term name into class") = forAll { (rname: TypeName) =>
+ property("unquote term name into class") = forAll { (rname: TypeName) =>
// add prefix to avoid failure in case rname is keyword
val name = TypeName("prefix$" + rname)
eqAst(q"class $name", "class " + name.toString)
}
- property("splice method into class") = forAll { (name: TypeName, method: DefDef) =>
+ property("unquote method into class") = forAll { (name: TypeName, method: DefDef) =>
q"class $name { $method }" ≈ classWith(name, body = List(method))
}
- property("splice members into class") = forAll { (name: TypeName, defs: List[DefDef], extra: DefDef) =>
+ property("unquote members into class") = forAll { (name: TypeName, defs: List[DefDef], extra: DefDef) =>
q"""class $name {
..$defs
$extra
}""" ≈ classWith(name, body = defs :+ extra)
}
- property("splice type name into class parents") = forAll { (name: TypeName, parent: TypeName) =>
+ property("unquote type name into class parents") = forAll { (name: TypeName, parent: TypeName) =>
q"class $name extends $parent" ≈ classWith(name, parents = List(Ident(parent)))
}
@@ -84,27 +84,27 @@ trait ClassConstruction { self: QuasiquoteProperties =>
}
trait TraitConstruction { self: QuasiquoteProperties =>
- property("splice name into trait def") = test {
+ property("unquote name into trait def") = test {
val Foo = TypeName("Foo")
assert(q"trait $Foo" ≈ q"trait Foo")
}
- property("splice type params into trait def") = test {
+ property("unquote type params into trait def") = test {
val tparams = q"type A" :: q"type B" :: Nil
assert(q"trait Foo[..$tparams]" ≈ q"trait Foo[A, B]")
}
- property("splice defs into trait body") = test {
+ property("unquote defs into trait body") = test {
val body = q"def foo" :: q"val bar: Baz" :: Nil
assert(q"trait Foo { ..$body }" ≈ q"trait Foo { def foo; val bar: Baz }")
}
- property("splice parents into trait") = test {
+ property("unquote parents into trait") = test {
val parents = tq"A" :: tq"B" :: Nil
assert(q"trait Foo extends ..$parents" ≈ q"trait Foo extends A with B")
}
- property("splice early valdef into trait") = test {
+ property("unquote early valdef into trait") = test {
val x = q"val x: Int = 1"
assertEqAst(q"trait T extends { $x } with Any", "trait T extends { val x: Int = 1} with Any")
}
@@ -113,7 +113,7 @@ trait TraitConstruction { self: QuasiquoteProperties =>
assertEqAst(q"trait T extends { val x: Int = 1 } with Any", "trait T extends { val x: Int = 1 } with Any")
}
- property("splice defs into early block") = test {
+ property("unquote defs into early block") = test {
val defs = q"val x: Int = 0" :: q"type Foo = Bar" :: Nil
assert(q"trait T extends { ..$defs } with Bippy" ≈
q"trait T extends { val x: Int = 0; type Foo = Bar} with Bippy")
@@ -126,37 +126,37 @@ trait TraitConstruction { self: QuasiquoteProperties =>
}
trait TypeDefConstruction { self: QuasiquoteProperties =>
- property("splice type name into typedef") = forAll { (name1: TypeName, name2: TypeName) =>
+ property("unquote type name into typedef") = forAll { (name1: TypeName, name2: TypeName) =>
q"type $name1 = $name2" ≈ TypeDef(Modifiers(), name1, List(), Ident(name2))
}
- property("splice type names into type bounds") = forAll { (T1: TypeName, T2: TypeName, T3: TypeName) =>
+ property("unquote type names into type bounds") = forAll { (T1: TypeName, T2: TypeName, T3: TypeName) =>
q"type $T1 >: $T2 <: $T3" ≈
TypeDef(
Modifiers(DEFERRED), T1, List(),
TypeBoundsTree(Ident(T2), Ident(T3)))
}
- property("splice trees names into type bounds") = forAll { (T: TypeName, t1: Tree, t2: Tree) =>
+ property("unquote trees names into type bounds") = forAll { (T: TypeName, t1: Tree, t2: Tree) =>
q"type $T >: $t1 <: $t2" ≈
TypeDef(
Modifiers(DEFERRED), T, List(),
TypeBoundsTree(t1, t2))
}
- property("splice tparams into typedef (1)") = forAll { (T: TypeName, targs: List[TypeDef], t: Tree) =>
+ property("unquote tparams into typedef (1)") = forAll { (T: TypeName, targs: List[TypeDef], t: Tree) =>
q"type $T[..$targs] = $t" ≈ TypeDef(Modifiers(), T, targs, t)
}
- property("splice tparams into typedef (2)") = forAll { (T: TypeName, targs1: List[TypeDef], targs2: List[TypeDef], t: Tree) =>
+ property("unquote tparams into typedef (2)") = forAll { (T: TypeName, targs1: List[TypeDef], targs2: List[TypeDef], t: Tree) =>
q"type $T[..$targs1, ..$targs2] = $t" ≈ TypeDef(Modifiers(), T, targs1 ++ targs2, t)
}
- property("splice tparams into typedef (3)") = forAll { (T: TypeName, targ: TypeDef, targs: List[TypeDef], t: Tree) =>
+ property("unquote tparams into typedef (3)") = forAll { (T: TypeName, targ: TypeDef, targs: List[TypeDef], t: Tree) =>
q"type $T[$targ, ..$targs] = $t" ≈ TypeDef(Modifiers(), T, targ :: targs, t)
}
- property("splice typename into typedef with default bounds") = forAll { (T1: TypeName, T2: TypeName, t: Tree) =>
+ property("unquote typename into typedef with default bounds") = forAll { (T1: TypeName, T2: TypeName, t: Tree) =>
q"type $T1[$T2 >: Any <: Nothing] = $t" ≈
TypeDef(
Modifiers(), T1,
@@ -169,7 +169,7 @@ trait TypeDefConstruction { self: QuasiquoteProperties =>
t)
}
- property("splice type names into compound type tree") = forAll { (T: TypeName, A: TypeName, B: TypeName) =>
+ property("unquote type names into compound type tree") = forAll { (T: TypeName, A: TypeName, B: TypeName) =>
q"type $T = $A with $B" ≈
TypeDef(
Modifiers(), T, List(),
@@ -177,7 +177,7 @@ trait TypeDefConstruction { self: QuasiquoteProperties =>
Template(List(Ident(A), Ident(B)), ValDef(Modifiers(PRIVATE), termNames.WILDCARD, TypeTree(), EmptyTree), List())))
}
- property("splice trees into existential type tree") = forAll {
+ property("unquote trees into existential type tree") = forAll {
(T1: TypeName, T2: TypeName, X: TypeName, Lo: TypeName, Hi: TypeName) =>
q"type $T1 = $T2[$X] forSome { type $X >: $Lo <: $Hi }" ≈
@@ -189,11 +189,11 @@ trait TypeDefConstruction { self: QuasiquoteProperties =>
TypeDef(Modifiers(DEFERRED), X, List(), TypeBoundsTree(Ident(Lo), Ident(Hi))))))
}
- property("splice tree into singleton type tree") = forAll { (name: TypeName, t: Tree) =>
+ property("unquote tree into singleton type tree") = forAll { (name: TypeName, t: Tree) =>
q"type $name = $t.type" ≈ q"type $name = ${SingletonTypeTree(t)}"
}
- property("splice into applied type tree") = forAll { (T1: TypeName, T2: TypeName, args: List[Tree]) =>
+ property("unquote into applied type tree") = forAll { (T1: TypeName, T2: TypeName, args: List[Tree]) =>
q"type $T1 = $T2[..$args]" ≈
TypeDef(Modifiers(), T1, List(),
if(args.nonEmpty) AppliedTypeTree(Ident(T2), args) else Ident(T2))
@@ -201,11 +201,11 @@ trait TypeDefConstruction { self: QuasiquoteProperties =>
}
trait ValDefConstruction { self: QuasiquoteProperties =>
- property("splice into val") = forAll { (name: TermName, tpt: Tree, rhs: Tree) =>
+ property("unquote into val") = forAll { (name: TermName, tpt: Tree, rhs: Tree) =>
q"val $name: $tpt = $rhs" ≈ ValDef(Modifiers(), name, tpt, rhs)
}
- property("splice into var") = forAll { (name: TermName, tpt: Tree, rhs: Tree) =>
+ property("unquote into var") = forAll { (name: TermName, tpt: Tree, rhs: Tree) =>
q"var $name: $tpt = $rhs" ≈ ValDef(Modifiers(MUTABLE), name, tpt, rhs)
}
@@ -216,28 +216,28 @@ trait ValDefConstruction { self: QuasiquoteProperties =>
}
trait PatDefConstruction { self: QuasiquoteProperties =>
- property("splice pattern into pat def") = test {
+ property("unquote pattern into pat def") = test {
val pat = pq"(a, b)"
assertEqAst(q"val $pat = (1, 2)", "val (a, b) = (1, 2)")
val tpt = tq"(Int, Int)"
assertEqAst(q"val $pat: $tpt = (1, 2)", "val (a, b): (Int, Int) = (1, 2)")
}
- property("splice pattern into pat def within other pattern (1)") = test {
+ property("unquote pattern into pat def within other pattern (1)") = test {
val pat = pq"(a, b)"
assertEqAst(q"val Foo($pat) = Foo((1, 2))", "val Foo((a, b)) = Foo((1, 2))")
val tpt = tq"Foo"
assertEqAst(q"val Foo($pat): $tpt = Foo((1, 2))", "val Foo((a, b)): Foo = Foo((1, 2))")
}
- property("splice patterns into pat def within other pattern (2)") = test {
+ property("unquote patterns into pat def within other pattern (2)") = test {
val pat1 = pq"(a, b)"; val pat2 = pq"(c, d)"
assertEqAst(q"val ($pat1, $pat2) = ((1, 2), (3, 4))", "val ((a, b), (c, d)) = ((1, 2), (3, 4))")
val tpt = tq"((Int, Int), (Int, Int))"
assertEqAst(q"val ($pat1, $pat2): $tpt = ((1, 2), (3, 4))", "val ((a, b), (c, d)): ((Int, Int), (Int, Int)) = ((1, 2), (3, 4))")
}
- property("splice pattern without free vars into pat def") = test {
+ property("unquote pattern without free vars into pat def") = test {
val pat = pq"((1, 2), 3)"
assertEqAst(q"val $pat = ((1, 2), 3)", "{ val ((1, 2), 3) = ((1, 2), 3) }")
val tpt = tq"((Int, Int), Int)"
@@ -245,19 +245,19 @@ trait PatDefConstruction { self: QuasiquoteProperties =>
}
// won't result into pattern match due to SI-8211
- property("splice typed pat into pat def") = test {
+ property("unquote typed pat into pat def") = test {
val pat = pq"x: Int"
assertEqAst(q"val $pat = 2", "{ val x: Int = 2 }")
}
}
trait MethodConstruction { self: QuasiquoteProperties =>
- property("splice paramss into defdef") = test {
+ property("unquote paramss into defdef") = test {
val paramss = List(q"val x: Int") :: List(q"val y: Int = 1") :: Nil
assert(q"def foo(...$paramss)" ≈ parse("def foo(x: Int)(y: Int = 1)"))
}
- property("splice tparams into defdef") = test {
+ property("unquote tparams into defdef") = test {
val tparams = q"type A" :: q"type B <: Bippy" :: Nil
assert(q"def foo[..$tparams]" ≈ parse("def foo[A, B <: Bippy]"))
}
@@ -270,84 +270,84 @@ trait MethodConstruction { self: QuasiquoteProperties =>
assert(tree1.mods.annotations ≈ tree2.mods.annotations,
s"${tree1.mods.annotations} =/= ${tree2.mods.annotations}")
- property("splice type name into annotation") = test {
+ property("unquote type name into annotation") = test {
val name = TypeName("annot")
assertSameAnnots(q"@$name def foo", List(q"new $name"))
}
- property("splice ident into annotation") = test {
+ property("unquote ident into annotation") = test {
val name = TypeName("annot")
val ident = Ident(name)
assertSameAnnots(q"@$ident def foo", List(q"new $name"))
}
- property("splice idents into annotation") = test {
+ property("unquote idents into annotation") = test {
val idents = List(Ident(TypeName("annot1")), Ident(TypeName("annot2")))
assertSameAnnots(q"@..$idents def foo",
idents.map { ident => Apply(Select(New(ident), termNames.CONSTRUCTOR), List()) })
}
- property("splice constructor calls into annotation") = test {
+ property("unquote constructor calls into annotation") = test {
val ctorcalls = List(q"new a1", q"new a2")
assertSameAnnots(q"@..$ctorcalls def foo", ctorcalls)
}
- property("splice multiple annotations (1)") = test {
+ property("unquote multiple annotations (1)") = test {
val annot1 = q"new a1"
val annot2 = q"new a2"
val res = q"@$annot1 @$annot2 def foo"
assertSameAnnots(res, List(annot1, annot2))
}
- property("splice multiple annotations (2)") = test {
+ property("unquote multiple annotations (2)") = test {
val annot1 = q"new a1"
val annots = List(q"new a2", q"new a3")
val res = q"@$annot1 @..$annots def foo"
assertSameAnnots(res, annot1 :: annots)
}
- property("splice annotations with arguments (1)") = test {
+ property("unquote annotations with arguments (1)") = test {
val a = q"new a(x)"
assertSameAnnots(q"@$a def foo", q"@a(x) def foo")
}
- property("splice annotations with arguments (2)") = test {
+ property("unquote annotations with arguments (2)") = test {
val a = TypeName("a")
assertSameAnnots(q"@$a(x) def foo", q"@a(x) def foo")
}
- property("splice annotations with arguments (3") = test {
+ property("unquote annotations with arguments (3") = test {
val a = Ident(TypeName("a"))
assertSameAnnots(q"@$a(x) def foo", q"@a(x) def foo")
}
- property("splice improper tree into annot") = test {
+ property("unquote improper tree into annot") = test {
val t = tq"Foo[Baz]"
assertThrows[IllegalArgumentException] {
q"@$t def foo"
}
}
- property("can't splice annotations with arguments specificed twice") = test {
+ property("can't unquote annotations with arguments specificed twice") = test {
val a = q"new a(x)"
assertThrows[IllegalArgumentException] {
q"@$a(y) def foo"
}
}
- property("splice annotation with targs") = test {
+ property("unquote annotation with targs") = test {
val a = q"new Foo[A, B]"
assertEqAst(q"@$a def foo", "@Foo[A,B] def foo")
}
- property("splice annotation with multiple argument lists") = test {
+ property("unquote annotation with multiple argument lists") = test {
val a = q"new Foo(a)(b)"
assertEqAst(q"@$a def foo", "@Foo(a)(b) def foo")
}
}
trait PackageConstruction { self: QuasiquoteProperties =>
- property("splice select into package name") = test {
+ property("unquote select into package name") = test {
val name = q"foo.bar"
assertEqAst(q"package $name { }", "package foo.bar { }")
}
@@ -357,12 +357,12 @@ trait PackageConstruction { self: QuasiquoteProperties =>
assertEqAst(q"package $name { }", "package bippy { }")
}
- property("splice members into package body") = test {
+ property("unquote members into package body") = test {
val members = q"class C" :: q"object O" :: Nil
assertEqAst(q"package foo { ..$members }", "package foo { class C; object O }")
}
- property("splice illegal members into package body") = test {
+ property("unquote illegal members into package body") = test {
val f = q"def f"
assertThrows[IllegalArgumentException] { q"package foo { $f }" }
val v = q"val v = 0"
@@ -371,24 +371,24 @@ trait PackageConstruction { self: QuasiquoteProperties =>
assertThrows[IllegalArgumentException] { q"package foo { $expr }" }
}
- property("splice name into package object") = test {
+ property("unquote name into package object") = test {
val foo = TermName("foo")
assertEqAst(q"package object $foo", "package object foo")
}
- property("splice parents into package object") = test {
+ property("unquote parents into package object") = test {
val parents = tq"a" :: tq"b" :: Nil
assertEqAst(q"package object foo extends ..$parents",
"package object foo extends a with b")
}
- property("splice members into package object") = test {
+ property("unquote members into package object") = test {
val members = q"def foo" :: q"val x = 1" :: Nil
assertEqAst(q"package object foo { ..$members }",
"package object foo { def foo; val x = 1 }")
}
- property("splice early def into package object") = test {
+ property("unquote early def into package object") = test {
val edefs = q"val x = 1" :: q"type I = Int" :: Nil
assertEqAst(q"package object foo extends { ..$edefs } with Any",
"package object foo extends { val x = 1; type I = Int } with Any")
diff --git a/test/files/scalacheck/quasiquotes/DefinitionDeconstructionProps.scala b/test/files/scalacheck/quasiquotes/DefinitionDeconstructionProps.scala
index 512b81c0e6..996ac65b36 100644
--- a/test/files/scalacheck/quasiquotes/DefinitionDeconstructionProps.scala
+++ b/test/files/scalacheck/quasiquotes/DefinitionDeconstructionProps.scala
@@ -259,7 +259,7 @@ trait ImportDeconstruction { self: QuasiquoteProperties =>
val pq"_" = right
}
- property("splice names into import selector") = forAll {
+ property("unquote names into import selector") = forAll {
(expr: Tree, plain: TermName, oldname: TermName, newname: TermName, discard: TermName) =>
val Import(expr1, List(
diff --git a/test/files/scalacheck/quasiquotes/ErrorProps.scala b/test/files/scalacheck/quasiquotes/ErrorProps.scala
index 1ba9bba381..d61119d98f 100644
--- a/test/files/scalacheck/quasiquotes/ErrorProps.scala
+++ b/test/files/scalacheck/quasiquotes/ErrorProps.scala
@@ -1,21 +1,21 @@
import org.scalacheck._, Prop._, Gen._, Arbitrary._
object ErrorProps extends QuasiquoteProperties("errors") {
- property("can't extract two .. cardinalities in a row") = fails(
+ property("can't extract two .. rankinalities in a row") = fails(
"Can't extract with .. here",
"""
val xs = List(q"x1", q"x2")
val q"f(..$xs1, ..$xs2)" = xs
""")
- property("can't splice with given cardinality") = fails(
- "Can't splice List[reflect.runtime.universe.Ident], consider using ..",
+ property("can't unquote with given rank") = fails(
+ "Can't unquote List[reflect.runtime.universe.Ident], consider using ..",
"""
val xs = List(q"x", q"x")
q"$xs"
""")
- property("splice typename into typedef with default bounds") = fails(
+ property("unquote typename into typedef with default bounds") = fails(
"reflect.runtime.universe.Name expected but reflect.runtime.universe.TypeDef found",
"""
val T1 = TypeName("T1")
@@ -25,8 +25,8 @@ object ErrorProps extends QuasiquoteProperties("errors") {
TypeDef(Modifiers(), T1, List(T2), t)
""")
- property("can't splice annotations with ... cardinality") = fails(
- "Can't splice with ... here",
+ property("can't unquote annotations with ... rank") = fails(
+ "Can't unquote with ... here",
"""
val annots = List(List(q"Foo"))
q"@...$annots def foo"
@@ -39,15 +39,15 @@ object ErrorProps extends QuasiquoteProperties("errors") {
StringContext(s).q()
""")
- property("don't know how to splice inside of strings") = fails(
- "Don't know how to splice here",
+ property("don't know how to unquote inside of strings") = fails(
+ "Don't know how to unquote here",
"""
val x: Tree = EmptyTree
StringContext("\"", "\"").q(x)
""")
property("non-liftable type ..") = fails(
- "Can't splice List[StringBuilder] with .., consider omitting the dots or providing an implicit instance of Liftable[StringBuilder]",
+ "Can't unquote List[StringBuilder] with .., consider omitting the dots or providing an implicit instance of Liftable[StringBuilder]",
"""
import java.lang.StringBuilder
val bazs = List(new StringBuilder)
@@ -55,38 +55,38 @@ object ErrorProps extends QuasiquoteProperties("errors") {
""")
property("non-liftable type ...") = fails(
- "Can't splice List[List[StringBuilder]] with .., consider using ... or providing an implicit instance of Liftable[StringBuilder]",
+ "Can't unquote List[List[StringBuilder]] with .., consider using ... or providing an implicit instance of Liftable[StringBuilder]",
"""
import java.lang.StringBuilder
val bazs = List(List(new StringBuilder))
q"f(..$bazs)"
""")
- property("use .. card or provide liftable") = fails(
- "Can't splice List[StringBuilder], consider using .. or providing an implicit instance of Liftable[List[StringBuilder]]",
+ property("use .. rank or provide liftable") = fails(
+ "Can't unquote List[StringBuilder], consider using .. or providing an implicit instance of Liftable[List[StringBuilder]]",
"""
import java.lang.StringBuilder
val lst: List[StringBuilder] = Nil
q"f($lst)"
""")
- property("use ... card or provide liftable") = fails(
- "Can't splice List[List[reflect.runtime.universe.Ident]], consider using ...",
+ property("use ... rank or provide liftable") = fails(
+ "Can't unquote List[List[reflect.runtime.universe.Ident]], consider using ...",
"""
val xs = List(List(q"x", q"x"))
q"$xs"
""")
property("not liftable or natively supported") = fails(
- "Can't splice StringBuilder, consider providing an implicit instance of Liftable[StringBuilder]",
+ "Can't unquote StringBuilder, consider providing an implicit instance of Liftable[StringBuilder]",
"""
import java.lang.StringBuilder
val sb = new StringBuilder
q"f($sb)"
""")
- property("can't splice with ... card here") = fails(
- "Can't splice with ... here",
+ property("can't unquote with ... rank here") = fails(
+ "Can't unquote with ... here",
"""
val lst: List[List[Tree]] = Nil; val t = EmptyTree
q"f(...$lst, $t)"
@@ -106,29 +106,29 @@ object ErrorProps extends QuasiquoteProperties("errors") {
q"$t def foo"
""")
- property("cant splice flags together with mods") = fails(
- "Can't splice flags together with modifiers, consider merging flags into modifiers",
+ property("cant unquote flags together with mods") = fails(
+ "Can't unquote flags together with modifiers, consider merging flags into modifiers",
"""
val f = Flag.IMPLICIT; val m = NoMods
q"$f $m def foo"
""")
- property("can't splice mods with annots") = fails(
- "Can't splice modifiers together with annotations, consider merging annotations into modifiers",
+ property("can't unquote mods with annots") = fails(
+ "Can't unquote modifiers together with annotations, consider merging annotations into modifiers",
"""
val m = NoMods
q"@annot $m def foo"
""")
- property("can't splice modifiers with inline flags") = fails(
- "Can't splice modifiers together with flags, consider merging flags into modifiers",
+ property("can't unquote modifiers with inline flags") = fails(
+ "Can't unquote modifiers together with flags, consider merging flags into modifiers",
"""
val m = NoMods
q"$m implicit def foo"
""")
- property("can't splice multiple mods") = fails(
- "Can't splice multiple modifiers, consider merging them into a single modifiers instance",
+ property("can't unquote multiple mods") = fails(
+ "Can't unquote multiple modifiers, consider merging them into a single modifiers instance",
"""
val m1 = NoMods; val m2 = NoMods
q"$m1 $m2 def foo"
@@ -146,15 +146,15 @@ object ErrorProps extends QuasiquoteProperties("errors") {
val q"$m1 $m2 def foo" = EmptyTree
""")
- property("can't splice values of Null") = fails(
- "Can't splice Null, bottom type values often indicate programmer mistake",
+ property("can't unquote values of Null") = fails(
+ "Can't unquote Null, bottom type values often indicate programmer mistake",
"""
val n = null
q"$n"
""")
- property("can't splice values of Nothing") = fails(
- "Can't splice Nothing, bottom type values often indicate programmer mistake",
+ property("can't unquote values of Nothing") = fails(
+ "Can't unquote Nothing, bottom type values often indicate programmer mistake",
"""
def n = ???
q"$n"
diff --git a/test/files/scalacheck/quasiquotes/LiftableProps.scala b/test/files/scalacheck/quasiquotes/LiftableProps.scala
index 20cfcbe139..5d0eeb53c6 100644
--- a/test/files/scalacheck/quasiquotes/LiftableProps.scala
+++ b/test/files/scalacheck/quasiquotes/LiftableProps.scala
@@ -2,62 +2,62 @@ import org.scalacheck._, Prop._, Gen._, Arbitrary._
import scala.reflect.runtime.universe._, Flag._
object LiftableProps extends QuasiquoteProperties("liftable") {
- property("splice byte") = test {
+ property("unquote byte") = test {
val c: Byte = 0
assert(q"$c" ≈ Literal(Constant(c)))
assert(q"${0: Byte}" ≈ Literal(Constant(c)))
}
- property("splice short") = test {
+ property("unquote short") = test {
val c: Short = 0
assert(q"$c" ≈ Literal(Constant(c)))
assert(q"${0: Short}" ≈ Literal(Constant(c)))
}
- property("splice char") = test {
+ property("unquote char") = test {
val c: Char = 'c'
assert(q"$c" ≈ Literal(Constant(c)))
assert(q"${'c'}" ≈ Literal(Constant(c)))
}
- property("splice int") = test {
+ property("unquote int") = test {
val c: Int = 0
assert(q"$c" ≈ Literal(Constant(c)))
assert(q"${0: Int}" ≈ Literal(Constant(c)))
}
- property("splice long") = test {
+ property("unquote long") = test {
val c: Long = 0
assert(q"$c" ≈ Literal(Constant(c)))
assert(q"${0: Long}" ≈ Literal(Constant(c)))
}
- property("splice float") = test {
+ property("unquote float") = test {
val c: Float = 0.0f
assert(q"$c" ≈ Literal(Constant(c)))
assert(q"${0.0f: Float}" ≈ Literal(Constant(c)))
}
- property("splice double") = test {
+ property("unquote double") = test {
val c: Double = 0.0
assert(q"$c" ≈ Literal(Constant(c)))
assert(q"${0.0: Double}" ≈ Literal(Constant(c)))
}
- property("splice boolean") = test {
+ property("unquote boolean") = test {
val c: Boolean = false
assert(q"$c" ≈ Literal(Constant(c)))
assert(q"${true}" ≈ Literal(Constant(true)))
assert(q"${false}" ≈ Literal(Constant(false)))
}
- property("splice string") = test {
+ property("unquote string") = test {
val c: String = "s"
assert(q"$c" ≈ Literal(Constant(c)))
assert(q"${"s"}" ≈ Literal(Constant(c)))
}
- property("splice unit") = test {
+ property("unquote unit") = test {
val c: Unit = ()
assert(q"$c" ≈ Literal(Constant(c)))
assert(q"${()}" ≈ Literal(Constant(c)))
diff --git a/test/files/scalacheck/quasiquotes/PatternConstructionProps.scala b/test/files/scalacheck/quasiquotes/PatternConstructionProps.scala
index fffaf1b363..7ed95fa984 100644
--- a/test/files/scalacheck/quasiquotes/PatternConstructionProps.scala
+++ b/test/files/scalacheck/quasiquotes/PatternConstructionProps.scala
@@ -2,35 +2,35 @@ import org.scalacheck._, Prop._, Gen._, Arbitrary._
import scala.reflect.runtime.universe._, Flag._
object PatternConstructionProps extends QuasiquoteProperties("pattern construction") {
- property("splice bind") = forAll { (bind: Bind) =>
+ property("unquote bind") = forAll { (bind: Bind) =>
pq"$bind" ≈ bind
}
- property("splice name into bind") = forAll { (name: TermName) =>
+ property("unquote name into bind") = forAll { (name: TermName) =>
pq"$name" ≈ Bind(name, Ident(termNames.WILDCARD))
}
- property("splice name and tree into bind") = forAll { (name: TermName, tree: Tree) =>
+ property("unquote name and tree into bind") = forAll { (name: TermName, tree: Tree) =>
pq"$name @ $tree" ≈ Bind(name, tree)
}
- property("splice type name into typed") = forAll { (name: TypeName) =>
+ property("unquote type name into typed") = forAll { (name: TypeName) =>
pq"_ : $name" ≈ Typed(Ident(termNames.WILDCARD), Ident(name))
}
- property("splice tree into typed") = forAll { (typ: Tree) =>
+ property("unquote tree into typed") = forAll { (typ: Tree) =>
pq"_ : $typ" ≈ Typed(Ident(termNames.WILDCARD), typ)
}
- property("splice into apply") = forAll { (pat: Tree, subpat: Tree) =>
+ property("unquote into apply") = forAll { (pat: Tree, subpat: Tree) =>
pq"$pat($subpat)" ≈ Apply(pat, List(subpat))
}
- property("splice into casedef") = forAll { (pat: Tree, cond: Tree, body: Tree) =>
+ property("unquote into casedef") = forAll { (pat: Tree, cond: Tree, body: Tree) =>
cq"$pat if $cond => $body" ≈ CaseDef(pat, cond, body)
}
- property("splice into alternative") = forAll { (first: Tree, rest: List[Tree]) =>
+ property("unquote into alternative") = forAll { (first: Tree, rest: List[Tree]) =>
pq"$first | ..$rest" ≈ Alternative(first :: rest)
}
}
diff --git a/test/files/scalacheck/quasiquotes/TermConstructionProps.scala b/test/files/scalacheck/quasiquotes/TermConstructionProps.scala
index 4dbf746cfe..10ce1604b1 100644
--- a/test/files/scalacheck/quasiquotes/TermConstructionProps.scala
+++ b/test/files/scalacheck/quasiquotes/TermConstructionProps.scala
@@ -2,41 +2,41 @@ import org.scalacheck._, Prop._, Gen._, Arbitrary._
import scala.reflect.runtime.universe._, Flag._
object TermConstructionProps extends QuasiquoteProperties("term construction") {
- property("splice single tree return tree itself") = forAll { (t: Tree) =>
+ property("unquote single tree return tree itself") = forAll { (t: Tree) =>
q"$t" ≈ t
}
- property("splice trees into if expression") = forAll { (t1: Tree, t2: Tree, t3: Tree) =>
+ property("unquote trees into if expression") = forAll { (t1: Tree, t2: Tree, t3: Tree) =>
q"if($t1) $t2 else $t3" ≈ If(t1, t2, t3)
}
- property("splice trees into ascriptiopn") = forAll { (t1: Tree, t2: Tree) =>
+ property("unquote trees into ascriptiopn") = forAll { (t1: Tree, t2: Tree) =>
q"$t1 : $t2" ≈ Typed(t1, t2)
}
- property("splice trees into apply") = forAll { (t1: Tree, t2: Tree, t3: Tree) =>
+ property("unquote trees into apply") = forAll { (t1: Tree, t2: Tree, t3: Tree) =>
q"$t1($t2, $t3)" ≈ Apply(t1, List(t2, t3))
}
- property("splice trees with .. cardinality into apply") = forAll { (ts: List[Tree]) =>
+ property("unquote trees with .. rank into apply") = forAll { (ts: List[Tree]) =>
q"f(..$ts)" ≈ Apply(q"f", ts)
}
- property("splice iterable into apply") = forAll { (trees: List[Tree]) =>
+ property("unquote iterable into apply") = forAll { (trees: List[Tree]) =>
val itrees: Iterable[Tree] = trees
q"f(..$itrees)" ≈ Apply(q"f", trees)
}
- property("splice trees with ... cardinality into apply") = forAll { (ts1: List[Tree], ts2: List[Tree]) =>
+ property("unquote trees with ... rank into apply") = forAll { (ts1: List[Tree], ts2: List[Tree]) =>
val argss = List(ts1, ts2)
q"f(...$argss)" ≈ Apply(Apply(q"f", ts1), ts2)
}
- property("splice term name into assign") = forAll { (name: TermName, t: Tree) =>
+ property("unquote term name into assign") = forAll { (name: TermName, t: Tree) =>
q"$name = $t" ≈ Assign(Ident(name), t)
}
- property("splice trees into block") = forAll { (t1: Tree, t2: Tree, t3: Tree) =>
+ property("unquote trees into block") = forAll { (t1: Tree, t2: Tree, t3: Tree) =>
blockInvariant(q"""{
$t1
$t2
@@ -45,25 +45,25 @@ object TermConstructionProps extends QuasiquoteProperties("term construction") {
}
- property("splice tree into new") = forAll { (tree: Tree) =>
+ property("unquote tree into new") = forAll { (tree: Tree) =>
q"new $tree" ≈ Apply(Select(New(tree), termNames.CONSTRUCTOR), List())
}
- property("splice tree into return") = forAll { (tree: Tree) =>
+ property("unquote tree into return") = forAll { (tree: Tree) =>
q"return $tree" ≈ Return(tree)
}
- property("splice a list of arguments") = forAll { (fun: Tree, args: List[Tree]) =>
+ property("unquote a list of arguments") = forAll { (fun: Tree, args: List[Tree]) =>
q"$fun(..$args)" ≈ Apply(fun, args)
}
- property("splice list and non-list fun arguments") = forAll { (fun: Tree, arg1: Tree, arg2: Tree, args: List[Tree]) =>
+ property("unquote list and non-list fun arguments") = forAll { (fun: Tree, arg1: Tree, arg2: Tree, args: List[Tree]) =>
q"$fun(..$args, $arg1, $arg2)" ≈ Apply(fun, args ++ List(arg1) ++ List(arg2)) &&
q"$fun($arg1, ..$args, $arg2)" ≈ Apply(fun, List(arg1) ++ args ++ List(arg2)) &&
q"$fun($arg1, $arg2, ..$args)" ≈ Apply(fun, List(arg1) ++ List(arg2) ++ args)
}
- property("splice into new") = forAll { (name: TypeName, body: List[Tree]) =>
+ property("unquote into new") = forAll { (name: TypeName, body: List[Tree]) =>
q"new $name { ..$body }" ≈
q"""{
final class $$anon extends $name {
@@ -73,29 +73,29 @@ object TermConstructionProps extends QuasiquoteProperties("term construction") {
}"""
}
- property("splice type name into this") = forAll { (T: TypeName) =>
+ property("unquote type name into this") = forAll { (T: TypeName) =>
q"$T.this" ≈ This(T)
}
- property("splice tree into throw") = forAll { (t: Tree) =>
+ property("unquote tree into throw") = forAll { (t: Tree) =>
q"throw $t" ≈ Throw(t)
}
- property("splice trees into type apply") = forAll { (fun: TreeIsTerm, types: List[Tree]) =>
+ property("unquote trees into type apply") = forAll { (fun: TreeIsTerm, types: List[Tree]) =>
q"$fun[..$types]" ≈ (if (types.nonEmpty) TypeApply(fun, types) else fun)
}
- property("splice trees into while loop") = forAll { (cond: Tree, body: Tree) =>
+ property("unquote trees into while loop") = forAll { (cond: Tree, body: Tree) =>
val LabelDef(_, List(), If(cond1, Block(List(body1), Apply(_, List())), Literal(Constant(())))) = q"while($cond) $body"
body1 ≈ body && cond1 ≈ cond
}
- property("splice trees into do while loop") = forAll { (cond: Tree, body: Tree) =>
+ property("unquote trees into do while loop") = forAll { (cond: Tree, body: Tree) =>
val LabelDef(_, List(), Block(List(body1), If(cond1, Apply(_, List()), Literal(Constant(()))))) = q"do $body while($cond)"
body1 ≈ body && cond1 ≈ cond
}
- property("splice trees into alternative") = forAll { (c: Tree, A: Tree, B: Tree) =>
+ property("unquote trees into alternative") = forAll { (c: Tree, A: Tree, B: Tree) =>
q"$c match { case $A | $B => }" ≈
Match(c, List(
CaseDef(Alternative(List(A, B)), EmptyTree, Literal(Constant(())))))
@@ -109,24 +109,24 @@ object TermConstructionProps extends QuasiquoteProperties("term construction") {
case init :+ last => Block(init, last)
})
- property("splice list of trees into block (1)") = forAll { (trees: List[Tree]) =>
+ property("unquote list of trees into block (1)") = forAll { (trees: List[Tree]) =>
blockInvariant(q"{ ..$trees }", trees)
}
- property("splice list of trees into block (2)") = forAll { (trees1: List[Tree], trees2: List[Tree]) =>
+ property("unquote list of trees into block (2)") = forAll { (trees1: List[Tree], trees2: List[Tree]) =>
blockInvariant(q"{ ..$trees1 ; ..$trees2 }", trees1 ++ trees2)
}
- property("splice list of trees into block (3)") = forAll { (trees: List[Tree], tree: Tree) =>
+ property("unquote list of trees into block (3)") = forAll { (trees: List[Tree], tree: Tree) =>
blockInvariant(q"{ ..$trees; $tree }", trees :+ tree)
}
- property("splice term into brackets") = test {
+ property("unquote term into brackets") = test {
val a = q"a"
assert(q"($a)" ≈ a)
}
- property("splice terms into tuple") = test {
+ property("unquote terms into tuple") = test {
val a1 = q"a1"
val a2 = q"a2"
val as = List(a1, a2)
@@ -134,12 +134,12 @@ object TermConstructionProps extends QuasiquoteProperties("term construction") {
assert(q"(a0, ..$as)" ≈ q"scala.Tuple3(a0, $a1, $a2)")
}
- property("splice empty list into tuple") = test {
+ property("unquote empty list into tuple") = test {
val empty = List[Tree]()
assert(q"(..$empty)" ≈ q"()")
}
- property("splice single element list into tuple") = test {
+ property("unquote single element list into tuple") = test {
val xs = q"x" :: Nil
assert(q"(..$xs)" ≈ xs.head)
}
@@ -196,7 +196,7 @@ object TermConstructionProps extends QuasiquoteProperties("term construction") {
assert(q"f(${if (true) q"a" else q"b"})" ≈ q"f(a)")
}
- property("splice iterable of non-parametric type") = test {
+ property("unquote iterable of non-parametric type") = test {
object O extends Iterable[Tree] { def iterator = List(q"foo").iterator }
q"f(..$O)"
}
diff --git a/test/files/scalacheck/quasiquotes/TypeConstructionProps.scala b/test/files/scalacheck/quasiquotes/TypeConstructionProps.scala
index 07875af326..27ad4c50e9 100644
--- a/test/files/scalacheck/quasiquotes/TypeConstructionProps.scala
+++ b/test/files/scalacheck/quasiquotes/TypeConstructionProps.scala
@@ -6,7 +6,7 @@ object TypeConstructionProps extends QuasiquoteProperties("type construction")
tq"x" ≈ Ident(TypeName("x"))
}
- property("splice type names into AppliedTypeTree") = forAll { (name1: TypeName, name2: TypeName) =>
+ property("unquote type names into AppliedTypeTree") = forAll { (name1: TypeName, name2: TypeName) =>
tq"$name1[$name2]" ≈ AppliedTypeTree(Ident(name1), List(Ident(name2)))
}
diff --git a/test/files/scalacheck/quasiquotes/TypecheckedProps.scala b/test/files/scalacheck/quasiquotes/TypecheckedProps.scala
index 8b1cb6cc49..432c0959c9 100644
--- a/test/files/scalacheck/quasiquotes/TypecheckedProps.scala
+++ b/test/files/scalacheck/quasiquotes/TypecheckedProps.scala
@@ -65,7 +65,7 @@ object TypecheckedProps extends QuasiquoteProperties("typechecked") {
}
property("extract UnApply (2)") = test {
- val q"object $_ { $_; $_; $m }" = typecheck(q"""
+ val q"object $_ { $_; $m }" = typecheck(q"""
object Test {
case class Cell(val x: Int)
new Cell(0) match { case Cell(v) => v }
@@ -82,4 +82,74 @@ object TypecheckedProps extends QuasiquoteProperties("typechecked") {
val q"val x: ${tq""} = 42" = typechecked
val q"val x: ${t: Type} = 42" = typechecked
}
+
+ property("class with param (1)") = test {
+ val paramName = TermName("x")
+ val q"class $_($param)" = typecheck(q"class Test(val $paramName: Int)")
+
+ assert(param.name == paramName)
+ }
+
+ property("class with param (2)") = test {
+ val paramName = TermName("y")
+ val q"{class $_($param)}" = typecheck(q"class Test(val $paramName: Int = 3)")
+
+ assert(param.name == paramName)
+ assert(param.rhs ≈ q"3")
+ }
+
+ property("class with params") = test {
+ val pName1 = TermName("x1")
+ val pName2 = TermName("x2")
+ val q"{class $_($param1)(..$params2)}" = typecheck(q"class Test(val x0: Float)(val $pName1: Int = 3, $pName2: String)")
+
+ val List(p1, p2, _*) = params2
+
+ assert(p1.name == pName1)
+ assert(p2.name == pName2)
+ assert(params2.size == 2)
+ }
+
+ property("implicit class") = test {
+ val clName = TypeName("Test")
+ val paramName = TermName("x")
+ val q"{implicit class $name($param)}" = typecheck(q"implicit class $clName(val $paramName: String)")
+
+ assert(name == clName)
+ assert(param.name == paramName)
+ }
+
+ property("block with lazy") = test {
+ val lazyName = TermName("x")
+ val lazyRhsVal = 42
+ val lazyRhs = Literal(Constant(lazyRhsVal))
+ val q"{lazy val $pname = $rhs}" = typecheck(q"{lazy val $lazyName = $lazyRhsVal}")
+
+ assert(pname == lazyName)
+ assert(rhs ≈ lazyRhs)
+ }
+
+ property("class with lazy") = test {
+ val clName = TypeName("Test")
+ val paramName = TermName("x")
+ val q"class $name{lazy val $pname = $_}" = typecheck(q"class $clName {lazy val $paramName = 42}")
+
+ assert(name == clName)
+ assert(pname == paramName)
+ }
+
+ property("case class with object") = test {
+ val defName = TermName("z")
+ val defRhsVal = 42
+ val defRhs = Literal(Constant(defRhsVal))
+ val q"object $_{ $_; object $_ extends ..$_ {def $name = $rhs} }" =
+ typecheck(q"""
+ object Test{
+ case class C(x: Int) { def y = x };
+ object C { def $defName = $defRhsVal }
+ }""")
+
+ assert(name == defName)
+ assert(rhs ≈ defRhs)
+ }
}
diff --git a/test/files/scalacheck/quasiquotes/UnliftableProps.scala b/test/files/scalacheck/quasiquotes/UnliftableProps.scala
index 4e996c90d7..1d7629aa29 100644
--- a/test/files/scalacheck/quasiquotes/UnliftableProps.scala
+++ b/test/files/scalacheck/quasiquotes/UnliftableProps.scala
@@ -99,13 +99,13 @@ object UnliftableProps extends QuasiquoteProperties("unliftable") {
assert(l5 == orig2)
}
- property("don't unlift non-tree splicee (1)") = test {
+ property("don't unlift non-tree unquotee (1)") = test {
val q"${a: TermName}.${b: TermName}" = q"a.b"
assert(a == TermName("a"))
assert(b == TermName("b"))
}
- property("don't unlift non-tree splicee (2)") = test {
+ property("don't unlift non-tree unquotee (2)") = test {
val q"${mods: Modifiers} def foo" = q"def foo"
assert(mods == Modifiers(DEFERRED))
}
diff --git a/test/junit/scala/reflect/internal/PrintersTest.scala b/test/junit/scala/reflect/internal/PrintersTest.scala
index 9fec112c99..62cb401aa9 100644
--- a/test/junit/scala/reflect/internal/PrintersTest.scala
+++ b/test/junit/scala/reflect/internal/PrintersTest.scala
@@ -821,4 +821,4 @@
// |case class X(x: Int, s: String) {
// | def y = "test"
// |}""", q"""case class X(x: Int, s: String){ def y = "test" }""")
-// }
+// } \ No newline at end of file
diff --git a/test/scaladoc/run/diagrams-base.scala b/test/scaladoc/run/diagrams-base.scala
index b7aeed51d2..1e83a78b38 100644
--- a/test/scaladoc/run/diagrams-base.scala
+++ b/test/scaladoc/run/diagrams-base.scala
@@ -46,7 +46,7 @@ object Test extends ScaladocModelTest {
val (incoming, outgoing) = diag.edges.partition(!_._1.isThisNode)
assert(incoming.length == 5)
- assert(outgoing.head._2.length == 4)
+ assert(outgoing.head._2.length == 4, s"${outgoing.head._2} has length ${outgoing.head._2.length}, expecting 4")
val (outgoingSuperclass, outgoingImplicit) = outgoing.head._2.partition(_.isNormalNode)
assert(outgoingSuperclass.length == 3)
diff --git a/test/scaladoc/run/diagrams-filtering.scala b/test/scaladoc/run/diagrams-filtering.scala
index 54e3e9ac63..12b5f4caba 100644
--- a/test/scaladoc/run/diagrams-filtering.scala
+++ b/test/scaladoc/run/diagrams-filtering.scala
@@ -57,7 +57,7 @@ object Test extends ScaladocModelTest {
// Assert we have just 3 nodes and 2 edges
val A = base._trait("A")
val ADiag = A.inheritanceDiagram.get
- assert(ADiag.nodes.length == 3)
+ assert(ADiag.nodes.length == 3, s"${ADiag.nodes} has length ${ADiag.nodes.length}, expected 3")
assert(ADiag.edges.map(_._2.length).sum == 2)
// trait C