diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index 22f788e34ecff143f74cf7e8a46f75c95931559c..4a6841aedca1299a33bce3f8ede40a90e5025850 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -95,7 +95,7 @@ fn from_str(src: &str) -> Result { // notify the expansion info that it is unhygienic let mark = Mark::fresh(mark); mark.set_expn_info(expn_info); - let span = call_site.with_ctxt(SyntaxContext::empty().apply_mark(mark)); + let span = call_site.with_ctxt(call_site.ctxt().apply_mark(mark)); let stream = parse::parse_stream_from_source_str(name, src, sess, Some(span)); Ok(__internal::token_stream_wrap(stream)) }) diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index dfa675f2e93514c768a0d5398375ff321c8293bc..7c2f0bc3cef8440b09f2b289f11dc3e8f0f6b927 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -575,7 +575,8 @@ pub fn create_def_with_parent(&mut self, self.node_to_def_index.insert(node_id, index); } - if expansion.is_modern() { + let expansion = expansion.modern(); + if expansion != Mark::root() { self.expansions.insert(index, expansion); } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 3243152527ffc42a74efe4bb2cd9758ff0fbd9b8..85e2144f6cd79423393e03fe06223f596398cf48 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1560,6 +1560,15 @@ fn per_ns T>(&mut self, mut f: F) -> PerNS< } } + fn macro_def(&self, mut ctxt: SyntaxContext) -> DefId { + loop { + match self.macro_defs.get(&ctxt.outer()) { + Some(&def_id) => return def_id, + None => ctxt.remove_mark(), + }; + } + } + /// Entry point to crate resolution. pub fn resolve_crate(&mut self, krate: &Crate) { ImportResolver { resolver: self }.finalize_imports(); @@ -1663,7 +1672,7 @@ fn resolve_ident_in_lexical_scope(&mut self, module = match self.ribs[ns][i].kind { ModuleRibKind(module) => module, - MacroDefinition(def) if def == self.macro_defs[&ident.ctxt.outer()] => { + MacroDefinition(def) if def == self.macro_def(ident.ctxt) => { // If an invocation of this macro created `ident`, give up on `ident` // and switch to `ident`'s source from the macro definition. ident.ctxt.remove_mark(); @@ -1830,7 +1839,7 @@ fn search_label(&self, mut ident: Ident, pred: P) -> Option // If an invocation of this macro created `ident`, give up on `ident` // and switch to `ident`'s source from the macro definition. MacroDefinition(def) => { - if def == self.macro_defs[&ident.ctxt.outer()] { + if def == self.macro_def(ident.ctxt) { ident.ctxt.remove_mark(); } } diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 951163d35fa0fbc7fe321e18a31e783bdbcc4ee0..6f20104dda5d78ee06f67d6221b60ef4dfb00dbd 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -73,6 +73,13 @@ impl<'a> StringReader<'a> { fn mk_sp(&self, lo: BytePos, hi: BytePos) -> Span { unwrap_or!(self.override_span, Span::new(lo, hi, NO_EXPANSION)) } + fn mk_ident(&self, string: &str) -> Ident { + let mut ident = Ident::from_str(string); + if let Some(span) = self.override_span { + ident.ctxt = span.ctxt(); + } + ident + } fn next_token(&mut self) -> TokenAndSpan where Self: Sized { let res = self.try_next_token(); @@ -1103,7 +1110,7 @@ fn next_token_inner(&mut self) -> Result { token::Underscore } else { // FIXME: perform NFKC normalization here. (Issue #2253) - token::Ident(Ident::from_str(string)) + token::Ident(self.mk_ident(string)) } })); } @@ -1286,13 +1293,13 @@ fn next_token_inner(&mut self) -> Result { // expansion purposes. See #12512 for the gory details of why // this is necessary. let ident = self.with_str_from(start, |lifetime_name| { - Ident::from_str(&format!("'{}", lifetime_name)) + self.mk_ident(&format!("'{}", lifetime_name)) }); // Conjure up a "keyword checking ident" to make sure that // the lifetime name is not a keyword. let keyword_checking_ident = self.with_str_from(start, |lifetime_name| { - Ident::from_str(lifetime_name) + self.mk_ident(lifetime_name) }); let keyword_checking_token = &token::Ident(keyword_checking_ident); let last_bpos = self.pos; diff --git a/src/test/compile-fail-fulldeps/proc-macro/lints_in_proc_macros.rs b/src/test/compile-fail-fulldeps/proc-macro/lints_in_proc_macros.rs index b1fb7d42d8683b064f1b88bafa85fa093fc70a5e..773b16b945f072ff359804c9d5e2c46d6e2be952 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/lints_in_proc_macros.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/lints_in_proc_macros.rs @@ -23,5 +23,5 @@ fn main() { bang_proc_macro2!(); //~^ ERROR cannot find value `foobar2` in this scope //~^^ did you mean `foobar`? - println!("{}", x); + println!("{}", x); //~ ERROR cannot find value `x` in this scope } diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/issue-42708.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/issue-42708.rs new file mode 100644 index 0000000000000000000000000000000000000000..58b4b2a5293b375a27c272de52613e7dc716fa6b --- /dev/null +++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/issue-42708.rs @@ -0,0 +1,28 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![feature(proc_macro)] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(Test)] +pub fn derive(_input: TokenStream) -> TokenStream { + "fn f(s: S) { s.x }".parse().unwrap() +} + +#[proc_macro_attribute] +pub fn attr_test(_attr: TokenStream, input: TokenStream) -> TokenStream { + input +} diff --git a/src/test/run-pass-fulldeps/proc-macro/issue-42708.rs b/src/test/run-pass-fulldeps/proc-macro/issue-42708.rs new file mode 100644 index 0000000000000000000000000000000000000000..e53e94ae475b25f44dc378bfbf667da7315f9c99 --- /dev/null +++ b/src/test/run-pass-fulldeps/proc-macro/issue-42708.rs @@ -0,0 +1,36 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:issue-42708.rs +// ignore-stage1 + +#![feature(decl_macro, proc_macro)] +#![allow(unused)] + +extern crate issue_42708; + +macro m() { + #[derive(issue_42708::Test)] + struct S { x: () } + + #[issue_42708::attr_test] + struct S2 { x: () } + + #[derive(Clone)] + struct S3 { x: () } + + fn g(s: S, s2: S2, s3: S3) { + (s.x, s2.x, s3.x); + } +} + +m!(); + +fn main() {}