Macros calling core or std functions

I'm making a crate that exports a few macros. I want to make the crate support compiling with and without no_std, which means sometimes calling std::mem::transmute and sometimes calling ::core::mem::transmute. Right now, the best solution I have found is this:

macro_rules! slice_as_array_transmute {
    ($slice:expr) => { ::std::mem::transmute($slice) }

macro_rules! slice_as_array_transmute {
    ($slice:expr) => { ::core::mem::transmute($slice) }

And then I call slice_as_array_transmute! from my macro with the actual meat. It works, but it is a lot of boilerplate and exports a macro that I would rather not. Is there a better way to do this?


Why don't you just use a function? Or heck, a conditional re-export?

pub use ::std::mem::transmute as transmute;
pub use ::core::mem::transmute as transmute;

You can also just pub use ::core as std or somesuch if you're only accessing the "core subset" of std.

I tried that, but if I define a function or do "pub use", the symbol I define there doesn't seem to be visible in the calling crate after the macro gets expanded. As a minimal example:

pub fn wont_be_visible() {

macro_rules! references_invisible_symbol {
    () => {

being used like

extern crate vistest;

fn try_to_use_macro() {

gives the error message:

<vistest macros>:1:11: 1:26 error: unresolved name `wont_be_visible` [E0425]
<vistest macros>:1 (  ) => { wont_be_visible (  ) }

It does work if I add

use vistest::wont_be_visible;

, but I'd rather not have the implementation details of the macro show up in code outside the crate.

Macros aren't like other things; they have no concept of names. The contents of the macro are interpreted in the expansion context, not the definition context.

Use $crate::wont_be_visible; $crate expands to a path to the crate that defined the macro. It's the one way to reliably name a symbol in your own crate from a macro.

Thanks! That is exactly what I needed.

In case anyone from the future stumbles on this thread, the documentation I should have read more carefully is here and what I ended up doing in the library defining the macros was:


pub use core as local_core;

and then called functions like


Edit: Actually, it looks like they are planning to make this code break in the future, so I'll probably have to define each function on its own.