diff --git a/derive_builder/CHANGELOG.md b/derive_builder/CHANGELOG.md index 0aa7993..b50581a 100644 --- a/derive_builder/CHANGELOG.md +++ b/derive_builder/CHANGELOG.md @@ -4,6 +4,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## Unreleased - Produce error when `default` is used with `field(type = "...")` rather than silently ignoring `default` #269 +- Add support for `crate = "..."` to support re-export scenarios #274 ## [0.11.2] - 2022-04-20 - Allow restricted visibility using `vis = "..."` for builders, build methods, setters, and fields #247 diff --git a/derive_builder/README.md b/derive_builder/README.md index ed3d9c1..e2dac3c 100644 --- a/derive_builder/README.md +++ b/derive_builder/README.md @@ -130,6 +130,7 @@ It's as simple as three steps: - **Builder derivations**: You can use `#[builder(derive(Trait1, Trait2, ...))]` to have the builder derive additonal traits. All builders derive `Default` and `Clone`, so you should not declare those in this attribute. - **Pass-through attributes**: Use `#[builder_struct_attr(...)]`, `#[builder_impl_attr(...)]`, `#[builder_field_attr(...)]`, and `#[builder_setter_attr(...)]` to declare attributes that will be added to the relevant part of the generated builder. - **no_std support**: Just add `#[builder(no_std)]` to your struct and add `extern crate alloc` to your crate. +- **Re-export support**: Use `#[builder(crate = "...")]` to set the root for `derive_builder`. This is useful if your crate is re-exporting `derive_builder::Builder` and needs the generated code to not directly reference the `derive_builder` crate. For more information and examples please take a look at our [documentation][doc]. diff --git a/derive_builder_core/src/build_method.rs b/derive_builder_core/src/build_method.rs index 6b09e24..ac438d8 100644 --- a/derive_builder_core/src/build_method.rs +++ b/derive_builder_core/src/build_method.rs @@ -40,6 +40,8 @@ use crate::DefaultExpression; /// ``` #[derive(Debug)] pub struct BuildMethod<'a> { + /// Path to the root of the derive_builder crate. + pub crate_root: &'a syn::Path, /// Enables code generation for this build method. pub enabled: bool, /// Name of this build fn. @@ -82,6 +84,7 @@ impl<'a> ToTokens for BuildMethod<'a> { }; let doc_comment = &self.doc_comment; let default_struct = self.default_struct.as_ref().map(|default_expr| { + let default_expr = default_expr.with_crate_root(self.crate_root); let ident = syn::Ident::new(DEFAULT_STRUCT_NAME, Span::call_site()); quote!(let #ident: #target_ty #target_ty_generics = #default_expr;) }); @@ -92,10 +95,11 @@ impl<'a> ToTokens for BuildMethod<'a> { let error_ty = &self.error_ty; if self.enabled { + let crate_root = &self.crate_root; tokens.append_all(quote!( #doc_comment #vis fn #ident(#self_param) - -> ::derive_builder::export::core::result::Result<#target_ty #target_ty_generics, #error_ty> + -> #crate_root::export::core::result::Result<#target_ty #target_ty_generics, #error_ty> { #validate_fn #default_struct @@ -138,6 +142,7 @@ impl<'a> BuildMethod<'a> { macro_rules! default_build_method { () => { BuildMethod { + crate_root: &parse_quote!(::derive_builder), enabled: true, ident: &syn::Ident::new("build", ::proc_macro2::Span::call_site()), visibility: ::std::borrow::Cow::Owned(syn::parse_quote!(pub)), diff --git a/derive_builder_core/src/builder.rs b/derive_builder_core/src/builder.rs index d2a1fdc..e55a2d0 100644 --- a/derive_builder_core/src/builder.rs +++ b/derive_builder_core/src/builder.rs @@ -86,6 +86,8 @@ use Setter; /// ``` #[derive(Debug)] pub struct Builder<'a> { + /// Path to the root of the derive_builder crate. + pub crate_root: &'a Path, /// Enables code generation for this builder struct. pub enabled: bool, /// Name of this builder struct. @@ -143,6 +145,7 @@ pub struct Builder<'a> { impl<'a> ToTokens for Builder<'a> { fn to_tokens(&self, tokens: &mut TokenStream) { if self.enabled { + let crate_root = self.crate_root; let builder_vis = &self.visibility; let builder_ident = &self.ident; let bounded_generics = self.compute_impl_bounds(); @@ -216,7 +219,7 @@ impl<'a> ToTokens for Builder<'a> { if self.impl_default { tokens.append_all(quote!( - impl #impl_generics ::derive_builder::export::core::default::Default for #builder_ident #ty_generics #where_clause { + impl #impl_generics #crate_root::export::core::default::Default for #builder_ident #ty_generics #where_clause { fn default() -> Self { Self::#create_empty() } @@ -236,23 +239,23 @@ impl<'a> ToTokens for Builder<'a> { /// Uninitialized field UninitializedField(&'static str), /// Custom validation error - ValidationError(::derive_builder::export::core::string::String), + ValidationError(#crate_root::export::core::string::String), } - impl ::derive_builder::export::core::convert::From<::derive_builder::UninitializedFieldError> for #builder_error_ident { - fn from(s: ::derive_builder::UninitializedFieldError) -> Self { + impl #crate_root::export::core::convert::From<#crate_root::UninitializedFieldError> for #builder_error_ident { + fn from(s: #crate_root::UninitializedFieldError) -> Self { Self::UninitializedField(s.field_name()) } } - impl ::derive_builder::export::core::convert::From<::derive_builder::export::core::string::String> for #builder_error_ident { - fn from(s: ::derive_builder::export::core::string::String) -> Self { + impl #crate_root::export::core::convert::From<#crate_root::export::core::string::String> for #builder_error_ident { + fn from(s: #crate_root::export::core::string::String) -> Self { Self::ValidationError(s) } } - impl ::derive_builder::export::core::fmt::Display for #builder_error_ident { - fn fmt(&self, f: &mut ::derive_builder::export::core::fmt::Formatter) -> ::derive_builder::export::core::fmt::Result { + impl #crate_root::export::core::fmt::Display for #builder_error_ident { + fn fmt(&self, f: &mut #crate_root::export::core::fmt::Formatter) -> #crate_root::export::core::fmt::Result { match self { Self::UninitializedField(ref field) => write!(f, "`{}` must be initialized", field), Self::ValidationError(ref error) => write!(f, "{}", error), @@ -309,11 +312,13 @@ impl<'a> Builder<'a> { return generics; } + let crate_root = self.crate_root; + let clone_bound = TypeParamBound::Trait(TraitBound { paren_token: None, modifier: TraitBoundModifier::None, lifetimes: None, - path: syn::parse_quote!(::derive_builder::export::core::clone::Clone), + path: syn::parse_quote!(#crate_root::export::core::clone::Clone), }); for typ in generics.type_params_mut() { @@ -334,6 +339,7 @@ impl<'a> Builder<'a> { macro_rules! default_builder { () => { Builder { + crate_root: &parse_quote!(::derive_builder), enabled: true, ident: syn::Ident::new("FooBuilder", ::proc_macro2::Span::call_site()), pattern: Default::default(), diff --git a/derive_builder_core/src/builder_field.rs b/derive_builder_core/src/builder_field.rs index bf33673..fabebea 100644 --- a/derive_builder_core/src/builder_field.rs +++ b/derive_builder_core/src/builder_field.rs @@ -31,6 +31,8 @@ use syn; /// ``` #[derive(Debug, Clone)] pub struct BuilderField<'a> { + /// Path to the root of the derive_builder crate. + pub crate_root: &'a syn::Path, /// Name of the target field. pub field_ident: &'a syn::Ident, /// Type of the builder field. @@ -45,7 +47,7 @@ impl<'a> ToTokens for BuilderField<'a> { fn to_tokens(&self, tokens: &mut TokenStream) { let ident = self.field_ident; let vis = &self.field_visibility; - let ty = &self.field_type; + let ty = &self.field_type.with_crate_root(self.crate_root); let attrs = self.attrs; tokens.append_all(quote!( #(#attrs)* #vis #ident: #ty, @@ -57,7 +59,8 @@ impl<'a> BuilderField<'a> { /// Emits a struct field initializer that initializes the field to `Default::default`. pub fn default_initializer_tokens(&self) -> TokenStream { let ident = self.field_ident; - quote! { #ident : ::derive_builder::export::core::default::Default::default(), } + let crate_root = self.crate_root; + quote! { #ident : #crate_root::export::core::default::Default::default(), } } } @@ -94,17 +97,30 @@ impl<'a> BuilderFieldType<'a> { BuilderFieldType::Phantom(_ty) => panic!("phantom fields should never have setters"), } } + + fn with_crate_root(&'a self, crate_root: &'a syn::Path) -> BuilderFieldTypeWithCrateRoot<'a> { + BuilderFieldTypeWithCrateRoot { + crate_root, + field_type: self, + } + } } -impl<'a> ToTokens for BuilderFieldType<'a> { +struct BuilderFieldTypeWithCrateRoot<'a> { + crate_root: &'a syn::Path, + field_type: &'a BuilderFieldType<'a>, +} + +impl<'a> ToTokens for BuilderFieldTypeWithCrateRoot<'a> { fn to_tokens(&self, tokens: &mut TokenStream) { - match self { + let crate_root = self.crate_root; + match self.field_type { BuilderFieldType::Optional(ty) => tokens.append_all(quote!( - ::derive_builder::export::core::option::Option<#ty> + #crate_root::export::core::option::Option<#ty> )), BuilderFieldType::Precise(ty) => ty.to_tokens(tokens), BuilderFieldType::Phantom(ty) => tokens.append_all(quote!( - ::derive_builder::export::core::marker::PhantomData<#ty> + #crate_root::export::core::marker::PhantomData<#ty> )), } } @@ -118,6 +134,7 @@ impl<'a> ToTokens for BuilderFieldType<'a> { macro_rules! default_builder_field { () => {{ BuilderField { + crate_root: &parse_quote!(::derive_builder), field_ident: &syn::Ident::new("foo", ::proc_macro2::Span::call_site()), field_type: BuilderFieldType::Optional(Box::leak(Box::new(parse_quote!(String)))), field_visibility: ::std::borrow::Cow::Owned(parse_quote!(pub)), diff --git a/derive_builder_core/src/default_expression.rs b/derive_builder_core/src/default_expression.rs index c45f8ca..27e62fa 100644 --- a/derive_builder_core/src/default_expression.rs +++ b/derive_builder_core/src/default_expression.rs @@ -1,5 +1,6 @@ use crate::BlockContents; -use quote::{ToTokens, TokenStreamExt}; +use proc_macro2::Span; +use quote::ToTokens; /// A `DefaultExpression` can be either explicit or refer to the canonical trait. #[derive(Debug, Clone)] @@ -9,6 +10,19 @@ pub enum DefaultExpression { } impl DefaultExpression { + /// Add the crate root path so the default expression can be emitted + /// to a `TokenStream`. + /// + /// This function is needed because the crate root is inherited from the container, so it cannot + /// be provided at parse time to [`darling::FromMeta::from_word`] when reading, and [`ToTokens`] does not + /// accept any additional parameters, so it annot be provided at emit time. + pub fn with_crate_root<'a>(&'a self, crate_root: &'a syn::Path) -> impl 'a + ToTokens { + DefaultExpressionWithCrateRoot { + crate_root, + expr: self, + } + } + #[cfg(test)] pub fn explicit>(content: I) -> Self { DefaultExpression::Explicit(content.into()) @@ -25,13 +39,30 @@ impl darling::FromMeta for DefaultExpression { } } -impl ToTokens for DefaultExpression { +impl syn::spanned::Spanned for DefaultExpression { + fn span(&self) -> Span { + match self { + DefaultExpression::Explicit(block) => block.span(), + DefaultExpression::Trait => Span::call_site(), + } + } +} + +/// Wrapper for `DefaultExpression` +struct DefaultExpressionWithCrateRoot<'a> { + crate_root: &'a syn::Path, + expr: &'a DefaultExpression, +} + +impl<'a> ToTokens for DefaultExpressionWithCrateRoot<'a> { fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { - match *self { - Self::Explicit(ref block) => block.to_tokens(tokens), - Self::Trait => tokens.append_all(quote!( - ::derive_builder::export::core::default::Default::default() - )), + let crate_root = self.crate_root; + match self.expr { + DefaultExpression::Explicit(ref block) => block.to_tokens(tokens), + DefaultExpression::Trait => quote!( + #crate_root::export::core::default::Default::default() + ) + .to_tokens(tokens), } } } diff --git a/derive_builder_core/src/initializer.rs b/derive_builder_core/src/initializer.rs index 6cb1725..617ac5e 100644 --- a/derive_builder_core/src/initializer.rs +++ b/derive_builder_core/src/initializer.rs @@ -37,6 +37,8 @@ use crate::{BlockContents, DefaultExpression}; /// ``` #[derive(Debug, Clone)] pub struct Initializer<'a> { + /// Path to the root of the derive_builder crate. + pub crate_root: &'a syn::Path, /// Name of the target field. pub field_ident: &'a syn::Ident, /// Whether the builder implements a setter for this field. @@ -108,36 +110,45 @@ impl<'a> Initializer<'a> { fn match_some(&'a self) -> MatchSome { match self.builder_pattern { BuilderPattern::Owned => MatchSome::Move, - BuilderPattern::Mutable | BuilderPattern::Immutable => MatchSome::Clone, + BuilderPattern::Mutable | BuilderPattern::Immutable => MatchSome::Clone { + crate_root: self.crate_root, + }, } } /// To be used inside of `#struct_field: match self.#builder_field { ... }` fn match_none(&'a self) -> MatchNone<'a> { match self.default_value { - Some(expr) => MatchNone::DefaultTo(expr), + Some(expr) => MatchNone::DefaultTo { + expr, + crate_root: self.crate_root, + }, None => { if self.use_default_struct { MatchNone::UseDefaultStructField(self.field_ident) } else { - MatchNone::ReturnError( - self.field_ident.to_string(), - self.custom_error_type_span, - ) + MatchNone::ReturnError { + crate_root: self.crate_root, + field_name: self.field_ident.to_string(), + span: self.custom_error_type_span, + } } } } } fn default(&'a self) -> TokenStream { + let crate_root = self.crate_root; match self.default_value { - Some(ref expr) => quote!(#expr), + Some(expr) => expr.with_crate_root(crate_root).into_token_stream(), None if self.use_default_struct => { let struct_ident = syn::Ident::new(DEFAULT_STRUCT_NAME, Span::call_site()); let field_ident = self.field_ident; quote!(#struct_ident.#field_ident) } - None => quote!(::derive_builder::export::core::default::Default::default()), + None => { + quote!(#crate_root::export::core::default::Default::default()) + } } } } @@ -155,34 +166,46 @@ pub enum FieldConversion<'a> { /// To be used inside of `#struct_field: match self.#builder_field { ... }` enum MatchNone<'a> { /// Inner value must be a valid Rust expression - DefaultTo(&'a DefaultExpression), + DefaultTo { + expr: &'a DefaultExpression, + crate_root: &'a syn::Path, + }, /// Inner value must be the field identifier /// /// The default struct must be in scope in the build_method. UseDefaultStructField(&'a syn::Ident), /// Inner value must be the field name - ReturnError(String, Option), + ReturnError { + crate_root: &'a syn::Path, + field_name: String, + span: Option, + }, } impl<'a> ToTokens for MatchNone<'a> { fn to_tokens(&self, tokens: &mut TokenStream) { match *self { - MatchNone::DefaultTo(expr) => tokens.append_all(quote!( - None => #expr - )), + MatchNone::DefaultTo { expr, crate_root } => { + let expr = expr.with_crate_root(crate_root); + tokens.append_all(quote!(None => #expr)); + } MatchNone::UseDefaultStructField(field_ident) => { let struct_ident = syn::Ident::new(DEFAULT_STRUCT_NAME, Span::call_site()); tokens.append_all(quote!( None => #struct_ident.#field_ident )) } - MatchNone::ReturnError(ref field_name, ref span) => { + MatchNone::ReturnError { + ref field_name, + ref span, + crate_root, + } => { let conv_span = span.unwrap_or_else(Span::call_site); - let err_conv = quote_spanned!(conv_span => ::derive_builder::export::core::convert::Into::into( - ::derive_builder::UninitializedFieldError::from(#field_name) + let err_conv = quote_spanned!(conv_span => #crate_root::export::core::convert::Into::into( + #crate_root::UninitializedFieldError::from(#field_name) )); tokens.append_all(quote!( - None => return ::derive_builder::export::core::result::Result::Err(#err_conv) + None => return #crate_root::export::core::result::Result::Err(#err_conv) )); } } @@ -190,19 +213,19 @@ impl<'a> ToTokens for MatchNone<'a> { } /// To be used inside of `#struct_field: match self.#builder_field { ... }` -enum MatchSome { +enum MatchSome<'a> { Move, - Clone, + Clone { crate_root: &'a syn::Path }, } -impl ToTokens for MatchSome { +impl ToTokens for MatchSome<'_> { fn to_tokens(&self, tokens: &mut TokenStream) { match *self { Self::Move => tokens.append_all(quote!( Some(value) => value )), - Self::Clone => tokens.append_all(quote!( - Some(ref value) => ::derive_builder::export::core::clone::Clone::clone(value) + Self::Clone { crate_root } => tokens.append_all(quote!( + Some(ref value) => #crate_root::export::core::clone::Clone::clone(value) )), } } @@ -215,6 +238,7 @@ impl ToTokens for MatchSome { macro_rules! default_initializer { () => { Initializer { + crate_root: &parse_quote!(::derive_builder), field_ident: &syn::Ident::new("foo", ::proc_macro2::Span::call_site()), field_enabled: true, builder_pattern: BuilderPattern::Mutable, diff --git a/derive_builder_core/src/macro_options/darling_opts.rs b/derive_builder_core/src/macro_options/darling_opts.rs index ebe1f38..0781330 100644 --- a/derive_builder_core/src/macro_options/darling_opts.rs +++ b/derive_builder_core/src/macro_options/darling_opts.rs @@ -494,6 +494,10 @@ impl Visibility for Field { } } +fn default_crate_root() -> Path { + parse_quote!(::derive_builder) +} + fn default_create_empty() -> Ident { Ident::new("create_empty", Span::call_site()) } @@ -530,6 +534,11 @@ pub struct Options { /// The name of the generated builder. Defaults to `#{ident}Builder`. name: Option, + /// The path to the root of the derive_builder crate used in generated + /// code. + #[darling(rename = "crate", default = "default_crate_root")] + crate_root: Path, + #[darling(default)] pattern: BuilderPattern, @@ -685,6 +694,7 @@ impl Options { impl Options { pub fn as_builder(&self) -> Builder { Builder { + crate_root: &self.crate_root, enabled: true, ident: self.builder_ident(), pattern: self.pattern, @@ -709,6 +719,7 @@ impl Options { pub fn as_build_method(&self) -> BuildMethod { let (_, ty_generics, _) = self.generics.split_for_impl(); BuildMethod { + crate_root: &self.crate_root, enabled: !self.build_fn.skip, ident: &self.build_fn.name, visibility: self.build_method_vis(), @@ -875,6 +886,7 @@ impl<'a> FieldWithDefaults<'a> { /// Returns a `Setter` according to the options. pub fn as_setter(&'a self) -> Setter<'a> { Setter { + crate_root: &self.parent.crate_root, setter_enabled: self.setter_enabled(), try_setter: self.try_setter(), visibility: self.setter_vis(), @@ -897,6 +909,7 @@ impl<'a> FieldWithDefaults<'a> { /// if `default_expression` can not be parsed as `Block`. pub fn as_initializer(&'a self) -> Initializer<'a> { Initializer { + crate_root: &self.parent.crate_root, field_enabled: self.field_enabled(), field_ident: self.field_ident(), builder_pattern: self.pattern(), @@ -914,6 +927,7 @@ impl<'a> FieldWithDefaults<'a> { pub fn as_builder_field(&'a self) -> BuilderField<'a> { BuilderField { + crate_root: &self.parent.crate_root, field_ident: self.field_ident(), field_type: self.field_type(), field_visibility: self.field_vis(), diff --git a/derive_builder_core/src/setter.rs b/derive_builder_core/src/setter.rs index 5728e65..1c6982e 100644 --- a/derive_builder_core/src/setter.rs +++ b/derive_builder_core/src/setter.rs @@ -41,6 +41,8 @@ use Each; /// ``` #[derive(Debug, Clone)] pub struct Setter<'a> { + /// Path to the root of the derive_builder crate. + pub crate_root: &'a syn::Path, /// Enables code generation for this setter fn. pub setter_enabled: bool, /// Enables code generation for the `try_` variant of this setter fn. @@ -73,6 +75,7 @@ pub struct Setter<'a> { impl<'a> ToTokens for Setter<'a> { fn to_tokens(&self, tokens: &mut TokenStream) { if self.setter_enabled { + let crate_root = self.crate_root; let pattern = self.pattern; let vis = &self.visibility; let field_ident = self.field_ident; @@ -99,7 +102,7 @@ impl<'a> ToTokens for Setter<'a> { self_param = quote!(&self); return_ty = quote!(Self); self_into_return_ty = - quote!(::derive_builder::export::core::clone::Clone::clone(self)); + quote!(#crate_root::export::core::clone::Clone::clone(self)); } }; @@ -121,7 +124,7 @@ impl<'a> ToTokens for Setter<'a> { }; if self.generic_into { - ty_params = quote!(>); + ty_params = quote!(>); param_ty = quote!(VALUE); into_value = quote!(value.into()); } else { @@ -132,10 +135,10 @@ impl<'a> ToTokens for Setter<'a> { // If both `stripped_option` and `builder_field_is_option`, the target field is `Option`, // the builder field is `Option>`, and the setter takes `file_type`, so we must wrap it twice. if stripped_option { - into_value = wrap_expression_in_some(into_value); + into_value = wrap_expression_in_some(crate_root, into_value); } if builder_field_is_option { - into_value = wrap_expression_in_some(into_value); + into_value = wrap_expression_in_some(crate_root, into_value); } tokens.append_all(quote!( @@ -153,18 +156,18 @@ impl<'a> ToTokens for Setter<'a> { if self.try_setter { let try_ty_params = - quote!(>); + quote!(>); let try_ident = syn::Ident::new(&format!("try_{}", ident), Span::call_site()); let mut converted = quote! {converted}; if builder_field_is_option { - converted = wrap_expression_in_some(converted); + converted = wrap_expression_in_some(crate_root, converted); } tokens.append_all(quote!( #(#attrs)* #vis fn #try_ident #try_ty_params (#self_param, value: VALUE) - -> ::derive_builder::export::core::result::Result<#return_ty, VALUE::Error> + -> #crate_root::export::core::result::Result<#return_ty, VALUE::Error> { let converted : #ty = value.try_into()?; let mut new = #self_into_return_ty; @@ -181,13 +184,13 @@ impl<'a> ToTokens for Setter<'a> { let get_initialized_collection = if stripped_option { // Outer (builder) Option -> Inner (field) Option -> collection. quote!(get_or_insert_with(|| Some( - ::derive_builder::export::core::default::Default::default() + #crate_root::export::core::default::Default::default() )) - .get_or_insert_with(::derive_builder::export::core::default::Default::default)) + .get_or_insert_with(#crate_root::export::core::default::Default::default)) } else { // Outer (builder) Option -> collection. quote!(get_or_insert_with( - ::derive_builder::export::core::default::Default::default + #crate_root::export::core::default::Default::default )) }; @@ -196,9 +199,9 @@ impl<'a> ToTokens for Setter<'a> { let into_item: TokenStream; if each.into { - ty_params = quote!(>); + ty_params = quote!(>); param_ty = quote!(FROM_VALUE); - into_item = quote!(::derive_builder::export::core::convert::Into::into(item)); + into_item = quote!(#crate_root::export::core::convert::Into::into(item)); } else { ty_params = quote!(); param_ty = quote!(VALUE); @@ -210,13 +213,13 @@ impl<'a> ToTokens for Setter<'a> { #[allow(unused_mut)] #vis fn #ident_each #ty_params(#self_param, item: #param_ty) -> #return_ty where - #ty: ::derive_builder::export::core::default::Default + ::derive_builder::export::core::iter::Extend, + #ty: #crate_root::export::core::default::Default + #crate_root::export::core::iter::Extend, { #deprecation_notes let mut new = #self_into_return_ty; new.#field_ident .#get_initialized_collection - .extend(::derive_builder::export::core::option::Option::Some(#into_item)); + .extend(#crate_root::export::core::option::Option::Some(#into_item)); new } )); @@ -226,8 +229,8 @@ impl<'a> ToTokens for Setter<'a> { } /// Returns expression wrapping `bare_value` in `Some` -fn wrap_expression_in_some(bare_value: impl ToTokens) -> TokenStream { - quote!( ::derive_builder::export::core::option::Option::Some(#bare_value) ) +fn wrap_expression_in_some(crate_root: &syn::Path, bare_value: impl ToTokens) -> TokenStream { + quote!( #crate_root::export::core::option::Option::Some(#bare_value) ) } // adapted from https://stackoverflow.com/a/55277337/469066 @@ -284,6 +287,7 @@ fn extract_type_from_option(ty: &syn::Type) -> Option<&syn::Type> { macro_rules! default_setter { () => { Setter { + crate_root: &parse_quote!(::derive_builder), setter_enabled: true, try_setter: false, visibility: ::std::borrow::Cow::Owned(parse_quote!(pub)),