Skip to content

Commit 79e9434

Browse files
committed
respect @unchecked in type patterns
1 parent 17cf095 commit 79e9434

File tree

2 files changed

+13
-5
lines changed

2 files changed

+13
-5
lines changed

compiler/src/dotty/tools/dotc/transform/patmat/Space.scala

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import ProtoTypes._
2020
import transform.SymUtils._
2121
import reporting.diagnostic.messages._
2222
import config.Printers.{exhaustivity => debug}
23-
import util.Positions.Position
2423

2524
/** Space logic for checking exhaustivity and unreachability of pattern matching
2625
*
@@ -404,20 +403,23 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
404403
else
405404
Prod(pat.tpe.stripAnnots, fun.tpe.widen, fun.symbol, pats.map(project), irrefutable(fun))
406405
case Typed(pat @ UnApply(_, _, _), _) => project(pat)
407-
case Typed(expr, tp) => Typ(erase(expr.tpe.stripAnnots)(tp.pos), true)
406+
case Typed(expr, tpt) =>
407+
val unchecked = expr.tpe.hasAnnotation(ctx.definitions.UncheckedAnnot)
408+
def warn(msg: String): Unit = if (!unchecked) ctx.warning(UncheckedTypePattern(msg), tpt.pos)
409+
Typ(erase(expr.tpe.stripAnnots)(warn), true)
408410
case _ =>
409411
debug.println(s"unknown pattern: $pat")
410412
Empty
411413
}
412414

413415
/* Erase a type binding according to erasure semantics in pattern matching */
414-
def erase(tp: Type)(implicit pos: Position): Type = tp match {
416+
def erase(tp: Type)(implicit warn: String => Unit): Type = tp match {
415417
case tp @ AppliedType(tycon, args) =>
416418
if (tycon.isRef(defn.ArrayClass)) tp.derivedAppliedType(tycon, args.map(erase))
417419
else {
418420
val ignoreWarning = args.forall(p => p.typeSymbol.is(BindDefinedType) || p.isInstanceOf[TypeBounds])
419421
if (!ignoreWarning)
420-
ctx.warning(UncheckedTypePattern("type arguments are not checked since they are eliminated by erasure"), pos)
422+
warn("type arguments are not checked since they are eliminated by erasure")
421423

422424
tp.derivedAppliedType(tycon, args.map(t => WildcardType))
423425
}
@@ -426,7 +428,7 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
426428
case AndType(tp1, tp2) =>
427429
AndType(erase(tp1), erase(tp2))
428430
case tp: RefinedType =>
429-
ctx.warning(UncheckedTypePattern("type refinement is not checked since it is eliminated by erasure"), pos)
431+
warn("type refinement is not checked since it is eliminated by erasure")
430432
tp.derivedRefinedType(erase(tp.parent), tp.refinedName, WildcardType)
431433
case _ => tp
432434
}

tests/patmat/3144b.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
class Test {
2+
def f(x: Any): Int = x match {
3+
case xs: List[Int] @unchecked => xs.head
4+
case _ => 0
5+
}
6+
}

0 commit comments

Comments
 (0)