Skip to content

Inline expressions with non-trivial computations inside annotations should work or error #22367

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

Closed
belamenso opened this issue Jan 14, 2025 · 2 comments · Fixed by #22371
Closed

Comments

@belamenso
Copy link

Compiler version

3.6.2

Minimized code

inline val msg = "cba".reverse
trait E[T]
def f(using @annotation.implicitNotFound(msg) e: E[Int]): Unit = ()
@main def hello(): Unit = f

Output

[error] -- [E172] Type Error: Main.scala:5:27 
[error] 5 |@main def hello(): Unit = f
[error]   |                           ^
[error]   |    No given instance of type E[Int] was found for parameter e of method f

Expectation

What happened here is that the complex expression "cba".reverse was assigned to an inline constant which was then used inside an annotation, disabling it. What should happens is one of two things. Either print an error that Scala does not support non-trivial inline expressions used inside annotations, or, it should work:

[error] -- [E172] Type Error: Main.scala:5:27 
[error] 5 |@main def hello(): Unit = f
[error]   |                           ^
[error]   |                           abc

Please note that expressions like "ab" + "c" already work, even when the concatenation is split into multiple inline constants.

@som-snytt
Copy link
Contributor

som-snytt commented Jan 14, 2025

I'm curious whether compiletime is supported in annotations.

Edit: no, if the intention was to leverage the special formatting "${A}", which is magic.

def g[A <: String](using @implicitNotFound("ach ${Length[A]}") x: Length[A] < 5 =:= true) = ()

On error,

ach ?Length[A]

and otherwise it is checked

  |Invalid reference to a type variable `Length[A]` found in the annotation argument.
  |The variable does not occur as a parameter in the scope of method `f`.

@hamzaremmal
Copy link
Member

To answer the question in the title of the issue, this should error. There is actually two issues in this issue. The first one (that is related to #22346) is that the inline val should emit an error. In this snippet, it doesn't because an error in Typer is emitted while that check only happens later in InlineVals:

else if tp.derivesFrom(defn.StringClass) || defn.ScalaValueClasses().exists(tp.derivesFrom(_)) then
val pos = if tpt.span.isZeroExtent then rhs.srcPos else tpt.srcPos
report.error(em"inline value must have a literal constant type", pos)
.

The second issue can be reflected by the following snippet:

trait E[T]
def f(using @annotation.implicitNotFound("cba".reverse) e: E[Int]): Unit = ()

Explanation: The code above should error because the parameter of implicitNotFound should be a constant expression. As of today, "cba".reverse is not a constant expression.

@Gedochao Gedochao added area:annotations area:inline and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels Jan 15, 2025
@Gedochao Gedochao changed the title Inilne expressions with non-trivial computations inside annotations should work or error Inline expressions with non-trivial computations inside annotations should work or error Jan 15, 2025
@hamzaremmal hamzaremmal self-assigned this Jan 15, 2025
@WojciechMazur WojciechMazur added this to the 3.7.0 milestone Mar 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants