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

Trait default method segfault #4451

Open
tetotechy opened this issue Sep 24, 2023 · 4 comments
Open

Trait default method segfault #4451

tetotechy opened this issue Sep 24, 2023 · 4 comments
Labels
bug Something isn't working help wanted Extra attention is needed needs investigation This needs to be looked into before its "ready for work"

Comments

@tetotechy
Copy link

Hi!

Pony is an amazing project, it was love at first sight for me. Having tried so many other languages, I can tell you I am having a great deal of fun and satisfaction coding in Pony. Congratulations, please keep it up!

I have bumped into this problem trying to define a default trait method that returns a literal object. The example is overly-simplified and looks useless and dumb, but the intent is to provide a capability-adding method to the object adopting the trait. New capabilities are additive, so it makes sense that the new augmented object, in turn, implement the trait.
As an alternative solution, I have implemented a separate class that returns the object literal in its apply method.
I am wondering whether I am hitting some consistent limitation I am not aware of, or this might be a bug.

Thanks!

@ponylang-main ponylang-main added the discuss during sync Should be discussed during an upcoming sync label Sep 24, 2023
@SeanTAllen SeanTAllen added help wanted Extra attention is needed bug Something isn't working needs investigation This needs to be looked into before its "ready for work" labels Sep 24, 2023
@SeanTAllen
Copy link
Member

Code in question:

actor Main
  new create(env: Env) =>
    Foo[String box](env, "message")
    Foo[String box].double()(env, "message")

    
trait Printer[T: Stringable box]
  fun apply(env: Env, msg: T)
  
  fun double(): Printer[T] =>
    object ref is Printer[T]
      fun apply(env: Env, msg: T) =>
        env.out.print("First " + msg.string())
        env.out.print("Second " + msg.string())
    end


class Foo[T: Stringable box] is Printer[T]
  fun apply(env: Env, msg: T) =>
    env.out.print("Just one " + msg.string())

@SeanTAllen
Copy link
Member

SeanTAllen commented Sep 24, 2023

Here's the backtrace from a debug version of the compiler:

/home/sean/code/ponylang/ponyc/src/libponyc/pass/expr.c:661: pass_expr: Assertion `errors_get_count(options->check.errors) > 0` failed.

Backtrace:
  /home/sean/code/ponylang/ponyc/build/debug/ponyc(ponyint_assert_fail+0x96) [0x555555d2afb6]
  /home/sean/code/ponylang/ponyc/build/debug/ponyc(pass_expr+0x534) [0x555555c868e4]
  /home/sean/code/ponylang/ponyc/build/debug/ponyc(ast_visit+0x2a4) [0x555555c87224]
  /home/sean/code/ponylang/ponyc/build/debug/ponyc(ast_visit+0x1e4) [0x555555c87164]
  /home/sean/code/ponylang/ponyc/build/debug/ponyc(ast_visit+0x1e4) [0x555555c87164]
  /home/sean/code/ponylang/ponyc/build/debug/ponyc(ast_visit+0x1e4) [0x555555c87164]
  /home/sean/code/ponylang/ponyc/build/debug/ponyc(ast_visit+0x1e4) [0x555555c87164]
  /home/sean/code/ponylang/ponyc/build/debug/ponyc(ast_visit+0x1e4) [0x555555c87164]
  /home/sean/code/ponylang/ponyc/build/debug/ponyc(ast_visit+0x1e4) [0x555555c87164]
  /home/sean/code/ponylang/ponyc/build/debug/ponyc(ast_visit+0x1e4) [0x555555c87164]
  /home/sean/code/ponylang/ponyc/build/debug/ponyc(ast_visit+0x1e4) [0x555555c87164]
  /home/sean/code/ponylang/ponyc/build/debug/ponyc(ast_visit+0x1e4) [0x555555c87164]
  /home/sean/code/ponylang/ponyc/build/debug/ponyc(ast_visit+0x1e4) [0x555555c87164]
  /home/sean/code/ponylang/ponyc/build/debug/ponyc(+0x733ce6) [0x555555c87ce6]
  /home/sean/code/ponylang/ponyc/build/debug/ponyc(+0x7336aa) [0x555555c876aa]
  /home/sean/code/ponylang/ponyc/build/debug/ponyc(ast_passes_type+0x114) [0x555555c879f4]
  /home/sean/code/ponylang/ponyc/build/debug/ponyc(+0x7bc485) [0x555555d10485]
  /home/sean/code/ponylang/ponyc/build/debug/ponyc(expr_object+0x1a15) [0x555555d0f905]
  /home/sean/code/ponylang/ponyc/build/debug/ponyc(pass_expr+0x422) [0x555555c867d2]
  /home/sean/code/ponylang/ponyc/build/debug/ponyc(ast_visit+0x2a4) [0x555555c87224]
  /home/sean/code/ponylang/ponyc/build/debug/ponyc(ast_visit+0x1e4) [0x555555c87164]
  /home/sean/code/ponylang/ponyc/build/debug/ponyc(ast_visit+0x1e4) [0x555555c87164]
  /home/sean/code/ponylang/ponyc/build/debug/ponyc(ast_visit+0x1e4) [0x555555c87164]
  /home/sean/code/ponylang/ponyc/build/debug/ponyc(ast_visit+0x1e4) [0x555555c87164]
  /home/sean/code/ponylang/ponyc/build/debug/ponyc(ast_visit+0x1e4) [0x555555c87164]
  /home/sean/code/ponylang/ponyc/build/debug/ponyc(ast_visit+0x1e4) [0x555555c87164]
  /home/sean/code/ponylang/ponyc/build/debug/ponyc(ast_visit+0x1e4) [0x555555c87164]
  /home/sean/code/ponylang/ponyc/build/debug/ponyc(+0x733ce6) [0x555555c87ce6]
  /home/sean/code/ponylang/ponyc/build/debug/ponyc(+0x7336aa) [0x555555c876aa]
  /home/sean/code/ponylang/ponyc/build/debug/ponyc(ast_passes_program+0x22) [0x555555c872f2]
  /home/sean/code/ponylang/ponyc/build/debug/ponyc(program_load+0xb8) [0x555555ca9e58]
  /home/sean/code/ponylang/ponyc/build/debug/ponyc(+0x6d232c) [0x555555c2632c]
  /home/sean/code/ponylang/ponyc/build/debug/ponyc(main+0x261) [0x555555c261d1]
  /lib/x86_64-linux-gnu/libc.so.6(+0x29d90) [0x7ffff7ca6d90]
  /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x80) [0x7ffff7ca6e40]
  /home/sean/code/ponylang/ponyc/build/debug/ponyc(_start+0x25) [0x555555c25ea5]
Process 1091 stopped
* thread #1, name = 'ponyc', stop reason = signal SIGABRT

For the uninitated, when you go to look at pass_expr, what this is indicating is that when we attempted to compile this, something returned false from an expression pass handling step (setting r to false) but didn't get an error. That is "ungood".

@SeanTAllen
Copy link
Member

The AST item in question when we go boom appears to be a TK_DOT.

tk_dot ends up in entity_access which definitely returns false from some locations without setting an error.

Next step is additional debugging to figure out what is the unexpected bit and probably one of:

  • how we getting this far without having already displayed an error earlier
  • what was supposed to have been done earlier that wasn't
  • what's the unhandled case

in all likelihood, its the first in that list.

@SeanTAllen
Copy link
Member

SeanTAllen commented Sep 24, 2023

Changing to:

actor Main
  new create(env: Env) =>
    Foo[String box](env, "message")
    Foo[String box].double()(env, "message")

    
trait Printer[T: Stringable box]
  fun apply(env: Env, msg: T)
  
  fun double(): Printer[T] =>
    Foo[T]


class Foo[T: Stringable box] is Printer[T]
  fun apply(env: Env, msg: T) =>
    env.out.print("Just one " + msg.string())

fixes the issue, so, focus on the object literal when debugging.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working help wanted Extra attention is needed needs investigation This needs to be looked into before its "ready for work"
Projects
None yet
Development

No branches or pull requests

3 participants