aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-05-28 11:27:11 +0200
committerMartin Odersky <odersky@gmail.com>2014-05-30 15:43:02 +0200
commitc2175ec910165308e81c48bd8ca8910c50862be4 (patch)
tree82af4c43d1167cc0d897d31b1afa855c068f856e /src/dotty/tools
parent70e785f5d8a583dae127dadf4d9add70bdea71f7 (diff)
downloaddotty-c2175ec910165308e81c48bd8ca8910c50862be4.tar.gz
dotty-c2175ec910165308e81c48bd8ca8910c50862be4.tar.bz2
dotty-c2175ec910165308e81c48bd8ca8910c50862be4.zip
Avoid classtype checking for refinements.
In a refinement type T { R } we do not need T to be a class. But analyzing the refeinement type will create a temporary class type. This refinement class has to be treated specially in what concerns parent types.
Diffstat (limited to 'src/dotty/tools')
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala51
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala3
2 files changed, 53 insertions, 1 deletions
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index 498f912f9..606966be9 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -321,6 +321,9 @@ object SymDenotations {
final def isAnonymousClass(implicit ctx: Context): Boolean =
initial.asSymDenotation.name startsWith tpnme.ANON_CLASS
+ final def isRefinementClass(implicit ctx: Context): Boolean =
+ name.decode == tpnme.REFINE_CLASS
+
/** Is this symbol a package object or its module class? */
def isPackageObject(implicit ctx: Context): Boolean = {
val poName = if (isType) nme.PACKAGE_CLS else nme.PACKAGE
@@ -701,6 +704,54 @@ object SymDenotations {
else
Iterator.empty
+ /** The symbol overriding this symbol in given subclass `ofclazz`.
+ *
+ * @param ofclazz is a subclass of this symbol's owner
+ */
+ final def overridingSymbol(inClass: ClassSymbol)(implicit ctx: Context): Symbol =
+ if (canMatchInheritedSymbols) matchingSymbol(inClass, inClass.thisType)
+ else NoSymbol
+
+ /** If false, this symbol cannot possibly participate in an override,
+ * either as overrider or overridee. For internal use; you should consult
+ * with isOverridingSymbol. This is used by isOverridingSymbol to escape
+ * the recursive knot.
+ */
+ private def canMatchInheritedSymbols = (
+ owner.isClass
+ && !this.isClass
+ && !this.isConstructor
+ )
+
+ /** The symbol accessed by a super in the definition of this symbol when
+ * seen from class `base`. This symbol is always concrete.
+ * pre: `this.owner` is in the base class sequence of `base`.
+ */
+ final def superSymbolIn(base: Symbol)(implicit ctx: Context): Symbol = {
+ def loop(bcs: List[ClassSymbol]): Symbol = bcs match {
+ case bc :: bcs1 =>
+ val sym = matchingSymbol(bcs.head, base.thisType)
+ .suchThat(alt => !(alt is Deferred)).symbol
+ if (sym.exists) sym else loop(bcs.tail)
+ case _ =>
+ NoSymbol
+ }
+ loop(base.info.baseClasses.dropWhile(owner != _).tail)
+ }
+
+
+ /** A a member of class `base` is incomplete if
+ * (1) it is declared deferred or
+ * (2) it is abstract override and its super symbol in `base` is
+ * nonexistent or incomplete.
+ */
+ final def isIncompleteIn(base: Symbol)(implicit ctx: Context): Boolean =
+ (this is Deferred) ||
+ (this is AbsOverride) && {
+ val supersym = superSymbolIn(base)
+ supersym == NoSymbol || supersym.isIncompleteIn(base)
+ }
+
/** The class or term symbol up to which this symbol is accessible,
* or RootClass if it is public. As java protected statics are
* otherwise completely inaccessible in scala, they are treated
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala
index e9195a072..681523bd2 100644
--- a/src/dotty/tools/dotc/typer/Namer.scala
+++ b/src/dotty/tools/dotc/typer/Namer.scala
@@ -459,7 +459,8 @@ class Namer { typer: Typer =>
def checkedParentType(parent: untpd.Tree): Type = {
val ptype = parentType(parent)(ctx.fresh addMode Mode.InSuperCall)
- checkClassTypeWithStablePrefix(ptype, parent.pos, traitReq = parent ne parents.head)
+ if (cls.isRefinementClass) ptype
+ else checkClassTypeWithStablePrefix(ptype, parent.pos, traitReq = parent ne parents.head)
}
val selfInfo =