Repository: scalameta/scalameta (scala)

Issue:
InvariantFailedException when printing a type with a literal type parameter
`Foo[42]` can be parsed but can't be printed.

```scala
@ import $ivy.`org.scalameta::scalameta:4.5.3`, scala.meta._
import $ivy.$                               , scala.meta._

@ t"Foo[42]"
res1: Type.Apply = Type.Apply(tpe = Type.Name(value = "Foo"), args = List(Lit.Int(value = 42)))

@ res1.syntax
org.scalameta.invariants.InvariantFailedException: invariant failed:
when verifying og.categories.intersect[String](ig.categories).nonEmpty
found that og.categories.intersect[String](ig.categories).nonEmpty is false
where ig = Literal
where og = Typ
  org.scalameta.invariants.InvariantFailedException$.raise(Exceptions.scala:19)
  scala.meta.internal.prettyprinters.TreeSyntax$SyntaxInstances.groupNeedsParens$1(TreeSyntax.scala:105)
  scala.meta.internal.prettyprinters.TreeSyntax$SyntaxInstances.p(TreeSyntax.scala:115)
  scala.meta.internal.prettyprinters.TreeSyntax$SyntaxInstances.$anonfun$syntaxTree$35(TreeSyntax.scala:620)
  scala.collection.immutable.List.map(List.scala:246)
  scala.meta.internal.prettyprinters.TreeSyntax$SyntaxInstances.$anonfun$syntaxTree$1(TreeSyntax.scala:620)
  scala.meta.prettyprinters.Syntax$$anon$1.apply(Syntax.scala:9)
  scala.meta.internal.prettyprinters.TreeSyntax$.reprint(TreeSyntax.scala:1228)
  scala.meta.internal.prettyprinters.TreeSyntax$.$anonfun$apply$1(TreeSyntax.scala:1222)
  scala.meta.prettyprinters.Syntax$$anon$1.apply(Syntax.scala:9)
  scala.meta.prettyprinters.Api$XtensionSyntax.syntax(Api.scala:11)
  ammonite.$sess.cmd2$.<clinit>(cmd2.sc:1)
```

Pull request:
Fixes #2725 

This innocent-looking one-line change fixes my issue (by allowing literals to be treated as types by the printer), but I'm a little worried it might have some other impact I'm not aware of.

Patch:
diff --git a/scalameta/trees/shared/src/main/scala/scala/meta/internal/prettyprinters/TreeSyntax.scala b/scalameta/trees/shared/src/main/scala/scala/meta/internal/prettyprinters/TreeSyntax.scala
index fe11712059..bc8aa9c359 100644
--- a/scalameta/trees/shared/src/main/scala/scala/meta/internal/prettyprinters/TreeSyntax.scala
+++ b/scalameta/trees/shared/src/main/scala/scala/meta/internal/prettyprinters/TreeSyntax.scala
@@ -64,8 +64,8 @@ object TreeSyntax {
         @leaf class Pattern3(op: String) extends Pat { def precedence = 3 }
         @leaf object SimplePattern extends Pat { def precedence = 6 }
       }
-      @leaf object Literal extends Term with Pat {
-        override def categories = List("Term", "Pat"); def precedence = 6
+      @leaf object Literal extends Term with Pat with Type {
+        override def categories = List("Term", "Pat", "Type"); def precedence = 6
       }
       require(
         Literal.precedence == Term.SimpleExpr1.precedence && Literal.precedence == Pat.SimplePattern.precedence


Test patch:
diff --git a/tests/shared/src/test/scala/scala/meta/tests/prettyprinters/SyntacticSuite.scala b/tests/shared/src/test/scala/scala/meta/tests/prettyprinters/SyntacticSuite.scala
index 897330dbd9..9a97c0da33 100644
--- a/tests/shared/src/test/scala/scala/meta/tests/prettyprinters/SyntacticSuite.scala
+++ b/tests/shared/src/test/scala/scala/meta/tests/prettyprinters/SyntacticSuite.scala
@@ -300,6 +300,15 @@ class SyntacticSuite extends scala.meta.tests.parsers.ParseSuite {
     assertEquals(pat("_: false").syntax, "_: false")
   }
 
+  test("type with a literal type param (#2725)") {
+    val Scala211 = null
+    import dialects.Scala3
+    assertEquals(t"Foo[42]".syntax, "Foo[42]")
+    assertEquals(t"Foo @@ 42".syntax, "Foo @@ 42")
+    assertEquals(t"Foo[true]".syntax, "Foo[true]")
+    assertEquals(q"val x = new Foo[42]".syntax, "val x = new Foo[42]")
+  }
+
   test("packages") {
     assertEquals(source("package foo.bar; class C").syntax, s"package foo.bar${EOL}class C")
     assertEquals(