fix generics for relationships (#18136)
# Objective Allow Relationship to be derived for structs with generics. fixes #18133 ## Solution "X" inside #[relationship_target(relationship = X)] was previously parsed as Idents, now they are parsed as syn::Type ## Testing ```rust #[derive(Component)] #[relationship(relationship_target = Attachments<T>)] pub struct AttachedTo<T: Send + Sync + 'static> { #[relationship] pub entity: Entity, pub marker: PhantomData<T>, } #[derive(Component)] #[relationship_target(relationship = AttachedTo<T>)] pub struct Attachments<T: Send + Sync + 'static> { #[relationship] entities: Vec<Entity>, pub marker: PhantomData<T>, } ``` This now compiles!
This commit is contained in:
parent
236091adce
commit
173680944f
@ -10,7 +10,7 @@ use syn::{
|
|||||||
spanned::Spanned,
|
spanned::Spanned,
|
||||||
token::{Comma, Paren},
|
token::{Comma, Paren},
|
||||||
Data, DataStruct, DeriveInput, ExprClosure, ExprPath, Field, Fields, Ident, Index, LitStr,
|
Data, DataStruct, DeriveInput, ExprClosure, ExprPath, Field, Fields, Ident, Index, LitStr,
|
||||||
Member, Path, Result, Token, Visibility,
|
Member, Path, Result, Token, Type, Visibility,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn derive_event(input: TokenStream) -> TokenStream {
|
pub fn derive_event(input: TokenStream) -> TokenStream {
|
||||||
@ -474,11 +474,11 @@ enum RequireFunc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct Relationship {
|
struct Relationship {
|
||||||
relationship_target: Ident,
|
relationship_target: Type,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RelationshipTarget {
|
struct RelationshipTarget {
|
||||||
relationship: Ident,
|
relationship: Type,
|
||||||
linked_spawn: bool,
|
linked_spawn: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -613,14 +613,14 @@ impl Parse for Relationship {
|
|||||||
input.parse::<relationship_target>()?;
|
input.parse::<relationship_target>()?;
|
||||||
input.parse::<Token![=]>()?;
|
input.parse::<Token![=]>()?;
|
||||||
Ok(Relationship {
|
Ok(Relationship {
|
||||||
relationship_target: input.parse::<Ident>()?,
|
relationship_target: input.parse::<Type>()?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parse for RelationshipTarget {
|
impl Parse for RelationshipTarget {
|
||||||
fn parse(input: syn::parse::ParseStream) -> Result<Self> {
|
fn parse(input: syn::parse::ParseStream) -> Result<Self> {
|
||||||
let mut relationship_ident = None;
|
let mut relationship_type: Option<Type> = None;
|
||||||
let mut linked_spawn_exists = false;
|
let mut linked_spawn_exists = false;
|
||||||
syn::custom_keyword!(relationship);
|
syn::custom_keyword!(relationship);
|
||||||
syn::custom_keyword!(linked_spawn);
|
syn::custom_keyword!(linked_spawn);
|
||||||
@ -629,7 +629,7 @@ impl Parse for RelationshipTarget {
|
|||||||
if input.peek(relationship) {
|
if input.peek(relationship) {
|
||||||
input.parse::<relationship>()?;
|
input.parse::<relationship>()?;
|
||||||
input.parse::<Token![=]>()?;
|
input.parse::<Token![=]>()?;
|
||||||
relationship_ident = Some(input.parse::<Ident>()?);
|
relationship_type = Some(input.parse()?);
|
||||||
} else if input.peek(linked_spawn) {
|
} else if input.peek(linked_spawn) {
|
||||||
input.parse::<linked_spawn>()?;
|
input.parse::<linked_spawn>()?;
|
||||||
linked_spawn_exists = true;
|
linked_spawn_exists = true;
|
||||||
@ -644,7 +644,7 @@ impl Parse for RelationshipTarget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let relationship = relationship_ident.ok_or_else(|| syn::Error::new(input.span(), "RelationshipTarget derive must specify a relationship via #[relationship_target(relationship = X)"))?;
|
let relationship = relationship_type.ok_or_else(|| syn::Error::new(input.span(), "RelationshipTarget derive must specify a relationship via #[relationship_target(relationship = X)"))?;
|
||||||
Ok(RelationshipTarget {
|
Ok(RelationshipTarget {
|
||||||
relationship,
|
relationship,
|
||||||
linked_spawn: linked_spawn_exists,
|
linked_spawn: linked_spawn_exists,
|
||||||
|
Loading…
Reference in New Issue
Block a user