diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index b72f2ee4b9ef..f89bc8691e2d 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -830,6 +830,7 @@ class Definitions { @tu lazy val ReflectSelectableTypeRef: TypeRef = requiredClassRef("scala.reflect.Selectable") + @tu lazy val TypeableType: TypeSymbol = requiredPackage("scala.reflect.Typeable$package").moduleClass.requiredType("Typeable") @tu lazy val TypeTestClass: ClassSymbol = requiredClass("scala.reflect.TypeTest") @tu lazy val TypeTest_unapply: Symbol = TypeTestClass.requiredMethod(nme.unapply) @tu lazy val TypeTestModule_identity: Symbol = TypeTestClass.companionModule.requiredMethod(nme.identity) diff --git a/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala b/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala index 5e7858c51296..1ada3caab408 100644 --- a/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala +++ b/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala @@ -68,8 +68,11 @@ class CheckUnused private (phaseMode: PhaseMode, suffix: String) extends MiniPha val name = tree.removeAttachment(OriginalName).getOrElse(nme.NO_NAME) if tree.srcPos.isSynthetic && tree.symbol == defn.TypeTest_unapply then tree.qualifier.tpe.underlying.finalResultType match - case AppliedType(_, args) => // tycon.typeSymbol == defn.TypeTestClass - val res = args(1) // T in TypeTest[-S, T] + case AppliedType(tycon, args) => + val res = + if tycon.typeSymbol == defn.TypeTestClass then args(1) // T in TypeTest[-S, T] + else if tycon.typeSymbol == defn.TypeableType then args(0) // T in Typeable[T] + else return tree val target = res.dealias.typeSymbol resolveUsage(target, target.name, res.importPrefix.skipPackageObject) // case _: T => case _ => diff --git a/tests/warn/i15503d.scala b/tests/warn/i15503d.scala index 494952e2e4b0..2981986daff6 100644 --- a/tests/warn/i15503d.scala +++ b/tests/warn/i15503d.scala @@ -1,7 +1,5 @@ //> using options -Wunused:patvars -import scala.reflect.Typeable - sealed trait Calc sealed trait Const extends Calc case class Sum(a: Calc, b: Calc) extends Calc @@ -74,13 +72,6 @@ class C(c0: Option[Int], k0: K): for case Some(value) <- List(Option(42)) yield 27 - /* - def tester[A](a: A)(using Typeable[K]) = - a match - case S(i, j) => i + j - case _ => 0 - */ - class Wild: def f(x: Any) = x match diff --git a/tests/warn/i21525.scala b/tests/warn/i21525.scala index aa156dc3960e..721486c4bd64 100644 --- a/tests/warn/i21525.scala +++ b/tests/warn/i21525.scala @@ -1,6 +1,7 @@ //> using options -Werror -Wunused:imports -import scala.reflect.TypeTest +import scala.reflect.{Typeable, TypeTest} +import compiletime.* trait A { type B @@ -18,3 +19,18 @@ def f(a: A, b: a.B): Boolean = { false } } + +trait T: + type X + given Typeable[X] = deferred + +def g(t: T, x: Any) = + import t.X + x match + case _: X => true + case _ => false + +def typer[T: Typeable](x: Any) = + x match + case _: T => 1 + case _ => 0