Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable stricter pattern binding warnings by default #14294

Merged
merged 12 commits into from
May 17, 2022
10 changes: 5 additions & 5 deletions compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
// but I was able to derrive it by reading
// AbstractValidatingLambdaMetafactory.validateMetafactoryArgs

val DesugaredSelect(prefix, _) = fun
val DesugaredSelect(prefix, _) = fun: @unchecked
genLoad(prefix)
}

Expand Down Expand Up @@ -725,7 +725,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
lineNumber(app)
app match {
case Apply(_, args) if app.symbol eq defn.newArrayMethod =>
val List(elemClaz, Literal(c: Constant), ArrayValue(_, dims)) = args
val List(elemClaz, Literal(c: Constant), ArrayValue(_, dims)) = args: @unchecked

generatedType = toTypeKind(c.typeValue)
mkArrayConstructorCall(generatedType.asArrayBType, app, dims)
Expand Down Expand Up @@ -802,7 +802,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
if (invokeStyle.hasInstance) genLoadQualifier(fun)
genLoadArguments(args, paramTKs(app))

val DesugaredSelect(qual, name) = fun // fun is a Select, also checked in genLoadQualifier
val DesugaredSelect(qual, name) = fun: @unchecked // fun is a Select, also checked in genLoadQualifier
val isArrayClone = name == nme.clone_ && qual.tpe.widen.isInstanceOf[JavaArrayType]
if (isArrayClone) {
// Special-case Array.clone, introduced in 36ef60e. The goal is to generate this call
Expand Down Expand Up @@ -845,7 +845,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
} // end of genApply()

private def genArrayValue(av: tpd.JavaSeqLiteral): BType = {
val ArrayValue(tpt, elems) = av
val ArrayValue(tpt, elems) = av: @unchecked

lineNumber(av)
genArray(elems, tpt)
Expand Down Expand Up @@ -1530,7 +1530,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
import ScalaPrimitivesOps.{ ZNOT, ZAND, ZOR, EQ }

// lhs and rhs of test
lazy val DesugaredSelect(lhs, _) = fun
lazy val DesugaredSelect(lhs, _) = fun: @unchecked
val rhs = if (args.isEmpty) tpd.EmptyTree else args.head // args.isEmpty only for ZNOT

def genZandOrZor(and: Boolean): Unit = {
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
// sorting ensures nested classes are listed after their enclosing class thus satisfying the Eclipse Java compiler
for (nestedClass <- allNestedClasses.sortBy(_.internalName.toString)) {
// Extract the innerClassEntry - we know it exists, enclosingNestedClassesChain only returns nested classes.
val Some(e) = nestedClass.innerClassAttributeEntry
val Some(e) = nestedClass.innerClassAttributeEntry: @unchecked
jclass.visitInnerClass(e.name, e.outerName, e.innerName, e.flags)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -689,7 +689,7 @@ trait BCodeSkelBuilder extends BCodeHelpers {
val origSym = dd.symbol.asTerm
val newSym = makeStatifiedDefSymbol(origSym, origSym.name)
tpd.DefDef(newSym, { paramRefss =>
val selfParamRef :: regularParamRefs = paramRefss.head
val selfParamRef :: regularParamRefs = paramRefss.head: @unchecked
val enclosingClass = origSym.owner.asClass
new TreeTypeMap(
typeMap = _.substThis(enclosingClass, selfParamRef.symbol.termRef)
Expand Down
28 changes: 14 additions & 14 deletions compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1025,7 +1025,7 @@ class JSCodeGen()(using genCtx: Context) {
*/

val (primaryTree :: Nil, secondaryTrees) =
constructorTrees.partition(_.symbol.isPrimaryConstructor)
constructorTrees.partition(_.symbol.isPrimaryConstructor): @unchecked

val primaryCtor = genPrimaryJSClassCtor(primaryTree)
val secondaryCtors = secondaryTrees.map(genSecondaryJSClassCtor(_))
Expand Down Expand Up @@ -1106,7 +1106,7 @@ class JSCodeGen()(using genCtx: Context) {

private def genPrimaryJSClassCtor(dd: DefDef): PrimaryJSCtor = {
val sym = dd.symbol
val Block(stats, _) = dd.rhs
val Block(stats, _) = dd.rhs: @unchecked
assert(sym.isPrimaryConstructor, s"called with non-primary ctor: $sym")

var jsSuperCall: Option[js.JSSuperConstructorCall] = None
Expand Down Expand Up @@ -1179,7 +1179,7 @@ class JSCodeGen()(using genCtx: Context) {

assert(thisCall.isDefined,
i"could not find the this() call in secondary JS constructor at ${dd.sourcePos}:\n${stats.map(_.show).mkString("\n")}")
val Some((targetCtor, ctorArgs)) = thisCall
val Some((targetCtor, ctorArgs)) = thisCall: @unchecked

new SplitSecondaryJSCtor(sym, genParamsAndInfo(sym, dd.paramss),
beforeThisCall.result(), targetCtor, ctorArgs, afterThisCall.result())
Expand Down Expand Up @@ -2139,7 +2139,7 @@ class JSCodeGen()(using genCtx: Context) {
*/
private def genSuperCall(tree: Apply, isStat: Boolean): js.Tree = {
implicit val pos = tree.span
val Apply(fun @ Select(sup @ Super(qual, _), _), args) = tree
val Apply(fun @ Select(sup @ Super(qual, _), _), args) = tree: @unchecked
val sym = fun.symbol

if (sym == defn.Any_getClass) {
Expand Down Expand Up @@ -2180,7 +2180,7 @@ class JSCodeGen()(using genCtx: Context) {
private def genApplyNew(tree: Apply): js.Tree = {
implicit val pos: SourcePosition = tree.sourcePos

val Apply(fun @ Select(New(tpt), nme.CONSTRUCTOR), args) = tree
val Apply(fun @ Select(New(tpt), nme.CONSTRUCTOR), args) = tree: @unchecked
val ctor = fun.symbol
val tpe = tpt.tpe

Expand Down Expand Up @@ -2229,7 +2229,7 @@ class JSCodeGen()(using genCtx: Context) {
acquireContextualJSClassValue { jsClassValue =>
implicit val pos: Position = tree.span

val Apply(fun @ Select(New(tpt), _), args) = tree
val Apply(fun @ Select(New(tpt), _), args) = tree: @unchecked
val cls = tpt.tpe.typeSymbol
val ctor = fun.symbol

Expand Down Expand Up @@ -2898,7 +2898,7 @@ class JSCodeGen()(using genCtx: Context) {

implicit val pos = tree.span

val Apply(fun, args) = tree
val Apply(fun, args) = tree: @unchecked
val arrayObj = qualifierOf(fun)

val genArray = genExpr(arrayObj)
Expand Down Expand Up @@ -3167,7 +3167,7 @@ class JSCodeGen()(using genCtx: Context) {
private def genJSSuperCall(tree: Apply, isStat: Boolean): js.Tree = {
acquireContextualJSClassValue { explicitJSSuperClassValue =>
implicit val pos = tree.span
val Apply(fun @ Select(sup @ Super(qual, _), _), args) = tree
val Apply(fun @ Select(sup @ Super(qual, _), _), args) = tree: @unchecked
val sym = fun.symbol

val genReceiver = genExpr(qual)
Expand Down Expand Up @@ -3242,7 +3242,7 @@ class JSCodeGen()(using genCtx: Context) {
/** Gen JS code for a switch-`Match`, which is translated into an IR `js.Match`. */
def genMatch(tree: Tree, isStat: Boolean): js.Tree = {
implicit val pos = tree.span
val Match(selector, cases) = tree
val Match(selector, cases) = tree: @unchecked

def abortMatch(msg: String): Nothing =
throw new FatalError(s"$msg in switch-like pattern match at ${tree.span}: $tree")
Expand Down Expand Up @@ -3441,7 +3441,7 @@ class JSCodeGen()(using genCtx: Context) {
val call = if (isStaticCall) {
genApplyStatic(sym, formalCaptures.map(_.ref) ::: actualParams)
} else {
val thisCaptureRef :: argCaptureRefs = formalCaptures.map(_.ref)
val thisCaptureRef :: argCaptureRefs = formalCaptures.map(_.ref): @unchecked
if (!sym.owner.isNonNativeJSClass || sym.isJSExposed)
genApplyMethodMaybeStatically(thisCaptureRef, sym, argCaptureRefs ::: actualParams)
else
Expand All @@ -3458,7 +3458,7 @@ class JSCodeGen()(using genCtx: Context) {
}

if (isThisFunction) {
val thisParam :: otherParams = formalParams
val thisParam :: otherParams = formalParams: @unchecked
js.Closure(
arrow = false,
formalCaptures,
Expand Down Expand Up @@ -3970,7 +3970,7 @@ class JSCodeGen()(using genCtx: Context) {
*/
private def genReflectiveCall(tree: Apply, isSelectDynamic: Boolean): js.Tree = {
implicit val pos = tree.span
val Apply(fun @ Select(receiver, _), args) = tree
val Apply(fun @ Select(receiver, _), args) = tree: @unchecked

val selectedValueTree = js.Apply(js.ApplyFlags.empty, genExpr(receiver),
js.MethodIdent(selectedValueMethodName), Nil)(jstpe.AnyType)
Expand Down Expand Up @@ -4213,7 +4213,7 @@ class JSCodeGen()(using genCtx: Context) {
private def genCaptureValuesFromFakeNewInstance(tree: Tree): List[js.Tree] = {
implicit val pos: Position = tree.span

val Apply(fun @ Select(New(_), _), args) = tree
val Apply(fun @ Select(New(_), _), args) = tree: @unchecked
val sym = fun.symbol

/* We use the same strategy as genActualJSArgs to detect which parameters were
Expand Down Expand Up @@ -4539,7 +4539,7 @@ class JSCodeGen()(using genCtx: Context) {
pathName.split('.').toList

def parseGlobalPath(pathName: String): Global = {
val globalRef :: path = parsePath(pathName)
val globalRef :: path = parsePath(pathName): @unchecked
Global(globalRef, path)
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/backend/sjs/JSExportsGen.scala
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ final class JSExportsGen(jsCodeGen: JSCodeGen)(using Context) {
None
} else {
val formalArgsRegistry = new FormalArgsRegistry(1, false)
val (List(arg), None) = formalArgsRegistry.genFormalArgs()
val (List(arg), None) = formalArgsRegistry.genFormalArgs(): @unchecked
val body = genOverloadDispatchSameArgc(jsName, formalArgsRegistry,
setters.map(new ExportedSymbol(_, static)), jstpe.AnyType, None)
Some((arg, body))
Expand Down
26 changes: 10 additions & 16 deletions compiler/src/dotty/tools/dotc/ast/Desugar.scala
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ object desugar {

/** The expansion of a class definition. See inline comments for what is involved */
def classDef(cdef: TypeDef)(using Context): Tree = {
val impl @ Template(constr0, _, self, _) = cdef.rhs
val impl @ Template(constr0, _, self, _) = cdef.rhs: @unchecked
val className = normalizeName(cdef, impl).asTypeName
val parents = impl.parents
val mods = cdef.mods
Expand Down Expand Up @@ -695,7 +695,7 @@ object desugar {
.withMods(companionMods | Synthetic))
.withSpan(cdef.span).toList
if (companionDerived.nonEmpty)
for (modClsDef @ TypeDef(_, _) <- mdefs)
for (case modClsDef @ TypeDef(_, _) <- mdefs)
modClsDef.putAttachment(DerivingCompanion, impl.srcPos.startPos)
mdefs
}
Expand Down Expand Up @@ -753,7 +753,7 @@ object desugar {

enumCompanionRef match {
case ref: TermRefTree => // have the enum import watch the companion object
val (modVal: ValDef) :: _ = companions
val (modVal: ValDef) :: _ = companions: @unchecked
ref.watching(modVal)
case _ =>
}
Expand Down Expand Up @@ -1215,7 +1215,7 @@ object desugar {

/** Expand variable identifier x to x @ _ */
def patternVar(tree: Tree)(using Context): Bind = {
val Ident(name) = unsplice(tree)
val Ident(name) = unsplice(tree): @unchecked
Bind(name, Ident(nme.WILDCARD)).withSpan(tree.span)
}

Expand Down Expand Up @@ -1553,7 +1553,7 @@ object desugar {
Function(derivedValDef(gen.pat, named, tpt, EmptyTree, Modifiers(Param)) :: Nil, body)
case _ =>
val matchCheckMode =
if (gen.checkMode == GenCheckMode.Check) MatchCheck.IrrefutableGenFrom
if (gen.checkMode == GenCheckMode.Check || gen.checkMode == GenCheckMode.CheckAndFilter) MatchCheck.IrrefutableGenFrom
else MatchCheck.None
makeCaseLambda(CaseDef(gen.pat, EmptyTree, body) :: Nil, matchCheckMode)
}
Expand Down Expand Up @@ -1640,13 +1640,11 @@ object desugar {
case IdPattern(_) => true
case _ => false

def needsNoFilter(gen: GenFrom): Boolean =
if (gen.checkMode == GenCheckMode.FilterAlways) // pattern was prefixed by `case`
false
else
gen.checkMode != GenCheckMode.FilterNow
|| isVarBinding(gen.pat)
|| isIrrefutable(gen.pat, gen.expr)
def needsNoFilter(gen: GenFrom): Boolean = gen.checkMode match
case GenCheckMode.FilterAlways => false // pattern was prefixed by `case`
case GenCheckMode.FilterNow | GenCheckMode.CheckAndFilter => isVarBinding(gen.pat) || isIrrefutable(gen.pat, gen.expr)
case GenCheckMode.Check => true
case GenCheckMode.Ignore => true

/** rhs.name with a pattern filter on rhs unless `pat` is irrefutable when
* matched against `rhs`.
Expand All @@ -1656,10 +1654,6 @@ object desugar {
Select(rhs, name)
}

def checkMode(gen: GenFrom) =
if (gen.checkMode == GenCheckMode.Check) MatchCheck.IrrefutableGenFrom
else MatchCheck.None // refutable paterns were already eliminated in filter step

enums match {
case (gen: GenFrom) :: Nil =>
Apply(rhsSelect(gen, mapName), makeLambda(gen, body))
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/ast/MainProxies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ object MainProxies {
case TypeDef(_, template: Template) =>
template.body.flatMap((_: Tree) match {
case dd: DefDef if dd.name.is(DefaultGetterName) && dd.name.firstPart == funSymbol.name =>
val DefaultGetterName.NumberedInfo(index) = dd.name.info
val DefaultGetterName.NumberedInfo(index) = dd.name.info: @unchecked
List(index -> dd.symbol)
case _ => Nil
}).toMap
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/ast/TreeInfo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -956,7 +956,7 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
Some(tree.args.head)
else if tree.symbol == defn.QuotedTypeModule_of then
// quoted.Type.of[<body>](quotes)
val TypeApply(_, body :: _) = tree.fun
val TypeApply(_, body :: _) = tree.fun: @unchecked
Some(body)
else None
}
Expand Down
3 changes: 2 additions & 1 deletion compiler/src/dotty/tools/dotc/ast/TreeTypeMap.scala
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,10 @@ class TreeTypeMap(

private def transformAllParamss(paramss: List[ParamClause]): (TreeTypeMap, List[ParamClause]) = paramss match
case params :: paramss1 =>
val (tmap1, params1: ParamClause) = (params: @unchecked) match
val (tmap1, params1: ParamClause) = ((params: @unchecked) match
case ValDefs(vparams) => transformDefs(vparams)
case TypeDefs(tparams) => transformDefs(tparams)
): @unchecked
val (tmap2, paramss2) = tmap1.transformAllParamss(paramss1)
(tmap2, params1 :: paramss2)
case nil =>
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/ast/tpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
ta.assignType(untpd.TypeDef(sym.name, TypeTree(sym.info)), sym)

def ClassDef(cls: ClassSymbol, constr: DefDef, body: List[Tree], superArgs: List[Tree] = Nil)(using Context): TypeDef = {
val firstParent :: otherParents = cls.info.parents
val firstParent :: otherParents = cls.info.parents: @unchecked
val superRef =
if (cls.is(Trait)) TypeTree(firstParent)
else {
Expand Down
3 changes: 2 additions & 1 deletion compiler/src/dotty/tools/dotc/ast/untpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,8 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
enum GenCheckMode {
case Ignore // neither filter nor check since filtering was done before
case Check // check that pattern is irrefutable
case FilterNow // filter out non-matching elements since we are not yet in 3.x
case CheckAndFilter // both check and filter (transitional period starting with 3.2)
case FilterNow // filter out non-matching elements if we are not in 3.2 or later
case FilterAlways // filter out non-matching elements since pattern is prefixed by `case`
}

Expand Down
5 changes: 2 additions & 3 deletions compiler/src/dotty/tools/dotc/config/Feature.scala
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,9 @@ object Feature:
/** If current source migrates to `version`, issue given warning message
* and return `true`, otherwise return `false`.
*/
def warnOnMigration(msg: Message, pos: SrcPos,
version: SourceVersion)(using Context): Boolean =
def warnOnMigration(msg: Message, pos: SrcPos, version: SourceVersion)(using Context): Boolean =
if sourceVersion.isMigrating && sourceVersion.stable == version
|| (version == `3.0` || version == `3.1` || version == `3.2`) && migrateTo3
|| (version == `3.0` || version == `3.1`) && migrateTo3
then
report.migrationWarning(msg, pos)
true
Expand Down
6 changes: 5 additions & 1 deletion compiler/src/dotty/tools/dotc/config/ScalaSettings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import scala.language.unsafeNulls

import dotty.tools.dotc.config.PathResolver.Defaults
import dotty.tools.dotc.config.Settings.{Setting, SettingGroup}
import dotty.tools.dotc.config.SourceVersion
import dotty.tools.dotc.core.Contexts._
import dotty.tools.dotc.rewrites.Rewrites
import dotty.tools.io.{AbstractFile, Directory, JDK9Reflectors, PlainDirectory}
Expand All @@ -31,6 +32,9 @@ object ScalaSettings:
def supportedScalaReleaseVersions: List[String] =
ScalaRelease.values.toList.map(_.show)

def supportedSourceVersions: List[String] =
SourceVersion.values.toList.map(_.toString)

def defaultClasspath: String = sys.env.getOrElse("CLASSPATH", ".")

def defaultPageWidth: Int = {
Expand All @@ -51,7 +55,7 @@ trait AllScalaSettings extends CommonScalaSettings, PluginSettings, VerboseSetti
/* Path related settings */
val semanticdbTarget: Setting[String] = PathSetting("-semanticdb-target", "Specify an alternative output directory for SemanticDB files.", "")

val source: Setting[String] = ChoiceSetting("-source", "source version", "source version", List("3.0", "3.1", "future", "3.0-migration", "future-migration"), "3.0", aliases = List("--source"))
val source: Setting[String] = ChoiceSetting("-source", "source version", "source version", ScalaSettings.supportedSourceVersions, SourceVersion.defaultSourceVersion.toString, aliases = List("--source"))
val uniqid: Setting[Boolean] = BooleanSetting("-uniqid", "Uniquely tag all identifiers in debugging output.", aliases = List("--unique-id"))
val rewrite: Setting[Option[Rewrites]] = OptionSetting[Rewrites]("-rewrite", "When used in conjunction with a `...-migration` source version, rewrites sources to migrate to new version.", aliases = List("--rewrite"))
val fromTasty: Setting[Boolean] = BooleanSetting("-from-tasty", "Compile classes from tasty files. The arguments are .tasty or .jar files.", aliases = List("--from-tasty"))
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/config/Settings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ object Settings:
}

def tryToSet(state: ArgsSummary): ArgsSummary = {
val ArgsSummary(sstate, arg :: args, errors, warnings) = state
val ArgsSummary(sstate, arg :: args, errors, warnings) = state: @unchecked
def update(value: Any, args: List[String]): ArgsSummary =
var dangers = warnings
val value1 =
Expand Down
Loading