@@ -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
@@ -598,12 +598,12 @@ object CheckUnused:
598598 warnAt(pos)(UnusedSymbol .localDefs)
599599
600600 def checkPatvars () =
601- // convert the one non-synthetic span so all are comparable
601+ // convert the one non-synthetic span so all are comparable; filter NoSpan below
602602 def uniformPos (sym : Symbol , pos : SrcPos ): SrcPos =
603603 if pos.span.isSynthetic then pos else pos.sourcePos.withSpan(pos.span.toSynthetic)
604604 // patvars in for comprehensions share the pos of where the name was introduced
605605 val byPos = infos.pats.groupMap(uniformPos(_, _))((sym, pos) => sym)
606- for (pos, syms) <- byPos if ! syms.exists(_.hasAnnotation(defn.UnusedAnnot )) do
606+ for (pos, syms) <- byPos if pos.span.exists && ! syms.exists(_.hasAnnotation(defn.UnusedAnnot )) do
607607 if ! syms.exists(infos.refs(_)) then
608608 if ! syms.exists(v => ! v.isLocal && ! v.is(Private )) then
609609 warnAt(pos)(UnusedSymbol .patVars)
@@ -664,7 +664,10 @@ object CheckUnused:
664664 val selector = textAt(sel.srcPos) // keep original
665665 s " $qual. $selector" // don't succumb to vagaries of show
666666 // begin actionable
667- val sortedImps = infos.imps.keySet.nn.asScala.toArray.sortBy(_.srcPos.span.point) // sorted by pos
667+ val sortedImps = infos.imps.keySet.nn.asScala
668+ .filter(_.srcPos.span.exists) // extra caution
669+ .toArray
670+ .sortBy(_.srcPos.span.point) // sorted by pos, not sort in place
668671 var index = 0
669672 while index < sortedImps.length do
670673 val nextImport = sortedImps.indexSatisfying(from = index + 1 )(_.isPrimaryClause) // next import statement
@@ -763,7 +766,11 @@ object CheckUnused:
763766 if ctx.settings.WunusedHas .imports || ctx.settings.WunusedHas .strictNoImplicitWarn then
764767 checkImports()
765768
766- warnings.result().sortBy(_._2.span.point)
769+ def sortOrder (msgInfo : MessageInfo ): Int =
770+ val srcPos = msgInfo._2
771+ if srcPos.span.exists then srcPos.span.point else 0
772+
773+ warnings.result().sortBy(sortOrder)
767774 end warnings
768775
769776 // Specific exclusions
@@ -880,8 +887,7 @@ object CheckUnused:
880887 extension (imp : Import )
881888 /** Is it the first import clause in a statement? `a.x` in `import a.x, b.{y, z}` */
882889 def isPrimaryClause (using Context ): Boolean =
883- val span = imp.srcPos.span
884- span.start != span.point // primary clause starts at `import` keyword
890+ imp.srcPos.span.pointDelta > 0 // primary clause starts at `import` keyword with point at clause proper
885891
886892 /** Generated import of cases from enum companion. */
887893 def isGeneratedByEnum (using Context ): Boolean =
@@ -903,7 +909,8 @@ object CheckUnused:
903909 else imp.expr.tpe.member(sel.name.toTermName).hasAltWith(_.symbol.isCanEqual)
904910
905911 extension (pos : SrcPos )
906- def isZeroExtentSynthetic : Boolean = pos.span.isSynthetic && pos.span.start == pos.span.end
912+ def isZeroExtentSynthetic : Boolean = pos.span.isSynthetic && pos.span.isZeroExtent
913+ def isSynthetic : Boolean = pos.span.isSynthetic && pos.span.exists
907914
908915 extension [A <: AnyRef ](arr : Array [A ])
909916 // returns `until` if not satisfied
0 commit comments