New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
quasiquotes (and reify) mishandle string literals #8547
Comments
Imported From: https://issues.scala-lang.org/browse/SI-8547?orig=1 |
@paulp said: |
@paulp said: """bob\'s"""
res5: String = bob\'s So when it says I have a Literal "bob's" I ought to have a literal "bob's" and that's the literal I ought to have. |
@xeno-by said: scala> val Literal(Constant(x1)) = q""" "bob's" """
x1: Any = bob's
scala> x1.asInstanceOf[String].length
res2: Int = 5
scala> val Literal(Constant(x2)) = q""" "bob\'s" """
x2: Any = bob's
scala> x2.asInstanceOf[String].length
res4: Int = 5 Looks like the former is just a repl printing bug, whereas the latter seems to be a genuine problem. Maybe that's caused by one of the string interpolation issues? |
@som-snytt said: case Literal(x) => print(x.escapedStringValue) Eugene's x2 is just normal parsing of the thing inside triple quotes, where normal escaping happens for normal strings. Isn't that normal? scala> val Literal(Constant(s: String)) = q""" "bob\\'s" """ // normal escaping required for literal
s: String = bob\'s
scala> val Literal(Constant(s: String)) = q""" "\"bob's\"" """
s: String = "bob's"
scala> val Literal(Constant(s: String)) = q""""bob\\'s"""" // it's possible to ruin your eyesight
s: String = bob\'s I was just improving messages for interactions like s"\d".r // expecting wrongly that \d is preserved for regex
s"abc\"def" // expecting wrongly that quote is escaped under interpolation
// so s/interpolation/interpretation/
scala> s"\d".r // real people spend hours debugging this
scala.StringContext$InvalidEscapeException: invalid escape '\d' not one of [\b, \t, \n, \f, \r, \\, \", \'] at index 0 in "\d". Use \\ for literal \. My two thoughts were that s should be a macro to get ahead of the errors, as f can, and that it's impossible to warn in general for arbitrary interpolators, so it would be nice if non-macro interpolators could have a compile-time verify feature, because you don't know in advance what the escape policy is for the macro. What if by convention, |
@paulp said: Part of the overall difficulty is that all the quoting forms are overloaded for quasiquoting and for the literals you might be quasiquoting. How do you express a triple-quoted string literal in quasiquotes? Some of these are errors right now but shouldn't be: """-quasiquote containing """-literal // this may not be expressible
"""-quasiquote containing "-literal // this does the wrong thing (injecting backslashes)
"-quasiquote containing """-literal // this is not presently expressible but should be
"-quasiquote containing "-literal // this does the wrong thing (parse error) The poor design of string interpolation most likely excludes any good solution. But in a single quoted quasiquote, backslash-quote should be escaped from the quasiquote and thus act like a normal double-quote within the quasiquote context. This should be a string literal "b" not a weird error. scala> q"\"b\""
<console>:1: error: ';' expected but string literal found.
q"\"b\""
^ If I switch to reify (is there a block-syntax quasiquoting mode?) then I get the right behavior for all the quoting forms. scala> val Literal(Constant(x1)) = (reify { """bob's""" }).tree
x1: Any = bob's
scala> val Literal(Constant(x1)) = (reify { """bob\'s""" }).tree
x1: Any = bob\'s
scala> val Literal(Constant(x1)) = (reify { "bob's" }).tree
x1: Any = bob's
scala> val Literal(Constant(x1)) = (reify { "bob\'s" }).tree
x1: Any = bob's
scala> val Literal(Constant(x1)) = (reify { "bob\\'s" }).tree
x1: Any = bob\'s |
@som-snytt said: |
@paulp said: import scala.reflect.runtime.universe._
object Test {
def main(args: Array[String]): Unit = {
println(q""" "bob's" """.value)
println(q""" "bob\'s" """.value)
println(q""" "bob\\'s" """.value)
println(q""" "bob\\\'s" """.value)
println(q""" "\n" """.value)
println(q""" "\\n" """.value)
println(q""" "\\\n" """.value)
println(q""" "\\\\n" """.value)
}
}
Constant(bob's)
Constant(bob's)
Constant(bob\'s)
Constant(bob\'s)
Constant(
)
Constant(\n)
Constant(\
)
Constant(\\n) |
@paulp said: The requirement that many different tasks be accomplished via string interpolation yet with no way to nest strings indicates foresight comparable to that shown by the US during the invasion of iraq. "Freedom is untidy," we heard after that one. |
@paulp said: |
@som-snytt said: It's not a question of if guillemets are coming, but what feature they will serve when they arrive. scala> s«"bob's"»
res0: String = "bob's" It will depend on Martin's keyboard. |
I also just noticed this doesn't deconst the type argument to Expr.
The text was updated successfully, but these errors were encountered: