Skip to content

Implementation for #355#697

Open
EpicVon2468 wants to merge 5 commits into
TheDan64:masterfrom
EpicVon2468:master
Open

Implementation for #355#697
EpicVon2468 wants to merge 5 commits into
TheDan64:masterfrom
EpicVon2468:master

Conversation

@EpicVon2468

Copy link
Copy Markdown

Description

Implementation for the AnyTypeEnum::fn_type and AnyTypeEnum::array_type functions as described in #335

Related Issue

#335

How This Has Been Tested

Works on my machine (Ubuntu 26.10, raptorlake).
There (probably) can't really be any issues with this breaking stuff.

Checklist

Comment thread src/types/enums.rs Outdated
#[derive(thiserror::Error, Debug)]
#[error("The variant `AnyTypeEnum::{}` cannot be used with `{}()`!", self.variant, self.function)]
pub struct InvalidVariant {
// TODO: Shorten lifetime?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Wasn't sure how else to display the variant and function name; If there's a better way let me know)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should add a lifetime generic, that's more flexible.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll get on this once I'm home

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, wait, what is this? Is this an error message? Why is it implemented with strings? This could very well be an enum.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, this error type would clash with inkwell's internal error types. It would make working with errors unwieldy if users have to switch between incompatible error types.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, wait, what is this? Is this an error message? Why is it implemented with strings? This could very well be an enum.

Yeah admittedly I was probably a bit too tired for implementing this yesterday. I'll try to fix it up now

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now uses enumeration variant, but if there's a different way to implement the error type then lmk

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error type I was referring to is in src/error.rs

@ErisianArchitect ErisianArchitect Jun 19, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I typed the last comment on my phone and didn't feel like being detailed.

It would be a good idea to add your new error type to the main error in src/error.rs.

pub enum Error {

You can add a new error variant to it that implements #[from] for your error type. This will enable users to use the ? operator on your error type and it will be recognized by inkwell's top-level error type.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per the other comments I have below: this is causing issues related to lifetimes; need to find the best way to fix

@EpicVon2468

EpicVon2468 commented Jun 18, 2026

Copy link
Copy Markdown
Author

Another follow-up: should any other methods have wrappers implemented? should other *TypeEnum types have similar or identical methods implemented?

@TheDan64 TheDan64 self-requested a review June 19, 2026 16:29
Comment thread src/types/enums.rs Outdated

#[derive(thiserror::Error, Debug)]
#[error("This variant of `AnyTypeEnum` cannot be used with `{self:?}()`!")]
pub enum InvalidVariant {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think each variant should have the AnyTypeEnum inside like a tuple. And move the error macro to individual variants. So you'd have something like:

#[error("The fn_type method cannot be called by the {0} variant")]
FnType(AnyTypeEnum<'ctx>),

which would produce a really nice and explanatory error message

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good to me, I'll implement when I'm free

@EpicVon2468

Copy link
Copy Markdown
Author

Running into some slight issues around the lifetime of the error
Seems that Error requires 'static, meaning this is seemingly the only way to meet the criterion of storing AnyTypeEnum<'ctx> as well as integrating with src/error.rs...
image

@EpicVon2468

Copy link
Copy Markdown
Author

Oopsy I broke it
Forgot to ran tests before committing so I found out rust catches that leak only after pushing

@EpicVon2468

Copy link
Copy Markdown
Author

Actually, forget regular compile errors, I'm getting ICEs when I try to run tests 😭
Probably user error on my end, would explain why no errors showed up in my IDE until compile-time

@TheDan64

Copy link
Copy Markdown
Owner

If you're getting an ICE on stable, you should definitely open a rust bug is one doesn't already exist. Sorry this seemingly small change has been so painful lol

@EpicVon2468

EpicVon2468 commented Jun 20, 2026

Copy link
Copy Markdown
Author

Haha it's fine. I run nightly for everything (My projects use nightly features, so it's easier to make it the default than to try and fix some weird config issues I was having) & the bug was just about incremental cache, cargo clean fixed it.

yes I know running nightly for everything is a horrible idea, it's a price I'm willing to pay

Although I'm sorry if this has been a pain, normally I'd like to think I'm good at programming, but I tend to over-doubt everything I do for contributions to projects :p

A more on-topic note:
While it's technically possible to just add a lifetime to inkwell::error::Error to (possibly?) avoid the 'static problem, I'm not sure how that would go compatibility wise, and would rather not be at fault for however many people updating only to find their code is broken because of lifetimes on the error type 😅

@ErisianArchitect

ErisianArchitect commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Hmm. That's a tough one. What I think is that it's not necessary to include the original value within the error variant. I don't think there's any precedent for doing that. Otherwise, perhaps we could just exclude it from the crate-level error type and just expect users to handle the error themselves. I don't know if this is a case where someone would want to retry something using the AnyTypeEnum. I would think that it would be a bug in your code, and perhaps we should nudge the programmer into handling the bug properly rather than doing something weird. Perhaps we could give a method that would tell you whether or not this transformation can even happen before attempting it. Just some thoughts. You're doing fine, by the way. Programming is tricky sometimes.

@EpicVon2468

Copy link
Copy Markdown
Author

Omitting the original value would fix lifetime issues, but it also means people would have to do more tracing of which value was being passed on their end.

I personally would've opted for using Option on these methods out of personal preference, but if we're doing Result then it's more a matter of choosing how the programmer would have to handle the result.

@ErisianArchitect

Copy link
Copy Markdown
Contributor

Can you really not make a fn_type for a function type?

@TheDan64

TheDan64 commented Jun 20, 2026

Copy link
Copy Markdown
Owner

Another option would be to add a variant_name method to the type, which returns a static str, and then just do:

#[derive(Error)]
#[error("An invalid method was called by variant {0}")]
struct InvalidVariant(&'static str);

impl From<AnyTypeEnum<'_>> for InvalidVariant {
    fn from(ate) -> Self {
        InvalidVariant(ate.variant_name())
    }
}

This nice thing about this approach is that we could eventually use it for other types like BasicTypeEnum as well. Although this lacks method info..

@ErisianArchitect

Copy link
Copy Markdown
Contributor

I think it would be better to just have a *Kind enum that specifies the kind rather than relying on strings that will ultimately take up unnecessary space in the binary.

@EpicVon2468

Copy link
Copy Markdown
Author

Can you really not make a fn_type for a function type?

Counter-intuitively, a function type in LLVM does not appear to be a "type" similar to the rest (to my understanding).

From what I know, it isn't a closure or lambda or function pointer type...

@EpicVon2468

Copy link
Copy Markdown
Author

Another option would be to add a variant_name method to the type, which returns a static str, and then just do:

#[derive(Error)]
#[error("An invalid method was called by variant {0}")]
struct InvalidVariant(&'static str);

impl From<AnyTypeEnum<'_>> for InvalidVariant {
    fn from(ate) -> Self {
        InvalidVariant(ate.variant_name())
    }
}

This nice thing about this approach is that we could eventually use it for other types like BasicTypeEnum as well. Although this lacks method info..

We've gone full circle to what I had before 😭

@ErisianArchitect

Copy link
Copy Markdown
Contributor

I just don't think that a string is the right call. If there's only a limited number of values that it could be, it would be better off as an enum.

@EpicVon2468

Copy link
Copy Markdown
Author

I won't take sides on which would be the better implementation, but if we do use enums I'd suggest marking them as #[non_exhaustive] so the API can be updated without breaking compatibility

@EpicVon2468

Copy link
Copy Markdown
Author

Yeah the lack of 'static is causing issues with anyhow as well.
image
image
Because InvalidVariantError is not 'static, it doesn't like it.

@ErisianArchitect

ErisianArchitect commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

You almost gave me a heart attack, I thought anyhow had become a dependency in inkwell. Lol

@EpicVon2468

EpicVon2468 commented Jun 21, 2026

Copy link
Copy Markdown
Author

Hahahah no, I use it in my project (and I know other people like to use it (I think?)), and given the fact it (and most other Error related things (including std / core)) depend on the 'static bound, this definitely needs a fix

@ErisianArchitect

Copy link
Copy Markdown
Contributor

Not that there's anything wrong with anyhow, it's just that we already have thiserror as a dependency, so if anyhow were added, it would just signal that someone had given up on writing decent errors and opted to basically just pass the trouble onto users. I'm glad that's not the case.

@EpicVon2468

Copy link
Copy Markdown
Author

Sorry to have made this and then left it alone a while, it's currently midyear exam time for me.

In just over a week or two I should be free to try and patch this up fully, although I could definitely work on fixes for the error type when I have some gaps in my schedule

@ErisianArchitect

Copy link
Copy Markdown
Contributor

I wouldn't worry about it, Dan takes his time.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants