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.

贡献者指南