Skip to content

Fix quote macros (e.g. quote_pat) and make a test that we can un-ignore-test #12264

Closed
@pnkfelix

Description

@pnkfelix

The #[feature(quote)] offers a collection of macros like quote_expr! for turning inline code into AST's. Unfortunately, quote_pat! broken at some point (the interface to parse_pat seems like it probably changed), but we failed to notice because the test for quote macros was xfailed in 9c18510 (circa October 2013).

The test was xfailed because the test itself makes use of IO features (to pretty-print the results and then compare the pretty-print outputs), but this was not robust and according to @alexcrichton we were getting spurious failures.

Anyway, there are at least two action items for this ticket:

  1. Make some new version of the tests that we can un-ignore. I would be happy with e.g. one file that just invokes the macros without checking the correctness of their results, and a second file (perhaps the current ignored one) that both invokes the macros and checks their outputs.
  2. Fix quote_pat! and any other quote_foo! macros that have broken in the meantime.

Here is some sample code illustrating the issue. (Sorry about the length; we could also do more to ease using these macros. :) )

When attempting to compile the code below, I get the following error from rustc

% rustc --version
rustc 0.10-pre (58eeb07 2014-02-12 14:51:48 -0800)
host: x86_64-apple-darwin
%  rustc /tmp/qp.rs
/tmp/qp.rs:15:15: 15:41 error: this function takes 0 parameters but 1 parameter was supplied
/tmp/qp.rs:15     let pat = quote_pat!(fake, Some(_));
                            ^~~~~~~~~~~~~~~~~~~~~~~~~~
note: in expansion of quote_pat!
/tmp/qp.rs:15:15: 15:41 note: expansion site
error: aborting due to previous error
% 

Here's the aforementioned /tmp/qp.rs:

#[feature(quote)];
#[feature(managed_boxes)];
#[feature(macro_rules)];

extern mod syntax;

use syntax::ast;
use syntax::codemap;
use syntax::parse;
use syntax::parse::token;
use syntax::print::pprust;

fn main() {
    let fake = (); // fake context
    let pat = quote_pat!(fake, Some(_));
    println!("pat: {:?}", pat);
}

trait QuoteCtxt {
    fn parse_sess(&self) -> @syntax::parse::ParseSess;
    fn cfg(&self) -> ast::CrateConfig;
    fn call_site(&self) -> codemap::Span;
    fn ident_of(&self, st: &str) -> ast::Ident;
}

impl QuoteCtxt for () {
    fn parse_sess(&self)         -> @syntax::parse::ParseSess { parse::new_parse_sess() }
    fn cfg(&self)                -> ast::CrateConfig          { ~[] }
    fn call_site(&self)          -> codemap::Span             { codemap::DUMMY_SP }
    fn ident_of(&self, st: &str) -> ast::Ident                { token::str_to_ident(st) }
}

trait SyntaxToStr {
    fn get_interner(&self) -> @token::IdentInterner { token::get_ident_interner() }
    fn get_to_str() -> fn (_: &Self, intr: @token::IdentInterner) -> ~str;
    fn to_str(&self) -> ~str { SyntaxToStr::get_to_str()(self, self.get_interner()) }
}

macro_rules! impl_stx_to_str {
    ($Type:path, $func:path) => {
        impl SyntaxToStr for $Type {
            fn get_to_str() -> fn (_: &$Type, intr: @token::IdentInterner) -> ~str {
                $func
            }
        }
    }
}

impl_stx_to_str!(ast::Ty,       pprust::ty_to_str)
impl_stx_to_str!(ast::Pat,      pprust::pat_to_str)
impl_stx_to_str!(ast::Expr,     pprust::expr_to_str)
impl_stx_to_str!(ast::Stmt,     pprust::stmt_to_str)
impl_stx_to_str!(ast::Item,     pprust::item_to_str)
impl_stx_to_str!(ast::Generics, pprust::generics_to_str)
impl_stx_to_str!(ast::Path,     pprust::path_to_str)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-macrosArea: All kinds of macros (custom derive, macro_rules!, proc macros, ..)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions