Skip to content

Commit

Permalink
macro improvements (#342)
Browse files Browse the repository at this point in the history
- Removes the transform of `trait TraitName: TraitDep` into `trait TraitName: Into<TraitDep>`
- Removes the generated `lazy_static!` (was always a bit hard to read in the macro expansion, and `once_cell::Lazy` does the same without a macro)
- Generates unique names for all `impl`s, before implementing 2 traits with the same function name would lead to a compile error because they got the same func ident
  • Loading branch information
ForsakenHarmony committed Sep 21, 2022
1 parent 37e2f73 commit 2748ba7
Show file tree
Hide file tree
Showing 15 changed files with 162 additions and 89 deletions.
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

85 changes: 58 additions & 27 deletions crates/turbo-tasks-build/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use syn::{
PathArguments, PathSegment, TraitItem, TraitItemMethod, Type, TypePath,
};
use turbo_tasks_macros_shared::{
get_function_ident, get_ref_ident, get_register_trait_methods_ident,
get_function_ident, get_impl_function_ident, get_ref_ident, get_register_trait_methods_ident,
get_register_value_type_ident, get_trait_default_impl_function_ident,
get_trait_impl_function_ident, get_trait_type_ident, ValueTraitArguments,
};
Expand Down Expand Up @@ -203,7 +203,7 @@ impl<'a> RegisterContext<'a> {
let ident = &fn_item.sig.ident;
let type_ident = get_function_ident(ident);

self.register(type_ident, self.get_global_name(ident, None))?;
self.register(type_ident, self.get_global_name(&[ident]))?;
}
Ok(())
}
Expand All @@ -221,11 +221,11 @@ impl<'a> RegisterContext<'a> {
ident: struct_ident,
}) = segments.first()
{
if let Some(trait_ident) =
let trait_ident =
impl_item.trait_.as_ref().and_then(|(_, trait_path, _)| {
trait_path.segments.last().map(|s| &s.ident)
})
{
});
if let Some(trait_ident) = trait_ident {
self.add_value_trait(struct_ident, trait_ident);
}

Expand All @@ -235,13 +235,23 @@ impl<'a> RegisterContext<'a> {
// is_attribute(a,
// "function")) {
let method_ident = &method_item.sig.ident;
let function_type_ident =
get_trait_impl_function_ident(struct_ident, method_ident);

self.register(
function_type_ident,
self.get_global_name(struct_ident, Some(method_ident)),
)?;
let function_type_ident = if let Some(trait_ident) = trait_ident {
get_trait_impl_function_ident(
struct_ident,
trait_ident,
method_ident,
)
} else {
get_impl_function_ident(struct_ident, method_ident)
};

let global_name = if let Some(trait_ident) = trait_ident {
self.get_global_name(&[struct_ident, trait_ident, method_ident])
} else {
self.get_global_name(&[struct_ident, method_ident])
};

self.register(function_type_ident, global_name)?;
}
}
}
Expand Down Expand Up @@ -298,44 +308,46 @@ impl<'a> RegisterContext<'a> {

self.register(
function_type_ident,
self.get_global_name(trait_ident, Some(method_ident)),
self.get_global_name(&[trait_ident, method_ident]),
)?;
}
}

let trait_type_ident = get_trait_type_ident(trait_ident);
self.register(trait_type_ident, self.get_global_name(trait_ident, None))?;
self.register(trait_type_ident, self.get_global_name(&[trait_ident]))?;

let trait_args: ValueTraitArguments = parse_attr_args(attr)?.unwrap_or_default();
if trait_args.debug {
let ref_ident = get_ref_ident(trait_ident);
self.register_debug_impl(&ref_ident)?;
self.register_debug_impl(&ref_ident, DebugType::Trait)?;
}
}
Ok(())
}
}

