Skip to content

Commit 9f53f2d

Browse files
som-snytttgodzik
authored andcommitted
Check span.exists where necessary
1 parent f2519e4 commit 9f53f2d

File tree

1 file changed

+15
-8
lines changed

1 file changed

+15
-8
lines changed

compiler/src/dotty/tools/dotc/transform/CheckUnused.scala

+15-8
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
@@ -592,12 +592,12 @@ object CheckUnused:
592592
warnAt(pos)(UnusedSymbol.localDefs)
593593

594594
def checkPatvars() =
595-
// convert the one non-synthetic span so all are comparable
595+
// convert the one non-synthetic span so all are comparable; filter NoSpan below
596596
def uniformPos(sym: Symbol, pos: SrcPos): SrcPos =
597597
if pos.span.isSynthetic then pos else pos.sourcePos.withSpan(pos.span.toSynthetic)
598598
// patvars in for comprehensions share the pos of where the name was introduced
599599
val byPos = infos.pats.groupMap(uniformPos(_, _))((sym, pos) => sym)
600-
for (pos, syms) <- byPos if !syms.exists(_.hasAnnotation(defn.UnusedAnnot)) do
600+
for (pos, syms) <- byPos if pos.span.exists && !syms.exists(_.hasAnnotation(defn.UnusedAnnot)) do
601601
if !syms.exists(infos.refs(_)) then
602602
if !syms.exists(v => !v.isLocal && !v.is(Private)) then
603603
warnAt(pos)(UnusedSymbol.patVars)
@@ -658,7 +658,10 @@ object CheckUnused:
658658
val selector = textAt(sel.srcPos) // keep original
659659
s"$qual.$selector" // don't succumb to vagaries of show
660660
// begin actionable
661-
val sortedImps = infos.imps.keySet.nn.asScala.toArray.sortBy(_.srcPos.span.point) // sorted by pos
661+
val sortedImps = infos.imps.keySet.nn.asScala
662+
.filter(_.srcPos.span.exists) // extra caution
663+
.toArray
664+
.sortBy(_.srcPos.span.point) // sorted by pos, not sort in place
662665
var index = 0
663666
while index < sortedImps.length do
664667
val nextImport = sortedImps.indexSatisfying(from = index + 1)(_.isPrimaryClause) // next import statement
@@ -757,7 +760,11 @@ object CheckUnused:
757760
if ctx.settings.WunusedHas.imports || ctx.settings.WunusedHas.strictNoImplicitWarn then
758761
checkImports()
759762

760-
warnings.result().sortBy(_._2.span.point)
763+
def sortOrder(msgInfo: MessageInfo): Int =
764+
val srcPos = msgInfo._2
765+
if srcPos.span.exists then srcPos.span.point else 0
766+
767+
warnings.result().sortBy(sortOrder)
761768
end warnings
762769

763770
// Specific exclusions
@@ -881,8 +888,7 @@ object CheckUnused:
881888
extension (imp: Import)
882889
/** Is it the first import clause in a statement? `a.x` in `import a.x, b.{y, z}` */
883890
def isPrimaryClause(using Context): Boolean =
884-
val span = imp.srcPos.span
885-
span.start != span.point // primary clause starts at `import` keyword
891+
imp.srcPos.span.pointDelta > 0 // primary clause starts at `import` keyword with point at clause proper
886892

887893
/** Generated import of cases from enum companion. */
888894
def isGeneratedByEnum(using Context): Boolean =
@@ -905,6 +911,7 @@ object CheckUnused:
905911

906912
extension (pos: SrcPos)
907913
def isZeroExtentSynthetic: Boolean = pos.span.isSynthetic && pos.span.isZeroExtent
914+
def isSynthetic: Boolean = pos.span.isSynthetic && pos.span.exists
908915

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

0 commit comments

Comments
 (0)