// Within `exp`, you can bring things into scope with `extern crate`.
//
// We don't want to assume that `num_traits::` is in scope - the user may have imported it under a
// different name, or may have imported it in a non-toplevel module (common when putting impls
// behind a feature gate).
//
// Solution: let's just generate `extern crate num_traits as _num_traits` and then refer to
// `_num_traits` in the derived code.  However, macros are not allowed to produce `extern crate`
// statements at the toplevel.
//
// Solution: let's generate `mod _impl_foo` and import num_traits within that.  However, now we
// lose access to private members of the surrounding module.  This is a problem if, for example,
// 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
// here, but everything from the surrounding module is in scope.  This trick is taken from serde.
Within `exp`, you can bring things into scope with `extern crate`.
We don't want to assume that `num_traits::` is in scope - the user may have imported it under a
different name, or may have imported it in a non-toplevel module (common when putting impls
behind a feature gate).

let's just generate `extern crate num_traits as _num_traits` and then refer to
`_num_traits` in the derived code.  However, macros are not allowed to produce `extern crate`
statements at the toplevel.

let's generate `mod _impl_foo` and import num_traits within that.  However, now we
lose access to private members of the surrounding module.  This is a problem if, for example,
we're deriving for a newtype, where the inner type is defined in the same module, but not
exported.

use the dummy 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.
Within ` exp ` you can bring things into scope with ` extern crate ` . We don ' t want to assume that ` num_traits :: ` is in scope - the user may have imported it under a different name or may have imported it in a non - toplevel module ( common when putting impls behind a feature gate ) . let ' s just generate ` extern crate num_traits as _num_traits ` and then refer to ` _num_traits ` in the derived code . However macros are not allowed to produce ` extern crate ` statements at the toplevel . let ' s generate ` mod _impl_foo ` and import num_traits within that . However now we lose access to private members of the surrounding module . This is a problem if for example we ' re deriving for a newtype where the inner type is defined in the same module but not exported . use the dummy 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(),
    );
    quote! {
        #[allow(non_upper_case_globals, unused_qualifications)]
        const #dummy_const: () = {
            #[allow(clippy::useless_attribute)]
            #[allow(rust_2018_idioms)]
            extern crate num_traits as _num_traits;
            #exp
        };
    }
}
fn dummy_const_trick ( trait_ : & str , name : & Ident , exp : TokenStream2 ) -> TokenStream2 { let dummy_const = Ident :: new ( & format ! ( " " trait_ unraw ( name ) ) , Span :: call_site ( ) , ) ; quote ! { [ allow ( non_upper_case_globals unused_qualifications ) ] const dummy_const ( ) { [ allow ( clippy useless_attribute ) ] [ allow ( rust_2018_idioms ) ] extern crate num_traits as _num_traits exp } } }
Within `exp`, you can bring things into scope with `extern crate`.
Within ` exp ` you can bring things into scope with ` extern crate ` .
trait_
&str
name
&Ident
exp
TokenStream2