Open dhardy opened 4 years ago
Since this issue was created, the make_widget!
macro has been separated from derive(Widget)
and a few work-arounds added, however the fundamental issue remains: something like RFC 2524 is required to make it work properly (replacing use of generics with various hacky bounds, and allowing visibility outside of the generated code without explicit typing).
Note: this is still an issue, but the macro in question has been renamed to impl_singleton!
.
As an experiment, tried using type_alias_impl_trait
instead of type generics to declare inferred field types:
let ty = make_ident(format_args!("{singleton_ty}{}", &ty_name[1..]), span);
pre_items.append_all(quote! { type #ty = impl #bound; });
// or, for widgets with omitted type:
pre_items.append_all(quote! { type #ty = impl ::kas::Widget; });
The result appears to function identically (except where there are zero bounds, but such fields are only useful for extending the life of some object). It does not solve the issue of opaque types, nor offers any other advantage.
When creating a widget with
make_widget!{ .. }
, fields cannot be accessed from outside the defining macro due to the anonymous type.I had hoped this could be fixed with some type of type alias feature, but alas, this appears limited to trait implementations.
To some extent this can be worked around with traits, e.g. from the
stopwatch
example:allowing
self.display.set_text(tk, &self.dur_buf);
to be called from the outer widget later.Ideally in the above, it would be possible to directly call
self.display.display.set_text(tk, ..)
.Proposal:
build_widget!
macroMove most of the
make_widget!
code into a separate macro, defining the type, and allow direct use of this.Issue: implicit typing within
make_widget!
uses generics, thus the resulting type requires parameterisation on use. Ideally, we would not have to use generics but could use some type of "magic type alias".