-
Notifications
You must be signed in to change notification settings - Fork 43
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
generic arenas #26
generic arenas #26
Conversation
Yeah I'm not crazy about the Is there a "standard" for the format here? Do you happen to know of another crate that has to do roughly the same thing? If we're copying an existing technique I'll feel much better about picking a syntax. I know it's a pretty minor thing.. |
TIL! |
Ok, well in that case I decided to take the time and write a proper tt muncher for it, so now we use angle brackets instead like normal generics. It's probably more prone to edge case issues. For instance, I didn't build in support for writing trait bounds on the introduced generics, but generic type aliases don't allow those anyway - we'll just need to document that fact. I'll add some doc info about it after we settle on any other style changes. One I was considering was making it more obvious this was a special type alias (which have different generic behaviors) by doing something like |
Another thing to consider is whether we want to continue doing the auto-insertion of |
Oh shoot, thank you for doing all that work writing the muncher but I actually think I like the simpler solution more 😭 I should have been more clear before! I'd MUCH rather have something simpler that works, I just wanted to know if there was any standard practice because I'm just really unfamiliar with it. I'm sorry to make you do a bunch of work without explaining it better! I want to merge this because I think having this ability is important, but I need to take a step back and actually think about whether this macro needs to exist at all. I originally wanted to replace the macro with a trait and GATs, but @Aaron1011, who knows a lot more about this than me (they are a rustc dev), said that it was more compatible to avoid doing this and use a different technique.
Okay, this is a bunch more context for these decisions, this is not as important, feel free to skip, I just want to put this down in writing somewhere while I work on it... I originally was ready to hand maintenance of this crate over to @Aaron1011 or anyone else who more actively used it, because I haven't used this crate in ages. I still think I should share maintenance and I'm glad I gave them maintenance privileges on the crate so it doesn't have a bus factor of 1, and I would even be willing to bring on more maintainers. Tbh I'm not good at open source stuff at all, so any help is appreciated. I'm a game dev by trade, I'm not even used to PR based development and code reviews really! And speaking of that... In the last few days I had what might be a Very Good Idea:tm: about how to rework the I stopped updating the I think I might have a way to make all this work, but it will require making many different types root-able, and it will also maybe require having an actual Root trait.. I think it will in fact, so my plans for what to do here matter for how the My idea for how to make this work is to have a linked list chain of Root-able structs that are basically the reified "stack" of an async function, and I think I can design the API to use this to not be completely insane. If I can make this work I actually might pick I'm gonna try to do this in a branch but it might involve.. I dunno what it will involve, probably taking the [1] rust-lang/rust#101520 (comment) Apparently transmuting lifetimes of types other than simple pointers / references is not technically allowed by the compiler until the current nightly: 1.67, but 1) it worked in this crate before now, and 2) it will work in this crate officially as of 1.67 anyway. Originally when I wrote this, I actually looked into it and I could have sworn this was already at least tacitly considered to be the way forward, that lifetime parameters would have no effect on codegen, but apparently it was less settled than I had imagined. IF a Obviously I am open to discussion about all of this in any case. |
I think if you just go back to the very simple syntax, even if it's not ideal, I would be okay with merging this. That way no matter what ends up happening with the experiment I want to try, there will at least be a way to support generics. If everybody hates the simple syntax we can try the more complex tt muncher strategy but I am not thrilled about needing to do something like that, I'd much rather have syntax that I don't love than the additional complication to make a slightly better syntax work, I can live with weird syntax. |
I just reverted back to the parenthesis notation. The more complex one is left in the commit history for reference in case we ever want something like that down the line. The only other issue is whether or not to auto-insert the first |
I am the literal worst! I was planning on letting you know that there's a PR that is almost ready to merge that supersedes this, #32, and I didn't actually do that when I should have. The new syntax for the macro is actually vastly simpler and avoids the problem entirely: gc-arena/src/gc-arena/src/arena.rs Line 109 in 39f75f8
I'm sorry for giving you the runaround, it was not my intention 😭 BUT if you wanna go take a look at #32 I'm interested in your opinion, particularly anything that might make using the API easier. If for any reason #32 gets delayed or there are any problems, I will definitely merge this PR, otherwise I'll merge #32 and close this one. |
Okay, this should be resolved by #32 now. |
I ran into an issue where a generic function needs to take a type
T
as input and internally use an arena based onT
. But rust doesn't allow items to reference type parameters of the parent scope, so (I believe) this is impossible currently. Easy solution: allow arenas to be generic. This just adds a little syntax to themake_arena!
macro that lets you introduce and use generic parameters by just dumping the entire contents of a parenthesis-wrapped token tree into generic param brackets. So we can now do things like this:The reason for taking token trees like
( $($t:tt)* )
rather than a comma-separated ident list like< $($t:ident),* >
was for two reasons: 1) it allows the left (introducing) side to have const generics likeFoo(const N: usize)
and 2) it allows the right to have non-trivial type expressions likeBar(<T as Thingy>::Output)
. It also makes it really easy to parse withmacro_rules!
since parenthesis mark the boundaries of token trees. There's probably some token munching magic we could do to allow angle brackets instead of parenthesis for this, but I don't think it's worth the effort in this case as long as we document it well.This also renames the
'a
lifetime in the dyn trait decl to'gc
to match existing standards since it is exposed to the root type generic parameters: e.g., you can write something likemake_arena!(Foo(T), Bar(Gc<'gc, T>)
.I also removed the macro overload without
$vis:vis
because apparently:vis
matches empty string and in that case is equivalent topub(self)
anyway.