diff options
Diffstat (limited to 'src/dotty/tools/dotc/typer')
-rw-r--r-- | src/dotty/tools/dotc/typer/Checking.scala | 1 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Namer.scala | 34 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 19 |
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) |