Skip to content

Commit cfb8e76

Browse files
author
Ariel Ben-Yehuda
authored
Rollup merge of rust-lang#46343 - jseyfried:fix_hygiene_bug, r=nrc
Fix hygiene bug. Fixes rust-lang#42708. r? @nrc
2 parents be51c4d + dfa6c25 commit cfb8e76

File tree

7 files changed

+89
-8
lines changed

7 files changed

+89
-8
lines changed

src/libproc_macro/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ impl FromStr for TokenStream {
9595
// notify the expansion info that it is unhygienic
9696
let mark = Mark::fresh(mark);
9797
mark.set_expn_info(expn_info);
98-
let span = call_site.with_ctxt(SyntaxContext::empty().apply_mark(mark));
98+
let span = call_site.with_ctxt(call_site.ctxt().apply_mark(mark));
9999
let stream = parse::parse_stream_from_source_str(name, src, sess, Some(span));
100100
Ok(__internal::token_stream_wrap(stream))
101101
})

src/librustc/hir/map/definitions.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -575,7 +575,8 @@ impl Definitions {
575575
self.node_to_def_index.insert(node_id, index);
576576
}
577577

578-
if expansion.is_modern() {
578+
let expansion = expansion.modern();
579+
if expansion != Mark::root() {
579580
self.expansions.insert(index, expansion);
580581
}
581582

src/librustc_resolve/lib.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -1560,6 +1560,15 @@ impl<'a> Resolver<'a> {
15601560
}
15611561
}
15621562

1563+
fn macro_def(&self, mut ctxt: SyntaxContext) -> DefId {
1564+
loop {
1565+
match self.macro_defs.get(&ctxt.outer()) {
1566+
Some(&def_id) => return def_id,
1567+
None => ctxt.remove_mark(),
1568+
};
1569+
}
1570+
}
1571+
15631572
/// Entry point to crate resolution.
15641573
pub fn resolve_crate(&mut self, krate: &Crate) {
15651574
ImportResolver { resolver: self }.finalize_imports();
@@ -1663,7 +1672,7 @@ impl<'a> Resolver<'a> {
16631672

16641673
module = match self.ribs[ns][i].kind {
16651674
ModuleRibKind(module) => module,
1666-
MacroDefinition(def) if def == self.macro_defs[&ident.ctxt.outer()] => {
1675+
MacroDefinition(def) if def == self.macro_def(ident.ctxt) => {
16671676
// If an invocation of this macro created `ident`, give up on `ident`
16681677
// and switch to `ident`'s source from the macro definition.
16691678
ident.ctxt.remove_mark();
@@ -1830,7 +1839,7 @@ impl<'a> Resolver<'a> {
18301839
// If an invocation of this macro created `ident`, give up on `ident`
18311840
// and switch to `ident`'s source from the macro definition.
18321841
MacroDefinition(def) => {
1833-
if def == self.macro_defs[&ident.ctxt.outer()] {
1842+
if def == self.macro_def(ident.ctxt) {
18341843
ident.ctxt.remove_mark();
18351844
}
18361845
}

src/libsyntax/parse/lexer/mod.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,13 @@ impl<'a> StringReader<'a> {
7373
fn mk_sp(&self, lo: BytePos, hi: BytePos) -> Span {
7474
unwrap_or!(self.override_span, Span::new(lo, hi, NO_EXPANSION))
7575
}
76+
fn mk_ident(&self, string: &str) -> Ident {
77+
let mut ident = Ident::from_str(string);
78+
if let Some(span) = self.override_span {
79+
ident.ctxt = span.ctxt();
80+
}
81+
ident
82+
}
7683

7784
fn next_token(&mut self) -> TokenAndSpan where Self: Sized {
7885
let res = self.try_next_token();
@@ -1103,7 +1110,7 @@ impl<'a> StringReader<'a> {
11031110
token::Underscore
11041111
} else {
11051112
// FIXME: perform NFKC normalization here. (Issue #2253)
1106-
token::Ident(Ident::from_str(string))
1113+
token::Ident(self.mk_ident(string))
11071114
}
11081115
}));
11091116
}
@@ -1286,13 +1293,13 @@ impl<'a> StringReader<'a> {
12861293
// expansion purposes. See #12512 for the gory details of why
12871294
// this is necessary.
12881295
let ident = self.with_str_from(start, |lifetime_name| {
1289-
Ident::from_str(&format!("'{}", lifetime_name))
1296+
self.mk_ident(&format!("'{}", lifetime_name))
12901297
});
12911298

12921299
// Conjure up a "keyword checking ident" to make sure that
12931300
// the lifetime name is not a keyword.
12941301
let keyword_checking_ident = self.with_str_from(start, |lifetime_name| {
1295-
Ident::from_str(lifetime_name)
1302+
self.mk_ident(lifetime_name)
12961303
});
12971304
let keyword_checking_token = &token::Ident(keyword_checking_ident);
12981305
let last_bpos = self.pos;

src/test/compile-fail-fulldeps/proc-macro/lints_in_proc_macros.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,5 @@ fn main() {
2323
bang_proc_macro2!();
2424
//~^ ERROR cannot find value `foobar2` in this scope
2525
//~^^ did you mean `foobar`?
26-
println!("{}", x);
26+
println!("{}", x); //~ ERROR cannot find value `x` in this scope
2727
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright 2017 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+
// no-prefer-dynamic
12+
13+
#![crate_type = "proc-macro"]
14+
#![feature(proc_macro)]
15+
16+
extern crate proc_macro;
17+
18+
use proc_macro::TokenStream;
19+
20+
#[proc_macro_derive(Test)]
21+
pub fn derive(_input: TokenStream) -> TokenStream {
22+
"fn f(s: S) { s.x }".parse().unwrap()
23+
}
24+
25+
#[proc_macro_attribute]
26+
pub fn attr_test(_attr: TokenStream, input: TokenStream) -> TokenStream {
27+
input
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright 2017 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+
// aux-build:issue-42708.rs
12+
// ignore-stage1
13+
14+
#![feature(decl_macro, proc_macro)]
15+
#![allow(unused)]
16+
17+
extern crate issue_42708;
18+
19+
macro m() {
20+
#[derive(issue_42708::Test)]
21+
struct S { x: () }
22+
23+
#[issue_42708::attr_test]
24+
struct S2 { x: () }
25+
26+
#[derive(Clone)]
27+
struct S3 { x: () }
28+
29+
fn g(s: S, s2: S2, s3: S3) {
30+
(s.x, s2.x, s3.x);
31+
}
32+
}
33+
34+
m!();
35+
36+
fn main() {}

0 commit comments

Comments
 (0)