Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

ExistentialTypeTree.whereClauses are now MemberDefs

Today’s flight back to Lausanne wasn’t as productive as the recent flight
to Minsk (#3305), but I noticed
one minor thingie: ExistentialTypeTree had an imprecise type specified
for its whereClauses. This is now fixed.

I didn’t increment PickleFormat.*Version numbers, because this change
introduces only a miniscule incompatibility with what would have been
a meaningless and most likely crash-inducing pickle anyway.
  • Loading branch information...
commit db6e3062c13cc3c4d4a8a8245269b0c371657257 1 parent 527fd9a
@xeno-by xeno-by authored
View
20 src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -623,15 +623,6 @@ self =>
syntaxError(tpt.pos, "no * parameter type allowed here", skipIt = false)
}
- /** Check that tree is a legal clause of a forSome. */
- def checkLegalExistential(t: Tree) = t match {
- case TypeDef(_, _, _, TypeBoundsTree(_, _)) |
- ValDef(_, _, _, EmptyTree) | EmptyTree =>
- ;
- case _ =>
- syntaxError(t.pos, "not a legal existential clause", skipIt = false)
- }
-
/* -------------- TOKEN CLASSES ------------------------------------------- */
def isModifier: Boolean = in.token match {
@@ -885,9 +876,14 @@ self =>
}
}
private def makeExistentialTypeTree(t: Tree) = {
- val whereClauses = refinement()
- whereClauses foreach checkLegalExistential
- ExistentialTypeTree(t, whereClauses)
+ // EmptyTrees in the result of refinement() stand for parse errors
+ // so it's okay for us to filter them out here
+ ExistentialTypeTree(t, refinement() flatMap {
+ case t @ TypeDef(_, _, _, TypeBoundsTree(_, _)) => Some(t)
+ case t @ ValDef(_, _, _, EmptyTree) => Some(t)
+ case EmptyTree => None
+ case _ => syntaxError(t.pos, "not a legal existential clause", skipIt = false); None
+ })
}
/** {{{
View
16 src/reflect/scala/reflect/api/Trees.scala
@@ -2058,8 +2058,8 @@ trait Trees { self: Universe =>
* @group Extractors
*/
abstract class ExistentialTypeTreeExtractor {
- def apply(tpt: Tree, whereClauses: List[Tree]): ExistentialTypeTree
- def unapply(existentialTypeTree: ExistentialTypeTree): Option[(Tree, List[Tree])]
+ def apply(tpt: Tree, whereClauses: List[MemberDef]): ExistentialTypeTree
+ def unapply(existentialTypeTree: ExistentialTypeTree): Option[(Tree, List[MemberDef])]
}
/** The API that all existential type trees support
@@ -2069,8 +2069,12 @@ trait Trees { self: Universe =>
/** The underlying type of the existential type. */
def tpt: Tree
- /** The clauses of the definition of the existential type. */
- def whereClauses: List[Tree]
+ /** The clauses of the definition of the existential type.
+ * Elements are one of the following:
+ * 1) TypeDef with TypeBoundsTree right-hand side
+ * 2) ValDef with empty right-hand side
+ */
+ def whereClauses: List[MemberDef]
}
/** A synthetic tree holding an arbitrary type. Not to be confused with
@@ -2533,7 +2537,7 @@ trait Trees { self: Universe =>
/** Creates a `ExistentialTypeTree` node from the given components, having a given `tree` as a prototype.
* Having a tree as a prototype means that the tree's attachments, type and symbol will be copied into the result.
*/
- def ExistentialTypeTree(tree: Tree, tpt: Tree, whereClauses: List[Tree]): ExistentialTypeTree
+ def ExistentialTypeTree(tree: Tree, tpt: Tree, whereClauses: List[MemberDef]): ExistentialTypeTree
}
// ---------------------- traversing and transforming ------------------------------
@@ -2654,6 +2658,8 @@ trait Trees { self: Universe =>
def transformValDefss(treess: List[List[ValDef]]): List[List[ValDef]] =
treess mapConserve (transformValDefs(_))
/** Transforms a list of `CaseDef` nodes. */
+ def transformMemberDefs(trees: List[MemberDef]): List[MemberDef] =
+ trees mapConserve (tree => transform(tree).asInstanceOf[MemberDef])
def transformCaseDefs(trees: List[CaseDef]): List[CaseDef] =
trees mapConserve (tree => transform(tree).asInstanceOf[CaseDef])
/** Transforms a list of `Ident` nodes. */
View
3  src/reflect/scala/reflect/internal/Importers.scala
@@ -409,7 +409,7 @@ trait Importers extends api.Importers { to: SymbolTable =>
case from.TypeBoundsTree(lo, hi) =>
new TypeBoundsTree(importTree(lo), importTree(hi))
case from.ExistentialTypeTree(tpt, whereClauses) =>
- new ExistentialTypeTree(importTree(tpt), whereClauses map importTree)
+ new ExistentialTypeTree(importTree(tpt), whereClauses map importMemberDef)
case from.EmptyTree =>
EmptyTree
case null =>
@@ -475,6 +475,7 @@ trait Importers extends api.Importers { to: SymbolTable =>
new ImportSelector(importName(sel.name), sel.namePos, if (sel.rename != null) importName(sel.rename) else null, sel.renamePos)
def importValDef(tree: from.ValDef): ValDef = importTree(tree).asInstanceOf[ValDef]
def importTypeDef(tree: from.TypeDef): TypeDef = importTree(tree).asInstanceOf[TypeDef]
+ def importMemberDef(tree: from.MemberDef): MemberDef = importTree(tree).asInstanceOf[MemberDef]
def importTemplate(tree: from.Template): Template = importTree(tree).asInstanceOf[Template]
def importRefTree(tree: from.RefTree): RefTree = importTree(tree).asInstanceOf[RefTree]
def importIdent(tree: from.Ident): Ident = importTree(tree).asInstanceOf[Ident]
View
8 src/reflect/scala/reflect/internal/Trees.scala
@@ -541,7 +541,7 @@ trait Trees extends api.Trees {
extends TypTree with TypeBoundsTreeApi
object TypeBoundsTree extends TypeBoundsTreeExtractor
- case class ExistentialTypeTree(tpt: Tree, whereClauses: List[Tree])
+ case class ExistentialTypeTree(tpt: Tree, whereClauses: List[MemberDef])
extends TypTree with ExistentialTypeTreeApi
object ExistentialTypeTree extends ExistentialTypeTreeExtractor
@@ -694,7 +694,7 @@ trait Trees extends api.Trees {
new AppliedTypeTree(tpt, args).copyAttrs(tree)
def TypeBoundsTree(tree: Tree, lo: Tree, hi: Tree) =
new TypeBoundsTree(lo, hi).copyAttrs(tree)
- def ExistentialTypeTree(tree: Tree, tpt: Tree, whereClauses: List[Tree]) =
+ def ExistentialTypeTree(tree: Tree, tpt: Tree, whereClauses: List[MemberDef]) =
new ExistentialTypeTree(tpt, whereClauses).copyAttrs(tree)
}
@@ -910,7 +910,7 @@ trait Trees extends api.Trees {
if (lo0 == lo) && (hi0 == hi) => t
case _ => treeCopy.TypeBoundsTree(tree, lo, hi)
}
- def ExistentialTypeTree(tree: Tree, tpt: Tree, whereClauses: List[Tree]) = tree match {
+ def ExistentialTypeTree(tree: Tree, tpt: Tree, whereClauses: List[MemberDef]) = tree match {
case t @ ExistentialTypeTree(tpt0, whereClauses0)
if (tpt0 == tpt) && (whereClauses0 == whereClauses) => t
case _ => treeCopy.ExistentialTypeTree(tree, tpt, whereClauses)
@@ -1421,7 +1421,7 @@ trait Trees extends api.Trees {
case CompoundTypeTree(templ) =>
treeCopy.CompoundTypeTree(tree, transformTemplate(templ))
case ExistentialTypeTree(tpt, whereClauses) =>
- treeCopy.ExistentialTypeTree(tree, transform(tpt), transformTrees(whereClauses))
+ treeCopy.ExistentialTypeTree(tree, transform(tpt), transformMemberDefs(whereClauses))
case Return(expr) =>
treeCopy.Return(tree, transform(expr))
case Alternative(trees) =>
View
9 src/reflect/scala/reflect/internal/pickling/UnPickler.scala
@@ -487,6 +487,7 @@ abstract class UnPickler {
def nameRef() = readNameRef()
def tparamRef() = readTypeDefRef()
def vparamRef() = readValDefRef()
+ def memberRef() = readMemberDefRef()
def constRef() = readConstantRef()
def idRef() = readIdentRef()
def termNameRef() = readNameRef().toTermName
@@ -520,7 +521,7 @@ abstract class UnPickler {
case CLASStree => ClassDef(modsRef, typeNameRef, rep(tparamRef), implRef)
case COMPOUNDTYPEtree => CompoundTypeTree(implRef)
case DEFDEFtree => DefDef(modsRef, termNameRef, rep(tparamRef), rep(rep(vparamRef)), ref, ref)
- case EXISTENTIALTYPEtree => ExistentialTypeTree(ref, all(ref))
+ case EXISTENTIALTYPEtree => ExistentialTypeTree(ref, all(memberRef))
case FUNCTIONtree => Function(rep(vparamRef), ref)
case IMPORTtree => Import(ref, selectorsRef)
case LABELtree => LabelDef(termNameRef, rep(idRef), ref)
@@ -634,6 +635,12 @@ abstract class UnPickler {
case other =>
errorBadSignature("expected an TypeDef (" + other + ")")
}
+ protected def readMemberDefRef(): MemberDef =
+ readTreeRef() match {
+ case tree:MemberDef => tree
+ case other =>
+ errorBadSignature("expected an MemberDef (" + other + ")")
+ }
protected def errorBadSignature(msg: String) =
throw new RuntimeException("malformed Scala signature of " + classRoot.name + " at " + readIndex + "; " + msg)
View
2  test/files/scalacheck/quasiquotes/ArbitraryTreesAndNames.scala
@@ -92,7 +92,7 @@ trait ArbitraryTreesAndNames {
yield DefDef(mods, name, tparams, vparamss, tpt, rhs)
def genExistentialTypeTree(size: Int) =
- for(tpt <- genTree(size - 1); where <- smallList(size, genTree(size - 1)))
+ for(tpt <- genTree(size - 1); where <- smallList(size, oneOf(genValDef(size - 1), genTypeDef(size - 1))))
yield ExistentialTypeTree(tpt, where)
def genFunction(size: Int) =
Please sign in to comment.
Something went wrong with that request. Please try again.