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

Array.clone should return an iso #1360

Closed
wants to merge 1 commit into from

Conversation

malthe
Copy link
Contributor

@malthe malthe commented Oct 24, 2016

This is analogous to String.clone and allows for example cloning an Array ref and then make it sendable.

With this change, we can write a valid program such as:

actor Foo
  let _s: Array[String val]

  new create(s: Array[String val] iso) =>
    _s = consume s

actor Main
  var _s: Array[String val] = [""]

  new create(env:Env) =>
    let s = _s.clone()
    Foo.create(consume s)

Note that I added a test case for Array.clone() – it was missing.

This is analogous to String.clone and allows for example
cloning an Array ref and then make it sendable.
@Praetonus
Copy link
Member

Unfortunately this isn't safe because Array.clone does a shallow copy. With your change, the following very bad program is allowed.

class A
  var x: USize = 0

actor Main
  new create(env: Env) =>
    let array = [as A: A]
    let array2: Array[A] val = array.clone()
    try
      env.out.print(array2(0).x.string())
      array(0).x = 1
      env.out.print(array2(0).x.string())
    end

This prints 0 then 1.

@Praetonus
Copy link
Member

Praetonus commented Oct 24, 2016

In fact, I think that this recurrent Array iso clone problem can be solved with the method specialisation of this RFC, with a signature like this.

fun clone(): Array[this->A!] iso^ iftype A <: Any #send

So there might be a good solution to this problem after all.

@jemc
Copy link
Member

jemc commented Oct 24, 2016

Yes, this isn't safe. I actually tried to make the same change over a year ago: #279

The reason that you (and historically, I) assumed it was safe was because the compiler didn't halt with a refcap related error message. It didn't halt with an error because Array is built on potentially unsafe Pointer operations - it is possible to violate memory and refcap safety in Array because it holds a Pointer ref, and has access to the private methods of Pointer that are accessible in builtin.

@jemc
Copy link
Member

jemc commented Oct 24, 2016

And yes, I was about to also mention @Praetonus' pending RFC that brings us specialization that can solve this problem. In fact, this specific problem was one of the original motivations for me bringing forward the ticket that formed the basis of that RFC: #683.

@jemc jemc closed this Oct 24, 2016
@jemc
Copy link
Member

jemc commented Oct 24, 2016

Specifically, after @Praetonus' RFC is accepted, we'll be able to do things like:

fun clone(): Array[this->A!] => // ...
fun clone(): Array[A] iso^ iftype A <: Any #share => // ...

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 this pull request may close these issues.

3 participants