Stream: cranelift

Topic: Fallible constructors in ISLE


view this post on Zulip Leon von Mulert (Jan 03 2025 at 18:16):

I have defined a partial constructor to turn an Index into a FlatExpr, i.e. just a lookup into an arena-style container. Obviously, if the index is out of bounds, an expression cannot be constructed, thus it's fallible/partial.

(decl partial to_node (Index) FlatExpr)
(extern constructor to_node to_node)

I'm then using that constructor in a simple nested traversal/peeling operation:

(rule zext
      (lower_cl (FlatExpr.Zext a (FlatExpr.Const 64 64) 64))
      (lower_cl (to_node a)))

(If a value is zero-extended to 64 bits, ignore the zext and continue with the inner expression)
However, the code generated is as follows:

                                let v65 = &C::to_node(ctx, v58);
                                let v66 = v65?;

And this fails to compile, because the ? operator can not be applied to &Option<...>. In short: Why does it immediately take a reference here from the constructor, even though the constructor returns an owned value?

Additionally: Does ISLE support actual errors? I.e. in the example above, failing to use a valid index for arena-lookup should bubble an error to the top, rather than panicing (non-partial constructor) or just failing to match the rule (partial constructor). The lack of keywords for this in the language references leads me to believe there's no such thing in ISLE. I don't want to catch panics for this kind of use-case.

view this post on Zulip Chris Fallin (Jan 03 2025 at 18:48):

The short answer is that the ABI to the Rust FFI, and in particular details around borrowing vs owning, have been hacked together just-so to make the Cranelift use-case work, but we don't have a coherent philosophy beyond that. You're welcome to jump in and work one out, making fixes as needed. (We're pretty thinly staffed and it's not anyone's job to be a fulltime maintainer of the ISLE compiler at the moment, or to take it beyond Cranelift's use-case.)

Re: "actual errors": no, we don't have a Result or error monad or anything like that. The intent of the partial matching was to let None mean "fall back to the old framework" during our transition phase; that could potentially be used, together with an out-of-band "set error" side-effect in a constructor. Other ideas welcome though.

view this post on Zulip Leon von Mulert (Jan 03 2025 at 18:55):

I'm sorry if my post came across as entitled, I assumed as much but wanted to verify I wasn't missing anything, especially given that guides/tutorials/language references tend to be out of date ;)

I'm still learning the ins and outs of ISLE, but once I have a more thorough understanding of it I might look to make some improvements :) For now, ISLE itself is intimidating enough, no need to dive into its implementation just yet.

Out-of-band errors seem like a good solution for now, even if it hurts throwing away some of Rust's core learnings.

view this post on Zulip Chris Fallin (Jan 03 2025 at 18:58):

Oh, no worries, more just to say "please help, improvements welcome". We could definitely use some help getting things polished to the point that third-party users of ISLE aren't as intimidated and have more docs


Last updated: Jan 24 2025 at 00:11 UTC