I'm getting an error when deriving Data for the following struct:
#[derive(Debug, Clone, Data)]
pub struct KnobData<T: Data> {
pub origin: f64,
pub min: f64,
pub max: f64,
pub step: f64,
pub value: f64,
pub modulation: f64,
pub context: T,
}
--> kiro-synth-host/src/ui/widgets/knob.rs:25:24
|
25 | #[derive(Debug, Clone, Data)]
| ^^^^
When I put a println in the proc-macro, this is what I see:
impl < T : Data : :: druid :: Data, > druid :: Data for KnobData < T : Data >
{
fn same (& self, other : & Self) -> bool
{
druid :: Data :: same (& self . origin, & other . origin) && druid ::
Data :: same (& self . min, & other . min) && druid :: Data :: same
(& self . max, & other . max) && druid :: Data :: same
(& self . step, & other . step) && druid :: Data :: same
(& self . value, & other . value) && druid :: Data :: same
(& self . modulation, & other . modulation)
}
}
Apparently the mistake is here: impl < T : Data : :: druid :: Data,>
The problem is that the generics_bounds function is hard coding the type parameters to be bound to Data:
Type(ty) => quote_spanned!(ty.span()=> #ty : ::druid::Data),
Removing the context bound for the struct type parameter makes it work again.
The solution seems pretty easy, by removing the hard-coded bounding to Data, but that would break backward compatibility for existing code. I'm willing to PR the solution, but I'd like to check whether it is ok to break backwards compat or not.
I'm willing to PR the solution, but I'd like to check whether it is ok to break backwards compat or not.
I haven't really analyzed the specifics of the issue, but generally speaking we are very welcoming of breaking changes if they improve things. We are under heavy development and the goal is to get things right not to keep things the same, especially while still on version 0.
It doesn鈥檛 need to remove anything or break compatibility, it just needs to check whether there鈥檚 a colon in there (thus, whether it has trait bounds) and put a plus sign instead of a colon. <T: Data + ::druid::Data> will work just fine.
Hi, I've spent some time with this, but I'm a complete noob of procedural macros, and haven't been able to get a successful result.
This is where I am right now:
fn generics_bounds(generics: &syn::Generics) -> proc_macro2::TokenStream {
let res = generics.params.iter().map(|gp| {
use syn::GenericParam::*;
match gp {
Type(ty) => {
let i = &ty.ident;
let b = &ty.bounds;
if ty.colon_token.is_some() {
quote_spanned!(ty.span()=> #i : #b + ::druid::Data)
} else {
quote_spanned!(ty.span()=> #ty : ::druid::Data)
}
},
Lifetime(lf) => quote!(#lf),
Const(cst) => quote!(#cst),
}
});
quote!( #( #res, )* )
}
and this is the code I use for checking it:
trait X {
}
#[derive(Clone, Data)]
struct A<T: X> {
a: T,
b: u32,
};
But I get these errors:
error[E0658]: associated type bounds are unstable
--> druid/src/app.rs:290:18
|
290 | struct A<T: X> {
| ^^^^
|
= note: see issue #52662 <https://github.com/rust-lang/rust/issues/52662> for more information
error[E0107]: wrong number of type arguments: expected 1, found 0
--> druid/src/app.rs:290:16
|
290 | struct A<T: X> {
| ^^^^^^^ expected 1 type argument
error[E0229]: associated type bindings are not allowed here
--> druid/src/app.rs:290:18
|
290 | struct A<T: X> {
| ^^^^ associated type not allowed here
Any clue ?
Can you post cargo expand output? I think that might help identify where things are going awry.
This is fixed by #1058, right? The same issue with Lens seems to be addressed by #1120.
Most helpful comment
It doesn鈥檛 need to remove anything or break compatibility, it just needs to check whether there鈥檚 a colon in there (thus, whether it has trait bounds) and put a plus sign instead of a colon.
<T: Data + ::druid::Data>will work just fine.