aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/typer/TypeAssigner.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/dotty/tools/dotc/typer/TypeAssigner.scala')
-rw-r--r--src/dotty/tools/dotc/typer/TypeAssigner.scala23
1 files changed, 20 insertions, 3 deletions
diff --git a/src/dotty/tools/dotc/typer/TypeAssigner.scala b/src/dotty/tools/dotc/typer/TypeAssigner.scala
index 30d6baf8a..2b7eb3936 100644
--- a/src/dotty/tools/dotc/typer/TypeAssigner.scala
+++ b/src/dotty/tools/dotc/typer/TypeAssigner.scala
@@ -392,13 +392,30 @@ trait TypeAssigner {
tree.withType(proto)
def assignType(tree: untpd.ValDef, sym: Symbol)(implicit ctx: Context) =
- tree.withType(if (sym.exists) sym.valRef else NoType)
+ tree.withType(if (sym.exists) assertExists(symbolicIfNeeded(sym).orElse(sym.valRef)) else NoType)
def assignType(tree: untpd.DefDef, sym: Symbol)(implicit ctx: Context) =
- tree.withType(sym.termRefWithSig)
+ tree.withType(symbolicIfNeeded(sym).orElse(sym.termRefWithSig))
def assignType(tree: untpd.TypeDef, sym: Symbol)(implicit ctx: Context) =
- tree.withType(sym.typeRef)
+ tree.withType(symbolicIfNeeded(sym).orElse(sym.typeRef))
+
+ private def symbolicIfNeeded(sym: Symbol)(implicit ctx: Context) = {
+ val owner = sym.owner
+ owner.infoOrCompleter match {
+ case info: ClassInfo if info.givenSelfType.exists =>
+ // In that case a simple typeRef/termWithWithSig could return a member of
+ // the self type, not the symbol itself. To avoid this, we make the reference
+ // symbolic. In general it seems to be faster to keep the non-symblic
+ // reference, since there is less pressure on the uniqueness tables that way
+ // and less work to update all the different references. That's why symbolic references
+ // are only used if necessary.
+ NamedType.withFixedSym(owner.thisType, sym)
+ case _ => NoType
+ }
+ }
+
+ def assertExists(tp: Type) = { assert(tp != NoType); tp }
def assignType(tree: untpd.Import, sym: Symbol)(implicit ctx: Context) =
tree.withType(sym.nonMemberTermRef)