aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-08-20 11:38:10 +0200
committerMartin Odersky <odersky@gmail.com>2014-08-24 17:45:37 +0200
commitab0105cf91fa452abae8ef1d0d14634d8d7d4ab8 (patch)
tree2d5fa53b68ffdf6617658571ed69514a5f4c8526 /src/dotty/tools
parentb10c590c59938576e7f27718fff245ea9ffe0629 (diff)
downloaddotty-ab0105cf91fa452abae8ef1d0d14634d8d7d4ab8.tar.gz
dotty-ab0105cf91fa452abae8ef1d0d14634d8d7d4ab8.tar.bz2
dotty-ab0105cf91fa452abae8ef1d0d14634d8d7d4ab8.zip
Comments about phase orderings and shadowed references.
... try to explain two tricky consequences of the denotation and signature model.
Diffstat (limited to 'src/dotty/tools')
-rw-r--r--src/dotty/tools/dotc/Compiler.scala27
-rw-r--r--src/dotty/tools/dotc/core/Types.scala23
2 files changed, 49 insertions, 1 deletions
diff --git a/src/dotty/tools/dotc/Compiler.scala b/src/dotty/tools/dotc/Compiler.scala
index d0d43a541..3355ce1f2 100644
--- a/src/dotty/tools/dotc/Compiler.scala
+++ b/src/dotty/tools/dotc/Compiler.scala
@@ -16,6 +16,33 @@ import dotty.tools.dotc.core.Denotations.SingleDenotation
class Compiler {
+ /** Meta-ordering constraint:
+ *
+ * DenotTransformers that change the signature of their denotation's info must go
+ * after erasure. The reason is that denotations are permanently referred to by
+ * TermRefs which contain a signature. If the signature of a symbol would change,
+ * all refs to it would become outdated - they could not be dereferenced in the
+ * new phase.
+ *
+ * As an example, addGetters would change a field
+ *
+ * val x: T
+ *
+ * to a method
+ *
+ * def x: T
+ *
+ * but this would affect the signature of `x` (goes from NotAMethod to a method
+ * signature). So we can't do this before erasure.
+ *
+ * After erasure, signature changing denot-transformers are OK because erasure
+ * will make sure that only term refs with fixed SymDenotations survive beyond it. This
+ * is possible because:
+ *
+ * - splitter has run, so every ident or select refers to a unique symbol
+ * - after erasure, asSeenFrom is the identity, so every reference has a
+ * plain SymDenotation, as opposed to a UniqueRefDenotation.
+ */
def phases: List[List[Phase]] =
List(
List(new FrontEnd),
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 17e7f4fb5..46cb92832 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -1276,7 +1276,28 @@ object Types {
protected def newLikeThis(prefix: Type)(implicit ctx: Context): NamedType =
NamedType(prefix, name)
- /** Create a NamedType of the same kind as this type, but with a new name.
+ /** Create a NamedType of the same kind as this type, but with a "inherited name".
+ * This is necessary to in situations like the following:
+ *
+ * class B { def m: T1 }
+ * class C extends B { private def m: T2; ... C.m }
+ * object C extends C
+ * object X { ... C.m }
+ *
+ * The two references of C.m in class C and object X refer to different
+ * definitions: The one in C refers to C#m whereas the one in X refers to B#m.
+ * But the type C.m must have only one denotation, so it can't refer to two
+ * members depending on context.
+ *
+ * In situations like this, the reference in X would get the type
+ * `<C.m>.shadowed` to make clear that we mean the inherited member, not
+ * the private one.
+ *
+ * Note: An alternative, possibly more robust scheme would be to give
+ * private members special names. A private definition would have a special
+ * name (say m' in the example above), but would be entered in its enclosing
+ * under both private and public names, so it could still be found by looking up
+ * the public name.
*/
final def shadowed(implicit ctx: Context): NamedType =
NamedType(prefix, name.inheritedName)