无法在使用该库的可执行文件中使用从库中导入的宏
Cannot use macros imported in a library in an executable that uses that library
我在从另一个 crate 中获取宏以在 Rust 中工作时遇到了很多麻烦。我的 lib.rs 文件如下所示:
#[macro_use]
extern crate session_types;
mod main;
这里是我的 main.rs 的简化部分,演示了 offer!
宏的正确使用:
use session_types::*;
type Server = Offer<Choose<Var<Z>, Var<Z>>, Choose<Var<Z>, Var<Z>>>;
struct Foo;
impl Foo {
fn server(&self, c: Chan<(), Rec<Server>>) {
let mut c = c.enter();
loop {
c = offer!{ c,
LEFT_BRANCH => c.sel1().zero(),
RIGHT_BRANCH => c.sel2().zero()
};
}
}
}
我知道编译器能够扩展 offer!
因为我已经调试了该宏中块中的代码,并且我收到有关该宏中未使用变量的警告,如下所示:
<session_types macros>:1:1: 5:16 note: in expansion of offer!
src/main.rs:107:21: 133:14 note: expansion site
<session_types macros>:3:53: 3:57: warning: unused variable: 'right', #[warn(unused_variables)] on by default
<session_types macros>:3 Branch:: Left ( $id ) => $code, Branch:: Right ( $id ) => offer! {
这显然包含了宏的一部分。但是,我收到编译错误,指出在使用它们的行上,宏 offer!
未定义。
src/main.rs:107:21: 133:14 note: in this expansion of offer! (defined in <session_types macros>)
src/main.rs:57:17: 57:22 error: macro undefined: 'offer!'
src/main.rs:57 c = offer!{ c,
^~~~~
src/main.rs:107:21: 107:26 error: macro undefined: 'offer!'
src/main.rs:107 night = offer!{ night,
注意:这发生在编译器的夜间分支上。
此示例重现了您的问题:
Cargo.toml
[package]
name = "mac"
version = "0.1.0"
authors = ["An Devloper <an.devloper@example.com>"]
[dependencies]
lazy_static = "0.1.14"
src/lib.rs
#[macro_use]
extern crate lazy_static;
lazy_static! {
pub static ref LIBRARY_VERSION: u8 = 1;
}
pub fn adder(a: u8, b: u8) -> u8 { a + b }
src/main.rs
extern crate mac;
lazy_static! {
static ref EXECUTABLE_VERSION: u8 = 1;
}
fn main() {
println!("Adder version {} (lib version {})", *EXECUTABLE_VERSION, *mac::LIBRARY_VERSION);
println!("Result: {}", mac::adder(1, 2));
}
问题是宏包含不能跨板条箱传递。将它们包含在您的库文件中不会使它们在使用您的库的任何下游板条箱中可用。那将彻底消除任何形式的选择性使用;想一想在一个有 20 个依赖项的项目中会有多少项目(每个项目本身都可以有依赖项)!
您还需要在可执行文件中明确包含宏,因为它是不同的包:
#[macro_use]
extern crate lazy_static;
// ... rest of above src/main.rs
我在从另一个 crate 中获取宏以在 Rust 中工作时遇到了很多麻烦。我的 lib.rs 文件如下所示:
#[macro_use]
extern crate session_types;
mod main;
这里是我的 main.rs 的简化部分,演示了 offer!
宏的正确使用:
use session_types::*;
type Server = Offer<Choose<Var<Z>, Var<Z>>, Choose<Var<Z>, Var<Z>>>;
struct Foo;
impl Foo {
fn server(&self, c: Chan<(), Rec<Server>>) {
let mut c = c.enter();
loop {
c = offer!{ c,
LEFT_BRANCH => c.sel1().zero(),
RIGHT_BRANCH => c.sel2().zero()
};
}
}
}
我知道编译器能够扩展 offer!
因为我已经调试了该宏中块中的代码,并且我收到有关该宏中未使用变量的警告,如下所示:
<session_types macros>:1:1: 5:16 note: in expansion of offer!
src/main.rs:107:21: 133:14 note: expansion site
<session_types macros>:3:53: 3:57: warning: unused variable: 'right', #[warn(unused_variables)] on by default
<session_types macros>:3 Branch:: Left ( $id ) => $code, Branch:: Right ( $id ) => offer! {
这显然包含了宏的一部分。但是,我收到编译错误,指出在使用它们的行上,宏 offer!
未定义。
src/main.rs:107:21: 133:14 note: in this expansion of offer! (defined in <session_types macros>)
src/main.rs:57:17: 57:22 error: macro undefined: 'offer!'
src/main.rs:57 c = offer!{ c,
^~~~~
src/main.rs:107:21: 107:26 error: macro undefined: 'offer!'
src/main.rs:107 night = offer!{ night,
注意:这发生在编译器的夜间分支上。
此示例重现了您的问题:
Cargo.toml
[package]
name = "mac"
version = "0.1.0"
authors = ["An Devloper <an.devloper@example.com>"]
[dependencies]
lazy_static = "0.1.14"
src/lib.rs
#[macro_use]
extern crate lazy_static;
lazy_static! {
pub static ref LIBRARY_VERSION: u8 = 1;
}
pub fn adder(a: u8, b: u8) -> u8 { a + b }
src/main.rs
extern crate mac;
lazy_static! {
static ref EXECUTABLE_VERSION: u8 = 1;
}
fn main() {
println!("Adder version {} (lib version {})", *EXECUTABLE_VERSION, *mac::LIBRARY_VERSION);
println!("Result: {}", mac::adder(1, 2));
}
问题是宏包含不能跨板条箱传递。将它们包含在您的库文件中不会使它们在使用您的库的任何下游板条箱中可用。那将彻底消除任何形式的选择性使用;想一想在一个有 20 个依赖项的项目中会有多少项目(每个项目本身都可以有依赖项)!
您还需要在可执行文件中明确包含宏,因为它是不同的包:
#[macro_use]
extern crate lazy_static;
// ... rest of above src/main.rs