diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 5419f9955e4..2018d829597 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -356,7 +356,7 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { fn load_macro(&self, id: DefId, sess: &Session) -> LoadedMacro { let data = self.get_crate_data(id.krate); if let Some(ref proc_macros) = data.proc_macros { - return LoadedMacro::ProcMacro(proc_macros[id.index.as_usize()].1.clone()); + return LoadedMacro::ProcMacro(proc_macros[id.index.as_usize() - 1].1.clone()); } let (name, def) = data.get_macro(id.index); diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 6ffe5334533..79c90a04b37 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -23,7 +23,7 @@ use rustc::hir::intravisit::IdRange; use rustc::middle::cstore::{DepKind, InlinedItem, LinkagePreference}; use rustc::hir::def::{self, Def, CtorKind}; -use rustc::hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE}; +use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc::middle::lang_items; use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::subst::Substs; @@ -513,7 +513,14 @@ impl<'a, 'tcx> CrateMetadata { } pub fn get_def(&self, index: DefIndex) -> Option { - self.entry(index).kind.to_def(self.local_def_id(index)) + if self.proc_macros.is_some() { + Some(match index { + CRATE_DEF_INDEX => Def::Mod(self.local_def_id(index)), + _ => Def::Macro(self.local_def_id(index)), + }) + } else { + self.entry(index).kind.to_def(self.local_def_id(index)) + } } pub fn get_trait_def(&self, @@ -643,15 +650,24 @@ impl<'a, 'tcx> CrateMetadata { } pub fn get_stability(&self, id: DefIndex) -> Option { - self.entry(id).stability.map(|stab| stab.decode(self)) + match self.proc_macros { + Some(_) if id != CRATE_DEF_INDEX => None, + _ => self.entry(id).stability.map(|stab| stab.decode(self)), + } } pub fn get_deprecation(&self, id: DefIndex) -> Option { - self.entry(id).deprecation.map(|depr| depr.decode(self)) + match self.proc_macros { + Some(_) if id != CRATE_DEF_INDEX => None, + _ => self.entry(id).deprecation.map(|depr| depr.decode(self)), + } } pub fn get_visibility(&self, id: DefIndex) -> ty::Visibility { - self.entry(id).visibility + match self.proc_macros { + Some(_) => ty::Visibility::Public, + _ => self.entry(id).visibility, + } } fn get_impl_data(&self, id: DefIndex) -> ImplData<'tcx> { @@ -692,11 +708,11 @@ impl<'a, 'tcx> CrateMetadata { where F: FnMut(def::Export) { if let Some(ref proc_macros) = self.proc_macros { - for (id, &(name, _)) in proc_macros.iter().enumerate() { - callback(def::Export { - name: name, - def: Def::Macro(DefId { krate: self.cnum, index: DefIndex::new(id), }), - }) + if id == CRATE_DEF_INDEX { + for (id, &(name, _)) in proc_macros.iter().enumerate() { + let def = Def::Macro(DefId { krate: self.cnum, index: DefIndex::new(id + 1) }); + callback(def::Export { name: name, def: def }); + } } return } @@ -894,6 +910,9 @@ impl<'a, 'tcx> CrateMetadata { } pub fn get_item_attrs(&self, node_id: DefIndex) -> Vec { + if self.proc_macros.is_some() && node_id != CRATE_DEF_INDEX { + return Vec::new(); + } // The attributes for a tuple struct are attached to the definition, not the ctor; // we assume that someone passing in a tuple struct ctor is actually wanting to // look at the definition diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-a-b.rs b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-a-b.rs new file mode 100644 index 00000000000..8a92ca74f37 --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-a-b.rs @@ -0,0 +1,28 @@ +// Copyright 2016 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. + +// force-host +// no-prefer-dynamic + +#![feature(proc_macro, proc_macro_lib)] +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro_derive(A)] +pub fn derive_a(_: TokenStream) -> TokenStream { + "".parse().unwrap() +} + +#[proc_macro_derive(B)] +pub fn derive_b(_: TokenStream) -> TokenStream { + "".parse().unwrap() +} diff --git a/src/test/compile-fail-fulldeps/proc-macro/issue-37788.rs b/src/test/compile-fail-fulldeps/proc-macro/issue-37788.rs new file mode 100644 index 00000000000..6d1030026db --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/issue-37788.rs @@ -0,0 +1,21 @@ +// Copyright 2016 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:derive-a-b.rs + +#![feature(proc_macro)] + +#[macro_use] +extern crate derive_a_b; + +fn main() { + // Test that constructing the `visible_parent_map` (in `cstore_impl.rs`) does not ICE. + std::cell::Cell::new(0) //~ ERROR mismatched types +}