SecondHalfGames / yakui

yakui is a declarative Rust UI library for games
Apache License 2.0
237 stars 21 forks source link

`Widget::Props` could maybe be a type paramter, not an associated type #119

Closed Ralith closed 11 months ago

Ralith commented 1 year ago

Because Props is only used as a trait method argument, there is no need to restrict it to one possible assignment per impl. This change would allow one widget to accept Props of multiple types, such as different closures. That isn't currently useful, since every widget is associated with a single lexical callsite, but future refactoring might make it more relevant.

Unfortunately, it doesn't seem to currently be possible to type-erase a non-'static type parameter in a trait, and borrowed Props values do have obvious applications, so this should be shelved until better supported by Rust.

The core language limitation here is that a newtype involving PhantomData<fn(T)> must be used to adapt a generic Widget<Props> to an impl of an ErasedWidget trait, but despite fn(T) being documented as covariant in T, today's rustc thinks fn(T) has the same lifetime of T, so PhantomData<fn(T)> is not 'static. TODO: Find or open an issue upstream.

Alternative approaches that could offer the same flexibility:

LPGhatguy commented 11 months ago

Based on the discussion we had, we decided to instead use GATs to add a lifetime parameter to Widget::Props. While this doesn't enable polymorphic widgets like we had hoped, it does enable widget props to borrow non-'static data which we decided was probably more useful. That was merged in #116.

I think we could revisit this at a later date if we can wrangle some of the lifetime and trait issues that propped up while pursuing this work originally.

For now, thank you very much for the investigation and work on this! I'm going to close this issue as resolved.