Skip to content

Commit b7a13ee

Browse files
authored
Merge pull request #649 from scala/backport-lts-3.3-24258
Backport "Warn if type argument was inferred as union type" to 3.3 LTS
2 parents bb6767d + 1c73936 commit b7a13ee

File tree

5 files changed

+55
-1
lines changed

5 files changed

+55
-1
lines changed

compiler/src/dotty/tools/dotc/Compiler.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ class Compiler {
3434
protected def frontendPhases: List[List[Phase]] =
3535
List(new Parser) :: // Compiler frontend: scanner, parser
3636
List(new TyperPhase) :: // Compiler frontend: namer, typer
37-
List(CheckUnused.PostTyper(), CheckShadowing()) :: // Check for unused, shadowed elements
37+
List(new WInferUnion, // Check for type arguments inferred as union types
38+
CheckUnused.PostTyper(), // Check for unused
39+
CheckShadowing()) :: // Check for shadowed elements
3840
List(new YCheckPositions) :: // YCheck positions
3941
List(new sbt.ExtractDependencies) :: // Sends information on classes' dependencies to sbt via callbacks
4042
List(new semanticdb.ExtractSemanticDB.ExtractSemanticInfo) :: // Extract info into .semanticdb files

compiler/src/dotty/tools/dotc/config/ScalaSettings.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ private sealed trait WarningSettings:
177177
private val WtoStringInterpolated = BooleanSetting("-Wtostring-interpolated", "Warn a standard interpolator used toString on a reference type.")
178178
private val WrecurseWithDefault = BooleanSetting("-Wrecurse-with-default", "Warn when a method calls itself with a default argument.")
179179
private val WwrongArrow = BooleanSetting("-Wwrong-arrow", "Warn if function arrow was used instead of context literal ?=>.")
180+
private val WinferUnion = BooleanSetting("-Winfer-union", "Warn if type argument was inferred as union type.")
180181
private val Wunused: Setting[List[ChoiceWithHelp[String]]] = MultiChoiceHelpSetting(
181182
name = "-Wunused",
182183
helpArg = "warning",
@@ -291,6 +292,7 @@ private sealed trait WarningSettings:
291292
def recurseWithDefault(using Context): Boolean = allOr(WrecurseWithDefault)
292293
def checkInit(using Context): Boolean = allOr(YcheckInit)
293294
def wrongArrow(using Context): Boolean = allOr(WwrongArrow)
295+
def inferUnion(using Context): Boolean = allOr(WinferUnion)
294296

295297
/** -X "Extended" or "Advanced" settings */
296298
private sealed trait XSettings:
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package dotty.tools.dotc.transform
2+
3+
import dotty.tools.dotc.ast.tpd
4+
import dotty.tools.dotc.ast.tpd.InferredTypeTree
5+
import dotty.tools.dotc.core.Contexts.{Context, ctx}
6+
import dotty.tools.dotc.core.Decorators.em
7+
import dotty.tools.dotc.core.Types.OrType
8+
import dotty.tools.dotc.report
9+
import dotty.tools.dotc.transform.MegaPhase.MiniPhase
10+
11+
class WInferUnion extends MiniPhase {
12+
13+
override def phaseName: String = WInferUnion.name
14+
15+
override def description: String = WInferUnion.description
16+
17+
override def isEnabled(using Context): Boolean = ctx.settings.Whas.inferUnion
18+
19+
override def transformTypeApply(tree: tpd.TypeApply)(using Context): tpd.Tree =
20+
val inferredOrTypes = tree.args.find: tpt =>
21+
tpt.isInstanceOf[InferredTypeTree] && tpt.tpe.stripTypeVar.isInstanceOf[OrType]
22+
inferredOrTypes.foreach: tpt =>
23+
report.warning(
24+
em"""|A type argument was inferred to be union type ${tpt.tpe.stripTypeVar}
25+
|This may indicate a programming error.
26+
|""", tpt.srcPos)
27+
tree
28+
}
29+
30+
object WInferUnion:
31+
val name = "Winfer-union"
32+
val description = "check for type arguments inferred as union types"

tests/warn/infer-or-type.check

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
-- Warning: tests/warn/infer-or-type.scala:6:18 ------------------------------------------------------------------------
2+
6 | val _ = List(1).contains("") // warn
3+
| ^^^^^^^^^^^^^^^^
4+
| A type argument was inferred to be union type Int | String
5+
| This may indicate a programming error.
6+
-- Warning: tests/warn/infer-or-type.scala:7:10 ------------------------------------------------------------------------
7+
7 | val _ = Pair(1, "") // warn
8+
| ^^^^
9+
| A type argument was inferred to be union type Int | String
10+
| This may indicate a programming error.

tests/warn/infer-or-type.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//> using options -Winfer-union
2+
3+
case class Pair[A](x: A, y: A)
4+
5+
def test = {
6+
val _ = List(1).contains("") // warn
7+
val _ = Pair(1, "") // warn
8+
}

0 commit comments

Comments
 (0)