diff --git a/compiler/src/dotty/tools/dotc/tastyreflect/KernelImpl.scala b/compiler/src/dotty/tools/dotc/tastyreflect/KernelImpl.scala index a6bc87b6833b..5177654114d3 100644 --- a/compiler/src/dotty/tools/dotc/tastyreflect/KernelImpl.scala +++ b/compiler/src/dotty/tools/dotc/tastyreflect/KernelImpl.scala @@ -916,7 +916,7 @@ class KernelImpl(val rootContext: core.Contexts.Context, val rootPosition: util. def matchPattern_Value(pattern: Pattern): Option[Value] = pattern match { case lit: tpd.Literal => Some(lit) - case ref: tpd.RefTree if ref.isTerm => Some(ref) + case ref: tpd.RefTree if ref.isTerm && !tpd.isWildcardArg(ref) => Some(ref) case ths: tpd.This => Some(ths) case _ => None } @@ -999,6 +999,18 @@ class KernelImpl(val rootContext: core.Contexts.Context, val rootPosition: util. def Pattern_TypeTest_module_copy(original: TypeTest)(tpt: TypeTree)(implicit ctx: Context): TypeTest = tpd.cpy.Typed(original)(untpd.Ident(nme.WILDCARD).withSpan(original.span).withType(tpt.tpe), tpt) + type WildcardPattern = tpd.Ident + + def matchPattern_WildcardPattern(pattern: Pattern)(implicit ctx: Context): Option[WildcardPattern] = { + pattern match { + case pattern: tpd.Ident if tpd.isWildcardArg(pattern) => Some(pattern) + case _ => None + } + } + + def Pattern_WildcardPattern_module_apply(tpe: TypeOrBounds)(implicit ctx: Context): WildcardPattern = + untpd.Ident(nme.WILDCARD).withType(tpe) + // // TYPES // diff --git a/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala b/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala index 92054cbcc355..1da497b19109 100644 --- a/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala +++ b/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala @@ -66,7 +66,7 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages( } } else { - assert(!enclosingInlineds.nonEmpty, "unexpanded macro") + assert(enclosingInlineds.isEmpty, "unexpanded macro") assert(ctx.owner.isInlineMethod) if (Splicer.canBeSpliced(body)) { // level 0 inside an inline definition transform(body)(spliceContext) // Just check PCP diff --git a/docs/docs/reference/other-new-features/tasty-reflect.md b/docs/docs/reference/other-new-features/tasty-reflect.md index 8f631b640f47..08b9ea3f37e3 100644 --- a/docs/docs/reference/other-new-features/tasty-reflect.md +++ b/docs/docs/reference/other-new-features/tasty-reflect.md @@ -139,6 +139,7 @@ TASTy Reflect provides the following types: +- Unapply +- Alternative +- TypeTest + +- WildcardPattern +- NoPrefix diff --git a/library/src-bootstrapped/scala/internal/quoted/Matcher.scala b/library/src-bootstrapped/scala/internal/quoted/Matcher.scala index 11c86ee33fc7..da135333964b 100644 --- a/library/src-bootstrapped/scala/internal/quoted/Matcher.scala +++ b/library/src-bootstrapped/scala/internal/quoted/Matcher.scala @@ -246,6 +246,9 @@ object Matcher { case (Pattern.TypeTest(tpt1), Pattern.TypeTest(tpt2)) => (env, treeMatches(tpt1, tpt2)) + case (Pattern.WildcardPattern(), Pattern.WildcardPattern()) => + (env, Some(())) + case _ => if (debug) println( diff --git a/library/src/scala/tasty/reflect/Core.scala b/library/src/scala/tasty/reflect/Core.scala index dcc3bde5b4fd..42035a3d9e01 100644 --- a/library/src/scala/tasty/reflect/Core.scala +++ b/library/src/scala/tasty/reflect/Core.scala @@ -62,6 +62,7 @@ package scala.tasty.reflect * +- Unapply * +- Alternatives * +- TypeTest + * +- WildcardPattern * * * +- NoPrefix @@ -304,6 +305,9 @@ trait Core { /** Pattern representing a `x: Y` type test. */ type TypeTest = kernel.TypeTest + /** Pattern representing a `_` pattern */ + type WildcardPattern = kernel.WildcardPattern + /** Type or bounds */ type TypeOrBounds = kernel.TypeOrBounds diff --git a/library/src/scala/tasty/reflect/Kernel.scala b/library/src/scala/tasty/reflect/Kernel.scala index 07836b68054f..128312d720db 100644 --- a/library/src/scala/tasty/reflect/Kernel.scala +++ b/library/src/scala/tasty/reflect/Kernel.scala @@ -61,6 +61,7 @@ package scala.tasty.reflect * +- Unapply * +- Alternatives * +- TypeTest + * +- WildcardPattern * * * +- NoPrefix @@ -791,6 +792,13 @@ trait Kernel { def Pattern_TypeTest_module_apply(tpt: TypeTree)(implicit ctx: Context): TypeTest def Pattern_TypeTest_module_copy(original: TypeTest)(tpt: TypeTree)(implicit ctx: Context): TypeTest + /** Pattern representing a `_` pattern */ + type WildcardPattern <: Pattern + + def matchPattern_WildcardPattern(pattern: Pattern)(implicit ctx: Context): Option[WildcardPattern] + + def Pattern_WildcardPattern_module_apply(tpe: TypeOrBounds)(implicit ctx: Context): WildcardPattern + // // TYPES // diff --git a/library/src/scala/tasty/reflect/PatternOps.scala b/library/src/scala/tasty/reflect/PatternOps.scala index 35fe8eb4e765..dd5eb335773f 100644 --- a/library/src/scala/tasty/reflect/PatternOps.scala +++ b/library/src/scala/tasty/reflect/PatternOps.scala @@ -105,6 +105,18 @@ trait PatternOps extends Core { kernel.matchPattern_TypeTest(pattern).map(_.tpt) } + object IsWildcardPattern { + def unapply(pattern: Pattern)(implicit ctx: Context): Option[WildcardPattern] = + kernel.matchPattern_WildcardPattern(pattern) + } + + object WildcardPattern { + def apply(tpe: TypeOrBounds)(implicit ctx: Context): WildcardPattern = + kernel.Pattern_WildcardPattern_module_apply(tpe) + def unapply(pattern: Pattern)(implicit ctx: Context): Boolean = + kernel.matchPattern_WildcardPattern(pattern).isDefined + } + } } diff --git a/library/src/scala/tasty/reflect/Printers.scala b/library/src/scala/tasty/reflect/Printers.scala index ead0bffba496..28ecf25cdffd 100644 --- a/library/src/scala/tasty/reflect/Printers.scala +++ b/library/src/scala/tasty/reflect/Printers.scala @@ -256,6 +256,8 @@ trait Printers this += "Pattern.Alternative(" ++= patterns += ")" case Pattern.TypeTest(tpt) => this += "Pattern.TypeTest(" += tpt += ")" + case Pattern.WildcardPattern() => + this += "Pattern.WildcardPattern()" } def visitConstant(x: Constant): Buffer = x match { @@ -1293,12 +1295,12 @@ trait Printers def printPattern(pattern: Pattern): Buffer = pattern match { case Pattern.Value(v) => - v match { - case Ident("_") => this += "_" - case _ => printTree(v) - } + printTree(v) + + case Pattern.WildcardPattern() => + this += "_" - case Pattern.Bind(name, Pattern.Value(Ident("_"))) => + case Pattern.Bind(name, Pattern.WildcardPattern()) => this += name case Pattern.Bind(name, Pattern.TypeTest(tpt)) => diff --git a/library/src/scala/tasty/reflect/TreeUtils.scala b/library/src/scala/tasty/reflect/TreeUtils.scala index e67a2158af8f..5116cc90eed9 100644 --- a/library/src/scala/tasty/reflect/TreeUtils.scala +++ b/library/src/scala/tasty/reflect/TreeUtils.scala @@ -102,6 +102,7 @@ trait TreeUtils case Pattern.Unapply(fun, implicits, patterns) => foldPatterns(foldTrees(foldTree(x, fun), implicits), patterns) case Pattern.Alternatives(patterns) => foldPatterns(x, patterns) case Pattern.TypeTest(tpt) => foldTree(x, tpt) + case Pattern.WildcardPattern() => x } } @@ -243,7 +244,7 @@ trait TreeUtils } def transformPattern(pattern: Pattern)(implicit ctx: Context): Pattern = pattern match { - case Pattern.Value(_) => + case Pattern.Value(_) | Pattern.WildcardPattern() => pattern case Pattern.IsTypeTest(pattern) => Pattern.TypeTest.copy(pattern)(transformTypeTree(pattern.tpt)) diff --git a/tests/run-custom-args/Yretain-trees/tasty-definitions-2.check b/tests/run-custom-args/Yretain-trees/tasty-definitions-2.check index f40fe6a19705..ed1be985fd0b 100644 --- a/tests/run-custom-args/Yretain-trees/tasty-definitions-2.check +++ b/tests/run-custom-args/Yretain-trees/tasty-definitions-2.check @@ -1,3 +1,3 @@ DefDef("foo", Nil, Nil, TypeIdent("Int"), Some(Apply(Select(Literal(Constant.Int(1)), "+"), List(Literal(Constant.Int(2)))))) ValDef("bar", TypeIdent("Int"), Some(Apply(Select(Literal(Constant.Int(2)), "+"), List(Literal(Constant.Int(3)))))) -Pattern.Bind("x", Pattern.Value(Ident("_"))) +Pattern.Bind("x", Pattern.WildcardPattern()) diff --git a/tests/run-custom-args/Yretain-trees/tasty-definitions-3.check b/tests/run-custom-args/Yretain-trees/tasty-definitions-3.check index d1962c3dcc9d..5b7a3da23416 100644 --- a/tests/run-custom-args/Yretain-trees/tasty-definitions-3.check +++ b/tests/run-custom-args/Yretain-trees/tasty-definitions-3.check @@ -1,3 +1,3 @@ DefDef("foo", Nil, Nil, Inferred(), None) ValDef("bar", Inferred(), None) -Pattern.Bind("x", Pattern.Value(Ident("_"))) +Pattern.Bind("x", Pattern.WildcardPattern()) diff --git a/tests/run/tasty-extractors-1.check b/tests/run/tasty-extractors-1.check index 0b920ba33f1b..c2c2cae482a1 100644 --- a/tests/run/tasty-extractors-1.check +++ b/tests/run/tasty-extractors-1.check @@ -40,13 +40,13 @@ Type.SymRef(IsClassDefSymbol(), Type.ThisType(Type.SymRef(IsPackageDe Inlined(None, Nil, Match(Literal(Constant.String("a")), List(CaseDef(Pattern.Value(Literal(Constant.String("a"))), None, Block(Nil, Literal(Constant.Unit())))))) Type.SymRef(IsClassDefSymbol(), Type.ThisType(Type.SymRef(IsPackageDefSymbol(), NoPrefix()))) -Inlined(None, Nil, Match(Literal(Constant.String("b")), List(CaseDef(Pattern.Bind("n", Pattern.Value(Ident("_"))), None, Block(Nil, Literal(Constant.Unit())))))) +Inlined(None, Nil, Match(Literal(Constant.String("b")), List(CaseDef(Pattern.Bind("n", Pattern.WildcardPattern()), None, Block(Nil, Literal(Constant.Unit())))))) Type.SymRef(IsClassDefSymbol(), Type.ThisType(Type.SymRef(IsPackageDefSymbol(), NoPrefix()))) Inlined(None, Nil, Match(Literal(Constant.String("c")), List(CaseDef(Pattern.Bind("n", Pattern.TypeTest(TypeIdent("String"))), None, Block(Nil, Literal(Constant.Unit())))))) Type.SymRef(IsClassDefSymbol(), Type.ThisType(Type.SymRef(IsPackageDefSymbol(), NoPrefix()))) -Inlined(None, Nil, Match(Literal(Constant.String("e")), List(CaseDef(Pattern.Value(Ident("_")), None, Block(Nil, Literal(Constant.Unit())))))) +Inlined(None, Nil, Match(Literal(Constant.String("e")), List(CaseDef(Pattern.WildcardPattern(), None, Block(Nil, Literal(Constant.Unit())))))) Type.SymRef(IsClassDefSymbol(), Type.ThisType(Type.SymRef(IsPackageDefSymbol(), NoPrefix()))) Inlined(None, Nil, Match(Literal(Constant.String("f")), List(CaseDef(Pattern.TypeTest(TypeIdent("String")), None, Block(Nil, Literal(Constant.Unit())))))) @@ -55,22 +55,22 @@ Type.SymRef(IsClassDefSymbol(), Type.ThisType(Type.SymRef(IsPackageD Inlined(None, Nil, Match(Typed(Literal(Constant.String("g")), TypeIdent("Any")), List(CaseDef(Pattern.Alternative(List(Pattern.TypeTest(TypeIdent("String")), Pattern.TypeTest(TypeIdent("Int")))), None, Block(Nil, Literal(Constant.Unit())))))) Type.SymRef(IsClassDefSymbol(), Type.ThisType(Type.SymRef(IsPackageDefSymbol(), NoPrefix()))) -Inlined(None, Nil, Match(Literal(Constant.String("h")), List(CaseDef(Pattern.Value(Ident("_")), Some(Literal(Constant.Boolean(false))), Block(Nil, Literal(Constant.Unit())))))) +Inlined(None, Nil, Match(Literal(Constant.String("h")), List(CaseDef(Pattern.WildcardPattern(), Some(Literal(Constant.Boolean(false))), Block(Nil, Literal(Constant.Unit())))))) Type.SymRef(IsClassDefSymbol(), Type.ThisType(Type.SymRef(IsPackageDefSymbol(), NoPrefix()))) -Inlined(None, Nil, Block(List(ValDef("a", Inferred(), Some(Literal(Constant.String("o"))))), Match(Literal(Constant.String("i")), List(CaseDef(Pattern.Bind("a", Pattern.Value(Ident("_"))), None, Block(Nil, Literal(Constant.Unit()))))))) +Inlined(None, Nil, Block(List(ValDef("a", Inferred(), Some(Literal(Constant.String("o"))))), Match(Literal(Constant.String("i")), List(CaseDef(Pattern.Bind("a", Pattern.WildcardPattern()), None, Block(Nil, Literal(Constant.Unit()))))))) Type.SymRef(IsClassDefSymbol(), Type.ThisType(Type.SymRef(IsPackageDefSymbol(), NoPrefix()))) -Inlined(None, Nil, Match(Ident("Nil"), List(CaseDef(Pattern.Unapply(TypeApply(Select(Ident("List"), "unapplySeq"), List(Inferred())), Nil, List(Pattern.Bind("a", Pattern.Value(Ident("_"))), Pattern.Bind("b", Pattern.Value(Ident("_"))), Pattern.Bind("c", Pattern.Value(Ident("_"))))), None, Block(Nil, Literal(Constant.Unit())))))) +Inlined(None, Nil, Match(Ident("Nil"), List(CaseDef(Pattern.Unapply(TypeApply(Select(Ident("List"), "unapplySeq"), List(Inferred())), Nil, List(Pattern.Bind("a", Pattern.WildcardPattern()), Pattern.Bind("b", Pattern.WildcardPattern()), Pattern.Bind("c", Pattern.WildcardPattern()))), None, Block(Nil, Literal(Constant.Unit())))))) Type.SymRef(IsClassDefSymbol(), Type.ThisType(Type.SymRef(IsPackageDefSymbol(), NoPrefix()))) -Inlined(None, Nil, Try(Literal(Constant.Int(1)), List(CaseDef(Pattern.Value(Ident("_")), None, Block(Nil, Literal(Constant.Unit())))), None)) +Inlined(None, Nil, Try(Literal(Constant.Int(1)), List(CaseDef(Pattern.WildcardPattern(), None, Block(Nil, Literal(Constant.Unit())))), None)) Type.OrType(Type.SymRef(IsClassDefSymbol(), Type.ThisType(Type.SymRef(IsPackageDefSymbol(), NoPrefix()))), Type.SymRef(IsClassDefSymbol(), Type.ThisType(Type.SymRef(IsPackageDefSymbol(), NoPrefix())))) Inlined(None, Nil, Try(Literal(Constant.Int(2)), Nil, Some(Literal(Constant.Unit())))) Type.ConstantType(Constant.Int(2)) -Inlined(None, Nil, Try(Literal(Constant.Int(3)), List(CaseDef(Pattern.Value(Ident("_")), None, Block(Nil, Literal(Constant.Unit())))), Some(Literal(Constant.Unit())))) +Inlined(None, Nil, Try(Literal(Constant.Int(3)), List(CaseDef(Pattern.WildcardPattern(), None, Block(Nil, Literal(Constant.Unit())))), Some(Literal(Constant.Unit())))) Type.OrType(Type.SymRef(IsClassDefSymbol(), Type.ThisType(Type.SymRef(IsPackageDefSymbol(), NoPrefix()))), Type.SymRef(IsClassDefSymbol(), Type.ThisType(Type.SymRef(IsPackageDefSymbol(), NoPrefix())))) Inlined(None, Nil, Apply(Select(Literal(Constant.String("a")), "=="), List(Literal(Constant.String("b"))))) diff --git a/tests/run/tasty-extractors-2.check b/tests/run/tasty-extractors-2.check index 84563bdee5d0..cefe2ade91f3 100644 --- a/tests/run/tasty-extractors-2.check +++ b/tests/run/tasty-extractors-2.check @@ -49,7 +49,7 @@ Type.SymRef(IsClassDefSymbol(), Type.ThisType(Type.SymRef(IsPackageD Inlined(None, Nil, Block(List(ClassDef("Foo", DefDef("", Nil, List(Nil), Inferred(), None), List(Apply(Select(New(Inferred()), ""), Nil)), Nil, None, List(DefDef("a", Nil, Nil, Inferred(), Some(Literal(Constant.Int(0))))))), Literal(Constant.Unit()))) Type.SymRef(IsClassDefSymbol(), Type.ThisType(Type.SymRef(IsPackageDefSymbol(), NoPrefix()))) -Inlined(None, Nil, Block(List(ClassDef("Foo", DefDef("", Nil, List(Nil), Inferred(), None), List(Apply(Select(New(Inferred()), ""), Nil), TypeSelect(Select(Ident("_root_"), "scala"), "Product"), TypeSelect(Select(Ident("_root_"), "scala"), "Serializable")), Nil, None, List(DefDef("productElementName", Nil, List(List(ValDef("x$1", TypeSelect(Select(Ident("_root_"), "scala"), "Int"), None))), TypeSelect(Select(Ident("java"), "lang"), "String"), Some(Match(Ident("x$1"), List(CaseDef(Pattern.Value(Ident("_")), None, Apply(Ident("throw"), List(Apply(Select(New(TypeSelect(Select(Ident("java"), "lang"), "IndexOutOfBoundsException")), ""), List(Apply(Select(Select(Select(Ident("java"), "lang"), "String"), "valueOf"), List(Ident("x$1")))))))))))), DefDef("copy", Nil, List(Nil), Inferred(), Some(Apply(Select(New(Inferred()), ""), Nil))))), ValDef("Foo", TypeIdent("Foo$"), Some(Apply(Select(New(TypeIdent("Foo$")), ""), Nil))), ClassDef("Foo$", DefDef("", Nil, List(Nil), Inferred(), None), List(Apply(Select(New(Inferred()), ""), Nil), Applied(Inferred(), List(Inferred())), TypeSelect(Select(Ident("_root_"), "scala"), "Serializable")), Nil, Some(ValDef("_", Singleton(Ident("Foo")), None)), List(DefDef("apply", Nil, List(Nil), Inferred(), Some(Apply(Select(New(Inferred()), ""), Nil))), DefDef("unapply", Nil, List(List(ValDef("x$1", Inferred(), None))), Inferred(), Some(Literal(Constant.Boolean(true))))))), Literal(Constant.Unit()))) +Inlined(None, Nil, Block(List(ClassDef("Foo", DefDef("", Nil, List(Nil), Inferred(), None), List(Apply(Select(New(Inferred()), ""), Nil), TypeSelect(Select(Ident("_root_"), "scala"), "Product"), TypeSelect(Select(Ident("_root_"), "scala"), "Serializable")), Nil, None, List(DefDef("productElementName", Nil, List(List(ValDef("x$1", TypeSelect(Select(Ident("_root_"), "scala"), "Int"), None))), TypeSelect(Select(Ident("java"), "lang"), "String"), Some(Match(Ident("x$1"), List(CaseDef(Pattern.WildcardPattern(), None, Apply(Ident("throw"), List(Apply(Select(New(TypeSelect(Select(Ident("java"), "lang"), "IndexOutOfBoundsException")), ""), List(Apply(Select(Select(Select(Ident("java"), "lang"), "String"), "valueOf"), List(Ident("x$1")))))))))))), DefDef("copy", Nil, List(Nil), Inferred(), Some(Apply(Select(New(Inferred()), ""), Nil))))), ValDef("Foo", TypeIdent("Foo$"), Some(Apply(Select(New(TypeIdent("Foo$")), ""), Nil))), ClassDef("Foo$", DefDef("", Nil, List(Nil), Inferred(), None), List(Apply(Select(New(Inferred()), ""), Nil), Applied(Inferred(), List(Inferred())), TypeSelect(Select(Ident("_root_"), "scala"), "Serializable")), Nil, Some(ValDef("_", Singleton(Ident("Foo")), None)), List(DefDef("apply", Nil, List(Nil), Inferred(), Some(Apply(Select(New(Inferred()), ""), Nil))), DefDef("unapply", Nil, List(List(ValDef("x$1", Inferred(), None))), Inferred(), Some(Literal(Constant.Boolean(true))))))), Literal(Constant.Unit()))) Type.SymRef(IsClassDefSymbol(), Type.ThisType(Type.SymRef(IsPackageDefSymbol(), NoPrefix()))) Inlined(None, Nil, Block(List(ClassDef("Foo1", DefDef("", Nil, List(List(ValDef("a", TypeIdent("Int"), None))), Inferred(), None), List(Apply(Select(New(Inferred()), ""), Nil)), Nil, None, List(ValDef("a", Inferred(), None)))), Literal(Constant.Unit())))