Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ident sanitization causes name conflicts #42

Open
dschoepe opened this issue Jun 2, 2020 · 2 comments
Open

Ident sanitization causes name conflicts #42

dschoepe opened this issue Jun 2, 2020 · 2 comments

Comments

@dschoepe
Copy link

dschoepe commented Jun 2, 2020

Deduplicating consecutive underscores in sanitize_ident causes automatic derives to fail if one attempts to derive an implementation for a type Foo and _Foo. Here's a small example using abomonation_derive:

#[derive(Abomonation)]
pub struct Foo {
    x: String,
}

#[derive(Abomonation)]
pub struct _Foo {
    x: String,
}

Trying to compile this fails with the following error:

error[E0428]: the name `_DERIVE_abomonation_Abomonation_FOR_Foo` is defined multiple times
   --> dusty_example/src/main.rs:155:10
    |
149 | #[derive(Abomonation)]
    |          ----------- previous definition of the value `_DERIVE_abomonation_Abomonation_FOR_Foo` here
...
155 | #[derive(Abomonation)]
    |          ^^^^^^^^^^^ `_DERIVE_abomonation_Abomonation_FOR_Foo` redefined here
    |
    = note: `_DERIVE_abomonation_Abomonation_FOR_Foo` must be defined only once in the value namespace of this module
@mystor
Copy link
Owner

mystor commented Jun 2, 2020

This would also be fixed by #41 allowing avoiding generating a custom _DERIVE_ name.

@mystor
Copy link
Owner

mystor commented Jun 8, 2020

#43 has been merged, and published, which should allow avoiding this on rust >= 1.37 by using the new underscore_const method.

synstructure/src/lib.rs

Lines 1616 to 1660 in 864690b

/// Configure whether to use `const _` instead of a generated const name in
/// code generated by `gen_impl` and `bound_impl`.
///
/// This syntax is only supported by rust 1.37, and later versions.
///
/// Defaults to `false` for backwards compatibility reasons.
///
/// # Example
///
/// ```
/// # use synstructure::*;
/// let di: syn::DeriveInput = syn::parse_quote! {
/// struct MyStruct;
/// };
/// let mut s = Structure::new(&di);
///
/// assert_eq!(
/// s.underscore_const(true)
/// .gen_impl(quote! { gen impl Trait for @Self { } })
/// .to_string(),
/// quote! {
/// const _: () = {
/// impl Trait for MyStruct { }
/// };
/// }
/// .to_string()
/// );
///
/// assert_eq!(
/// s.underscore_const(false)
/// .gen_impl(quote! { gen impl Trait for @Self { } })
/// .to_string(),
/// quote! {
/// #[allow(non_upper_case_globals)]
/// const _DERIVE_Trait_FOR_MyStruct: () = {
/// impl Trait for MyStruct { }
/// };
/// }
/// .to_string()
/// );
/// ```
pub fn underscore_const(&mut self, enabled: bool) -> &mut Self {
self.underscore_const = enabled;
self
}

This will become the default behaviour in 0.13, if we end up making a breaking change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants