diff --git a/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala b/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala index f94eac90f037..14d5110ebdd0 100644 --- a/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala +++ b/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala @@ -448,6 +448,20 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler end extension end IdentMethods + type Wildcard = tpd.Ident + + object WildcardTypeTest extends TypeTest[Tree, Wildcard]: + def unapply(x: Tree): Option[Wildcard & x.type] = x match + case x: (tpd.Ident & x.type) if x.name == nme.WILDCARD => Some(x) + case _ => None + end WildcardTypeTest + + object Wildcard extends WildcardModule: + def apply(): Wildcard = + withDefaultPos(untpd.Ident(nme.WILDCARD).withType(dotc.core.Symbols.defn.AnyType)) + def unapply(pattern: Wildcard): true = true + end Wildcard + type Select = tpd.Select object SelectTypeTest extends TypeTest[Tree, Select]: diff --git a/compiler/src/scala/quoted/runtime/impl/printers/Extractors.scala b/compiler/src/scala/quoted/runtime/impl/printers/Extractors.scala index 361727bc8490..da6b32bef4f3 100644 --- a/compiler/src/scala/quoted/runtime/impl/printers/Extractors.scala +++ b/compiler/src/scala/quoted/runtime/impl/printers/Extractors.scala @@ -72,10 +72,14 @@ object Extractors { def result(): String = sb.result() def visitTree(x: Tree): this.type = x match { - case Ident(name) => - this += "Ident(\"" += name += "\")" - case Select(qualifier, name) => - this += "Select(" += qualifier += ", \"" += name += "\")" + case tree: Ref => + tree match + case Wildcard() => + this += "Wildcard()" + case Ident(name) => + this += "Ident(\"" += name += "\")" + case Select(qualifier, name) => + this += "Select(" += qualifier += ", \"" += name += "\")" case This(qual) => this += "This(" += qual += ")" case Super(qual, mix) => diff --git a/compiler/src/scala/quoted/runtime/impl/printers/SourceCode.scala b/compiler/src/scala/quoted/runtime/impl/printers/SourceCode.scala index 55d478bffa72..760182b396ea 100644 --- a/compiler/src/scala/quoted/runtime/impl/printers/SourceCode.scala +++ b/compiler/src/scala/quoted/runtime/impl/printers/SourceCode.scala @@ -328,7 +328,7 @@ object SourceCode { } this - case Ident("_") => + case Wildcard() => this += "_" case tree: Ident => @@ -896,13 +896,13 @@ object SourceCode { } private def printPattern(pattern: Tree): this.type = pattern match { - case Ident("_") => + case Wildcard() => this += "_" - case Bind(name, Ident("_")) => + case Bind(name, Wildcard()) => this += name - case Bind(name, Typed(Ident("_"), tpt)) => + case Bind(name, Typed(Wildcard(), tpt)) => this += highlightValDef(name) += ": " printTypeTree(tpt) @@ -928,7 +928,7 @@ object SourceCode { case Alternatives(trees) => inParens(printPatterns(trees, " | ")) - case Typed(Ident("_"), tpt) => + case Typed(Wildcard(), tpt) => this += "_: " printTypeTree(tpt) diff --git a/library/src/scala/quoted/Quotes.scala b/library/src/scala/quoted/Quotes.scala index d8f1c431a651..74cf211bae9c 100644 --- a/library/src/scala/quoted/Quotes.scala +++ b/library/src/scala/quoted/Quotes.scala @@ -123,7 +123,7 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => * | | +- DefDef * | | +- ValDef * | | - * | +- Term --------+- Ref -+- Ident + * | +- Term --------+- Ref -+- Ident -+- Wildcard * | | +- Select * | | * | +- Literal @@ -784,6 +784,23 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => end extension end IdentMethods + /** Pattern representing a `_` wildcard. */ + type Wildcard <: Ident + + /** `TypeTest` that allows testing at runtime in a pattern match if a `Tree` is a `Wildcard` */ + given WildcardTypeTest: TypeTest[Tree, Wildcard] + + /** Module object of `type Wildcard` */ + val Wildcard: WildcardModule + + /** Methods of the module object `val Wildcard` */ + trait WildcardModule { this: Wildcard.type => + /** Create a tree representing a `_` wildcard. */ + def apply(): Wildcard + /** Match a tree representing a `_` wildcard. */ + def unapply(wildcard: Wildcard): true + } + /** Tree representing a selection of definition with a given name on a given prefix */ type Select <: Ref diff --git a/project/MiMaFilters.scala b/project/MiMaFilters.scala index c4d52097eba8..fc3df64a0002 100644 --- a/project/MiMaFilters.scala +++ b/project/MiMaFilters.scala @@ -5,6 +5,8 @@ import com.typesafe.tools.mima.core.ProblemFilters._ object MiMaFilters { val Library: Seq[ProblemFilter] = Seq( // New APIs that will be introduced in 3.1.0 + exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule.Wildcard"), + exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule.WildcardTypeTest"), exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#SourceFileMethods.getJPath"), exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#SourceFileMethods.name"), exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#SourceFileMethods.path"), diff --git a/tests/pos-macros/i12188b/Macro_1.scala b/tests/pos-macros/i12188b/Macro_1.scala new file mode 100644 index 000000000000..fa9ea10e666a --- /dev/null +++ b/tests/pos-macros/i12188b/Macro_1.scala @@ -0,0 +1,13 @@ +import scala.quoted.* + +object MatchTest { + inline def test[T](inline obj: Any): Unit = ${testImpl('obj)} + + def testImpl[T](objExpr: Expr[T])(using Quotes): Expr[Unit] = { + import quotes.reflect.* + // test that the extractors work + val Inlined(None, Nil, Block(Nil, Match(param @ Ident("a"), List(CaseDef(Literal(IntConstant(1)), None, Block(Nil, Literal(UnitConstant()))), CaseDef(Wildcard(), None, Block(Nil, Literal(UnitConstant()))))))) = objExpr.asTerm + // test that the constructors work + Block(Nil, Match(param, List(CaseDef(Literal(IntConstant(1)), None, Block(Nil, Literal(UnitConstant()))), CaseDef(Wildcard(), None, Block(Nil, Literal(UnitConstant())))))).asExprOf[Unit] + } +} diff --git a/tests/pos-macros/i12188b/Test_2.scala b/tests/pos-macros/i12188b/Test_2.scala new file mode 100644 index 000000000000..ee6ef1fdf075 --- /dev/null +++ b/tests/pos-macros/i12188b/Test_2.scala @@ -0,0 +1,5 @@ +def test(a: Int) = MatchTest.test { + a match + case 1 => + case _ => +} diff --git a/tests/pos-macros/i12188c/Macro_1.scala b/tests/pos-macros/i12188c/Macro_1.scala new file mode 100644 index 000000000000..978e2280759c --- /dev/null +++ b/tests/pos-macros/i12188c/Macro_1.scala @@ -0,0 +1,14 @@ +import scala.quoted.* + +object MatchTest { + inline def test(a: Int): Unit = ${testImpl('a)} + + def testImpl(a: Expr[Any])(using Quotes): Expr[Unit] = { + import quotes.reflect.* + val matchTree = Match(a.asTerm, List( + CaseDef(Literal(IntConstant(1)), None, Block(Nil, Literal(UnitConstant()))), + CaseDef(Alternatives(List(Literal(IntConstant(2)), Literal(IntConstant(3)), Literal(IntConstant(4)))), None, Block(Nil, Literal(UnitConstant()))), + CaseDef(Typed(Wildcard(), TypeIdent(defn.IntClass)), None, Block(Nil, Literal(UnitConstant()))))) + matchTree.asExprOf[Unit] + } +} \ No newline at end of file diff --git a/tests/pos-macros/i12188c/Test_2.scala b/tests/pos-macros/i12188c/Test_2.scala new file mode 100644 index 000000000000..2e7bd48e4a0b --- /dev/null +++ b/tests/pos-macros/i12188c/Test_2.scala @@ -0,0 +1 @@ +def test(a: Int) = MatchTest.test(a) 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 3c2b67edfde0..206dda1448d6 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, TypeIdent("Int"), Some(Apply(Select(Literal(IntConstant(1)), "+"), List(Literal(IntConstant(2)))))) ValDef("bar", TypeIdent("Int"), Some(Apply(Select(Literal(IntConstant(2)), "+"), List(Literal(IntConstant(3)))))) -Bind("x", Ident("_")) +Bind("x", Wildcard()) 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 3c2b67edfde0..206dda1448d6 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, TypeIdent("Int"), Some(Apply(Select(Literal(IntConstant(1)), "+"), List(Literal(IntConstant(2)))))) ValDef("bar", TypeIdent("Int"), Some(Apply(Select(Literal(IntConstant(2)), "+"), List(Literal(IntConstant(3)))))) -Bind("x", Ident("_")) +Bind("x", Wildcard()) diff --git a/tests/run-macros/i12188/Macro_1.scala b/tests/run-macros/i12188/Macro_1.scala new file mode 100644 index 000000000000..619581802e35 --- /dev/null +++ b/tests/run-macros/i12188/Macro_1.scala @@ -0,0 +1,23 @@ +import scala.quoted.* + +object MatchTest { + inline def test[T](inline obj: T): String = ${testImpl('obj)} + + def testImpl[T](objExpr: Expr[T])(using qctx: Quotes, t: Type[T]): Expr[String] = { + import qctx.reflect.* + + val obj = objExpr.asTerm + val cases = obj.tpe.typeSymbol.children.map { child => + val subtype = TypeIdent(child) + val bind = Symbol.newBind(Symbol.spliceOwner, "c", Flags.EmptyFlags, subtype.tpe) + CaseDef(Bind(bind, Typed(Ref(bind), subtype)), None, Literal(StringConstant(subtype.show))) + } ::: { + CaseDef(Wildcard(), None, Literal(StringConstant("default"))) + } :: Nil + val bind = Symbol.newBind(Symbol.spliceOwner, "o", Flags.EmptyFlags, obj.tpe) + val result = Match(obj, cases) + val code = result.show(using Printer.TreeAnsiCode) + // println(code) + result.asExprOf[String] + } +} \ No newline at end of file diff --git a/tests/run-macros/i12188/Test_2.scala b/tests/run-macros/i12188/Test_2.scala new file mode 100644 index 000000000000..a3d0f0de58fb --- /dev/null +++ b/tests/run-macros/i12188/Test_2.scala @@ -0,0 +1,8 @@ +sealed trait P +case class PC1(a: String) extends P +case class PC2(b: Int) extends P + +@main def Test = + println(MatchTest.test(PC1("ab"): P)) + println(MatchTest.test(PC2(10): P)) + println(MatchTest.test(null: P)) diff --git a/tests/run-macros/tasty-extractors-1.check b/tests/run-macros/tasty-extractors-1.check index 5e7a330779eb..bebfa3d79dbc 100644 --- a/tests/run-macros/tasty-extractors-1.check +++ b/tests/run-macros/tasty-extractors-1.check @@ -40,37 +40,37 @@ OrType(ConstantType(IntConstant(1)), ConstantType(IntConstant(2))) Inlined(None, Nil, Match(Literal(StringConstant("a")), List(CaseDef(Literal(StringConstant("a")), None, Block(Nil, Literal(UnitConstant())))))) TypeRef(ThisType(TypeRef(NoPrefix(), "scala")), "Unit") -Inlined(None, Nil, Match(Literal(StringConstant("b")), List(CaseDef(Bind("n", Ident("_")), None, Block(Nil, Literal(UnitConstant())))))) +Inlined(None, Nil, Match(Literal(StringConstant("b")), List(CaseDef(Bind("n", Wildcard()), None, Block(Nil, Literal(UnitConstant())))))) TypeRef(ThisType(TypeRef(NoPrefix(), "scala")), "Unit") -Inlined(None, Nil, Match(Literal(StringConstant("c")), List(CaseDef(Bind("n", Typed(Ident("_"), TypeIdent("String"))), None, Block(Nil, Literal(UnitConstant())))))) +Inlined(None, Nil, Match(Literal(StringConstant("c")), List(CaseDef(Bind("n", Typed(Wildcard(), TypeIdent("String"))), None, Block(Nil, Literal(UnitConstant())))))) TypeRef(ThisType(TypeRef(NoPrefix(), "scala")), "Unit") -Inlined(None, Nil, Match(Literal(StringConstant("e")), List(CaseDef(Ident("_"), None, Block(Nil, Literal(UnitConstant())))))) +Inlined(None, Nil, Match(Literal(StringConstant("e")), List(CaseDef(Wildcard(), None, Block(Nil, Literal(UnitConstant())))))) TypeRef(ThisType(TypeRef(NoPrefix(), "scala")), "Unit") -Inlined(None, Nil, Match(Literal(StringConstant("f")), List(CaseDef(Typed(Ident("_"), TypeIdent("String")), None, Block(Nil, Literal(UnitConstant())))))) +Inlined(None, Nil, Match(Literal(StringConstant("f")), List(CaseDef(Typed(Wildcard(), TypeIdent("String")), None, Block(Nil, Literal(UnitConstant())))))) TypeRef(ThisType(TypeRef(NoPrefix(), "scala")), "Unit") -Inlined(None, Nil, Match(Typed(Literal(StringConstant("g")), TypeIdent("Any")), List(CaseDef(Alternatives(List(Typed(Ident("_"), TypeIdent("String")), Typed(Ident("_"), TypeIdent("Int")))), None, Block(Nil, Literal(UnitConstant())))))) +Inlined(None, Nil, Match(Typed(Literal(StringConstant("g")), TypeIdent("Any")), List(CaseDef(Alternatives(List(Typed(Wildcard(), TypeIdent("String")), Typed(Wildcard(), TypeIdent("Int")))), None, Block(Nil, Literal(UnitConstant())))))) TypeRef(ThisType(TypeRef(NoPrefix(), "scala")), "Unit") -Inlined(None, Nil, Match(Literal(StringConstant("h")), List(CaseDef(Ident("_"), Some(Literal(BooleanConstant(false))), Block(Nil, Literal(UnitConstant())))))) +Inlined(None, Nil, Match(Literal(StringConstant("h")), List(CaseDef(Wildcard(), Some(Literal(BooleanConstant(false))), Block(Nil, Literal(UnitConstant())))))) TypeRef(ThisType(TypeRef(NoPrefix(), "scala")), "Unit") -Inlined(None, Nil, Block(List(ValDef("a", Inferred(), Some(Literal(StringConstant("o"))))), Match(Literal(StringConstant("i")), List(CaseDef(Bind("a", Ident("_")), None, Block(Nil, Literal(UnitConstant()))))))) +Inlined(None, Nil, Block(List(ValDef("a", Inferred(), Some(Literal(StringConstant("o"))))), Match(Literal(StringConstant("i")), List(CaseDef(Bind("a", Wildcard()), None, Block(Nil, Literal(UnitConstant()))))))) TypeRef(ThisType(TypeRef(NoPrefix(), "scala")), "Unit") -Inlined(None, Nil, Match(Ident("Nil"), List(CaseDef(Unapply(TypeApply(Select(Ident("List"), "unapplySeq"), List(Inferred())), Nil, List(Bind("a", Ident("_")), Bind("b", Ident("_")), Bind("c", Ident("_")))), None, Block(Nil, Literal(UnitConstant())))))) +Inlined(None, Nil, Match(Ident("Nil"), List(CaseDef(Unapply(TypeApply(Select(Ident("List"), "unapplySeq"), List(Inferred())), Nil, List(Bind("a", Wildcard()), Bind("b", Wildcard()), Bind("c", Wildcard()))), None, Block(Nil, Literal(UnitConstant())))))) TypeRef(ThisType(TypeRef(NoPrefix(), "scala")), "Unit") -Inlined(None, Nil, Try(Literal(IntConstant(1)), List(CaseDef(Ident("_"), None, Block(Nil, Literal(UnitConstant())))), None)) +Inlined(None, Nil, Try(Literal(IntConstant(1)), List(CaseDef(Wildcard(), None, Block(Nil, Literal(UnitConstant())))), None)) OrType(ConstantType(IntConstant(1)), TypeRef(ThisType(TypeRef(NoPrefix(), "scala")), "Unit")) Inlined(None, Nil, Try(Literal(IntConstant(2)), Nil, Some(Literal(UnitConstant())))) ConstantType(IntConstant(2)) -Inlined(None, Nil, Try(Literal(IntConstant(3)), List(CaseDef(Ident("_"), None, Block(Nil, Literal(UnitConstant())))), Some(Literal(UnitConstant())))) +Inlined(None, Nil, Try(Literal(IntConstant(3)), List(CaseDef(Wildcard(), None, Block(Nil, Literal(UnitConstant())))), Some(Literal(UnitConstant())))) OrType(ConstantType(IntConstant(3)), TypeRef(ThisType(TypeRef(NoPrefix(), "scala")), "Unit")) Inlined(None, Nil, Literal(BooleanConstant(false))) diff --git a/tests/run-macros/tasty-extractors-2.check b/tests/run-macros/tasty-extractors-2.check index 1223a1fb71d9..5dd6af8d8b04 100644 --- a/tests/run-macros/tasty-extractors-2.check +++ b/tests/run-macros/tasty-extractors-2.check @@ -49,7 +49,7 @@ TypeRef(ThisType(TypeRef(NoPrefix(), "scala")), "Unit") Inlined(None, Nil, Block(List(ClassDef("Foo", DefDef("", List(TermParamClause(Nil)), Inferred(), None), List(Apply(Select(New(Inferred()), ""), Nil)), None, List(DefDef("a", Nil, Inferred(), Some(Literal(IntConstant(0))))))), Literal(UnitConstant()))) TypeRef(ThisType(TypeRef(NoPrefix(), "scala")), "Unit") -Inlined(None, Nil, Block(List(ClassDef("Foo", DefDef("", List(TermParamClause(Nil)), Inferred(), None), List(Apply(Select(New(Inferred()), ""), Nil), TypeSelect(Select(Ident("_root_"), "scala"), "Product"), TypeSelect(Select(Ident("_root_"), "scala"), "Serializable")), None, List(DefDef("hashCode", List(TermParamClause(Nil)), Inferred(), Some(Apply(Ident("_hashCode"), List(This(Some("Foo")))))), DefDef("equals", List(TermParamClause(List(ValDef("x$0", Inferred(), None)))), Inferred(), Some(Apply(Select(Apply(Select(This(Some("Foo")), "eq"), List(TypeApply(Select(Ident("x$0"), "$asInstanceOf$"), List(Inferred())))), "||"), List(Match(Ident("x$0"), List(CaseDef(Bind("x$0", Typed(Ident("_"), Inferred())), None, Apply(Select(Literal(BooleanConstant(true)), "&&"), List(Apply(Select(Ident("x$0"), "canEqual"), List(This(Some("Foo"))))))), CaseDef(Ident("_"), None, Literal(BooleanConstant(false))))))))), DefDef("toString", List(TermParamClause(Nil)), Inferred(), Some(Apply(Ident("_toString"), List(This(Some("Foo")))))), DefDef("canEqual", List(TermParamClause(List(ValDef("that", Inferred(), None)))), Inferred(), Some(TypeApply(Select(Ident("that"), "isInstanceOf"), List(Inferred())))), DefDef("productArity", Nil, Inferred(), Some(Literal(IntConstant(0)))), DefDef("productPrefix", Nil, Inferred(), Some(Literal(StringConstant("Foo")))), DefDef("productElement", List(TermParamClause(List(ValDef("n", Inferred(), None)))), Inferred(), Some(Match(Ident("n"), List(CaseDef(Ident("_"), None, Apply(Ident("throw"), List(Apply(Select(New(Inferred()), ""), List(Apply(Select(Ident("n"), "toString"), Nil)))))))))), DefDef("productElementName", List(TermParamClause(List(ValDef("n", Inferred(), None)))), Inferred(), Some(Match(Ident("n"), List(CaseDef(Ident("_"), None, Apply(Ident("throw"), List(Apply(Select(New(Inferred()), ""), List(Apply(Select(Ident("n"), "toString"), Nil)))))))))), DefDef("copy", List(TermParamClause(Nil)), Inferred(), Some(Apply(Select(New(Inferred()), ""), Nil))))), ValDef("Foo", TypeIdent("Foo$"), Some(Apply(Select(New(TypeIdent("Foo$")), ""), Nil))), ClassDef("Foo$", DefDef("", List(TermParamClause(Nil)), Inferred(), None), List(Apply(Select(New(Inferred()), ""), Nil), Inferred()), Some(ValDef("_", Singleton(Ident("Foo")), None)), List(DefDef("apply", List(TermParamClause(Nil)), Inferred(), Some(Apply(Select(New(Inferred()), ""), Nil))), DefDef("unapply", List(TermParamClause(List(ValDef("x$1", Inferred(), None)))), Singleton(Literal(BooleanConstant(true))), Some(Literal(BooleanConstant(true)))), DefDef("toString", Nil, Inferred(), Some(Literal(StringConstant("Foo")))), TypeDef("MirroredMonoType", TypeBoundsTree(Inferred(), Inferred())), DefDef("fromProduct", List(TermParamClause(List(ValDef("x$0", Inferred(), None)))), Inferred(), Some(Apply(Select(New(Inferred()), ""), Nil)))))), Literal(UnitConstant()))) +Inlined(None, Nil, Block(List(ClassDef("Foo", DefDef("", List(TermParamClause(Nil)), Inferred(), None), List(Apply(Select(New(Inferred()), ""), Nil), TypeSelect(Select(Ident("_root_"), "scala"), "Product"), TypeSelect(Select(Ident("_root_"), "scala"), "Serializable")), None, List(DefDef("hashCode", List(TermParamClause(Nil)), Inferred(), Some(Apply(Ident("_hashCode"), List(This(Some("Foo")))))), DefDef("equals", List(TermParamClause(List(ValDef("x$0", Inferred(), None)))), Inferred(), Some(Apply(Select(Apply(Select(This(Some("Foo")), "eq"), List(TypeApply(Select(Ident("x$0"), "$asInstanceOf$"), List(Inferred())))), "||"), List(Match(Ident("x$0"), List(CaseDef(Bind("x$0", Typed(Wildcard(), Inferred())), None, Apply(Select(Literal(BooleanConstant(true)), "&&"), List(Apply(Select(Ident("x$0"), "canEqual"), List(This(Some("Foo"))))))), CaseDef(Wildcard(), None, Literal(BooleanConstant(false))))))))), DefDef("toString", List(TermParamClause(Nil)), Inferred(), Some(Apply(Ident("_toString"), List(This(Some("Foo")))))), DefDef("canEqual", List(TermParamClause(List(ValDef("that", Inferred(), None)))), Inferred(), Some(TypeApply(Select(Ident("that"), "isInstanceOf"), List(Inferred())))), DefDef("productArity", Nil, Inferred(), Some(Literal(IntConstant(0)))), DefDef("productPrefix", Nil, Inferred(), Some(Literal(StringConstant("Foo")))), DefDef("productElement", List(TermParamClause(List(ValDef("n", Inferred(), None)))), Inferred(), Some(Match(Ident("n"), List(CaseDef(Wildcard(), None, Apply(Ident("throw"), List(Apply(Select(New(Inferred()), ""), List(Apply(Select(Ident("n"), "toString"), Nil)))))))))), DefDef("productElementName", List(TermParamClause(List(ValDef("n", Inferred(), None)))), Inferred(), Some(Match(Ident("n"), List(CaseDef(Wildcard(), None, Apply(Ident("throw"), List(Apply(Select(New(Inferred()), ""), List(Apply(Select(Ident("n"), "toString"), Nil)))))))))), DefDef("copy", List(TermParamClause(Nil)), Inferred(), Some(Apply(Select(New(Inferred()), ""), Nil))))), ValDef("Foo", TypeIdent("Foo$"), Some(Apply(Select(New(TypeIdent("Foo$")), ""), Nil))), ClassDef("Foo$", DefDef("", List(TermParamClause(Nil)), Inferred(), None), List(Apply(Select(New(Inferred()), ""), Nil), Inferred()), Some(ValDef("_", Singleton(Ident("Foo")), None)), List(DefDef("apply", List(TermParamClause(Nil)), Inferred(), Some(Apply(Select(New(Inferred()), ""), Nil))), DefDef("unapply", List(TermParamClause(List(ValDef("x$1", Inferred(), None)))), Singleton(Literal(BooleanConstant(true))), Some(Literal(BooleanConstant(true)))), DefDef("toString", Nil, Inferred(), Some(Literal(StringConstant("Foo")))), TypeDef("MirroredMonoType", TypeBoundsTree(Inferred(), Inferred())), DefDef("fromProduct", List(TermParamClause(List(ValDef("x$0", Inferred(), None)))), Inferred(), Some(Apply(Select(New(Inferred()), ""), Nil)))))), Literal(UnitConstant()))) TypeRef(ThisType(TypeRef(NoPrefix(), "scala")), "Unit") Inlined(None, Nil, Block(List(ClassDef("Foo1", DefDef("", List(TermParamClause(List(ValDef("a", TypeIdent("Int"), None)))), Inferred(), None), List(Apply(Select(New(Inferred()), ""), Nil)), None, List(ValDef("a", Inferred(), None)))), Literal(UnitConstant())))