Is there a compile-time `unwrap/expect`?

I am having a datatype whose construction might fail.

Some of the time this datatype is constructed with user-provided values. However, many other times they are created based on static information (i.e. 'hard-coded'). In those cases, we could not only do the construction at compile-time, but also tell at compile-time whether the construction would succeed or fail, transforming run-time errors into compile-time errors.

An example would be to create an URI-datatype from a string. Since there are many strings that indicate invalid URIs, this might fail. Finding out about this failure at compile-time would be very useful.

Currently, when these kind of 'hard-coded' datatypes are constructed, it is common to immediately call unwrap() or expect(error_message) on them. This will of course happily fail with a panic at runtime when the construction failed.

Is there a version of unwrap/expect that would be called at compile-time (and 'panic' at compile-time if a non-success was encountered)?
Or is there another way to do this?

RFC 2345 (tracking issue) enables panicking in const code, which will result in a compilation error. But note that for stuff like URI you probably want to use heap allocations and they will not work with const code. Well, one day we may be able to use heap allocations inside const functions, but creating a non-empty heap allocated constant will be probably forbidden forever.

If you need to parse some literal in compile-time, this can be done with procedural macros. Of course, you will need to have some "unchecked" way to generate the output object, so that the check will not be duplicated.

1 Like

Very interesting! It seems that in the future this will become easy indeed :smiley:!

As for the URI example and heap allocation: Why would you expect this structure to heap-allocate? There are of course many ways to build something like this (and my original explanation of it was very vague, it was only one motivating example of many potential ones after all). In any case, I'd expect it to take ownership of the string passed to it, and its resource itself to contain for the various fields (sheme, host, path, etc.) a string slice (wrapped in an Option).

This is probably the best we have right now? Besides being slightly more boilerplate-heavy than the concept RFC 2345 will introduce, it seems like a fine solution, especially since we can prevent unintentional abuse of the "unchecked" way to generate the output object by marking it as unsafe.

I vaguely recall there are length limits on URIs set in the URI standard, but they are well into kilobytes, so allocating statically sized structures that could accommodate any legal URI on stack or as part of larger structures would be rather wasteful because real world URIs tend to be short.

1 Like

I re-checked and I was wrong: the URI RFC does not impose any a priori limits on the length of URIs or their components. So a general purpose library that needs to represent URIs must use dynamic allocation.