Skip to content

Commit 728d2e6

Browse files
Normalize when verifying if TypeTestCasts are unchecked (#20258)
Tests `pos/i13433` with a classpath dependency
2 parents 7c67d7c + 1f9987c commit 728d2e6

File tree

4 files changed

+55
-0
lines changed

4 files changed

+55
-0
lines changed

compiler/src/dotty/tools/dotc/core/Types.scala

+4
Original file line numberDiff line numberDiff line change
@@ -5214,6 +5214,10 @@ object Types extends TypeUtils {
52145214
def thatReducesUsingGadt(tp: Type)(using Context): Boolean = tp.underlyingMatchType match
52155215
case mt: MatchType => mt.reducesUsingGadt
52165216
case _ => false
5217+
5218+
object Normalizing:
5219+
def unapply(tp: Type)(using Context): Option[Type] =
5220+
Some(tp.tryNormalize).filter(_.exists)
52175221
}
52185222

52195223
enum MatchTypeCasePattern:

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

+1
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ object TypeTestsCasts {
135135
def recur(X: Type, P: Type): String = trace(s"recur(${X.show}, ${P.show})") {
136136
(X <:< P) ||| P.dealias.match
137137
case _: SingletonType => ""
138+
case MatchType.Normalizing(tp) => recur(X, tp)
138139
case _: TypeProxy
139140
if isAbstract(P) => i"it refers to an abstract type member or type parameter"
140141
case defn.ArrayOf(tpT) =>

tests/warn/i13433c/A_1.scala

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import scala.reflect.TypeTest
2+
3+
type Matcher[A] = A match { case String => A }
4+
5+
def patternMatch[A](a: Any)(using tt: TypeTest[Any, Matcher[A]]): Option[Matcher[A]] = {
6+
// type T = RDF.Triple[Rdf]
7+
a match {
8+
case res: Matcher[A] => Some(res)
9+
case _ => None
10+
}
11+
}
12+
13+
def patternMatchWithAlias[A](a: Any)(using tt: TypeTest[Any, Matcher[A]]): Option[Matcher[A]] = {
14+
type T = Matcher[A]
15+
a match {
16+
case res: T => Some(res)
17+
case _ => None
18+
}
19+
}
20+
21+
type S = String
22+
type MS = Matcher[S]
23+
24+
type S2 = MS
25+
type MS2 = Matcher[S2]
26+
27+
type Mstuck = Matcher[Nothing]

tests/warn/i13433c/B_2.scala

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
2+
@main def main = {
3+
println(patternMatch[String]("abc"))
4+
println(patternMatchWithAlias[String]("abc"))
5+
println(patternMatch[String]("abc")(using (s: Any) => {
6+
if s.isInstanceOf[Matcher[String]] then Some[s.type & Matcher[String]](s.asInstanceOf[s.type & Matcher[String]]) else None }))
7+
println(patternMatchWithAlias[String]("abc")(using (s: Any) => {
8+
if s.isInstanceOf[Matcher[String]] then Some[s.type & Matcher[String]](s.asInstanceOf[s.type & Matcher[String]]) else None }))
9+
10+
println(patternMatch[String](1))
11+
println(patternMatchWithAlias[String](1))
12+
13+
println(patternMatch[String]("abc")(using (s: Any) => {
14+
if s.isInstanceOf[S] then Some[s.type & Matcher[String]](s.asInstanceOf[s.type & Matcher[String]]) else None}))
15+
println(patternMatch[String]("abc")(using (s: Any) => {
16+
if s.isInstanceOf[MS] then Some[s.type & Matcher[String]](s.asInstanceOf[s.type & Matcher[String]]) else None}))
17+
println(patternMatch[String]("abc")(using (s: Any) => {
18+
if s.isInstanceOf[S2] then Some[s.type & Matcher[String]](s.asInstanceOf[s.type & Matcher[String]]) else None}))
19+
println(patternMatch[String]("abc")(using (s: Any) => {
20+
if s.isInstanceOf[MS2] then Some[s.type & Matcher[String]](s.asInstanceOf[s.type & Matcher[String]]) else None}))
21+
println(patternMatch[String]("abc")(using (s: Any) => {
22+
if s.isInstanceOf[Mstuck] then Some[s.type & Matcher[String]](s.asInstanceOf[s.type & Matcher[String]]) else None})) // warn
23+
}

0 commit comments

Comments
 (0)