rwf2/Rocket

uri! scope resolution issues

開放

#1,120 建立於 2019年9月6日

 (9 則留言) (1 個反應) (0 位負責人)Rust (1,645 個分叉)batch import
deficiencyhelp wanted

倉庫指標

星標
 (25,738 顆星)
PR 合併指標
 (30 天內沒有已合併 PR)

描述

Now that uri! internally uses macro_rules! instead of macro (#964), path resolution works differently. As far as I can tell this is a direct consequence of the fact that macro was hygienic with respect to paths, resolving them at the macro definition site i.e. the "target" route. In contrast macro_rules! is not hygienic for item paths (only locals), so paths are resolved in the invocation scope of the uri macro.

As a consequence, code such as this now fails to compile because PathBuf is not in scope at the uri! call:

#![feature(proc_macro_hygiene)]
#[macro_use] extern crate rocket;

#[get("/")]
fn hello() -> String {
    format!("Try going to {}", uri!(submodule::echo_path: "example/path"))
}

mod submodule {
    use std::path::PathBuf;

    #[get("/<path..>")]
    pub fn echo_path(path: PathBuf) -> String {
        path.display().to_string()
    }
}

fn main() {
    rocket::ignite().mount("/", routes![hello, submodule::echo_path]).launch();
}

The best possible solution for this issue is to use macro once it stabilizes, but that is pretty far off. If it works, we could try fudging some Spans in the generated macro_rules! macro. Another solution would be to use structs instead of a macro to encode the route information at compile time, but that is a much more significant rewrite of uri! that probably can't be done with the same feature set that is implemented now.

貢獻者指南