From 8d5a04c10942f12634f612af7396c96d5b6b3630 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 12 Dec 2023 09:29:41 +0100 Subject: [PATCH] Avoid crashes on missing positions All positions should be set on these trees and symbols at this point. If one is missing it is due to a compiler bug. We default the position to 0 if there is a missing position to avoid crashing when calling methods on Position. To make it possible for us to fix these missing positions, we warn if there is a missing position when compiling with -Xcheck-macros. --- .../scala/quoted/runtime/impl/QuotesImpl.scala | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala b/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala index 6aa279129f2b..ff544505053d 100644 --- a/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala +++ b/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala @@ -96,7 +96,13 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler given TreeMethods: TreeMethods with extension (self: Tree) - def pos: Position = self.sourcePos + def pos: Position = + val treePos = self.sourcePos + if treePos.exists then treePos + else + if xCheckMacro then report.warning(s"Missing tree position (defaulting to position 0): ${Printer.TreeStructure.show(self)}\nThis is a compiler bug. Please report it.") + self.source.atSpan(dotc.util.Spans.Span(0)) + def symbol: Symbol = self.symbol def show(using printer: Printer[Tree]): String = printer.show(self) def isExpr: Boolean = @@ -2625,7 +2631,13 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler def info: TypeRepr = self.denot.info def pos: Option[Position] = - if self.exists then Some(self.sourcePos) else None + if self.exists then + val symPos = self.sourcePos + if symPos.exists then Some(symPos) + else + if xCheckMacro then report.warning(s"Missing symbol position (defaulting to position 0): $self\nThis is a compiler bug. Please report it.") + Some(self.source.atSpan(dotc.util.Spans.Span(0))) + else None def docstring: Option[String] = import dotc.core.Comments.CommentsContext