From c1ff1836122d61570daf9562267fa30135dd7998 Mon Sep 17 00:00:00 2001 From: Benjamin Saunders Date: Sat, 24 Jun 2023 14:45:13 -0700 Subject: [PATCH] Don't clutter caller namespace with derive(Query) internals Rather than giving the Fetch/State types names unlikely to collide, we can introduce fully hygenic names by moving the type definitions and the trait impls that depend on them into an anonymous scope. --- macros/src/query.rs | 118 ++++++++++++++++++++++---------------------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/macros/src/query.rs b/macros/src/query.rs index f7a4bb1e..84830727 100644 --- a/macros/src/query.rs +++ b/macros/src/query.rs @@ -67,7 +67,7 @@ pub fn derive(input: DeriveInput) -> Result { .iter() .map(|ty| quote! { <#ty as ::hecs::Query>::Fetch }) .collect::>(); - let fetch_ident = Ident::new(&format!("__HecsInternal{}Fetch", ident), Span::call_site()); + let fetch_ident = Ident::new(&format!("{}Fetch", ident), Span::call_site()); let fetch = match data.fields { syn::Fields::Named(_) => quote! { #vis struct #fetch_ident { @@ -83,7 +83,7 @@ pub fn derive(input: DeriveInput) -> Result { #vis struct #fetch_ident; }, }; - let state_ident = Ident::new(&format!("__HecsInternal{}State", ident), Span::call_site()); + let state_ident = Ident::new(&format!("{}State", ident), Span::call_site()); let state = match data.fields { syn::Fields::Named(_) => quote! { #[derive(Clone, Copy)] @@ -114,81 +114,81 @@ pub fn derive(input: DeriveInput) -> Result { .collect::>(); Ok(quote! { - impl<'a> ::hecs::Query for #ident<'a> { - type Item<'q> = #ident<'q>; + const _: () = { + #fetch - type Fetch = #fetch_ident; + impl<'a> ::hecs::Query for #ident<'a> { + type Item<'q> = #ident<'q>; - #[allow(unused_variables)] - unsafe fn get<'q>(fetch: &Self::Fetch, n: usize) -> Self::Item<'q> { - #( - let #intermediates: <#queries as ::hecs::Query>::Item<'q> = <#queries as ::hecs::Query>::get(&fetch.#fields, n); - )* - #ident {#(#fields: #intermediates,)*} + type Fetch = #fetch_ident; + + #[allow(unused_variables)] + unsafe fn get<'q>(fetch: &Self::Fetch, n: usize) -> Self::Item<'q> { + #( + let #intermediates: <#queries as ::hecs::Query>::Item<'q> = <#queries as ::hecs::Query>::get(&fetch.#fields, n); + )* + #ident {#(#fields: #intermediates,)*} + } } - } - #[doc(hidden)] - #fetch + #state - #[doc(hidden)] - #state + unsafe impl ::hecs::Fetch for #fetch_ident { + type State = #state_ident; - unsafe impl ::hecs::Fetch for #fetch_ident { - type State = #state_ident; + fn dangling() -> Self { + Self { + #( + #fields: #fetches::dangling(), + )* + } + } - fn dangling() -> Self { - Self { + #[allow(unused_variables, unused_mut)] + fn access(archetype: &::hecs::Archetype) -> ::std::option::Option<::hecs::Access> { + let mut access = ::hecs::Access::Iterate; #( - #fields: #fetches::dangling(), + access = ::core::cmp::max(access, #fetches::access(archetype)?); )* + ::std::option::Option::Some(access) } - } - #[allow(unused_variables, unused_mut)] - fn access(archetype: &::hecs::Archetype) -> ::std::option::Option<::hecs::Access> { - let mut access = ::hecs::Access::Iterate; - #( - access = ::core::cmp::max(access, #fetches::access(archetype)?); - )* - ::std::option::Option::Some(access) - } + #[allow(unused_variables)] + fn borrow(archetype: &::hecs::Archetype, state: Self::State) { + #(#fetches::borrow(archetype, state.#fields);)* + } - #[allow(unused_variables)] - fn borrow(archetype: &::hecs::Archetype, state: Self::State) { - #(#fetches::borrow(archetype, state.#fields);)* - } + #[allow(unused_variables)] + fn prepare(archetype: &::hecs::Archetype) -> ::std::option::Option { + ::std::option::Option::Some(#state_ident { + #( + #fields: #fetches::prepare(archetype)?, + )* + }) + } - #[allow(unused_variables)] - fn prepare(archetype: &::hecs::Archetype) -> ::std::option::Option { - ::std::option::Option::Some(#state_ident { - #( - #fields: #fetches::prepare(archetype)?, - )* - }) - } + #[allow(unused_variables)] + fn execute(archetype: &::hecs::Archetype, state: Self::State) -> Self { + Self { + #( + #fields: #fetches::execute(archetype, state.#fields), + )* + } + } + + #[allow(unused_variables)] + fn release(archetype: &::hecs::Archetype, state: Self::State) { + #(#fetches::release(archetype, state.#fields);)* + } - #[allow(unused_variables)] - fn execute(archetype: &::hecs::Archetype, state: Self::State) -> Self { - Self { + #[allow(unused_variables, unused_mut)] + fn for_each_borrow(mut f: impl ::core::ops::FnMut(::core::any::TypeId, bool)) { #( - #fields: #fetches::execute(archetype, state.#fields), + <#fetches as ::hecs::Fetch>::for_each_borrow(&mut f); )* } } - - #[allow(unused_variables)] - fn release(archetype: &::hecs::Archetype, state: Self::State) { - #(#fetches::release(archetype, state.#fields);)* - } - - #[allow(unused_variables, unused_mut)] - fn for_each_borrow(mut f: impl ::core::ops::FnMut(::core::any::TypeId, bool)) { - #( - <#fetches as ::hecs::Fetch>::for_each_borrow(&mut f); - )* - } - } + }; }) }