Skip to content

Commit

Permalink
Replace dummy-const with anon-const
Browse files Browse the repository at this point in the history
This has been supported since Rust 1.37, and the old way is about to
start raising a warning from [RFC 3373][1].

[1]: https://rust-lang.github.io/rfcs/3373-avoid-nonlocal-definitions-in-fns.html
  • Loading branch information
cuviper committed Feb 6, 2024
1 parent 50ecdb1 commit 5ffc290
Showing 1 changed file with 14 additions and 22 deletions.
36 changes: 14 additions & 22 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,16 +97,12 @@ macro_rules! parse {
// we're deriving for a newtype, where the inner type is defined in the same module, but not
// exported.
//
// Solution: use the dummy const trick. For some reason, `extern crate` statements are allowed
// Solution: use the anonymous const trick. For some reason, `extern crate` statements are allowed
// here, but everything from the surrounding module is in scope. This trick is taken from serde.
fn dummy_const_trick(trait_: &str, name: &Ident, exp: TokenStream2) -> TokenStream2 {
let dummy_const = Ident::new(
&format!("_IMPL_NUM_{}_FOR_{}", trait_, unraw(name)),
Span::call_site(),
);
fn anon_const_trick(exp: TokenStream2) -> TokenStream2 {
quote! {
#[allow(non_upper_case_globals, unused_qualifications)]
const #dummy_const: () = {
const _: () = {
#[allow(clippy::useless_attribute)]
#[allow(rust_2018_idioms)]
extern crate num_traits as _num_traits;
Expand All @@ -115,10 +111,6 @@ fn dummy_const_trick(trait_: &str, name: &Ident, exp: TokenStream2) -> TokenStre
}
}

fn unraw(ident: &Ident) -> String {
ident.to_string().trim_start_matches("r#").to_owned()
}

// If `data` is a newtype, return the type it's wrapping.
fn newtype_inner(data: &syn::Data) -> Option<syn::Type> {
match *data {
Expand Down Expand Up @@ -189,11 +181,11 @@ impl NumTraits {
}
}

fn wrap(&self, trait_: &str, name: &Ident, output: TokenStream2) -> TokenStream2 {
fn wrap(&self, output: TokenStream2) -> TokenStream2 {
if self.explicit {
output
} else {
dummy_const_trick(trait_, name, output)
anon_const_trick(output)
}
}
}
Expand Down Expand Up @@ -369,7 +361,7 @@ pub fn from_primitive(input: TokenStream) -> TokenStream {
}
};

import.wrap("FromPrimitive", name, impl_).into()
import.wrap(impl_).into()
}

/// Derives [`num_traits::ToPrimitive`][to] for simple enums and newtypes.
Expand Down Expand Up @@ -544,7 +536,7 @@ pub fn to_primitive(input: TokenStream) -> TokenStream {
}
};

import.wrap("ToPrimitive", name, impl_).into()
import.wrap(impl_).into()
}

const NEWTYPE_ONLY: &str = "This trait can only be derived for newtypes";
Expand Down Expand Up @@ -623,7 +615,7 @@ pub fn num_cast(input: TokenStream) -> TokenStream {
}
};

import.wrap("NumCast", name, impl_).into()
import.wrap(impl_).into()
}

/// Derives [`num_traits::Zero`][zero] for newtypes. The inner type must already implement `Zero`.
Expand All @@ -650,7 +642,7 @@ pub fn zero(input: TokenStream) -> TokenStream {
}
};

import.wrap("Zero", name, impl_).into()
import.wrap(impl_).into()
}

/// Derives [`num_traits::One`][one] for newtypes. The inner type must already implement `One`.
Expand All @@ -677,7 +669,7 @@ pub fn one(input: TokenStream) -> TokenStream {
}
};

import.wrap("One", name, impl_).into()
import.wrap(impl_).into()
}

/// Derives [`num_traits::Num`][num] for newtypes. The inner type must already implement `Num`.
Expand All @@ -701,7 +693,7 @@ pub fn num(input: TokenStream) -> TokenStream {
}
};

import.wrap("Num", name, impl_).into()
import.wrap(impl_).into()
}

/// Derives [`num_traits::Float`][float] for newtypes. The inner type must already implement
Expand Down Expand Up @@ -950,7 +942,7 @@ pub fn float(input: TokenStream) -> TokenStream {
}
};

import.wrap("Float", name, impl_).into()
import.wrap(impl_).into()
}

/// Derives [`num_traits::Signed`][signed] for newtypes. The inner type must already implement
Expand Down Expand Up @@ -990,7 +982,7 @@ pub fn signed(input: TokenStream) -> TokenStream {
}
};

import.wrap("Signed", &name, impl_).into()
import.wrap(impl_).into()
}

/// Derives [`num_traits::Unsigned`][unsigned]. The inner type must already implement
Expand All @@ -1008,5 +1000,5 @@ pub fn unsigned(input: TokenStream) -> TokenStream {
impl #import::Unsigned for #name {}
};

import.wrap("Unsigned", &name, impl_).into()
import.wrap(impl_).into()
}

0 comments on commit 5ffc290

Please sign in to comment.