Skip to content

Instantly share code, notes, and snippets.

@zainab-ali
Last active January 21, 2026 14:10
Show Gist options
  • Select an option

  • Save zainab-ali/4e2a32e6442de4c960d531d45fe3cc7c to your computer and use it in GitHub Desktop.

Select an option

Save zainab-ali/4e2a32e6442de4c960d531d45fe3cc7c to your computer and use it in GitHub Desktop.
Scalameta 4.14.3+ `source` macro has strange behaviour when substituting types
//> using scala 2.13.18
//> using dep "org.scalameta::scalameta::4.14.3"
// Affected versions: 4.14.3, 4.14.4, 4.14.5
// Note that 4.14.2 is correct
import scala.meta._
// codeA has a type substitution
val fooType = t"Foo"
val codeA = q"""
type Bar = ${fooType}
val qux = "any message"
"""
println(s"Code A syntax:\n ${codeA.syntax}")
// Code A syntax:
// {
// type Bar = Foo
// val qux =
// }
println(s"Code A structure:\n ${codeA.structure}")
// Code A structure:
// Term.Block(List(
// Defn.Type(
// Nil,
// Type.Name("Bar"),
// Type.ParamClause(Nil),
// Type.Name("Foo"),
// Type.Bounds(
// None,
// None,
// Nil,
// Nil
// )
// ),
// Defn.Val(
// Nil,
// List(
// Pat.Var(Term.Name("qux"))
// ),
// None,
// Lit.String("any message")
// )
// ))
// codeB has no substitutions and works correctly
val codeB = q"""
type Bar = Foo
val qux = "any message"
"""
println(s"Code B structure:\n ${codeB.structure}")
// Code B structure:
// Term.Block(List(
// Defn.Type(
// Nil,
// Type.Name("Bar"),
// Type.ParamClause(Nil),
// Type.Name("Foo"),
// Type.Bounds(
// None,
// None,
// Nil,
// Nil
// )
// ),
// Defn.Val(
// Nil,
// List(
// Pat.Var(Term.Name("qux"))
// ),
// None,
// Lit.String("any message")
// )
// ))
println(s"Code B syntax:\n ${codeB.syntax}")
// type Bar = Foo
// val qux = "any message"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment