Skip to content

Commit 4e39163

Browse files
committed
Check span.exists where necessary
1 parent 0be00ad commit 4e39163

File tree

1 file changed

+16
-9
lines changed

1 file changed

+16
-9
lines changed

Diff for: compiler/src/dotty/tools/dotc/transform/CheckUnused.scala

+16-9
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,14 @@ class CheckUnused private (phaseMode: PhaseMode, suffix: String) extends MiniPha
6666
// import x.y; y may be rewritten x.y, also import x.z as y
6767
override def transformSelect(tree: Select)(using Context): tree.type =
6868
val name = tree.removeAttachment(OriginalName).getOrElse(nme.NO_NAME)
69-
if tree.span.isSynthetic && tree.symbol == defn.TypeTest_unapply then
69+
if tree.srcPos.isSynthetic && tree.symbol == defn.TypeTest_unapply then
7070
tree.qualifier.tpe.underlying.finalResultType match
7171
case AppliedType(_, args) => // tycon.typeSymbol == defn.TypeTestClass
7272
val res = args(1) // T in TypeTest[-S, T]
7373
val target = res.dealias.typeSymbol
7474
resolveUsage(target, target.name, res.importPrefix.skipPackageObject) // case _: T =>
7575
case _ =>
76-
else if tree.qualifier.span.isSynthetic || name.exists(_ != tree.symbol.name) then
76+
else if tree.qualifier.srcPos.isSynthetic || name.exists(_ != tree.symbol.name) then
7777
if !ignoreTree(tree) then
7878
resolveUsage(tree.symbol, name, tree.qualifier.tpe)
7979
else
@@ -597,12 +597,12 @@ object CheckUnused:
597597
warnAt(pos)(UnusedSymbol.localDefs)
598598

599599
def checkPatvars() =
600-
// convert the one non-synthetic span so all are comparable
600+
// convert the one non-synthetic span so all are comparable; filter NoSpan below
601601
def uniformPos(sym: Symbol, pos: SrcPos): SrcPos =
602602
if pos.span.isSynthetic then pos else pos.sourcePos.withSpan(pos.span.toSynthetic)
603603
// patvars in for comprehensions share the pos of where the name was introduced
604604
val byPos = infos.pats.groupMap(uniformPos(_, _))((sym, pos) => sym)
605-
for (pos, syms) <- byPos if !syms.exists(_.hasAnnotation(defn.UnusedAnnot)) do
605+
for (pos, syms) <- byPos if pos.span.exists && !syms.exists(_.hasAnnotation(defn.UnusedAnnot)) do
606606
if !syms.exists(infos.refs(_)) then
607607
if !syms.exists(v => !v.isLocal && !v.is(Private)) then
608608
warnAt(pos)(UnusedSymbol.patVars)
@@ -663,7 +663,10 @@ object CheckUnused:
663663
val selector = textAt(sel.srcPos) // keep original
664664
s"$qual.$selector" // don't succumb to vagaries of show
665665
// begin actionable
666-
val sortedImps = infos.imps.keySet.nn.asScala.toArray.sortBy(_.srcPos.span.point) // sorted by pos
666+
val sortedImps = infos.imps.keySet.nn.asScala
667+
.filter(_.srcPos.span.exists) // extra caution
668+
.toArray
669+
.sortBy(_.srcPos.span.point) // sorted by pos, not sort in place
667670
var index = 0
668671
while index < sortedImps.length do
669672
val nextImport = sortedImps.indexSatisfying(from = index + 1)(_.isPrimaryClause) // next import statement
@@ -762,7 +765,11 @@ object CheckUnused:
762765
if ctx.settings.WunusedHas.imports || ctx.settings.WunusedHas.strictNoImplicitWarn then
763766
checkImports()
764767

765-
warnings.result().sortBy(_._2.span.point)
768+
def sortOrder(msgInfo: MessageInfo): Int =
769+
val srcPos = msgInfo._2
770+
if srcPos.span.exists then srcPos.span.point else 0
771+
772+
warnings.result().sortBy(sortOrder)
766773
end warnings
767774

768775
// Specific exclusions
@@ -879,8 +886,7 @@ object CheckUnused:
879886
extension (imp: Import)
880887
/** Is it the first import clause in a statement? `a.x` in `import a.x, b.{y, z}` */
881888
def isPrimaryClause(using Context): Boolean =
882-
val span = imp.srcPos.span
883-
span.start != span.point // primary clause starts at `import` keyword
889+
imp.srcPos.span.pointDelta > 0 // primary clause starts at `import` keyword with point at clause proper
884890

885891
/** Generated import of cases from enum companion. */
886892
def isGeneratedByEnum(using Context): Boolean =
@@ -902,7 +908,8 @@ object CheckUnused:
902908
else imp.expr.tpe.member(sel.name.toTermName).hasAltWith(_.symbol.isCanEqual)
903909

904910
extension (pos: SrcPos)
905-
def isZeroExtentSynthetic: Boolean = pos.span.isSynthetic && pos.span.start == pos.span.end
911+
def isZeroExtentSynthetic: Boolean = pos.span.isSynthetic && pos.span.isZeroExtent
912+
def isSynthetic: Boolean = pos.span.isSynthetic && pos.span.exists
906913

907914
extension [A <: AnyRef](arr: Array[A])
908915
// returns `until` if not satisfied

0 commit comments

Comments
 (0)