Skip to content

macro_rules that "captures" outter variable fails to compile if used inside a function, but not if used inside a method #15504

Closed
@japaric

Description

@japaric

STR:

#![feature(macro_rules)]

macro_rules! check_len {
    () => { xs.len() == 0 }
}

struct Foo;

impl Foo {
    fn bar(self, xs: Vec<uint>) -> bool {
        // GOOD
        check_len!()

        // GOOD
        //xs.len() == 0
    }
}

fn baz(xs: Vec<uint>) -> bool {
    // BAD
    check_len!()

    // GOOD
    //xs.len() == 0
}

fn main() { }

Output:

$ rustc foo.rs
foo.rs:4:13: 4:15 error: unresolved name `xs`.
foo.rs:4     () => { xs.len() == 0 }
                     ^~
foo.rs:3:1: 5:2 note: in expansion of check_len!
foo.rs:21:5: 25:2 note: expansion site
error: aborting due to previous error

Expansion:

$ rustc --pretty expanded foo.rs
#![feature(macro_rules)]
#![feature(phase)]
#![no_std]
#![feature(globs)]
#[phase(plugin, link)]
extern crate std;
extern crate native;
use std::prelude::*;


struct Foo;

impl Foo {
    fn bar(self, xs: Vec<uint>) -> bool {

        // GOOD
        xs.len() == 0

        // GOOD
        //xs.len() == 0
    }
}

fn baz(xs: Vec<uint>) -> bool {

    // BAD
    xs.len() == 0

    // GOOD
    //xs.len() == 0
}

fn main() { }

Version:

$ rustc --version
rustc 0.11.0 (4f120e6bafe971452adfede158a7957b00562a4e 2014-07-07 08:16:29 +0000)

P.S. I got the impression that we are moving towards macros that can't "capture" outter variables (like xs in this case) for "hygienic" reasons. Is that correct? And, if that's the case, may I ask what is this "hygiene" about? (Is a concept related to compilers (only)?)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-syntaxextArea: Syntax extensions

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions