Skip to content
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

operator identifier with some characters from Unicode Sm and So categories can't be injected into string literal #12484

Closed
unkarjedy opened this issue Nov 6, 2021 · 4 comments · Fixed by scala/scala#9805
Assignees
Labels
Milestone

Comments

@unkarjedy
Copy link

unkarjedy commented Nov 6, 2021

Scala 2.13.7

from https://www.scala-lang.org/files/archive/spec/2.13/13-syntax-summary.html

opchar           ::=  ‘!’ | ‘#’ | ‘%’ | ‘&’ | ‘*’ | ‘+’ | ‘-’ | ‘/’ | ‘:’ |
                      ‘<’ | ‘=’ | ‘>’ | ‘?’ | ‘@’ | ‘\’ | ‘^’ | ‘|’ | ‘~’
                      and any character in Unicode categories Sm or So
...
op               ::=  opchar {opchar}
plainid          ::=  ... |  op
id               ::=  plainid |  ...
...
interpolatedStringPart  ::= printableChar \ (‘"’ | ‘$’ | ‘\’) | escape
escape                  ::=  ... |  ‘\$’ id |  ...

Example code

//noinspection TypeAnnotation,NotImplementedCode
class Wrapper2 {
  val  = 1 // category: So other
  val  = 1 // category: Sm math
  val 𝓅 = 1 // category: Ll math (suppl)
  val 𐐀 = 1 // category: Lu (suppl)

  s"$⚕" // bad
  s"$⨀" // bad
  s"$𝓅" // ok
  s"$𐐀" // ok
}

Expected
No compilation errors due to spec ^

Actual

invalid string interpolation $⨀, expected: $$, $", $identifier or ${expression}
invalid string interpolation $⚕, expected: $$, $", $identifier or ${expression}

It compiles fine with ${...} injector though:

s"${⚕}" // ok
s"${⨀}" // ok
s"${𝓅}" // ok
s"${𐐀}" // ok

relates to:
#12482
#1406
scala/scala#9687

@som-snytt
Copy link

Perhaps the spec (which was updated to include the interpolation SIP relatively recently) needs a tweak, but the "short" form has restrictions (which I don't even remember off the top of my head). My previous PR to "why can't we just accept all valid identifiers (including backticks!)" was rejected because I am not in charge around here.

Showing that ordinary "operator" identifiers are rejected:

Welcome to Scala 2.13.7 (OpenJDK 64-Bit Server VM, Java 17).
Type in expressions for evaluation. Or try :help.

scala> def * = 42
def $times: Int

scala> s"$*"
         ^
       error: invalid string interpolation $*, expected: $$, $", $identifier or ${expression}
           ^
       error: unclosed string literal

scala> def x_* = 42
def x_$times: Int

scala> s"$x_*"
          ^
       error: not found: value x_

@unkarjedy
Copy link
Author

unkarjedy commented Nov 6, 2021

Can we fix the spec then before closing the ticket?

@som-snytt
Copy link

I'll try to give it a lick of paint in the other PR! while it's fresh in my head. Actually I reopen here for tracking that. There are a few moving parts in the issues you raised.

@som-snytt
Copy link

Actually I got confused about what is supposed to be allowed. Why can't it just be all identifiers? he whined.

The spec already says the "simple form" of interpolation is restricted identifiers consisting of alnums.

It is less precise about legal interpolation ids, the identifier in front of the double quote.

I did not expect this to work just now:

Welcome to Scala 2.13.7 (OpenJDK 64-Bit Server VM, Java 17).
Type in expressions for evaluation. Or try :help.

scala> implicit class P(sc: StringContext) { def x_*(parts: Any*) = "ha" }
class P

scala> x_*"no"
val res0: String = ha

because of the restriction on interpolated identifiers. So the spec is correct not to say more.

I don't like the spec language where " is called a single quote. It is a single double quote! Oh, well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
3 participants