diff --git a/compiler/src/dotty/tools/dotc/tastyreflect/TastyImpl.scala b/compiler/src/dotty/tools/dotc/tastyreflect/TastyImpl.scala index c1981f6c6edd..f99822bf6b66 100644 --- a/compiler/src/dotty/tools/dotc/tastyreflect/TastyImpl.scala +++ b/compiler/src/dotty/tools/dotc/tastyreflect/TastyImpl.scala @@ -485,7 +485,7 @@ object TastyImpl extends scala.tasty.Tasty { object Bind extends BindExtractor { def unapply(x: Pattern)(implicit ctx: Context): Option[(String, Pattern)] = x match { - case x: tpd.Bind @unchecked if x.name.isInstanceOf[Names.TermName] => Some(x.name.toString, x.body) + case x: tpd.Bind @unchecked if x.name.isTermName => Some(x.name.toString, x.body) case _ => None } } @@ -623,6 +623,13 @@ object TastyImpl extends scala.tasty.Tasty { case _ => None } } + + object Bind extends BindExtractor { + def unapply(x: TypeTree)(implicit ctx: Context): Option[(String, TypeBoundsTree)] = x match { + case x: tpd.Bind @unchecked if x.name.isTypeName => Some((x.name.toString, x.body)) + case _ => None + } + } } // ----- TypeBoundsTrees ------------------------------------------------ @@ -645,6 +652,7 @@ object TastyImpl extends scala.tasty.Tasty { object SyntheticBounds extends SyntheticBoundsExtractor { def unapply(x: TypeBoundsTree)(implicit ctx: Context): Boolean = x match { case x @ Trees.TypeTree() => x.tpe.isInstanceOf[Types.TypeBounds] + case Trees.Ident(nme.WILDCARD) => x.tpe.isInstanceOf[Types.TypeBounds] case _ => false } } diff --git a/library/src/scala/tasty/Tasty.scala b/library/src/scala/tasty/Tasty.scala index 4c6f11350f8e..7a3c93d4d73c 100644 --- a/library/src/scala/tasty/Tasty.scala +++ b/library/src/scala/tasty/Tasty.scala @@ -482,6 +482,11 @@ abstract class Tasty { tasty => abstract class TypeLambdaTreeExtractor { def unapply(x: TypeTree)(implicit ctx: Context): Option[(List[TypeDef], TypeOrBoundsTree)] } + + val Bind: BindExtractor + abstract class BindExtractor{ + def unapply(x: TypeTree)(implicit ctx: Context): Option[(String, TypeBoundsTree)] + } } // ----- TypeBoundsTrees ------------------------------------------------ diff --git a/library/src/scala/tasty/util/ShowExtractors.scala b/library/src/scala/tasty/util/ShowExtractors.scala index 72c143c41db6..b6bf64a3ed9c 100644 --- a/library/src/scala/tasty/util/ShowExtractors.scala +++ b/library/src/scala/tasty/util/ShowExtractors.scala @@ -114,6 +114,8 @@ class ShowExtractors[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty this += "TypeTree.Annotated(" += arg += ", " += annot += ")" case TypeTree.TypeLambdaTree(tparams, body) => this += "LambdaTypeTree(" ++= tparams += ", " += body += ")" + case TypeTree.Bind(name, bounds) => + this += "Bind(" += name += ", " += bounds += ")" case TypeBoundsTree(lo, hi) => this += "TypeBoundsTree(" += lo += ", " += hi += ")" case SyntheticBounds() => diff --git a/library/src/scala/tasty/util/ShowSourceCode.scala b/library/src/scala/tasty/util/ShowSourceCode.scala index b128ebe8d4ec..2847f2c55734 100644 --- a/library/src/scala/tasty/util/ShowSourceCode.scala +++ b/library/src/scala/tasty/util/ShowSourceCode.scala @@ -754,6 +754,9 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty this += " => " printTypeOrBoundsTree(body) + case TypeTree.Bind(name, _) => + this += name + case _ => throw new MatchError(tree.show) @@ -761,7 +764,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty def printTypeOrBound(tpe: TypeOrBounds): Buffer = tpe match { case tpe@TypeBounds(lo, hi) => - this += " >: " + this += "_ >: " printType(lo) this += " <: " printType(hi) @@ -843,14 +846,21 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty case Type.TypeLambda(paramNames, tparams, body) => this += "[" + def printBounds(bounds: TypeBounds): Buffer = { + val TypeBounds(lo, hi) = bounds + this += " >: " + printType(lo) + this += " <: " + printType(hi) + } def printSeparated(list: List[(String, TypeBounds)]): Unit = list match { case Nil => case (name, bounds) :: Nil => this += name - printTypeOrBound(bounds) + printBounds(bounds) case (name, bounds) :: xs => this += name - printTypeOrBound(bounds) + printBounds(bounds) this += ", " printSeparated(xs) } diff --git a/tests/pos/i0306.decompiled b/tests/pos/i0306.decompiled new file mode 100644 index 000000000000..5e1d7cea46d1 --- /dev/null +++ b/tests/pos/i0306.decompiled @@ -0,0 +1,14 @@ +/** Decompiled from out/posTestFromTasty/pos/i0306/bar.class */ +object bar { + class C[T <: scala.Seq[_ >: scala.Nothing <: scala.Any]]() + val x: scala.AnyRef = new bar.C[scala.collection.Seq[_ >: scala.Nothing <: scala.Any]]() + val y: scala.collection.Seq[_ >: scala.Nothing <: scala.Any] = bar.x match { + case x: bar.C[u] => + def xx: u = xx + ((xx: u): scala.collection.Seq[_ >: scala.Nothing <: scala.Any]) + } + val z: java.lang.String = { + def xx: scala.Predef.String = xx + (xx: java.lang.String) + } +} diff --git a/tests/pos/tasty/definitions.scala b/tests/pos/tasty/definitions.scala index 7d1568824afa..823bd9be7c1a 100644 --- a/tests/pos/tasty/definitions.scala +++ b/tests/pos/tasty/definitions.scala @@ -102,6 +102,7 @@ object definitions { case Or(left: TypeTree, right: TypeTree) case ByName(tpt: TypeTree) case TypeLambda(tparams: List[TypeDef], body: Type | TypeBoundsTree) + case Bind(name: String, bounds: TypeBoundsTree) } /** Trees denoting type bounds */