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

Inline functions that do mutation rejected as ghost #1479

Closed
vkuncak opened this issue Nov 9, 2023 · 3 comments · Fixed by #1481
Closed

Inline functions that do mutation rejected as ghost #1479

vkuncak opened this issue Nov 9, 2023 · 3 comments · Fixed by #1481
Assignees

Comments

@vkuncak
Copy link
Collaborator

vkuncak commented Nov 9, 2023

It seems useful to make use of inline functions and assume they will be mostly taken care by Scala compiler.

Do we expect that something like this should work, or do we wish that the inline function is treated as a function?

object InvalidInvariantCopy {
  case class MyClass(var x: BigInt, var y: BigInt, var isValid: Boolean = true) {
    require(x <= y)    
  }

  inline def changeMyClass(m: MyClass)(inline body: => Unit): Unit =
    m.isValid = false
    body
    m.isValid = true

  def inc(m: MyClass): Unit =
    changeMyClass(m):
      m.x += 1
      m.y += 1
}

In any case, currently it reports

info Running phase AntiAliasing                               
Test.scala:6:14: error: Ghost function changeMyClass cannot have effect on non-ghost state: m.isValid
             inline def changeMyClass(m: MyClass)(inline body: => Unit): Unit =
                        ^
@mario-bucev
Copy link
Collaborator

What a strange error, I've checked against an older commit and the same error appears, at least it's not from #1476...

@vkuncak
Copy link
Collaborator Author

vkuncak commented Nov 9, 2023

The intention of having user-defined change blocks using inline seems doomed, but it helped uncover this.
Trying to make things ghost also confused me. It seems that marking an entire class ghost does not make its mutable fields ghost, but only methods defined in it (if any)? Do we have examples of people putting ghost on a class?

@mario-bucev
Copy link
Collaborator

changeMyClass is annotated with @ghost here because it is "an erased value or an erased inline method or field" according to the doc of isEffectivelyErased.
This check has been added here when we could use erased as a replacement for @ghost. Note that this check to isEffectivelyErased has no equivalent in the Scala 2 frontend.
I think it is safe to allow inline method, since this check was surely meant to only include erased.

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

Successfully merging a pull request may close this issue.

2 participants