aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-09-25 17:04:22 +0200
committerMartin Odersky <odersky@gmail.com>2016-09-25 17:04:22 +0200
commit80cbe114cc5d641d66512c58402eca4ae69f9f2a (patch)
treec2d137266a0ae6c59e44e15f959f0ca070ec0b7c /src
parent2d908c792fcf4287b4cb493f0e51dfbdb106cf69 (diff)
downloaddotty-80cbe114cc5d641d66512c58402eca4ae69f9f2a.tar.gz
dotty-80cbe114cc5d641d66512c58402eca4ae69f9f2a.tar.bz2
dotty-80cbe114cc5d641d66512c58402eca4ae69f9f2a.zip
Get rid of SelectFromType tree node.
Roll its functionality into Select. Since we can always tell whether a tree is a type or term there is no expressiveness gained by having a separate tree node.
Diffstat (limited to 'src')
-rw-r--r--src/dotty/tools/dotc/ast/TreeInfo.scala2
-rw-r--r--src/dotty/tools/dotc/ast/Trees.scala21
-rw-r--r--src/dotty/tools/dotc/ast/tpd.scala9
-rw-r--r--src/dotty/tools/dotc/ast/untpd.scala1
-rw-r--r--src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala2
-rw-r--r--src/dotty/tools/dotc/parsing/JavaParsers.scala6
-rw-r--r--src/dotty/tools/dotc/parsing/Parsers.scala2
-rw-r--r--src/dotty/tools/dotc/printing/RefinedPrinter.scala5
-rw-r--r--src/dotty/tools/dotc/transform/Erasure.scala3
-rw-r--r--src/dotty/tools/dotc/transform/TreeTransform.scala29
-rw-r--r--src/dotty/tools/dotc/typer/Checking.scala2
-rw-r--r--src/dotty/tools/dotc/typer/ReTyper.scala6
-rw-r--r--src/dotty/tools/dotc/typer/TypeAssigner.scala3
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala75
14 files changed, 51 insertions, 115 deletions
diff --git a/src/dotty/tools/dotc/ast/TreeInfo.scala b/src/dotty/tools/dotc/ast/TreeInfo.scala
index 0d4179218..d6df204c1 100644
--- a/src/dotty/tools/dotc/ast/TreeInfo.scala
+++ b/src/dotty/tools/dotc/ast/TreeInfo.scala
@@ -182,7 +182,7 @@ trait TreeInfo[T >: Untyped <: Type] { self: Trees.Instance[T] =>
case OrTypeTree(tpt1, tpt2) => mayBeTypePat(tpt1) || mayBeTypePat(tpt2)
case RefinedTypeTree(tpt, refinements) => mayBeTypePat(tpt) || refinements.exists(_.isInstanceOf[Bind])
case AppliedTypeTree(tpt, args) => mayBeTypePat(tpt) || args.exists(_.isInstanceOf[Bind])
- case SelectFromTypeTree(tpt, _) => mayBeTypePat(tpt)
+ case Select(tpt, _) => mayBeTypePat(tpt)
case Annotated(tpt, _) => mayBeTypePat(tpt)
case _ => false
}
diff --git a/src/dotty/tools/dotc/ast/Trees.scala b/src/dotty/tools/dotc/ast/Trees.scala
index 0f8a63c12..528e3c589 100644
--- a/src/dotty/tools/dotc/ast/Trees.scala
+++ b/src/dotty/tools/dotc/ast/Trees.scala
@@ -364,7 +364,7 @@ object Trees {
override def toString = s"BackquotedIdent($name)"
}
- /** qualifier.name */
+ /** qualifier.name, or qualifier#name, if qualifier is a type */
case class Select[-T >: Untyped] private[ast] (qualifier: Tree[T], name: Name)
extends RefTree[T] {
type ThisTree[-T >: Untyped] = Select[T]
@@ -549,15 +549,6 @@ object Trees {
type ThisTree[-T >: Untyped] = SingletonTypeTree[T]
}
- /** qualifier # name
- * In Scala, this always refers to a type, but in a Java
- * compilation unit this might refer to a term.
- */
- case class SelectFromTypeTree[-T >: Untyped] private[ast] (qualifier: Tree[T], name: Name)
- extends RefTree[T] {
- type ThisTree[-T >: Untyped] = SelectFromTypeTree[T]
- }
-
/** left & right */
case class AndTypeTree[-T >: Untyped] private[ast] (left: Tree[T], right: Tree[T])
extends TypTree[T] {
@@ -841,7 +832,6 @@ object Trees {
type JavaSeqLiteral = Trees.JavaSeqLiteral[T]
type TypeTree = Trees.TypeTree[T]
type SingletonTypeTree = Trees.SingletonTypeTree[T]
- type SelectFromTypeTree = Trees.SelectFromTypeTree[T]
type AndTypeTree = Trees.AndTypeTree[T]
type OrTypeTree = Trees.OrTypeTree[T]
type RefinedTypeTree = Trees.RefinedTypeTree[T]
@@ -1000,10 +990,6 @@ object Trees {
case tree: SingletonTypeTree if ref eq tree.ref => tree
case _ => finalize(tree, untpd.SingletonTypeTree(ref))
}
- def SelectFromTypeTree(tree: Tree)(qualifier: Tree, name: Name): SelectFromTypeTree = tree match {
- case tree: SelectFromTypeTree if (qualifier eq tree.qualifier) && (name == tree.name) => tree
- case _ => finalize(tree, untpd.SelectFromTypeTree(qualifier, name))
- }
def AndTypeTree(tree: Tree)(left: Tree, right: Tree): AndTypeTree = tree match {
case tree: AndTypeTree if (left eq tree.left) && (right eq tree.right) => tree
case _ => finalize(tree, untpd.AndTypeTree(left, right))
@@ -1144,8 +1130,6 @@ object Trees {
tree
case SingletonTypeTree(ref) =>
cpy.SingletonTypeTree(tree)(transform(ref))
- case SelectFromTypeTree(qualifier, name) =>
- cpy.SelectFromTypeTree(tree)(transform(qualifier), name)
case AndTypeTree(left, right) =>
cpy.AndTypeTree(tree)(transform(left), transform(right))
case OrTypeTree(left, right) =>
@@ -1248,8 +1232,6 @@ object Trees {
x
case SingletonTypeTree(ref) =>
this(x, ref)
- case SelectFromTypeTree(qualifier, name) =>
- this(x, qualifier)
case AndTypeTree(left, right) =>
this(this(x, left), right)
case OrTypeTree(left, right) =>
@@ -1325,7 +1307,6 @@ object Trees {
case tree: DefDef => cpy.DefDef(tree)(name = newName.asTermName)
case tree: untpd.PolyTypeDef => untpd.cpy.PolyTypeDef(tree)(newName.asTypeName, tree.tparams, tree.rhs).withMods(tree.rawMods)
case tree: TypeDef => cpy.TypeDef(tree)(name = newName.asTypeName)
- case tree: SelectFromTypeTree => cpy.SelectFromTypeTree(tree)(tree.qualifier, newName)
}
}.asInstanceOf[tree.ThisTree[T]]
}
diff --git a/src/dotty/tools/dotc/ast/tpd.scala b/src/dotty/tools/dotc/ast/tpd.scala
index 1d23bdfd9..31a9c6975 100644
--- a/src/dotty/tools/dotc/ast/tpd.scala
+++ b/src/dotty/tools/dotc/ast/tpd.scala
@@ -30,11 +30,8 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
def Select(qualifier: Tree, name: Name)(implicit ctx: Context): Select =
ta.assignType(untpd.Select(qualifier, name), qualifier)
- def SelectFromTypeTree(qualifier: Tree, name: Name)(implicit ctx: Context): SelectFromTypeTree =
- ta.assignType(untpd.SelectFromTypeTree(qualifier, name), qualifier)
-
- def SelectFromTypeTree(qualifier: Tree, tp: NamedType)(implicit ctx: Context): SelectFromTypeTree =
- untpd.SelectFromTypeTree(qualifier, tp.name).withType(tp)
+ def Select(qualifier: Tree, tp: NamedType)(implicit ctx: Context): Select =
+ untpd.Select(qualifier, tp.name).withType(tp)
def This(cls: ClassSymbol)(implicit ctx: Context): This =
untpd.This(cls.name).withType(cls.thisType)
@@ -333,7 +330,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
Ident(tp)
else tp.prefix match {
case pre: SingletonType => followOuterLinks(singleton(pre)).select(tp)
- case pre => SelectFromTypeTree(TypeTree(pre), tp)
+ case pre => Select(TypeTree(pre), tp)
} // no checks necessary
def ref(sym: Symbol)(implicit ctx: Context): Tree =
diff --git a/src/dotty/tools/dotc/ast/untpd.scala b/src/dotty/tools/dotc/ast/untpd.scala
index ae444d123..d6af6ecd0 100644
--- a/src/dotty/tools/dotc/ast/untpd.scala
+++ b/src/dotty/tools/dotc/ast/untpd.scala
@@ -154,7 +154,6 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
def TypeTree(original: Tree): TypeTree = new TypeTree(original)
def TypeTree() = new TypeTree(EmptyTree)
def SingletonTypeTree(ref: Tree): SingletonTypeTree = new SingletonTypeTree(ref)
- def SelectFromTypeTree(qualifier: Tree, name: Name): SelectFromTypeTree = new SelectFromTypeTree(qualifier, name)
def AndTypeTree(left: Tree, right: Tree): AndTypeTree = new AndTypeTree(left, right)
def OrTypeTree(left: Tree, right: Tree): OrTypeTree = new OrTypeTree(left, right)
def RefinedTypeTree(tpt: Tree, refinements: List[Tree]): RefinedTypeTree = new RefinedTypeTree(tpt, refinements)
diff --git a/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala b/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala
index a667438be..d278fdef1 100644
--- a/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala
+++ b/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala
@@ -1194,7 +1194,7 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
case SELECTFROMTYPEtree =>
val qualifier = readTreeRef()
val selector = readTypeNameRef()
- SelectFromTypeTree(qualifier, symbol.namedType)
+ Select(qualifier, symbol.namedType)
case COMPOUNDTYPEtree =>
readTemplateRef()
diff --git a/src/dotty/tools/dotc/parsing/JavaParsers.scala b/src/dotty/tools/dotc/parsing/JavaParsers.scala
index 4c549039d..a5418340a 100644
--- a/src/dotty/tools/dotc/parsing/JavaParsers.scala
+++ b/src/dotty/tools/dotc/parsing/JavaParsers.scala
@@ -227,7 +227,7 @@ object JavaParsers {
def convertToTypeId(tree: Tree): Tree = convertToTypeName(tree) match {
case Some(t) => t withPos tree.pos
case _ => tree match {
- case AppliedTypeTree(_, _) | SelectFromTypeTree(_, _) =>
+ case AppliedTypeTree(_, _) | Select(_, _) =>
tree
case _ =>
syntaxError("identifier expected", tree.pos)
@@ -285,10 +285,10 @@ object JavaParsers {
// SelectFromTypeTree otherwise. See #3567.
// Select nodes can be later
// converted in the typechecker to SelectFromTypeTree if the class
- // turns out to be an instance ionner class instead of a static inner class.
+ // turns out to be an instance inner class instead of a static inner class.
def typeSelect(t: Tree, name: Name) = t match {
case Ident(_) | Select(_, _) => Select(t, name)
- case _ => SelectFromTypeTree(t, name.toTypeName)
+ case _ => Select(t, name.toTypeName)
}
while (in.token == DOT) {
in.nextToken()
diff --git a/src/dotty/tools/dotc/parsing/Parsers.scala b/src/dotty/tools/dotc/parsing/Parsers.scala
index 21a6a232f..d43b12684 100644
--- a/src/dotty/tools/dotc/parsing/Parsers.scala
+++ b/src/dotty/tools/dotc/parsing/Parsers.scala
@@ -795,7 +795,7 @@ object Parsers {
private def typeProjection(t: Tree): Tree = {
accept(HASH)
val id = typeIdent()
- atPos(t.pos.start, id.pos.start) { SelectFromTypeTree(t, id.name) }
+ atPos(t.pos.start, id.pos.start) { Select(t, id.name) }
}
/** NamedTypeArg ::= id `=' Type
diff --git a/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/src/dotty/tools/dotc/printing/RefinedPrinter.scala
index cbe48409c..1125f5f01 100644
--- a/src/dotty/tools/dotc/printing/RefinedPrinter.scala
+++ b/src/dotty/tools/dotc/printing/RefinedPrinter.scala
@@ -281,7 +281,8 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
case _ => toText(name)
}
case tree @ Select(qual, name) =>
- toTextLocal(qual) ~ ("." ~ nameIdText(tree) provided name != nme.CONSTRUCTOR)
+ if (qual.isType) toTextLocal(qual) ~ "#" ~ toText(name)
+ else toTextLocal(qual) ~ ("." ~ nameIdText(tree) provided name != nme.CONSTRUCTOR)
case tree: This =>
optDotPrefix(tree) ~ "this" ~ idText(tree)
case Super(qual: This, mix) =>
@@ -349,8 +350,6 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
if (tree.hasType) toText(tree.typeOpt) else toText(orig)
case SingletonTypeTree(ref) =>
toTextLocal(ref) ~ ".type"
- case SelectFromTypeTree(qual, name) =>
- toTextLocal(qual) ~ "#" ~ toText(name)
case AndTypeTree(l, r) =>
changePrec(AndPrec) { toText(l) ~ " & " ~ toText(r) }
case OrTypeTree(l, r) =>
diff --git a/src/dotty/tools/dotc/transform/Erasure.scala b/src/dotty/tools/dotc/transform/Erasure.scala
index 24dea5118..a503d55e5 100644
--- a/src/dotty/tools/dotc/transform/Erasure.scala
+++ b/src/dotty/tools/dotc/transform/Erasure.scala
@@ -388,9 +388,6 @@ object Erasure extends TypeTestsCasts{
recur(typed(tree.qualifier, AnySelectionProto))
}
- override def typedSelectFromTypeTree(tree: untpd.SelectFromTypeTree, pt: Type)(implicit ctx: Context) =
- untpd.Ident(tree.name).withPos(tree.pos).withType(erasedType(tree))
-
override def typedThis(tree: untpd.This)(implicit ctx: Context): Tree =
if (tree.symbol == ctx.owner.enclosingClass || tree.symbol.isStaticOwner) promote(tree)
else {
diff --git a/src/dotty/tools/dotc/transform/TreeTransform.scala b/src/dotty/tools/dotc/transform/TreeTransform.scala
index f31116629..05961508a 100644
--- a/src/dotty/tools/dotc/transform/TreeTransform.scala
+++ b/src/dotty/tools/dotc/transform/TreeTransform.scala
@@ -82,7 +82,6 @@ object TreeTransforms {
def prepareForTry(tree: Try)(implicit ctx: Context) = this
def prepareForSeqLiteral(tree: SeqLiteral)(implicit ctx: Context) = this
def prepareForTypeTree(tree: TypeTree)(implicit ctx: Context) = this
- def prepareForSelectFromTypeTree(tree: SelectFromTypeTree)(implicit ctx: Context) = this
def prepareForBind(tree: Bind)(implicit ctx: Context) = this
def prepareForAlternative(tree: Alternative)(implicit ctx: Context) = this
def prepareForTypeDef(tree: TypeDef)(implicit ctx: Context) = this
@@ -114,7 +113,6 @@ object TreeTransforms {
def transformTry(tree: Try)(implicit ctx: Context, info: TransformerInfo): Tree = tree
def transformSeqLiteral(tree: SeqLiteral)(implicit ctx: Context, info: TransformerInfo): Tree = tree
def transformTypeTree(tree: TypeTree)(implicit ctx: Context, info: TransformerInfo): Tree = tree
- def transformSelectFromTypeTree(tree: SelectFromTypeTree)(implicit ctx: Context, info: TransformerInfo): Tree = tree
def transformBind(tree: Bind)(implicit ctx: Context, info: TransformerInfo): Tree = tree
def transformAlternative(tree: Alternative)(implicit ctx: Context, info: TransformerInfo): Tree = tree
def transformUnApply(tree: UnApply)(implicit ctx: Context, info: TransformerInfo): Tree = tree
@@ -276,7 +274,6 @@ object TreeTransforms {
nxPrepTry = index(transformations, "prepareForTry")
nxPrepSeqLiteral = index(transformations, "prepareForSeqLiteral")
nxPrepTypeTree = index(transformations, "prepareForTypeTree")
- nxPrepSelectFromTypeTree = index(transformations, "prepareForSelectFromTypeTree")
nxPrepBind = index(transformations, "prepareForBind")
nxPrepAlternative = index(transformations, "prepareForAlternative")
nxPrepUnApply = index(transformations, "prepareForUnApply")
@@ -307,7 +304,6 @@ object TreeTransforms {
nxTransTry = index(transformations, "transformTry")
nxTransSeqLiteral = index(transformations, "transformSeqLiteral")
nxTransTypeTree = index(transformations, "transformTypeTree")
- nxTransSelectFromTypeTree = index(transformations, "transformSelectFromTypeTree")
nxTransBind = index(transformations, "transformBind")
nxTransAlternative = index(transformations, "transformAlternative")
nxTransUnApply = index(transformations, "transformUnApply")
@@ -348,7 +344,6 @@ object TreeTransforms {
nxPrepTry = indexUpdate(prev.nxPrepTry, changedTransformationClass, transformationIndex, "prepareForTry", copy)
nxPrepSeqLiteral = indexUpdate(prev.nxPrepSeqLiteral, changedTransformationClass, transformationIndex, "prepareForSeqLiteral", copy)
nxPrepTypeTree = indexUpdate(prev.nxPrepTypeTree, changedTransformationClass, transformationIndex, "prepareForTypeTree", copy)
- nxPrepSelectFromTypeTree = indexUpdate(prev.nxPrepSelectFromTypeTree, changedTransformationClass, transformationIndex, "prepareForSelectFromTypeTree", copy)
nxPrepBind = indexUpdate(prev.nxPrepBind, changedTransformationClass, transformationIndex, "prepareForBind", copy)
nxPrepAlternative = indexUpdate(prev.nxPrepAlternative, changedTransformationClass, transformationIndex, "prepareForAlternative", copy)
nxPrepUnApply = indexUpdate(prev.nxPrepUnApply, changedTransformationClass, transformationIndex, "prepareForUnApply", copy)
@@ -378,7 +373,6 @@ object TreeTransforms {
nxTransTry = indexUpdate(prev.nxTransTry, changedTransformationClass, transformationIndex, "transformTry", copy)
nxTransSeqLiteral = indexUpdate(prev.nxTransSeqLiteral, changedTransformationClass, transformationIndex, "transformSeqLiteral", copy)
nxTransTypeTree = indexUpdate(prev.nxTransTypeTree, changedTransformationClass, transformationIndex, "transformTypeTree", copy)
- nxTransSelectFromTypeTree = indexUpdate(prev.nxTransSelectFromTypeTree, changedTransformationClass, transformationIndex, "transformSelectFromTypeTree", copy)
nxTransBind = indexUpdate(prev.nxTransBind, changedTransformationClass, transformationIndex, "transformBind", copy)
nxTransAlternative = indexUpdate(prev.nxTransAlternative, changedTransformationClass, transformationIndex, "transformAlternative", copy)
nxTransUnApply = indexUpdate(prev.nxTransUnApply, changedTransformationClass, transformationIndex, "transformUnApply", copy)
@@ -414,7 +408,6 @@ object TreeTransforms {
var nxPrepTry: Array[Int] = _
var nxPrepSeqLiteral: Array[Int] = _
var nxPrepTypeTree: Array[Int] = _
- var nxPrepSelectFromTypeTree: Array[Int] = _
var nxPrepBind: Array[Int] = _
var nxPrepAlternative: Array[Int] = _
var nxPrepUnApply: Array[Int] = _
@@ -445,7 +438,6 @@ object TreeTransforms {
var nxTransTry: Array[Int] = _
var nxTransSeqLiteral: Array[Int] = _
var nxTransTypeTree: Array[Int] = _
- var nxTransSelectFromTypeTree: Array[Int] = _
var nxTransBind: Array[Int] = _
var nxTransAlternative: Array[Int] = _
var nxTransUnApply: Array[Int] = _
@@ -524,7 +516,6 @@ object TreeTransforms {
val prepForTry: Mutator[Try] = (trans, tree, ctx) => trans.prepareForTry(tree)(ctx)
val prepForSeqLiteral: Mutator[SeqLiteral] = (trans, tree, ctx) => trans.prepareForSeqLiteral(tree)(ctx)
val prepForTypeTree: Mutator[TypeTree] = (trans, tree, ctx) => trans.prepareForTypeTree(tree)(ctx)
- val prepForSelectFromTypeTree: Mutator[SelectFromTypeTree] = (trans, tree, ctx) => trans.prepareForSelectFromTypeTree(tree)(ctx)
val prepForBind: Mutator[Bind] = (trans, tree, ctx) => trans.prepareForBind(tree)(ctx)
val prepForAlternative: Mutator[Alternative] = (trans, tree, ctx) => trans.prepareForAlternative(tree)(ctx)
val prepForUnApply: Mutator[UnApply] = (trans, tree, ctx) => trans.prepareForUnApply(tree)(ctx)
@@ -761,17 +752,6 @@ object TreeTransforms {
}
@tailrec
- final private[TreeTransforms] def goSelectFromTypeTree(tree: SelectFromTypeTree, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
- if (cur < info.transformers.length) {
- val trans = info.transformers(cur)
- trans.transformSelectFromTypeTree(tree)(ctx.withPhase(trans.treeTransformPhase), info) match {
- case t: SelectFromTypeTree => goSelectFromTypeTree(t, info.nx.nxTransSelectFromTypeTree(cur + 1))
- case t => transformSingle(t, cur + 1)
- }
- } else tree
- }
-
- @tailrec
final private[TreeTransforms] def goBind(tree: Bind, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
val trans = info.transformers(cur)
@@ -880,8 +860,6 @@ object TreeTransforms {
tree match {
case tree: Ident => goIdent(tree, info.nx.nxTransIdent(cur))
case tree: Select => goSelect(tree, info.nx.nxTransSelect(cur))
- case tree: SelectFromTypeTree =>
- goSelectFromTypeTree(tree, info.nx.nxTransSelectFromTypeTree(cur))
case tree: Bind => goBind(tree, cur)
case tree: ValDef if !tree.isEmpty => goValDef(tree, info.nx.nxTransValDef(cur))
case tree: DefDef => goDefDef(tree, info.nx.nxTransDefDef(cur))
@@ -946,13 +924,6 @@ object TreeTransforms {
val qual = transform(tree.qualifier, mutatedInfo, cur)
goSelect(cpy.Select(tree)(qual, tree.name), mutatedInfo.nx.nxTransSelect(cur))
}
- case tree: SelectFromTypeTree =>
- implicit val mutatedInfo: TransformerInfo = mutateTransformers(info, prepForSelectFromTypeTree, info.nx.nxPrepSelectFromTypeTree, tree, cur)
- if (mutatedInfo eq null) tree
- else {
- val qual = transform(tree.qualifier, mutatedInfo, cur)
- goSelectFromTypeTree(cpy.SelectFromTypeTree(tree)(qual, tree.name), mutatedInfo.nx.nxTransSelectFromTypeTree(cur))
- }
case tree: Bind =>
implicit val mutatedInfo: TransformerInfo = mutateTransformers(info, prepForBind, info.nx.nxPrepBind, tree, cur)
if (mutatedInfo eq null) tree
diff --git a/src/dotty/tools/dotc/typer/Checking.scala b/src/dotty/tools/dotc/typer/Checking.scala
index 2db6d497e..415cd5d6a 100644
--- a/src/dotty/tools/dotc/typer/Checking.scala
+++ b/src/dotty/tools/dotc/typer/Checking.scala
@@ -99,8 +99,6 @@ object Checking {
checkValidIfHKApply(ctx.addMode(Mode.AllowLambdaWildcardApply))
case Select(qual, name) if name.isTypeName =>
checkRealizable(qual.tpe, qual.pos)
- case SelectFromTypeTree(qual, name) if name.isTypeName =>
- checkRealizable(qual.tpe, qual.pos)
case SingletonTypeTree(ref) =>
checkRealizable(ref.tpe, ref.pos)
case _ =>
diff --git a/src/dotty/tools/dotc/typer/ReTyper.scala b/src/dotty/tools/dotc/typer/ReTyper.scala
index a4f92271a..9750957bf 100644
--- a/src/dotty/tools/dotc/typer/ReTyper.scala
+++ b/src/dotty/tools/dotc/typer/ReTyper.scala
@@ -38,12 +38,6 @@ class ReTyper extends Typer {
untpd.cpy.Select(tree)(qual1, tree.name).withType(tree.typeOpt)
}
- override def typedSelectFromTypeTree(tree: untpd.SelectFromTypeTree, pt: Type)(implicit ctx: Context): Tree = {
- assert(tree.hasType)
- val qual1 = typed(tree.qualifier, AnySelectionProto)
- untpd.cpy.SelectFromTypeTree(tree)(qual1, tree.name).withType(tree.typeOpt)
- }
-
override def typedLiteral(tree: untpd.Literal)(implicit ctc: Context): Literal =
promote(tree)
diff --git a/src/dotty/tools/dotc/typer/TypeAssigner.scala b/src/dotty/tools/dotc/typer/TypeAssigner.scala
index 42302e5ff..ba8f35cd8 100644
--- a/src/dotty/tools/dotc/typer/TypeAssigner.scala
+++ b/src/dotty/tools/dotc/typer/TypeAssigner.scala
@@ -263,9 +263,6 @@ trait TypeAssigner {
tree.withType(tp)
}
- def assignType(tree: untpd.SelectFromTypeTree, qual: Tree)(implicit ctx: Context) =
- tree.withType(accessibleSelectionType(tree, qual))
-
def assignType(tree: untpd.New, tpt: Tree)(implicit ctx: Context) =
tree.withType(tpt.tpe)
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 072240248..2550da793 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -363,52 +363,45 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
else tree
def typedSelect(tree: untpd.Select, pt: Type)(implicit ctx: Context): Tree = track("typedSelect") {
- def asSelect(implicit ctx: Context): Tree = {
- val qual1 = typedExpr(tree.qualifier, selectionProto(tree.name, pt, this))
- if (tree.name.isTypeName) checkStable(qual1.tpe, qual1.pos)
- val select = typedSelect(tree, pt, qual1)
- if (select.tpe ne TryDynamicCallType) select
- else if (pt.isInstanceOf[PolyProto] || pt.isInstanceOf[FunProto] || pt == AssignProto) select
- else typedDynamicSelect(tree, Nil, pt)
- }
-
- def asJavaSelectFromTypeTree(implicit ctx: Context): Tree = {
- // Translate names in Select/Ident nodes to type names.
- def convertToTypeName(tree: untpd.Tree): Option[untpd.Tree] = tree match {
- case Select(qual, name) => Some(untpd.Select(qual, name.toTypeName))
- case Ident(name) => Some(untpd.Ident(name.toTypeName))
- case _ => None
+ def typeAsIs(implicit ctx: Context): Tree = {
+ if (tree.qualifier.isType) {
+ val qual1 = typedType(tree.qualifier, selectionProto(tree.name, pt, this))
+ assignType(cpy.Select(tree)(qual1, tree.name), qual1)
}
+ else {
+ val qual1 = typedExpr(tree.qualifier, selectionProto(tree.name, pt, this))
+ if (tree.name.isTypeName) checkStable(qual1.tpe, qual1.pos)
+ val select = typedSelect(tree, pt, qual1)
+ if (select.tpe ne TryDynamicCallType) select
+ else if (pt.isInstanceOf[PolyProto] || pt.isInstanceOf[FunProto] || pt == AssignProto) select
+ else typedDynamicSelect(tree, Nil, pt)
+ }
+ }
- // Try to convert Select(qual, name) to a SelectFromTypeTree.
- def convertToSelectFromType(qual: untpd.Tree, origName: Name): Option[untpd.SelectFromTypeTree] =
- convertToTypeName(qual) match {
- case Some(qual1) => Some(untpd.SelectFromTypeTree(qual1 withPos qual.pos, origName.toTypeName))
- case _ => None
- }
-
- convertToSelectFromType(tree.qualifier, tree.name) match {
- case Some(sftt) => typedSelectFromTypeTree(sftt, pt)
- case _ => ctx.error(em"Could not convert $tree to a SelectFromTypeTree"); EmptyTree
+ def asJavaSelectFromType(implicit ctx: Context): Tree = {
+ def typeSelectOnType(qual: untpd.Tree) =
+ typedSelect(untpd.cpy.Select(tree)(qual, tree.name.toTypeName), pt)
+ tree.qualifier match {
+ case Select(qual, name) => typeSelectOnType(untpd.Select(qual, name.toTypeName))
+ case Ident(name) => typeSelectOnType(untpd.Ident(name.toTypeName))
+ case _ => errorTree(tree, "cannot convert to type selection") // will never be printed due to fallback
}
}
- def selectWithFallback(fallBack: => Tree) =
- tryEither(tryCtx => asSelect(tryCtx))((_, _) => fallBack)
+ def selectWithFallback(fallBack: Context => Tree) =
+ tryAlternatively(typeAsIs(_))(fallBack)
if (ctx.compilationUnit.isJava && tree.name.isTypeName)
// SI-3120 Java uses the same syntax, A.B, to express selection from the
// value A and from the type A. We have to try both.
- selectWithFallback(asJavaSelectFromTypeTree(ctx))
+ selectWithFallback(asJavaSelectFromType(_)) // !!! possibly exponential bcs of qualifier retyping
else if (tree.name == nme.withFilter && tree.getAttachment(desugar.MaybeFilter).isDefined)
- selectWithFallback(typedSelect(untpd.cpy.Select(tree)(tree.qualifier, nme.filter), pt))
+ selectWithFallback {
+ implicit ctx =>
+ typedSelect(untpd.cpy.Select(tree)(tree.qualifier, nme.filter), pt) // !!! possibly exponential bcs of qualifier retyping
+ }
else
- asSelect(ctx)
- }
-
- def typedSelectFromTypeTree(tree: untpd.SelectFromTypeTree, pt: Type)(implicit ctx: Context): Tree = track("typedSelectFromTypeTree") {
- val qual1 = typedType(tree.qualifier, selectionProto(tree.name, pt, this))
- assignType(cpy.SelectFromTypeTree(tree)(qual1, tree.name), qual1)
+ typeAsIs(ctx)
}
def typedThis(tree: untpd.This)(implicit ctx: Context): Tree = track("typedThis") {
@@ -1393,7 +1386,6 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
tree match {
case tree: untpd.Ident => typedIdent(tree, pt)
case tree: untpd.Select => typedSelect(tree, pt)
- case tree: untpd.SelectFromTypeTree => typedSelectFromTypeTree(tree, pt)
case tree: untpd.Bind => typedBind(tree, pt)
case tree: untpd.ValDef =>
if (tree.isEmpty) tpd.EmptyValDef
@@ -1516,6 +1508,17 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
}
}
+ /** Try `op1`, if there are errors, try `op2`, if `op2` also causes errors, fall back
+ * to errors and result of `op1`.
+ */
+ def tryAlternatively[T](op1: Context => T)(op2: Context => T)(implicit ctx: Context): T =
+ tryEither(op1) { (failedVal, failedState) =>
+ tryEither(op2) { (_, _) =>
+ failedState.commit
+ failedVal
+ }
+ }
+
/** Add apply node or implicit conversions. Two strategies are tried, and the first
* that is successful is picked. If neither of the strategies are successful, continues with
* `fallBack`.