Skip to content

Commit

Permalink
Lint pattern varids which are backquotable
Browse files Browse the repository at this point in the history
For the `case x =>` where user intended to match
a value `x` in scope.
  • Loading branch information
som-snytt committed Mar 15, 2020
1 parent a5aeb41 commit 818aa90
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2019,7 +2019,7 @@ self =>
atPos(p.pos.start, p.pos.start, body.pos.end) {
val t = Bind(name, body)
body match {
case Ident(nme.WILDCARD) if settings.warnUnusedPatVars => t updateAttachment NoWarnAttachment
case Ident(nme.WILDCARD) if settings.warnUnusedPatVars || settings.warnPatternShadow => t updateAttachment NoWarnAttachment
case _ => t
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/compiler/scala/tools/nsc/settings/Warnings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ trait Warnings {
val ByNameImplicit = LintWarning("byname-implicit", "Block adapted by implicit with by-name parameter.")
val RecurseWithDefault = LintWarning("recurse-with-default", "Recursive call used default argument.")
val UnitSpecialization = LintWarning("unit-special", "Warn for specialization of Unit in parameter position.")
val PatternShadow = LintWarning("pattern-shadow", "Pattern variable id is also a term in scope.")

def allLintWarnings = values.toSeq.asInstanceOf[Seq[LintWarning]]
}
Expand Down Expand Up @@ -223,6 +224,7 @@ trait Warnings {
def warnByNameImplicit = lint contains ByNameImplicit
def warnRecurseWithDefault = lint contains RecurseWithDefault
def unitSpecialization = lint contains UnitSpecialization
def warnPatternShadow = lint contains PatternShadow

// The Xlint warning group.
val lint = MultiChoiceSetting(
Expand Down
3 changes: 3 additions & 0 deletions src/compiler/scala/tools/nsc/typechecker/Typers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4628,6 +4628,9 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
tree setSymbol sym setType sym.tpeHK

case Bind(name: TermName, body) =>
if (settings.warnPatternShadow && !tree.hasAttachment[NoWarnAttachment.type] && context.isNameInScope(name))
context.warning(tree.pos, s"Name $name is already in scope. Did you intend backquoted `$name`?", WarningCategory.OtherShadowing)

val sym =
if (tree.symbol != NoSymbol) tree.symbol
else context.owner.newValue(name, tree.pos)
Expand Down
6 changes: 6 additions & 0 deletions test/files/neg/t11850.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
t11850.scala:9: warning: Name x is already in scope. Did you intend backquoted `x`?
case x => 1 // warn
^
error: No warnings can be incurred under -Werror.
1 warning
1 error
15 changes: 15 additions & 0 deletions test/files/neg/t11850.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// scalac: -Werror -Xlint:pattern-shadow

trait T {
val x = 42

def f(i: Int) =
i match {
case `x` => 0 // presence of this case really obviates warning on the next?
case x => 1 // warn
}
def g(i: Int) =
i match {
case x @ _ => 1
}
}

0 comments on commit 818aa90

Please sign in to comment.