Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Quote/splice discard syntactic context #15750

Closed
kmcallister opened this issue Jul 17, 2014 · 3 comments
Closed

Quote/splice discard syntactic context #15750

kmcallister opened this issue Jul 17, 2014 · 3 comments
Labels
A-syntaxext Area: Syntax extensions

Comments

@kmcallister
Copy link
Contributor

This breaks even hygienic references to the environment at the macro use site. This has broken my match_token macro now that hygiene for self is enforced.

I think the right solution would involve a general overhaul of quote/splice, which currently works by pretty-printing and re-parsing the code :/

Example to reproduce the bug:

plugin.rs

#![crate_type="dylib"]
#![feature(plugin_registrar, quote)]

extern crate syntax;
extern crate rustc;

use rustc::plugin::Registry;

use syntax::codemap::Span;
use syntax::ext::base::{ExtCtxt, MacResult, MacExpr};
use syntax::parse;
use syntax::ast;

fn expand(cx: &mut ExtCtxt, _span: Span, tts: &[ast::TokenTree])
        -> Box<MacResult> {
    // Parse an expression and emit it unchanged.
    let mut parser = parse::new_parser_from_tts(cx.parse_sess(),
        cx.cfg(), Vec::from_slice(tts));
    let expr = parser.parse_expr();
    MacExpr::new(quote_expr!(&mut *cx, $expr))
}

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_macro("mymacro", expand);
}

test.rs

#![feature(phase)]

#[phase(plugin)]
extern crate plugin;

fn main() {
    let x = 3;
    println!("{}", mymacro!(x));
}

Result:

$ rustc -v
rustc 0.12.0-pre (459ffc2adc74f5e8b64a76f5670edb419b9f65da 2014-07-17 01:16:19 +0000)

$ rustc plugin.rs 

$ rustc -L. test.rs
test.rs:8:20: 8:31 error: unresolved name `x`.
test.rs:8     println!("{}", mymacro!(x));
                             ^~~~~~~~~~~
error: aborting due to previous error
@huonw
Copy link
Member

huonw commented Jul 29, 2014

I think this is due to quote_expr!: it works by stringifying everything and then reparsing, losing the hygiene information encoded in the identifier, #15962.

Unfortunately the only way around this for now is to never use quote_*! on things passed into the macro where hygiene is important. (Including values containing them, and values containing those values, and...)

@brson
Copy link
Contributor

brson commented Jul 29, 2014

@pnkfelix Is going to look into this a bit to see what our options are.

@huonw
Copy link
Member

huonw commented Jul 29, 2014

(Oh, rereading the issue, I see my comment was essentially just rephrasing it...)

pnkfelix added a commit to pnkfelix/rust that referenced this issue Aug 1, 2014
@bors bors closed this as completed in aa98b25 Aug 14, 2014
bors added a commit that referenced this issue Aug 15, 2014
…hton

Followup to PR #16477: a run-pass regression test for Issue #15750.
bors added a commit that referenced this issue Aug 30, 2014
Different Identifiers and Names can have identical textual representations, but different internal representations, due to the macro hygiene machinery (syntax contexts and gensyms). This provides a way to see these internals by compiling with `--pretty expanded,hygiene`.

This is useful for debugging & hacking on macros (e.g. diagnosing #15750 likely would've been faster with this functionality).

E.g. 

```rust
#![feature(macro_rules)]
// minimal junk
#![no_std]

macro_rules! foo {
    ($x: ident) => { y + $x }
}

fn bar() {
    foo!(x)
}
```
```rust
#![feature(macro_rules)]
// minimal junk
#![no_std]


fn bar /* 61#0 */() { y /* 60#2 */ + x /* 58#3 */ }
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-syntaxext Area: Syntax extensions
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants