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

segfault bug(?) re: unsafe functions and parsing #305

Open
RyanBrewer317 opened this issue Oct 5, 2022 · 2 comments
Open

segfault bug(?) re: unsafe functions and parsing #305

RyanBrewer317 opened this issue Oct 5, 2022 · 2 comments

Comments

@RyanBrewer317
Copy link

When I run the following code:

import std/text/parse

fun test(): parse char {
  fun test2(): parse char {
    char('r')
  }
  unsafe-no-div(test2)
}

pub fun main() {
  val code = "hi"
  val mb = parse(code.slice, test)
  println("success")
}

I get a segmentation fault, even though test2 is of course not divergent at all. Replacing unsafe-no-div with unsafe-no-ndet also leads to a segfault, but replacing it with unsafe-total results in printing "success," presumably because it gets rid of the parse effect. All three unsafe functions are of course implemented the same way, except for their typing.

I of course understand that using these unsafe functions are, well, unsafe, but this behavior is so odd that I figured I'd make an issue about it just in case it's caused by an unknown compiler bug.

I also want to add that the reason I got into this experimentation to begin with was wanting to build a recursive parser using the parser combinator library, then realizing that I would have to add the "div" effect to everything I'd written even when I knew that the top-level function expr-parsing function (which was the only recursive one) wasn't divergent. I knew that in std, functions like for use the unsafe functions to get the looping they need without getting the "div" effect. I say all of this just to say that this didn't come out of mindless messing-around with koka but an actual project, hopefully to show that if this is a bug, it's not a too-remote edge case.

@chtenb
Copy link
Contributor

chtenb commented Nov 29, 2023

I'm running into the same or very similar issue. In my case it doesn't matter if I use unsafe-no-div or unsafe-total, both will crash.

Here is an example. We define a take function which should turn a divergent iterator into a non-divergent one.
Furthermore, for some reason the to-list function also thinks it is divergent, requiring another unsafe-no-div there.

pub effect iter<a>
  ctl yield(elem : a) : ()

pub fun to-list(it : () -> iter<a> ()) : list<a>
  with unsafe-no-div()
  var result := Nil
  with fun yield(elem)
    result := Cons(elem, result)
  it()
  reverse(result) // List was accumulated in reverse order

pub fun take(n : int, it : () -> <div,iter<a>> ()) : iter<a> ()
  var count := 0
  with ctl yield(elem)
    if count < n then
      yield(elem) // Forward the yield to our new iterator
      count := count + 1
      resume(())
    else
      ()
  with unsafe-no-div()
  it()

And some test code

pub fun test-iter() : div list<int>
  fun fib-iter(n1 : int, n2 : int) : <div,iter<int>> ()
    val n3 = n1 + n2
    yield(n3)
    fib-iter(n2, n3)
    
  to-list
    take(100)
      fib-iter(1,1)

@Matthew-Mosior
Copy link

See #321 as well (I was running into seg faults too).

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

No branches or pull requests

4 participants