ponyc icon indicating copy to clipboard operation
ponyc copied to clipboard

Calls to ref function inside of box functions prints a missleading error

Open adri326 opened this issue 6 years ago • 3 comments

Howdy,

In a small project using Pony, I stumbled across a simple issue, which actually took me a while to figure out: I was trying to call a ref function inside of a box function, though the compiler gave me an error which made it hard for me to find the actual error. Let me phrase this with an example:

actor Main
  new create(env: Env) =>
    let fox = recover Fox(env) end
    let wolf = Wolf(env, consume fox)
    wolf()
    wolf()

class Wolf
  let _env: Env
  let fox: Fox ref

  new create(env: Env, fox': Fox iso) =>
    _env = env
    fox = consume fox'

  //  v-- inserting a "ref" here fixes the issue
  fun apply() =>
    _env.out.print("I'm in a box function! 🐺")
    fox()

class Fox
  let _env: Env
  var _x: U32 = 0

  new create(env: Env) =>
    _env = env

  fun ref apply() =>
    _x = _x + 1
    _env.out.print("I'm in a ref function, and look at my number: " + _x.string() + " 🦊")

You would have expected the compiler to output an error similar to the one you get when trying to write to a field in a box function:

Cannot write to a field in a box function. If you are trying to change state in a function use fun ref

Though the error I get when running the code looks like this:

/.../project/main.pony:19:8: receiver type is not a subtype of target type
    fox()
       ^
    Info:
    /.../project/main.pony:19:5: receiver type: this->Fox ref
        fox()
        ^
    /.../project/main.pony:28:3: target type: Fox ref
      fun ref apply() =>
      ^
    /.../project/main.pony:10:12: Fox box is not a subtype of Fox ref: box is not a subcap of ref
      let fox: Fox ref

My understanding:

This error message states that Fox box is not a subtype of Fox ref, where no references to any Fox box are made in the above infos. Either the first line of the info is wrong, or it is missing a line stating that the call is being made from withing a box function, meaning that the fox.apply() can only be ran if it would have been a ref function.

I would suggest having an error message saying cannot call a ref method from a field in a box function, use "fun ref" if you are trying to change state in a function.

Additional informations:

Running

0.25.0 [release]
compiled with: llvm 6.0.1 -- cc (GCC) 8.2.1 20180831
Defaults: pic=true ssl=openssl_1.1.0

On Anarchy Linux x86_64; ponyc downloaded from the AUR, version 0.25.0-1

adri326 avatar Jan 23 '19 15:01 adri326

Playground of the above-posted example

adri326 avatar Jan 24 '19 19:01 adri326

I totally agree with you. The error message is confusing and not very helpful. We should make a special case in the error handling where we check both the receiver capability (of this) inside the current method, the viewpoint-adapted capability of the field ehose method is called and the original capability of that field.

That will turn out very helpful, thanks for taking the time to report this one.

mfelsche avatar Jan 25 '19 08:01 mfelsche

Similar to #2083 (+bump).

I'll try to address it during the next two days.

adri326 avatar Jan 15 '20 19:01 adri326