propensive / contextual

Statically-checked string interpolation in Scala
https://soundness.dev/contextual/
251 stars 23 forks source link

Error macro has not been expanded in Scala 2.13.0 #54

Closed vilu closed 4 years ago

vilu commented 5 years ago
package com.mobimeo.ticketissuer.primitives

import contextual._

object Test  {
  val NonEmptyString = NonEmptyStringModule.Instance
  type NonEmptyString = NonEmptyString.Type

  sealed abstract class NonEmptyStringModule {
    type Type <: String

    def apply(string: String): Option[NonEmptyString] =
      NonEmptyStringParser.check(string).toOption
  }

  object NonEmptyStringModule {
    val Instance: NonEmptyStringModule = new NonEmptyStringModule {
      type Type = String
    }
  }

  object NonEmptyStringParser extends Verifier[NonEmptyString] {
    def check(string: String): Either[(Int, String), NonEmptyString] =
      if (string.isEmpty()) Left(0 -> "string must not be empty") else Right(string.asInstanceOf[NonEmptyString])
  }

  implicit class NonEmptyStringContext(sc: StringContext) {
    val n = Prefix(NonEmptyStringParser, sc)
  }

  n"foo"

}

This gives me an Error:(31, 3) macro has not been expanded n"foo"

It did work in Scala 2.12.x

mblaze commented 4 years ago

Did you figure out a workaround or pinpointed what causes the macro to not expand?

som-snytt commented 4 years ago

This must be due to the stabilizer change, where q.m() is rewritten to val stable = q ; stable.m() to bring parts of the stable type into implicit scope. I'll take a further look, because I already took a whack at stabilization issues, and I also wanted to learn more about this project. It's been a while since I hacked on macros. It's like Crisis on Infinite Earths, where everything you know or could imagine is about to be obliterated and replaced with something unimaginable, something void of imagination. Can one heroic act make a difference?

If the problem is the tree shape, why doesn't the f-interpolator fail?