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 Dec 15, 2023
1 parent 43aa816 commit d632c06
Show file tree
Hide file tree
Showing 80 changed files with 523 additions and 318 deletions.
2 changes: 1 addition & 1 deletion src/compiler/scala/reflect/reify/codegen/GenTrees.scala
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ trait GenTrees {
abort("free var local to the reifee, should have already been inlined by Metalevels: " + inlinedSymtab.symDef(sym))
state.symtab ++= inlinedSymtab
rtree
case tree =>
case _ =>
val migrated = Apply(Select(splicee, nme.in), List(Ident(nme.MIRROR_SHORT)))
Select(migrated, nme.tree)
}
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/scala/reflect/reify/phases/Metalevels.scala
Original file line number Diff line number Diff line change
Expand Up @@ -128,13 +128,13 @@ trait Metalevels {
// A: nothing. reified trees give us problems because they sometimes create dimensional rifts as described above
// to the contrast, reified types (i.e. synthetic typetags materialized by Implicits.scala) always stay on the same metalevel as their enclosing code
override def transform(tree: Tree): Tree = tree match {
case TreeSplice(ReifiedTree(universe, mirror, symtab, rtree, tpe, rtpe, concrete)) =>
case TreeSplice(ReifiedTree(_universe, _mirror, symtab, rtree, tpe, rtpe, _concrete)) =>
if (reifyDebug) println("entering inlineable splice: " + tree)
val inlinees = symtab.syms filter (_.isLocalToReifee)
inlinees foreach (inlinee => symtab.symAliases(inlinee) foreach (alias => inlineableBindings(alias) = symtab.symBinding(inlinee)))
val symtab1 = symtab -- inlinees
if (reifyDebug) println("trimmed %s inlineable free defs from its symbol table: %s".format(inlinees.length, inlinees map (inlinee => symtab.symName(inlinee)) mkString(", ")))
withinSplice { super.transform(TreeSplice(ReifiedTree(universe, mirror, symtab1, rtree, tpe, rtpe, concrete))) }
withinSplice { super.transform(TreeSplice(ReifiedTree(_universe, _mirror, symtab1, rtree, tpe, rtpe, _concrete))) }
case TreeSplice(splicee) =>
if (reifyDebug) println("entering splice: " + splicee)
val breaches = splicee filter (sub => sub.hasSymbolField && sub.symbol != NoSymbol && sub.symbol.metalevel > 0)
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/scala/reflect/reify/phases/Reshape.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import scala.annotation.tailrec
import scala.tools.nsc.symtab.Flags._

trait Reshape {
self: Reifier =>
this: Reifier =>

import global._
import definitions._
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/scala/reflect/reify/utils/Extractors.scala
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,8 @@ trait Extractors {

object FreeRef {
def unapply(tree: Tree): Option[(Tree, TermName)] = tree match {
case Apply(Select(Select(Select(uref @ Ident(_), internal), rs), mkIdent), List(Ident(name: TermName)))
if internal == nme.internal && rs == nme.reificationSupport && mkIdent == nme.mkIdent && name.startsWith(nme.REIFY_FREE_PREFIX) =>
case Apply(Select(Select(Select(uref @ Ident(_), nme.internal), nme.reificationSupport), nme.mkIdent), List(Ident(name: TermName)))
if name.startsWith(nme.REIFY_FREE_PREFIX) =>
Some((uref, name))
case _ =>
None
Expand Down
10 changes: 5 additions & 5 deletions src/compiler/scala/tools/nsc/ast/DocComments.scala
Original file line number Diff line number Diff line change
Expand Up @@ -258,9 +258,9 @@ trait DocComments { self: Global =>

def sectionString(param: String, paramMap: Map[String, (Int, Int)]): String =
paramMap.get(param) match {
case Some(section) =>
case Some(_section) =>
// Cleanup the section tag and parameter
val sectionTextBounds = extractSectionText(parent, section)
val sectionTextBounds = extractSectionText(parent, _section)
cleanupSectionText(parent.substring(sectionTextBounds._1, sectionTextBounds._2))
case None =>
reporter.echo(sym.pos, "The \"" + getSectionHeader + "\" annotation of the " + sym +
Expand Down Expand Up @@ -458,7 +458,7 @@ trait DocComments { self: Global =>
def getSite(name: Name): Type = {
def findIn(sites: List[Symbol]): Type = sites match {
case List() => NoType
case site :: sites1 => select(site.thisType, name, findIn(sites1))
case h :: sites1 => select(h.thisType, name, findIn(sites1))
}
// Previously, searching was taking place *only* in the current package and in the root package
// now we're looking for it everywhere in the hierarchy, so we'll be able to link variable expansions like
Expand Down Expand Up @@ -543,8 +543,8 @@ trait DocComments { self: Global =>

val substAliases = new TypeMap {
def apply(tp: Type) = mapOver(tp) match {
case tp1 @ TypeRef(pre, sym, args) if (sym.name.length > 1 && sym.name.startChar == '$') =>
subst(sym, aliases, aliasExpansions) match {
case tp1 @ TypeRef(_, sym0, args) if (sym0.name.length > 1 && sym0.name.startChar == '$') =>
subst(sym0, aliases, aliasExpansions) match {
case (TypeRef(pre1, sym1, _), canNormalize) =>
val tpe = typeRef(pre1, sym1, args)
if (canNormalize) tpe.normalize else tpe
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/scala/tools/nsc/ast/Trees.scala
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,9 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
override protected def xtransform(transformer: super.Transformer, tree: Tree): Tree = tree match {
case DocDef(comment, definition) =>
transformer.treeCopy.DocDef(tree, comment, transformer.transform(definition))
case SelectFromArray(qualifier, selector, erasure) =>
case SelectFromArray(qualifier, selector, erasure0) =>
transformer.treeCopy.SelectFromArray(
tree, transformer.transform(qualifier), selector, erasure)
tree, transformer.transform(qualifier), selector, erasure0)
case InjectDerivedValue(arg) =>
transformer.treeCopy.InjectDerivedValue(
tree, transformer.transform(arg))
Expand Down
11 changes: 6 additions & 5 deletions src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ self =>
if (syntaxErrors.isEmpty) firstTry
else in.healBraces() match {
case Nil => showSyntaxErrors() ; firstTry
case patches => withPatches(patches).parse()
case patches1 => withPatches(patches1).parse()
}
}
}
Expand Down Expand Up @@ -2225,7 +2225,7 @@ self =>
else 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 Expand Up @@ -3395,9 +3395,10 @@ self =>
* }}}
* @param isPre specifies whether in early initializer (true) or not (false)
*/
def templateBody(isPre: Boolean) = inBraces(templateStatSeq(isPre = isPre)) match {
case (self, Nil) => (self, EmptyTree.asList)
case result => result
def templateBody(isPre: Boolean) = {
val selfBody = inBraces(templateStatSeq(isPre = isPre))
if (selfBody._2.isEmpty) selfBody.copy(_2 = EmptyTree.asList)
else selfBody
}
def templateBodyOpt(parenMeansSyntaxError: Boolean): (ValDef, List[Tree]) = {
newLineOptWhenFollowedBy(LBRACE)
Expand Down
6 changes: 3 additions & 3 deletions src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,10 @@ abstract class TreeBuilder {
/** Create tree for a pattern alternative */
def makeAlternative(ts: List[Tree]): Tree = {
def alternatives(t: Tree): List[Tree] = t match {
case Alternative(ts) => ts
case _ => List(t)
case Alternative(alts) => alts
case _ => List(t)
}
Alternative(ts flatMap alternatives)
Alternative(ts.flatMap(alternatives))
}

/** Create tree for case definition <case pat if guard => rhs> */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -769,7 +769,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
else inlineAnnotatedCallsites += m
case _ =>
} else t match {
case Apply(fun, _) => recordInlineAnnotated(fun)
case Apply(tfun, _) => recordInlineAnnotated(tfun)
case _ =>
}
}
Expand Down
22 changes: 11 additions & 11 deletions src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala
Original file line number Diff line number Diff line change
Expand Up @@ -137,19 +137,19 @@ abstract class BTypesFromSymbols[G <: Global](val global: G) extends BTypes {
MethodBType(paramBTypes, resultType)
}

def bootstrapMethodArg(t: Constant, pos: Position): AnyRef = t match {
case Constant(mt: Type) =>
def bootstrapMethodArg(t: Constant, pos: Position): AnyRef = t.value match {
case mt: Type =>
transformedType(mt) match {
case mt1: MethodType =>
methodBTypeFromMethodType(mt1, isConstructor = false).toASMType
case t =>
typeToBType(t).toASMType
case transformed =>
typeToBType(transformed).toASMType
}
case c @ Constant(sym: Symbol) if sym.owner.isJavaDefined && sym.isStaticMember => staticHandleFromSymbol(sym)
case c @ Constant(sym: Symbol) => handleFromMethodSymbol(sym)
case c @ Constant(value: String) => value
case c @ Constant(value) if c.isNonUnitAnyVal => c.value.asInstanceOf[AnyRef]
case _ => reporter.error(pos, "Unable to convert static argument of ApplyDynamic into a classfile constant: " + t); null
case sym: Symbol if sym.owner.isJavaDefined && sym.isStaticMember => staticHandleFromSymbol(sym)
case sym: Symbol => handleFromMethodSymbol(sym)
case value: String => value
case value if t.isNonUnitAnyVal => value.asInstanceOf[AnyRef]
case _ => reporter.error(pos, s"Unable to convert static argument of ApplyDynamic into a classfile constant: $t"); null
}

def staticHandleFromSymbol(sym: Symbol): asm.Handle = {
Expand Down Expand Up @@ -233,8 +233,8 @@ abstract class BTypesFromSymbols[G <: Global](val global: G) extends BTypes {
case SingleType(_, sym) => primitiveOrClassToBType(sym)
case ConstantType(_) => typeToBType(t.underlying)
case RefinedType(parents, _) => parents.map(typeToBType(_).asClassBType).reduceLeft((a, b) => a.jvmWiseLUB(b).get)
case AnnotatedType(_, t) => typeToBType(t)
case ExistentialType(_, t) => typeToBType(t)
case AnnotatedType(_, at) => typeToBType(at)
case ExistentialType(_, et) => typeToBType(et)
case x => throw new MatchError(x)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,12 +196,11 @@ final class FileBasedCache[K, T] {
private case class Entry(k: K, stamps: Seq[Stamp], t: T) {
val referenceCount: AtomicInteger = new AtomicInteger(1)
var timerTask: TimerTask = null
def cancelTimer(): Unit = {
def cancelTimer(): Unit =
timerTask match {
case null =>
case t => t.cancel()
case task => task.cancel()
}
}
}
private val cache = collection.mutable.Map.empty[(K, Seq[Path]), Entry]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -811,7 +811,7 @@ class MutableSettings(val errorFn: String => Unit, val pathFactory: PathFactory)
def loop(seen: List[String], args: List[String]): (List[String], List[String]) = args match {
case Optionlike() :: _ if halting => (seen, args)
case "help" :: rest if helpText.isDefined => sawHelp = true ; loop(seen, rest)
case arg :: rest => loop(arg :: seen, rest)
case h :: rest => loop(h :: seen, rest)
case Nil => (seen, Nil)
}
val (seen, rest) = loop(Nil, args)
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 @@ -217,6 +217,7 @@ trait Warnings {
val ArgDiscard = LintWarning("arg-discard", "-Wvalue-discard for adapted arguments.")
val IntDivToFloat = LintWarning("int-div-to-float", "Warn when an integer division is converted (widened) to floating point: `(someInt / 2): Double`.")
val NamedBooleans = LintWarning("named-booleans", "Boolean literals should be named args unless param is @deprecatedName.")
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 @@ -254,6 +255,7 @@ trait Warnings {
def lintArgDiscard = lint.contains(ArgDiscard)
def lintIntDivToFloat = lint.contains(IntDivToFloat)
def lintNamedBooleans = lint.contains(NamedBooleans)
def warnPatternShadow = lint.contains(PatternShadow)

// The Xlint warning group.
val lint = MultiChoiceSetting(
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/scala/tools/nsc/symtab/BrowsingLoaders.scala
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ abstract class BrowsingLoaders extends GlobalSymbolLoaders {
}

override def traverse(tree: Tree): Unit = tree match {
case PackageDef(pkg, body) =>
inPackagePrefix(pkg) { body foreach traverse }
case PackageDef(pkg, pkgbody) =>
inPackagePrefix(pkg) { pkgbody.foreach(traverse) }

case ClassDef(_, name, _, _) =>
if (packagePrefix == root.fullName) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -648,13 +648,13 @@ abstract class ClassfileParser(reader: ReusableInstance[ReusableDataReader]) {
case BOOL_TAG => BooleanTpe
case 'L' =>
def processInner(tp: Type): Type = tp match {
case TypeRef(pre, sym, args) if (!sym.isStatic) =>
typeRef(processInner(pre.widen), sym, args)
case TypeRef(pre, tsym, args) if !tsym.isStatic =>
typeRef(processInner(pre.widen), tsym, args)
case _ =>
tp
}
def processClassType(tp: Type): Type = tp match {
case TypeRef(pre, classSym, args) =>
case TypeRef(pre, tsym, args) =>
val existentials = new ListBuffer[Symbol]()
if (sig.charAt(index) == '<') {
accept('<')
Expand Down Expand Up @@ -684,15 +684,15 @@ abstract class ClassfileParser(reader: ReusableInstance[ReusableDataReader]) {
}
accept('>')
assert(xs.length > 0, tp)
debuglogResult("new existential")(newExistentialType(existentials.toList, typeRef(pre, classSym, xs.toList)))
debuglogResult("new existential")(newExistentialType(existentials.toList, typeRef(pre, tsym, xs.toList)))
}
// isMonomorphicType is false if the info is incomplete, as it usually is here
// so have to check unsafeTypeParams.isEmpty before worrying about raw type case below,
// or we'll create a boatload of needless existentials.
else if (classSym.isMonomorphicType || classSym.unsafeTypeParams.isEmpty) tp
else debuglogResult(s"raw type from $classSym") {
else if (tsym.isMonomorphicType || tsym.unsafeTypeParams.isEmpty) tp
else debuglogResult(s"raw type from $tsym") {
// raw type - existentially quantify all type parameters
classExistentialType(pre, classSym)
classExistentialType(pre, tsym)
}
case tp =>
assert(sig.charAt(index) != '<', s"sig=$sig, index=$index, tp=$tp")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,7 @@ abstract class Pickler extends SubComponent {
case StringTag => writeRef(newTermName(c.stringValue))
case ClazzTag => writeRef(c.typeValue)
case EnumTag => writeRef(c.symbolValue)
case tag => if (ByteTag <= tag && tag <= LongTag) writeLong(c.longValue)
case ctag => if (ByteTag <= ctag && ctag <= LongTag) writeLong(c.longValue)
}

def writeModifiers(mods: Modifiers): Unit = {
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/scala/tools/nsc/tasty/bridge/TypeOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ trait TypeOps { self: TastyUniverse =>
if (self.typeSymbol.isSubClass(from)) {
def elemType(tp: Type): Type = tp.dealiasWiden match {
// case tp: AndOrType => tp.derivedAndOrType(elemType(tp.tp1), elemType(tp.tp2))
case tp: u.RefinedType => u.intersectionType(tp.parents.map(elemType))
case tdw: u.RefinedType => u.intersectionType(tdw.parents.map(elemType))
case _ => tp.baseType(from).typeArgs.head
}
val arg = elemType(self)
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -493,13 +493,13 @@ abstract class ExplicitOuter extends InfoTransform
case TypeApply(fun, targs) =>
val rewriteTypeToExplicitOuter = new TypeMap { typeMap =>
def apply(tp: Type) = tp match {
case ThisType(sym) if sym != currentClass && !(sym.hasModuleFlag && sym.isStatic) =>
case ThisType(tsym) if tsym != currentClass && !(tsym.hasModuleFlag && tsym.isStatic) =>
var cls = currentClass
var tpe = cls.thisType
do {
tpe = singleType(tpe, outerAccessor(cls))
cls = cls.outerClass
} while (cls != NoSymbol && sym != cls)
} while (cls != NoSymbol && tsym != cls)
tpe.mapOver(typeMap)
case tp => tp.mapOver(typeMap)
}
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/scala/tools/nsc/transform/PostErasure.scala
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ trait PostErasure extends InfoTransform with TypingTransformers with scala.refle
case AsInstanceOf(v, tpe) if v.tpe <:< tpe => finish(v) // x.asInstanceOf[X] ==> x
case ValueClass.BoxAndUnbox(v) => finish(v) // (new B(v)).unbox ==> v
case ValueClass.BoxAndCompare(v1, op, v2) => binop(v1, op, v2) // new B(v1) == new B(v2) ==> v1 == v2
case tree => tree
case transformed => transformed
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1744,9 +1744,9 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
treeCopy.PackageDef(tree, pid, transformStats(stats ::: specMembers, symbol.moduleClass))
}

case Template(parents, self, body) =>
case Template(parents, self, tbody) =>
def transformTemplate = {
val specMembers = makeSpecializedMembers(tree.symbol.enclClass) ::: (implSpecClasses(body) map localTyper.typed)
val specMembers = makeSpecializedMembers(tree.symbol.enclClass) ::: (implSpecClasses(tbody) map localTyper.typed)
if (!symbol.isPackageClass)
new CollectMethodBodies()(tree)
// currentOwner.info.parents.map(tpe => TypeTree(tpe) setPos parents.head.pos)
Expand All @@ -1756,7 +1756,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
case _ => TypeTree(tpe) setPos parent.pos
}
)
treeCopy.Template(tree, parents1, self, atOwner(currentOwner)(transformTrees(body ::: specMembers)))
treeCopy.Template(tree, parents1, self, atOwner(currentOwner)(transformTrees(tbody ::: specMembers)))
}
transformTemplate

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,9 @@ trait TypingTransformers {
expanded += t
}
def expandExpr(): Tree = transformedExpr match {
case blk @ Block(stats, expr) if blk.attachments.containsElement(ThicketAttachment) =>
stats.foreach { s => if (s != EmptyTree) expanded += s }
expr
case blk @ Block(xstats, xexpr) if blk.attachments.containsElement(ThicketAttachment) =>
xstats.foreach { s => if (s != EmptyTree) expanded += s }
xexpr
case t =>
t
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ private[async] trait AnfTransform extends TransformUtils {
case ld: LabelDef if ld.tpe.typeSymbol == definitions.UnitClass =>
currentStats += ld
literalUnit
case expr => expr
case s => s
}

case ValDef(mods, name, tpt, rhs) => atOwner(tree.symbol) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,7 @@ abstract class AsyncPhase extends Transform with TypingTransformers with AnfTran
currentTransformState = saved
}
}
case tree =>
tree
case transformed => transformed
}

private def asyncTransform(asyncBody: Tree): (Tree, List[Tree]) = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ trait ExprBuilder extends TransformUtils with AsyncAnalysis {
Block(StateTransitionStyle.UpdateAndContinue.trees(state, new StateSet), typedCurrentPos(literalUnit)).setType(definitions.UnitTpe)
case None => ap
}
case tree => tree
case transformed => transformed
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ trait MatchTranslation {
def pt = unbound match {
case Star(tpt) => seqType(tpt.tpe)
case TypeBound(tpe) => tpe
case tree => tree.tpe
case t => t.tpe
}

object SymbolAndTypeBound {
Expand Down

0 comments on commit d632c06

Please sign in to comment.