Register and stability check #[no_link] crates.

This commit is contained in:
Jeffrey Seyfried 2016-10-28 05:56:06 +00:00
parent a1d45d94b0
commit dd0781ea25
9 changed files with 50 additions and 41 deletions

View File

@ -65,6 +65,8 @@ pub struct CrateSource {
#[derive(RustcEncodable, RustcDecodable, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug)]
pub enum DepKind {
/// A dependency that is only used for its macros.
MacrosOnly,
/// A dependency that is always injected into the dependency list and so
/// doesn't need to be linked to an rlib, e.g. the injected allocator.
Implicit,

View File

@ -124,6 +124,7 @@ fn calculate_type(sess: &session::Session,
return v;
}
for cnum in sess.cstore.crates() {
if sess.cstore.dep_kind(cnum) == DepKind::MacrosOnly { continue }
let src = sess.cstore.used_crate_source(cnum);
if src.rlib.is_some() { continue }
sess.err(&format!("dependency `{}` not found in rlib format",
@ -156,6 +157,7 @@ fn calculate_type(sess: &session::Session,
// dependencies, ensuring there are no conflicts. The only valid case for a
// dependency to be relied upon twice is for both cases to rely on a dylib.
for cnum in sess.cstore.crates() {
if sess.cstore.dep_kind(cnum) == DepKind::MacrosOnly { continue }
let name = sess.cstore.crate_name(cnum);
let src = sess.cstore.used_crate_source(cnum);
if src.dylib.is_some() {

View File

@ -29,6 +29,7 @@
#![feature(staged_api)]
#![feature(linked_from)]
#![feature(concat_idents)]
#![cfg_attr(not(stage0), feature(rustc_private))]
extern crate libc;
#[macro_use]

View File

@ -67,16 +67,12 @@ fn dump_crates(cstore: &CStore) {
})
}
fn should_link(i: &ast::Item) -> bool {
!attr::contains_name(&i.attrs, "no_link")
}
#[derive(Debug)]
struct ExternCrateInfo {
ident: String,
name: String,
id: ast::NodeId,
should_link: bool,
dep_kind: DepKind,
}
fn register_native_lib(sess: &Session,
@ -168,7 +164,11 @@ impl<'a> CrateLoader<'a> {
ident: i.ident.to_string(),
name: name,
id: i.id,
should_link: should_link(i),
dep_kind: if attr::contains_name(&i.attrs, "no_link") {
DepKind::MacrosOnly
} else {
DepKind::Explicit
},
})
}
_ => None
@ -283,7 +283,7 @@ impl<'a> CrateLoader<'a> {
let Library { dylib, rlib, metadata } = lib;
let cnum_map = self.resolve_crate_deps(root, &crate_root, &metadata, cnum, span);
let cnum_map = self.resolve_crate_deps(root, &crate_root, &metadata, cnum, span, dep_kind);
if crate_root.macro_derive_registrar.is_some() {
self.sess.span_err(span, "crates of the `proc-macro` crate type \
@ -427,7 +427,8 @@ impl<'a> CrateLoader<'a> {
crate_root: &CrateRoot,
metadata: &MetadataBlob,
krate: CrateNum,
span: Span)
span: Span,
dep_kind: DepKind)
-> cstore::CrateNumMap {
debug!("resolving deps of external crate");
// The map from crate numbers in the crate we're resolving to local crate
@ -435,13 +436,14 @@ impl<'a> CrateLoader<'a> {
let deps = crate_root.crate_deps.decode(metadata);
let map: FxHashMap<_, _> = deps.enumerate().map(|(crate_num, dep)| {
debug!("resolving dep crate {} hash: `{}`", dep.name, dep.hash);
let (local_cnum, ..) = self.resolve_crate(root,
&dep.name.as_str(),
&dep.name.as_str(),
Some(&dep.hash),
span,
PathKind::Dependency,
dep.kind);
let dep_name = &dep.name.as_str();
let dep_kind = match dep_kind {
DepKind::MacrosOnly => DepKind::MacrosOnly,
_ => dep.kind,
};
let (local_cnum, ..) = self.resolve_crate(
root, dep_name, dep_name, Some(&dep.hash), span, PathKind::Dependency, dep_kind,
);
(CrateNum::new(crate_num + 1), local_cnum)
}).collect();
@ -455,8 +457,8 @@ impl<'a> CrateLoader<'a> {
}
fn read_extension_crate(&mut self, span: Span, info: &ExternCrateInfo) -> ExtensionCrate {
info!("read extension crate {} `extern crate {} as {}` linked={}",
info.id, info.name, info.ident, info.should_link);
info!("read extension crate {} `extern crate {} as {}` dep_kind={:?}",
info.id, info.name, info.ident, info.dep_kind);
let target_triple = &self.sess.opts.target_triple[..];
let is_cross = target_triple != config::host_triple();
let mut target_only = false;
@ -641,7 +643,7 @@ impl<'a> CrateLoader<'a> {
name: name.to_string(),
ident: name.to_string(),
id: ast::DUMMY_NODE_ID,
should_link: false,
dep_kind: DepKind::MacrosOnly,
});
if ekrate.target_only {
@ -984,30 +986,26 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> {
let ekrate = self.read_extension_crate(item.span, &info);
let loaded_macros = self.read_macros(item, &ekrate);
// If this is a proc-macro crate or `#[no_link]` crate, it is only used at compile time,
// so we return here to avoid registering the crate.
if loaded_macros.is_proc_macros() || !info.should_link {
// If this is a proc-macro crate, return here to avoid registering.
if loaded_macros.is_proc_macros() {
return Some(loaded_macros);
}
// Register crate now to avoid double-reading metadata
if let PMDSource::Owned(lib) = ekrate.metadata {
if ekrate.target_only || config::host_triple() == self.sess.opts.target_triple {
let ExternCrateInfo { ref ident, ref name, .. } = info;
self.register_crate(&None, ident, name, item.span, lib, DepKind::Explicit);
let ExternCrateInfo { ref ident, ref name, dep_kind, .. } = info;
self.register_crate(&None, ident, name, item.span, lib, dep_kind);
}
}
Some(loaded_macros)
} else {
if !info.should_link {
return None;
}
None
};
let (cnum, ..) = self.resolve_crate(
&None, &info.ident, &info.name, None, item.span, PathKind::Crate, DepKind::Explicit,
&None, &info.ident, &info.name, None, item.span, PathKind::Crate, info.dep_kind,
);
let def_id = definitions.opt_local_def_id(item.id).unwrap();

View File

@ -192,12 +192,13 @@ impl CStore {
let mut libs = self.metas
.borrow()
.iter()
.map(|(&cnum, data)| {
(cnum,
match prefer {
LinkagePreference::RequireDynamic => data.source.dylib.clone().map(|p| p.0),
LinkagePreference::RequireStatic => data.source.rlib.clone().map(|p| p.0),
})
.filter_map(|(&cnum, data)| {
if data.dep_kind.get() == DepKind::MacrosOnly { return None; }
let path = match prefer {
LinkagePreference::RequireDynamic => data.source.dylib.clone().map(|p| p.0),
LinkagePreference::RequireStatic => data.source.rlib.clone().map(|p| p.0),
};
Some((cnum, path))
})
.collect::<Vec<_>>();
libs.sort_by(|&(a, _), &(b, _)| {

View File

@ -21,7 +21,7 @@ use rustc::util::nodemap::FxHashMap;
use rustc::hir;
use rustc::hir::intravisit::IdRange;
use rustc::middle::cstore::{InlinedItem, LinkagePreference};
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::middle::lang_items;
@ -690,6 +690,10 @@ impl<'a, 'tcx> CrateMetadata {
pub fn each_child_of_item<F>(&self, id: DefIndex, mut callback: F)
where F: FnMut(def::Export)
{
if self.dep_kind.get() == DepKind::MacrosOnly {
return
}
// Find the item.
let item = match self.maybe_entry(id) {
None => return,

View File

@ -22,7 +22,7 @@ use {NameBinding, NameBindingKind, ToNameBinding};
use Resolver;
use {resolve_error, resolve_struct_error, ResolutionError};
use rustc::middle::cstore::LoadedMacros;
use rustc::middle::cstore::{DepKind, LoadedMacros};
use rustc::hir::def::*;
use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId};
use rustc::ty;
@ -499,8 +499,9 @@ impl<'b> Resolver<'b> {
fn get_extern_crate_root(&mut self, cnum: CrateNum) -> Module<'b> {
let def_id = DefId { krate: cnum, index: CRATE_DEF_INDEX };
let macros_only = self.session.cstore.dep_kind(cnum) == DepKind::MacrosOnly;
let arenas = self.arenas;
*self.extern_crate_roots.entry(cnum).or_insert_with(|| {
*self.extern_crate_roots.entry((cnum, macros_only)).or_insert_with(|| {
arenas.alloc_module(ModuleS {
populated: Cell::new(false),
..ModuleS::new(None, ModuleKind::Def(Def::Mod(def_id), keywords::Invalid.name()))

View File

@ -1083,7 +1083,7 @@ pub struct Resolver<'a> {
// There will be an anonymous module created around `g` with the ID of the
// entry block for `f`.
module_map: NodeMap<Module<'a>>,
extern_crate_roots: FxHashMap<CrateNum, Module<'a>>,
extern_crate_roots: FxHashMap<(CrateNum, bool /* MacrosOnly? */), Module<'a>>,
// Whether or not to print error messages. Can be set to true
// when getting additional info for error message suggestions,

View File

@ -8,11 +8,11 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// aux-build:empty-struct.rs
#[no_link]
extern crate libc;
extern crate empty_struct;
fn main() {
unsafe {
libc::abs(0); //~ ERROR unresolved name
}
empty_struct::XEmpty1; //~ ERROR unresolved name
}