Skip to content

Commit

Permalink
Add line number if not a member
Browse files Browse the repository at this point in the history
  • Loading branch information
som-snytt committed Jan 9, 2024
1 parent d250efa commit 686bcdf
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 15 deletions.
15 changes: 10 additions & 5 deletions src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2085,22 +2085,25 @@ abstract class RefChecks extends Transform {
case _ => super.traverse(t)
}
case bind @ Bind(name, _) =>
def richLocation(sym: Symbol): String = sym.ownsString match {
case "" => val n = sym.pos.line; if (n > 0) s"$sym at line $n" else sym.fullLocationString
case owns => s"$sym in $owns"
}
for (shade <- bind.getAndRemoveAttachment[PatShadowAttachment]) {
val shadowed = shade.shadowed
if (!absolved.contains(name) && !bind.symbol.hasTransOwner(shadowed.accessedOrSelf) && checkShadowed(shadowed)(selSym))
refchecksWarning(bind.pos, s"Name $name is already introduced in an enclosing scope as ${shadowed.fullLocationString}. Did you intend to match it using backquoted `$name`?", WarningCategory.OtherShadowing)
refchecksWarning(bind.pos, s"Name $name is already introduced in an enclosing scope as ${richLocation(shadowed)}. Did you intend to match it using backquoted `$name`?", WarningCategory.OtherShadowing)

}
case _ => super.traverse(t)
}
}
traverser.traverse(p)
}
def checkAllCases(): Unit = for (cdef <- cases) check(cdef.pat, selectorSymbol)
// check the patterns for unfriendly shadowing, patvars bearing PatShadowAttachment
def checkShadowingPatternVars(): Unit =
selector match {
// or for `(x, y) match case p(x, y) =>` check the corresponding args (whether they are aliases)
// or for `(x, y) match case p(x, y) =>` check the corresponding args
case treeInfo.Applied(Select(core, nme.apply), _, tupleArgs :: Nil) if isTupleSymbol(core.symbol.companion) =>
for (cdef <- cases)
cdef.pat match {
Expand All @@ -2110,11 +2113,13 @@ abstract class RefChecks extends Transform {
foreach2(args, tupleArgs)((arg, sel) => check(arg, notNull(sel.symbol)))
case p => check(p, selectorSymbol)
}
// or for `tp.dealiased match case tp =>` check `tp` if it looks like a derived value, but not `this.x` or `x.asInstanceOf`
case treeInfo.Applied(Select(core, _), _, _) if core.symbol != null && !core.symbol.isThisSym && selector.tpe <:< core.tpe.widen =>
for (cdef <- cases) check(cdef.pat, core.symbol)
case _ => checkAllCases()
case _ =>
for (cdef <- cases) check(cdef.pat, selectorSymbol)
}
checkShadowingPatternVars()
if (settings.warnPatternShadow) checkShadowingPatternVars()
tree
case _ => tree
}
Expand Down
13 changes: 7 additions & 6 deletions src/reflect/scala/reflect/internal/Symbols.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2719,6 +2719,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
isPrimaryConstructor)) ("primary constructor", "constructor", "PCTOR")
else if (isClassConstructor) ("constructor", "constructor", "CTOR")
else if (isMethod) ("method", "method", "METH")
//else if (isValueParameter) ("value parameter", "parameter", "VAL")
else if (isTerm) ("value", "value", "VAL")
else ("", "", "???")

Expand Down Expand Up @@ -2813,8 +2814,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* for backward compatibility reasons.
*/
def locationString: String = ownsString match {
case "" => ""
case s => " in " + s
case "" => ""
case s => s" in $s"
}
def fullLocationString: String = toString + locationString
def signatureString: String = if (hasRawInfo) infoString(rawInfo) else "<_>"
Expand Down Expand Up @@ -2857,8 +2858,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}

private def defStringCompose(infoString: String) = compose(
flagString,
keyString,
compose(flagString, keyString),
varianceString + nameString + infoString + flagsExplanationString
)

Expand All @@ -2877,8 +2877,9 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*/
def defStringSeenAs(info: Type) = defStringCompose(infoString(info))

/** Concatenate strings separated by spaces */
private def compose(ss: String*) = ss filter (_ != "") mkString " "
/** Concatenate non-empty strings separated by a space. */
private def compose(x: String, y: String): String =
if (x.isEmpty) y else if (y.isEmpty) x else s"$x $y"

def isSingletonExistential: Boolean =
nme.isSingletonName(name)
Expand Down
11 changes: 7 additions & 4 deletions test/files/neg/t11850.check
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ t11850.scala:9: warning: Name x is already introduced in an enclosing scope as v
t11850.scala:28: warning: Name x is already introduced in an enclosing scope as value x in class CT. Did you intend to match it using backquoted `x`?
case x => 1 // warn
^
t11850.scala:118: warning: Name x is already introduced in an enclosing scope as value x. Did you intend to match it using backquoted `x`?
t11850.scala:118: warning: Name x is already introduced in an enclosing scope as value x at line 117. Did you intend to match it using backquoted `x`?
case Y(x, y) => x+y // only allow 1-1
^
t11850.scala:118: warning: Name y is already introduced in an enclosing scope as value y. Did you intend to match it using backquoted `y`?
t11850.scala:118: warning: Name y is already introduced in an enclosing scope as value y at line 117. Did you intend to match it using backquoted `y`?
case Y(x, y) => x+y // only allow 1-1
^
t11850.scala:125: warning: Name self is already introduced in an enclosing scope as value self in class Selfie. Did you intend to match it using backquoted `self`?
Expand All @@ -16,12 +16,15 @@ t11850.scala:125: warning: Name self is already introduced in an enclosing scope
t11850.scala:170: warning: Name _1 is already introduced in an enclosing scope as value _1 in class weird but true. Did you intend to match it using backquoted `_1`?
case (_1, 27) => 3 // briefly did not warn as param name
^
t11850.scala:187: warning: Name x is already introduced in an enclosing scope as value x. Did you intend to match it using backquoted `x`?
t11850.scala:187: warning: Name x is already introduced in an enclosing scope as value x at line 186. Did you intend to match it using backquoted `x`?
case x => x.toString
^
t11850.scala:203: warning: Name c is already introduced in an enclosing scope as value c in class pattern matches occasionally appear in pattern-matching anonymous functions. Did you intend to match it using backquoted `c`?
def f = c.collect { case c if c.flag => c.toString }
^
t11850.scala:212: warning: Name x is already introduced in an enclosing scope as object x in object is it worth qualifying what kind of term. Did you intend to match it using backquoted `x`?
case x => 1
^
error: No warnings can be incurred under -Werror.
8 warnings
9 warnings
1 error
10 changes: 10 additions & 0 deletions test/files/neg/t11850.scala
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,13 @@ class `pattern matches occasionally appear in pattern-matching anonymous functio
val c = Collector()
def f = c.collect { case c if c.flag => c.toString }
}
object `is it worth qualifying what kind of term` {
trait T
object x extends T

def f(t: T) =
t match {
case `x` => 0
case x => 1
}
}

0 comments on commit 686bcdf

Please sign in to comment.