diff options
author | Martin Odersky <odersky@gmail.com> | 2014-08-20 11:38:10 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-08-24 17:45:37 +0200 |
commit | ab0105cf91fa452abae8ef1d0d14634d8d7d4ab8 (patch) | |
tree | 2d5fa53b68ffdf6617658571ed69514a5f4c8526 /src/dotty/tools | |
parent | b10c590c59938576e7f27718fff245ea9ffe0629 (diff) | |
download | dotty-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.scala | 27 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 23 |
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) |