From 48ee86e88ab9dce4ca3ea0bed98bdebdc6fc067e Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 11 Feb 2019 13:55:03 +0100 Subject: [PATCH] Make sure the span of EmptyTree and EmptyValDef are never set It is important not to set the span as if the sources differ the tree will be cloned and the EmptyTree will have multiple instances which are not comparable. --- compiler/src/dotty/tools/dotc/ast/Trees.scala | 4 +++- compiler/src/dotty/tools/dotc/parsing/Parsers.scala | 2 +- compiler/src/dotty/tools/dotc/transform/Staging.scala | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/ast/Trees.scala b/compiler/src/dotty/tools/dotc/ast/Trees.scala index 87c1dd605b2d..6589104fb158 100644 --- a/compiler/src/dotty/tools/dotc/ast/Trees.scala +++ b/compiler/src/dotty/tools/dotc/ast/Trees.scala @@ -820,13 +820,15 @@ object Trees { class EmptyTree[T >: Untyped] extends Thicket(Nil)(NoSource) { // assert(uniqueId != 1492) + override def withSpan(span: Span) = throw new AssertionError("Cannot change span of EmptyTree") } class EmptyValDef[T >: Untyped] extends ValDef[T]( nme.WILDCARD, genericEmptyTree[T], genericEmptyTree[T])(NoSource) with WithoutTypeOrPos[T] { myTpe = NoType.asInstanceOf[T] - override def isEmpty: Boolean = true setMods(untpd.Modifiers(PrivateLocal)) + override def isEmpty: Boolean = true + override def withSpan(span: Span) = throw new AssertionError("Cannot change span of EmptyValDef") } @sharable val theEmptyTree: EmptyTree[Type] = new EmptyTree[Type] diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 46cf3da79a6a..76c727a00a7e 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -2419,7 +2419,7 @@ object Parsers { makeTypeDef(typeBounds()) case _ => syntaxErrorOrIncomplete(ExpectedTypeBoundOrEquals(in.token)) - EmptyTree + return EmptyTree // return to avoid setting the span to EmptyTree } } } diff --git a/compiler/src/dotty/tools/dotc/transform/Staging.scala b/compiler/src/dotty/tools/dotc/transform/Staging.scala index 52314b0d89c3..33b7e6570cd2 100644 --- a/compiler/src/dotty/tools/dotc/transform/Staging.scala +++ b/compiler/src/dotty/tools/dotc/transform/Staging.scala @@ -144,8 +144,8 @@ class Staging extends MacroTransform { else if (enclosingInlineds.nonEmpty) { // level 0 in an inlined call val spliceCtx = ctx.outer // drop the last `inlineContext` val pos: SourcePosition = spliceCtx.source.atSpan(enclosingInlineds.head.span) - val evaluatedSplice = Splicer.splice(splice.qualifier, pos, macroClassLoader)(spliceCtx).withSpan(splice.span) - if (ctx.reporter.hasErrors) splice else transform(evaluatedSplice) + val evaluatedSplice = Splicer.splice(splice.qualifier, pos, macroClassLoader)(spliceCtx) + if (ctx.reporter.hasErrors) splice else transform(evaluatedSplice.withSpan(splice.span)) } else if (!ctx.owner.isInlineMethod) { // level 0 outside an inline method ctx.error(i"splice outside quotes or inline method", splice.sourcePos)