From 0553f08eaeee1f9ac7ef6c28b341a92e0fb452e3 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 29 Dec 2013 18:36:18 +0100 Subject: Tightening of position handlng 1) endPos works now even for NoPosition. 2) On the other hand, there's an assertion in Typer.typed which requires every non-empty tree that's type checked in a globally committable context to have a defined position. Some fixes were needed to make the tests pass the new assert. --- src/dotty/tools/dotc/core/TyperState.scala | 7 +++++++ src/dotty/tools/dotc/typer/Applications.scala | 2 +- src/dotty/tools/dotc/typer/Implicits.scala | 3 ++- src/dotty/tools/dotc/typer/Typer.scala | 3 ++- src/dotty/tools/dotc/util/Positions.scala | 6 +++--- 5 files changed, 15 insertions(+), 6 deletions(-) (limited to 'src/dotty/tools') diff --git a/src/dotty/tools/dotc/core/TyperState.scala b/src/dotty/tools/dotc/core/TyperState.scala index f46c58c90..455320ba8 100644 --- a/src/dotty/tools/dotc/core/TyperState.scala +++ b/src/dotty/tools/dotc/core/TyperState.scala @@ -41,6 +41,9 @@ class TyperState(val reporter: Reporter) extends DotClass with Showable { /** Is it allowed to commit this state? */ def isCommittable: Boolean = false + /** Can this state be transitively committed until the top-level? */ + def isGlobalCommittable: Boolean = false + override def toText(printer: Printer): Text = "ImmutableTyperState" } @@ -55,6 +58,10 @@ extends TyperState(reporter) { override def fresh(isCommittable: Boolean): TyperState = new MutableTyperState(this, new StoreReporter, isCommittable) + override val isGlobalCommittable = + isCommittable && + (!previous.isInstanceOf[MutableTyperState] || previous.isGlobalCommittable) + /** Commit typer state so that its information is copied into current typer state * In addition (1) the owning state of undetermined or temporarily instantiated * type variables changes from this typer state to the current one. (2) Variables diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala index aa2227d63..2c1384524 100644 --- a/src/dotty/tools/dotc/typer/Applications.scala +++ b/src/dotty/tools/dotc/typer/Applications.scala @@ -562,7 +562,7 @@ trait Applications extends Compatibility { self: Typer => ttree.tpe match { case alias: TypeRef if alias.symbol.isAliasType => companionRef(alias) match { - case companion: TermRef => return untpd.ref(companion) + case companion: TermRef => return untpd.ref(companion) withPos tree.pos case _ => } case _ => diff --git a/src/dotty/tools/dotc/typer/Implicits.scala b/src/dotty/tools/dotc/typer/Implicits.scala index 3878e5235..de74917a8 100644 --- a/src/dotty/tools/dotc/typer/Implicits.scala +++ b/src/dotty/tools/dotc/typer/Implicits.scala @@ -245,7 +245,8 @@ trait Implicits { self: Typer => !from.isError && !to.isError && (ctx.mode is Mode.ImplicitsEnabled) - && (inferView(dummyTreeOfType(from), to).isInstanceOf[SearchSuccess])) + && (inferView(dummyTreeOfType(from), to)(ctx.fresh.withExploreTyperState).isInstanceOf[SearchSuccess]) + ) /** Find an implicit conversion to apply to given tree `from` so that the * result is compatible with type `to`. diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index 85724b1ee..be84d1bea 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -492,7 +492,7 @@ class Typer extends Namer with Applications with Implicits { def typedIf(tree: untpd.If, pt: Type)(implicit ctx: Context) = track("typedIf") { val cond1 = typed(tree.cond, defn.BooleanType) val thenp1 = typed(tree.thenp, pt) - val elsep1 = typed(tree.elsep orElse untpd.unitLiteral, pt) + val elsep1 = typed(tree.elsep orElse untpd.unitLiteral withPos tree.pos, pt) cpy.If(tree, cond1, thenp1, elsep1).withType(thenp1.tpe | elsep1.tpe) } @@ -952,6 +952,7 @@ class Typer extends Namer with Applications with Implicits { } def typed(tree: untpd.Tree, pt: Type = WildcardType)(implicit ctx: Context): Tree = ctx.traceIndented (s"typing ${tree.show}", show = true) { + if (!tree.isEmpty && ctx.typerState.isGlobalCommittable) assert(tree.pos.exists, tree) try adapt(typedUnadapted(tree, pt), pt) catch { case ex: CyclicReference => errorTree(tree, cyclicErrorMsg(ex)) diff --git a/src/dotty/tools/dotc/util/Positions.scala b/src/dotty/tools/dotc/util/Positions.scala index 6dfb78c87..21ee788ca 100644 --- a/src/dotty/tools/dotc/util/Positions.scala +++ b/src/dotty/tools/dotc/util/Positions.scala @@ -78,13 +78,13 @@ object Positions { else this /** The zero-extent position with start and end at the point of this position */ - def focus = Position(point) + def focus = if (exists) Position(point) else NoPosition /** The zero-extent position with start and end at the start of this position */ - def startPos = Position(start) + def startPos = if (exists) Position(start) else NoPosition /** The zero-extent position with start and end at the end of this position */ - def endPos = Position(end) + def endPos = if (exists) Position(end) else NoPosition /** A copy of this position with a different start */ def withStart(start: Int) = -- cgit v1.2.3