Skip to content

Commit 6a0cfbc

Browse files
committed
Rollup merge of rust-lang#32923 - jseyfried:fix_hygiene, r=nrc
Fix macro hygiene bug This fixes rust-lang#32922 (EDIT: and fixes rust-lang#31856), macro hygiene bugs. It is a [breaking-change]. For example, the following would break: ```rust fn main() { let x = true; macro_rules! foo { () => { let x = 0; macro_rules! bar { () => {x} } let _: bool = bar!(); //^ `bar!()` used to resolve the first `x` (a bool), //| but will now resolve to the second x (an i32). }} foo! {}; } ``` r? @nrc
2 parents ccc7e95 + ca1d29c commit 6a0cfbc

File tree

2 files changed

+50
-8
lines changed

2 files changed

+50
-8
lines changed

Diff for: src/libsyntax/ext/expand.rs

+9-8
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,13 @@ pub fn expand_item_mac(it: P<ast::Item>,
504504

505505
/// Expand a stmt
506506
fn expand_stmt(stmt: Stmt, fld: &mut MacroExpander) -> SmallVector<Stmt> {
507+
// perform all pending renames
508+
let stmt = {
509+
let pending_renames = &mut fld.cx.syntax_env.info().pending_renames;
510+
let mut rename_fld = IdentRenamer{renames:pending_renames};
511+
rename_fld.fold_stmt(stmt).expect_one("rename_fold didn't return one value")
512+
};
513+
507514
let (mac, style, attrs) = match stmt.node {
508515
StmtKind::Mac(mac, style, attrs) => (mac, style, attrs),
509516
_ => return expand_non_macro_stmt(stmt, fld)
@@ -717,14 +724,8 @@ pub fn expand_block(blk: P<Block>, fld: &mut MacroExpander) -> P<Block> {
717724
pub fn expand_block_elts(b: P<Block>, fld: &mut MacroExpander) -> P<Block> {
718725
b.map(|Block {id, stmts, expr, rules, span}| {
719726
let new_stmts = stmts.into_iter().flat_map(|x| {
720-
// perform all pending renames
721-
let renamed_stmt = {
722-
let pending_renames = &mut fld.cx.syntax_env.info().pending_renames;
723-
let mut rename_fld = IdentRenamer{renames:pending_renames};
724-
rename_fld.fold_stmt(x).expect_one("rename_fold didn't return one value")
725-
};
726-
// expand macros in the statement
727-
fld.fold_stmt(renamed_stmt).into_iter()
727+
// perform pending renames and expand macros in the statement
728+
fld.fold_stmt(x).into_iter()
728729
}).collect();
729730
let new_expr = expr.map(|x| {
730731
let expr = {

Diff for: src/test/compile-fail/issue-32922.rs

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(rustc_attrs)]
12+
#![allow(warnings)]
13+
14+
macro_rules! foo { () => {
15+
let x = 1;
16+
macro_rules! bar { () => {x} }
17+
let _ = bar!();
18+
}}
19+
20+
macro_rules! bar { // test issue #31856
21+
($n:ident) => (
22+
let a = 1;
23+
let $n = a;
24+
)
25+
}
26+
27+
macro_rules! baz {
28+
($i:ident) => {
29+
let mut $i = 2;
30+
$i = $i + 1;
31+
}
32+
}
33+
34+
#[rustc_error]
35+
fn main() { //~ ERROR compilation successful
36+
foo! {};
37+
bar! {};
38+
39+
let mut a = true;
40+
baz!(a);
41+
}

0 commit comments

Comments
 (0)