Skip to content

Commit 92b3d5a

Browse files
committed
Warn if type argument was inferred as union type
1 parent 5c51b7b commit 92b3d5a

File tree

3 files changed

+20
-0
lines changed

3 files changed

+20
-0
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ private sealed trait WarningSettings:
169169
private val WtoStringInterpolated = BooleanSetting(WarningSetting, "Wtostring-interpolated", "Warn a standard interpolator used toString on a reference type.")
170170
private val WrecurseWithDefault = BooleanSetting(WarningSetting, "Wrecurse-with-default", "Warn when a method calls itself with a default argument.")
171171
private val WwrongArrow = BooleanSetting(WarningSetting, "Wwrong-arrow", "Warn if function arrow was used instead of context literal ?=>.")
172+
private val WinferUnion = BooleanSetting(WarningSetting, "Winfer-union", "Warn if type argument was inferred as union type.")
172173
private val Wunused: Setting[List[ChoiceWithHelp[String]]] = MultiChoiceHelpSetting(
173174
WarningSetting,
174175
name = "Wunused",
@@ -307,6 +308,7 @@ private sealed trait WarningSettings:
307308
def toStringInterpolated(using Context): Boolean = allOr(WtoStringInterpolated)
308309
def recurseWithDefault(using Context): Boolean = allOr(WrecurseWithDefault)
309310
def wrongArrow(using Context): Boolean = allOr(WwrongArrow)
311+
def inferUnion(using Context): Boolean = allOr(WinferUnion)
310312
def safeInit(using Context): Boolean = allOr(WsafeInit)
311313

312314
/** -X "Extended" or "Advanced" settings */

compiler/src/dotty/tools/dotc/transform/PostTyper.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,16 @@ class PostTyper extends MacroTransform with InfoTransformer { thisPhase =>
534534
if (fn.symbol != defn.ChildAnnot.primaryConstructor)
535535
// Make an exception for ChildAnnot, which should really have AnyKind bounds
536536
Checking.checkBounds(args, fn.tpe.widen.asInstanceOf[PolyType])
537+
if ctx.settings.Whas.inferUnion then
538+
val inferredOrTypes = args.filter(tpt =>
539+
tpt.isInstanceOf[InferredTypeTree] && tpt.tpe.stripTypeVar.isInstanceOf[OrType]
540+
)
541+
inferredOrTypes.headOption.foreach(tpt =>
542+
report.warning(
543+
em"""|A type argument was inferred to be union type ${tpt.tpe.stripTypeVar}
544+
|This may indicate a programming error.
545+
|""", tpt.srcPos)
546+
)
537547
fn match {
538548
case sel: Select =>
539549
val args1 = transform(args)

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)