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 withpub 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 - Clifford M. (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.