Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion compiler/src/dotty/tools/dotc/Compiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ class Compiler {
protected def frontendPhases: List[List[Phase]] =
List(new Parser) :: // Compiler frontend: scanner, parser
List(new TyperPhase) :: // Compiler frontend: namer, typer
List(CheckUnused.PostTyper(), CheckShadowing()) :: // Check for unused, shadowed elements
List(new WInferUnion, // Check for type arguments inferred as union types
CheckUnused.PostTyper(), // Check for unused
CheckShadowing()) :: // Check for shadowed elements
List(new YCheckPositions) :: // YCheck positions
List(new sbt.ExtractDependencies) :: // Sends information on classes' dependencies to sbt via callbacks
List(new semanticdb.ExtractSemanticDB.ExtractSemanticInfo) :: // Extract info into .semanticdb files
Expand Down
2 changes: 2 additions & 0 deletions compiler/src/dotty/tools/dotc/config/ScalaSettings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ private sealed trait WarningSettings:
private val WtoStringInterpolated = BooleanSetting(WarningSetting, "Wtostring-interpolated", "Warn a standard interpolator used toString on a reference type.")
private val WrecurseWithDefault = BooleanSetting(WarningSetting, "Wrecurse-with-default", "Warn when a method calls itself with a default argument.")
private val WwrongArrow = BooleanSetting(WarningSetting, "Wwrong-arrow", "Warn if function arrow was used instead of context literal ?=>.")
private val WinferUnion = BooleanSetting(WarningSetting, "Winfer-union", "Warn if type argument was inferred as union type.")
private val Wunused: Setting[List[ChoiceWithHelp[String]]] = MultiChoiceHelpSetting(
WarningSetting,
name = "Wunused",
Expand Down Expand Up @@ -307,6 +308,7 @@ private sealed trait WarningSettings:
def toStringInterpolated(using Context): Boolean = allOr(WtoStringInterpolated)
def recurseWithDefault(using Context): Boolean = allOr(WrecurseWithDefault)
def wrongArrow(using Context): Boolean = allOr(WwrongArrow)
def inferUnion(using Context): Boolean = allOr(WinferUnion)
def safeInit(using Context): Boolean = allOr(WsafeInit)

/** -X "Extended" or "Advanced" settings */
Expand Down
32 changes: 32 additions & 0 deletions compiler/src/dotty/tools/dotc/transform/WInferUnion.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package dotty.tools.dotc.transform

import dotty.tools.dotc.ast.tpd
import dotty.tools.dotc.ast.tpd.InferredTypeTree
import dotty.tools.dotc.core.Contexts.{Context, ctx}
import dotty.tools.dotc.core.Decorators.em
import dotty.tools.dotc.core.Types.OrType
import dotty.tools.dotc.report
import dotty.tools.dotc.transform.MegaPhase.MiniPhase

class WInferUnion extends MiniPhase {

override def phaseName: String = WInferUnion.name

override def description: String = WInferUnion.description

override def isEnabled(using Context): Boolean = ctx.settings.Whas.inferUnion

override def transformTypeApply(tree: tpd.TypeApply)(using Context): tpd.Tree =
val inferredOrTypes = tree.args.find: tpt =>
tpt.isInstanceOf[InferredTypeTree] && tpt.tpe.stripTypeVar.isInstanceOf[OrType]
inferredOrTypes.foreach: tpt =>
report.warning(
em"""|A type argument was inferred to be union type ${tpt.tpe.stripTypeVar}
|This may indicate a programming error.
|""", tpt.srcPos)
tree
}

object WInferUnion:
val name = "Winfer-union"
val description = "check for type arguments inferred as union types"
10 changes: 10 additions & 0 deletions tests/warn/infer-or-type.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
-- Warning: tests/warn/infer-or-type.scala:6:18 ------------------------------------------------------------------------
6 | val _ = List(1).contains("") // warn
| ^^^^^^^^^^^^^^^^
| A type argument was inferred to be union type Int | String
| This may indicate a programming error.
-- Warning: tests/warn/infer-or-type.scala:7:10 ------------------------------------------------------------------------
7 | val _ = Pair(1, "") // warn
| ^^^^
| A type argument was inferred to be union type Int | String
| This may indicate a programming error.
8 changes: 8 additions & 0 deletions tests/warn/infer-or-type.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//> using options -Winfer-union

case class Pair[A](x: A, y: A)

def test = {
val _ = List(1).contains("") // warn
val _ = Pair(1, "") // warn
}
Loading