2015-09-27 74 views
0

从另一个箱中获取宏以在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! { 

这显然INC宏的一部分。但是,我收到编译错误,说他们在使用的行上未定义宏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, 

注意:这发生在编译器的夜间分支上。

+0

你的问题是没有意义的。你说你有证据证明一个给定的宏正在被导入,但是然后证明它没有被导入。鉴于上面的例子,这是不可能的。我能想到的唯一事情就是*隐约地*就像你所描述的那样[来自APItMiR]的“一些更多的谜”](https://danielkeep.github.io/practical-intro-to-macros.html#some-more-陷阱);具体而言,“宏中的部分(有时)是词法范围的。”如果这不是你的问题,那么我不知道是什么。 –

+0

@DK。 - 我意识到这没有意义,这就是我发布我的问题的原因。对我来说,在编译器扩展宏之后,它突然决定它不能扩展宏,这似乎很荒谬。 就一个MCVE而言,我不确定还需要包括什么。由于它必须使用多个文件,因此我无法在Rust游乐场上演示此内容。我会尝试添加更多的显式代码,但main.rs示例。 – zrneely

回答

3

这个例子重现您的问题:

Cargo.toml

[package] 
name = "mac" 
version = "0.1.0" 
authors = ["An Devloper <[email protected]>"] 

[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 
相关问题