impl<'a> RegisterContext<'a> {
fn get_global_name(&self, type_ident: &Ident, fn_ident: Option<&Ident>) -> String {
fn get_global_name(&self, parts: &[&Ident]) -> String {
format!(
"r##\"{}{}::{type_ident}{}\"##",
"r##\"{}{}::{}\"##",
self.prefix,
self.mod_path,
fn_ident
.map(|name| format!("::{}", name))
.unwrap_or_default()
parts
.iter()
.map(ToString::to_string)
.collect::<Vec<_>>()
.join("::")
)
}

fn add_value(&mut self, ident: &Ident) {
let key: ValueKey = (self.mod_path.to_owned(), ident.clone());
let value: ValueEntry = (self.get_global_name(ident, None), Vec::new());
let value: ValueEntry = (self.get_global_name(&[ident]), Vec::new());

assert!(self.values.insert(key, value).is_none());

// register default debug impl generated by proc macro
self.register_debug_impl(ident).unwrap();
self.register_debug_impl(ident, DebugType::Value).unwrap();
self.add_value_trait(ident, &Ident::new("ValueDebug", ident.span()));
}

Expand All @@ -362,16 +374,35 @@ impl<'a> RegisterContext<'a> {
}

/// Declares the default derive of the `ValueDebug` trait.
fn register_debug_impl(&mut self, ident: &Ident) -> std::fmt::Result {
fn register_debug_impl(&mut self, ident: &Ident, dbg_ty: DebugType) -> std::fmt::Result {
let fn_ident = Ident::new("dbg", ident.span());

self.register(
get_trait_impl_function_ident(ident, &fn_ident),
self.get_global_name(ident, Some(&fn_ident)),
)
let (impl_fn_ident, global_name) = match dbg_ty {
DebugType::Value => {
let trait_ident = Ident::new("ValueDebug", ident.span());
(
get_trait_impl_function_ident(ident, &trait_ident, &fn_ident),
self.get_global_name(&[ident, &trait_ident, &fn_ident]),
)
}
DebugType::Trait => (
get_impl_function_ident(ident, &fn_ident),
self.get_global_name(&[ident, &fn_ident]),
),
};

self.register(impl_fn_ident, global_name)
}
}

// FIXME: traits currently don't implement the trait directly because
// `turbo_tasks::value_impl` would try to wrap the TraitVc in another Vc
// (TraitVcVc).
enum DebugType {
Value,
Trait,
}

fn has_attribute(attrs: &[Attribute], name: &str) -> bool {
attrs.iter().any(|a| is_attribute(a, name))
}
Expand Down
18 changes: 17 additions & 1 deletion crates/turbo-tasks-macros-shared/src/ident.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub fn get_trait_type_ident(ident: &Ident) -> Ident {
)
}

pub fn get_trait_impl_function_ident(struct_ident: &Ident, ident: &Ident) -> Ident {
pub fn get_impl_function_ident(struct_ident: &Ident, ident: &Ident) -> Ident {
Ident::new(
&format!(
"{}_IMPL_{}_FUNCTION",
Expand All @@ -39,6 +39,22 @@ pub fn get_trait_impl_function_ident(struct_ident: &Ident, ident: &Ident) -> Ide
)
}

pub fn get_trait_impl_function_ident(
struct_ident: &Ident,
trait_ident: &Ident,
ident: &Ident,
) -> Ident {
Ident::new(
&format!(
"{}_IMPL_TRAIT_{}_{}_FUNCTION",
struct_ident.to_string().to_uppercase(),
trait_ident.to_string().to_uppercase(),
ident.to_string().to_uppercase()
),
ident.span(),
)
}

pub fn get_ref_ident(ident: &Ident) -> Ident {
Ident::new(&(ident.to_string() + "Vc"), ident.span())
}
Expand Down
41 changes: 24 additions & 17 deletions crates/turbo-tasks-macros/src/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,24 +172,31 @@ pub fn gen_native_function_code(
};
(
quote! {
turbo_tasks::lazy_static! {
pub(crate) static ref #function_ident: turbo_tasks::NativeFunction = turbo_tasks::NativeFunction::new(#name_code.to_owned(), |inputs| {
let mut __iter = inputs.iter();
#(#input_extraction)*
if __iter.next().is_some() {
return Err(anyhow::anyhow!("{}() called with too many arguments", #name_code));
}
#(#input_convert)*
Ok(Box::new(move || {
#(#input_clone)*
Box::pin(async move {
#(#input_final)*
#original_call_code
})
}))
#[doc(hidden)]
pub(crate) static #function_ident: turbo_tasks::macro_helpers::Lazy<turbo_tasks::NativeFunction> =
turbo_tasks::macro_helpers::Lazy::new(|| {
turbo_tasks::NativeFunction::new(#name_code.to_owned(), |inputs| {
let mut __iter = inputs.iter();
#(#input_extraction)*
if __iter.next().is_some() {
return Err(anyhow::anyhow!("{}() called with too many arguments", #name_code));
}
#(#input_convert)*
Ok(Box::new(move || {
#(#input_clone)*
Box::pin(async move {
#(#input_final)*
#original_call_code
})
}))
})
});

#[doc(hidden)]
pub(crate) static #function_id_ident: turbo_tasks::macro_helpers::Lazy<turbo_tasks::FunctionId> =
turbo_tasks::macro_helpers::Lazy::new(|| {
turbo_tasks::registry::get_function_id(&#function_ident)
});
pub(crate) static ref #function_id_ident: turbo_tasks::FunctionId = turbo_tasks::registry::get_function_id(&#function_ident);
}
},
input_raw_vc_arguments,
)
Expand Down
1 change: 0 additions & 1 deletion crates/turbo-tasks-macros/src/ident.rs

This file was deleted.

31 changes: 25 additions & 6 deletions crates/turbo-tasks-macros/src/value_impl_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ use syn::{
Path, Receiver, ReturnType, Signature, Token, Type, TypePath,
};
use turbo_tasks_macros_shared::{
get_ref_ident, get_register_trait_methods_ident, get_trait_impl_function_ident,
get_impl_function_ident, get_ref_ident, get_register_trait_methods_ident,
get_trait_impl_function_ident,
};

use crate::{
Expand All @@ -21,7 +22,7 @@ fn get_internal_trait_impl_function_ident(trait_ident: &Ident, ident: &Ident) ->
)
}

fn get_trait_impl_function_id_ident(struct_ident: &Ident, ident: &Ident) -> Ident {
fn get_impl_function_id_ident(struct_ident: &Ident, ident: &Ident) -> Ident {
Ident::new(
&format!(
"{}_IMPL_{}_FUNCTION_ID",
Expand All @@ -32,6 +33,22 @@ fn get_trait_impl_function_id_ident(struct_ident: &Ident, ident: &Ident) -> Iden
)
}

fn get_trait_impl_function_id_ident(
struct_ident: &Ident,
trait_ident: &Ident,
ident: &Ident,
) -> Ident {
Ident::new(
&format!(
"{}_IMPL_TRAIT_{}_{}_FUNCTION_ID",
struct_ident.to_string().to_uppercase(),
trait_ident.to_string().to_uppercase(),
ident.to_string().to_uppercase()
),
ident.span(),
)
}

fn is_attribute(attr: &Attribute, name: &str) -> bool {
let path = &attr.path;
if path.leading_colon.is_some() {
Expand Down Expand Up @@ -80,8 +97,8 @@ pub fn value_impl(_args: TokenStream, input: TokenStream) -> TokenStream {
split_signature(sig);

let inline_ident = &inline_sig.ident;
let function_ident = get_trait_impl_function_ident(vc_ident, ident);
let function_id_ident = get_trait_impl_function_id_ident(vc_ident, ident);
let function_ident = get_impl_function_ident(vc_ident, ident);
let function_id_ident = get_impl_function_id_ident(vc_ident, ident);

let (native_function_code, input_raw_vc_arguments) = gen_native_function_code(
// use const string
Expand Down Expand Up @@ -159,8 +176,10 @@ pub fn value_impl(_args: TokenStream, input: TokenStream) -> TokenStream {
..
} = sig;
let output_type = get_return_type(output);
let function_ident = get_trait_impl_function_ident(struct_ident, ident);
let function_id_ident = get_trait_impl_function_id_ident(struct_ident, ident);
let function_ident =
get_trait_impl_function_ident(struct_ident, trait_ident, ident);
let function_id_ident =
get_trait_impl_function_id_ident(struct_ident, trait_ident, ident);
let internal_function_ident =
get_internal_trait_impl_function_ident(trait_ident, ident);
trait_registers.push(quote! {
Expand Down
5 changes: 4 additions & 1 deletion crates/turbo-tasks-macros/src/value_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ pub fn value(args: TokenStream, input: TokenStream) -> TokenStream {
}
} else {
quote! {
turbo_tasks::ReadRef<#ident>
turbo_tasks::ReadRef<#ident, #ident>
}
};
let read_ref = quote! {
Expand Down Expand Up @@ -562,9 +562,11 @@ pub fn value(args: TokenStream, input: TokenStream) -> TokenStream {
#cell_struct
}

#[doc(hidden)]
static #value_type_init_ident: turbo_tasks::macro_helpers::OnceCell<
turbo_tasks::ValueType,
> = turbo_tasks::macro_helpers::OnceCell::new();
#[doc(hidden)]
pub(crate) static #value_type_ident: turbo_tasks::macro_helpers::Lazy<&turbo_tasks::ValueType> =
turbo_tasks::macro_helpers::Lazy::new(|| {
#value_type_init_ident.get_or_init(|| {
Expand All @@ -576,6 +578,7 @@ pub fn value(args: TokenStream, input: TokenStream) -> TokenStream {
)
})
});
#[doc(hidden)]
static #value_type_id_ident: turbo_tasks::macro_helpers::Lazy<turbo_tasks::ValueTypeId> =
turbo_tasks::macro_helpers::Lazy::new(|| {
turbo_tasks::registry::get_value_type_id(*#value_type_ident)
Expand Down
16 changes: 10 additions & 6 deletions crates/turbo-tasks-macros/src/value_trait_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,20 +177,24 @@ pub fn value_trait(args: TokenStream, input: TokenStream) -> TokenStream {

let expanded = quote! {
#(#attrs)*
#vis #trait_token #ident #colon_token #(std::convert::Into<#supertrait_refs>)+* {
#vis #trait_token #ident #colon_token #(#supertraits)+* {
#(#items)*
}

#(#native_functions)*

turbo_tasks::lazy_static! {
pub(crate) static ref #trait_type_ident: turbo_tasks::TraitType = {
#[doc(hidden)]
pub(crate) static #trait_type_ident: turbo_tasks::macro_helpers::Lazy<turbo_tasks::TraitType> =
turbo_tasks::macro_helpers::Lazy::new(|| {
let mut trait_type = turbo_tasks::TraitType::new(std::any::type_name::<#ref_ident>().to_string());;
#(#default_method_registers)*
trait_type
};
pub(crate) static ref #trait_type_id_ident: turbo_tasks::TraitTypeId = turbo_tasks::registry::get_trait_type_id(&#trait_type_ident);
}
});
#[doc(hidden)]
static #trait_type_id_ident: turbo_tasks::macro_helpers::Lazy<turbo_tasks::TraitTypeId> =
turbo_tasks::macro_helpers::Lazy::new(|| {
turbo_tasks::registry::get_trait_type_id(&#trait_type_ident)
});

#[derive(Clone, Copy, Debug, std::cmp::PartialOrd, std::cmp::Ord, std::hash::Hash, std::cmp::Eq, std::cmp::PartialEq, serde::Serialize, serde::Deserialize)]
#vis struct #ref_ident {
Expand Down
1 change: 0 additions & 1 deletion crates/turbo-tasks/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ erased-serde = "0.3.20"
event-listener = "2.5.2"
flurry = "0.4.0"
futures = "0.3.21"
lazy_static = "1.4.0"
mopa = "0.2.0"
once_cell = "1.13.0"
serde = { version = "1.0.136", features = ["rc", "derive"] }
Expand Down
2 changes: 1 addition & 1 deletion crates/turbo-tasks/src/id_factory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ impl<T: From<usize> + Deref<Target = usize>> Default for IdFactory<T> {
}

impl<T: From<usize> + Deref<Target = usize>> IdFactory<T> {
pub fn new() -> Self {
pub const fn new() -> Self {
Self {
next_id: AtomicUsize::new(1),
phantom_data: PhantomData,
Expand Down
Loading

0 comments on commit 2748ba7

Please sign in to comment.