PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Monday, November 28, 2022

[FIXED] How to export function and macro with the same name?

 November 28, 2022     module, rust, rust-macros     No comments   

Issue

Is it possible to export a function and a macro with the same name from a module?

Example lib.rs

mod log;

fn foo() {
    log::info!("");
    log::info("");
}

In log.rs:

  • Using pub(crate) use info; conflicts with pub fn info() { .. }

  • Using #[macro_export] and #[macro_use] doesn't allow namespaces


Solution

Macros and functions belong to different namespaces so two with the same name should happily coexist. This compiles (playground):

macro_rules! info {
    ($v:expr) => {}
}

fn info(v: &str) { }

However, trouble seems to arise when when trying to make them public from within a module. Exporting the macro as shown in How do I use a macro across module files? seems to conflict somehow with the function declaration (playground):

mod log {
    macro_rules! info {
        ($v:expr) => {}
    }
    
    pub(crate) use info;
    
    pub fn info(v: &str) { }
}
error[E0255]: the name `info` is defined multiple times
 --> src/lib.rs:8:5
  |
6 |     pub(crate) use info;
  |                    ---- previous import of the value `info` here
7 |     
8 |     pub fn info(v: &str) { }
  |     ^^^^^^^^^^^^^^^^^^^^ `info` redefined here
  |
  = note: `info` must be defined only once in the value namespace of this module
help: you can use `as` to change the binding name of the import
  |
6 |     pub(crate) use info as other_info;
  |                    ~~~~~~~~~~~~~~~~~~

I do not know if this is a bug or intended behavior. Either way it is confusing.


A workaround that I found was to declare the function in a separate module and then re-export it by wildcard in the original module (playground):

mod log {
    mod imp {
        pub fn info(v: &str) { }
    }
    
    pub use imp::*;
    
    macro_rules! info {
        ($v:expr) => { }
    }
    
    pub(crate) use info;
}

You can do it the other way (i.e. putting the macro in a separate module) but the compiler strangely yields a warning that it didn't re-export anything even when it did (playground).



Answered By - kmdreko
Answer Checked By - Dawn Plyler (PHPFixing Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing