aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/typer
diff options
context:
space:
mode:
Diffstat (limited to 'src/dotty/tools/dotc/typer')
-rw-r--r--src/dotty/tools/dotc/typer/Checking.scala1
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala34
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala19
3 files changed, 35 insertions, 19 deletions
diff --git a/src/dotty/tools/dotc/typer/Checking.scala b/src/dotty/tools/dotc/typer/Checking.scala
index ea396519a..36822cb85 100644
--- a/src/dotty/tools/dotc/typer/Checking.scala
+++ b/src/dotty/tools/dotc/typer/Checking.scala
@@ -84,6 +84,7 @@ trait Checking extends NoChecking {
/** Check that (return) type of implicit definition is not empty */
override def checkImplicitTptNonEmpty(defTree: untpd.ValOrDefDef)(implicit ctx: Context): Unit = defTree.tpt match {
+ case tpt: untpd.DerivedTypeTree =>
case TypeTree(untpd.EmptyTree) =>
val resStr = if (defTree.isInstanceOf[untpd.DefDef]) "result " else ""
ctx.error(i"${resStr}type of implicit definition needs to be given explicitly", defTree.pos)
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala
index 162e13bbc..7885e85ac 100644
--- a/src/dotty/tools/dotc/typer/Namer.scala
+++ b/src/dotty/tools/dotc/typer/Namer.scala
@@ -72,6 +72,13 @@ trait NamerContextOps { this: Context =>
}
go(this)
}
+
+ /** Context where `sym` is defined, assuming we are in a nested context. */
+ def defContext(sym: Symbol) =
+ outersIterator
+ .dropWhile(_.owner != sym)
+ .dropWhile(_.owner == sym)
+ .next
}
/** This class creates symbols from definitions and imports and gives them
@@ -173,10 +180,10 @@ class Namer { typer: Typer =>
enclosingClassNamed(mods.privateWithin, mods.pos)
def record(sym: Symbol): Symbol = {
- val refs = tree.attachmentOrElse(desugar.References, Nil)
+ val refs = tree.attachmentOrElse(References, Nil)
if (refs.nonEmpty) {
- tree.removeAttachment(desugar.References)
- refs foreach (_.pushAttachment(desugar.OriginalSymbol, sym))
+ tree.removeAttachment(References)
+ refs foreach (_.pushAttachment(OriginalSymbol, sym))
}
tree.pushAttachment(SymOfTree, sym)
sym
@@ -449,17 +456,25 @@ class Namer { typer: Typer =>
if (self.isEmpty) NoType
else if (cls is Module) cls.owner.thisType select sourceModule
else createSymbol(self)
+
// pre-set info, so that parent types can refer to type params
denot.info = ClassInfo(cls.owner.thisType, cls, Nil, decls, selfInfo)
+
+ // Ensure constructor is completed so that any parameter accessors
+ // which have type trees deriving from its parameters can be
+ // completed in turn. Note that parent types access such parameter
+ // accessors, that's why the constructor needs to be completed before
+ // the parent types are elaborated.
+ index(constr)
+ symbolOfTree(constr).ensureCompleted()
+
val parentTypes = ensureFirstIsClass(parents map checkedParentType)
val parentRefs = ctx.normalizeToClassRefs(parentTypes, cls, decls)
typr.println(s"completing $denot, parents = $parents, parentTypes = $parentTypes, parentRefs = $parentRefs")
- index(constr)
index(rest)(inClassContext(selfInfo))
denot.info = ClassInfo(cls.owner.thisType, cls, parentRefs, decls, selfInfo)
// make sure constr parameters are all entered because we refer to them in desugarings:
- symbolOfTree(constr).ensureCompleted()
}
}
@@ -509,13 +524,6 @@ class Namer { typer: Typer =>
if (!mdef.tpt.isEmpty) WildcardType
else {
- /** Context where `sym` is defined */
- def defContext(sym: Symbol) =
- ctx.outersIterator
- .dropWhile(_.owner != sym)
- .dropWhile(_.owner == sym)
- .next
-
/** An type for this definition that might be inherited from elsewhere:
* If this is a setter parameter, the corresponding getter type.
* If this is a class member, the conjunction of all result types
@@ -561,7 +569,7 @@ class Namer { typer: Typer =>
if (original.isConstructorName && (sym.owner is ModuleClass))
sym.owner.companionClass.info.decl(nme.CONSTRUCTOR)
else
- defContext(sym).denotNamed(original)
+ ctx.defContext(sym).denotNamed(original)
def paramProto(paramss: List[List[Type]], idx: Int): Type = paramss match {
case params :: paramss1 =>
if (idx < params.length) wildApprox(params(idx))
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index e9a79eeb1..67e5c5902 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -637,12 +637,19 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
def typedTypeTree(tree: untpd.TypeTree, pt: Type)(implicit ctx: Context): TypeTree = track("typedTypeTree") {
if (tree.original.isEmpty)
tree match {
- case tree: desugar.DerivedTypeTree =>
- TypeTree(tree.derivedType(tree.attachment(desugar.OriginalSymbol))) withPos tree.pos
- // btw, no need to remove the attachment. The typed
- // tree is different from the untyped one, so the
- // untyped tree is no longer accessed after all
- // accesses with typedTypeTree are done.
+ case tree: untpd.DerivedTypeTree =>
+ tree.ensureCompletions
+ try
+ TypeTree(tree.derivedType(tree.attachment(untpd.OriginalSymbol))) withPos tree.pos
+ // btw, no need to remove the attachment. The typed
+ // tree is different from the untyped one, so the
+ // untyped tree is no longer accessed after all
+ // accesses with typedTypeTree are done.
+ catch {
+ case ex: NoSuchElementException =>
+ println(s"missing OriginalSymbol for ${ctx.owner.ownersIterator.toList}")
+ throw ex
+ }
case _ =>
assert(isFullyDefined(pt, ForceDegree.none))
tree.withType(pt)