Register and stability check #[no_link]
crates.
This commit is contained in:
parent
a1d45d94b0
commit
dd0781ea25
@ -65,6 +65,8 @@ pub struct CrateSource {
|
|||||||
|
|
||||||
#[derive(RustcEncodable, RustcDecodable, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug)]
|
#[derive(RustcEncodable, RustcDecodable, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug)]
|
||||||
pub enum DepKind {
|
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
|
/// 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.
|
/// doesn't need to be linked to an rlib, e.g. the injected allocator.
|
||||||
Implicit,
|
Implicit,
|
||||||
|
@ -124,6 +124,7 @@ fn calculate_type(sess: &session::Session,
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
for cnum in sess.cstore.crates() {
|
for cnum in sess.cstore.crates() {
|
||||||
|
if sess.cstore.dep_kind(cnum) == DepKind::MacrosOnly { continue }
|
||||||
let src = sess.cstore.used_crate_source(cnum);
|
let src = sess.cstore.used_crate_source(cnum);
|
||||||
if src.rlib.is_some() { continue }
|
if src.rlib.is_some() { continue }
|
||||||
sess.err(&format!("dependency `{}` not found in rlib format",
|
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
|
// 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.
|
// dependency to be relied upon twice is for both cases to rely on a dylib.
|
||||||
for cnum in sess.cstore.crates() {
|
for cnum in sess.cstore.crates() {
|
||||||
|
if sess.cstore.dep_kind(cnum) == DepKind::MacrosOnly { continue }
|
||||||
let name = sess.cstore.crate_name(cnum);
|
let name = sess.cstore.crate_name(cnum);
|
||||||
let src = sess.cstore.used_crate_source(cnum);
|
let src = sess.cstore.used_crate_source(cnum);
|
||||||
if src.dylib.is_some() {
|
if src.dylib.is_some() {
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#![feature(staged_api)]
|
#![feature(staged_api)]
|
||||||
#![feature(linked_from)]
|
#![feature(linked_from)]
|
||||||
#![feature(concat_idents)]
|
#![feature(concat_idents)]
|
||||||
|
#![cfg_attr(not(stage0), feature(rustc_private))]
|
||||||
|
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
@ -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)]
|
#[derive(Debug)]
|
||||||
struct ExternCrateInfo {
|
struct ExternCrateInfo {
|
||||||
ident: String,
|
ident: String,
|
||||||
name: String,
|
name: String,
|
||||||
id: ast::NodeId,
|
id: ast::NodeId,
|
||||||
should_link: bool,
|
dep_kind: DepKind,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn register_native_lib(sess: &Session,
|
fn register_native_lib(sess: &Session,
|
||||||
@ -168,7 +164,11 @@ impl<'a> CrateLoader<'a> {
|
|||||||
ident: i.ident.to_string(),
|
ident: i.ident.to_string(),
|
||||||
name: name,
|
name: name,
|
||||||
id: i.id,
|
id: i.id,
|
||||||
should_link: should_link(i),
|
dep_kind: if attr::contains_name(&i.attrs, "no_link") {
|
||||||
|
DepKind::MacrosOnly
|
||||||
|
} else {
|
||||||
|
DepKind::Explicit
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
_ => None
|
_ => None
|
||||||
@ -283,7 +283,7 @@ impl<'a> CrateLoader<'a> {
|
|||||||
|
|
||||||
let Library { dylib, rlib, metadata } = lib;
|
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() {
|
if crate_root.macro_derive_registrar.is_some() {
|
||||||
self.sess.span_err(span, "crates of the `proc-macro` crate type \
|
self.sess.span_err(span, "crates of the `proc-macro` crate type \
|
||||||
@ -427,7 +427,8 @@ impl<'a> CrateLoader<'a> {
|
|||||||
crate_root: &CrateRoot,
|
crate_root: &CrateRoot,
|
||||||
metadata: &MetadataBlob,
|
metadata: &MetadataBlob,
|
||||||
krate: CrateNum,
|
krate: CrateNum,
|
||||||
span: Span)
|
span: Span,
|
||||||
|
dep_kind: DepKind)
|
||||||
-> cstore::CrateNumMap {
|
-> cstore::CrateNumMap {
|
||||||
debug!("resolving deps of external crate");
|
debug!("resolving deps of external crate");
|
||||||
// The map from crate numbers in the crate we're resolving to local 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 deps = crate_root.crate_deps.decode(metadata);
|
||||||
let map: FxHashMap<_, _> = deps.enumerate().map(|(crate_num, dep)| {
|
let map: FxHashMap<_, _> = deps.enumerate().map(|(crate_num, dep)| {
|
||||||
debug!("resolving dep crate {} hash: `{}`", dep.name, dep.hash);
|
debug!("resolving dep crate {} hash: `{}`", dep.name, dep.hash);
|
||||||
let (local_cnum, ..) = self.resolve_crate(root,
|
let dep_name = &dep.name.as_str();
|
||||||
&dep.name.as_str(),
|
let dep_kind = match dep_kind {
|
||||||
&dep.name.as_str(),
|
DepKind::MacrosOnly => DepKind::MacrosOnly,
|
||||||
Some(&dep.hash),
|
_ => dep.kind,
|
||||||
span,
|
};
|
||||||
PathKind::Dependency,
|
let (local_cnum, ..) = self.resolve_crate(
|
||||||
dep.kind);
|
root, dep_name, dep_name, Some(&dep.hash), span, PathKind::Dependency, dep_kind,
|
||||||
|
);
|
||||||
(CrateNum::new(crate_num + 1), local_cnum)
|
(CrateNum::new(crate_num + 1), local_cnum)
|
||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
@ -455,8 +457,8 @@ impl<'a> CrateLoader<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn read_extension_crate(&mut self, span: Span, info: &ExternCrateInfo) -> ExtensionCrate {
|
fn read_extension_crate(&mut self, span: Span, info: &ExternCrateInfo) -> ExtensionCrate {
|
||||||
info!("read extension crate {} `extern crate {} as {}` linked={}",
|
info!("read extension crate {} `extern crate {} as {}` dep_kind={:?}",
|
||||||
info.id, info.name, info.ident, info.should_link);
|
info.id, info.name, info.ident, info.dep_kind);
|
||||||
let target_triple = &self.sess.opts.target_triple[..];
|
let target_triple = &self.sess.opts.target_triple[..];
|
||||||
let is_cross = target_triple != config::host_triple();
|
let is_cross = target_triple != config::host_triple();
|
||||||
let mut target_only = false;
|
let mut target_only = false;
|
||||||
@ -641,7 +643,7 @@ impl<'a> CrateLoader<'a> {
|
|||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
ident: name.to_string(),
|
ident: name.to_string(),
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
should_link: false,
|
dep_kind: DepKind::MacrosOnly,
|
||||||
});
|
});
|
||||||
|
|
||||||
if ekrate.target_only {
|
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 ekrate = self.read_extension_crate(item.span, &info);
|
||||||
let loaded_macros = self.read_macros(item, &ekrate);
|
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,
|
// If this is a proc-macro crate, return here to avoid registering.
|
||||||
// so we return here to avoid registering the crate.
|
if loaded_macros.is_proc_macros() {
|
||||||
if loaded_macros.is_proc_macros() || !info.should_link {
|
|
||||||
return Some(loaded_macros);
|
return Some(loaded_macros);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register crate now to avoid double-reading metadata
|
// Register crate now to avoid double-reading metadata
|
||||||
if let PMDSource::Owned(lib) = ekrate.metadata {
|
if let PMDSource::Owned(lib) = ekrate.metadata {
|
||||||
if ekrate.target_only || config::host_triple() == self.sess.opts.target_triple {
|
if ekrate.target_only || config::host_triple() == self.sess.opts.target_triple {
|
||||||
let ExternCrateInfo { ref ident, ref name, .. } = info;
|
let ExternCrateInfo { ref ident, ref name, dep_kind, .. } = info;
|
||||||
self.register_crate(&None, ident, name, item.span, lib, DepKind::Explicit);
|
self.register_crate(&None, ident, name, item.span, lib, dep_kind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(loaded_macros)
|
Some(loaded_macros)
|
||||||
} else {
|
} else {
|
||||||
if !info.should_link {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let (cnum, ..) = self.resolve_crate(
|
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();
|
let def_id = definitions.opt_local_def_id(item.id).unwrap();
|
||||||
|
@ -192,12 +192,13 @@ impl CStore {
|
|||||||
let mut libs = self.metas
|
let mut libs = self.metas
|
||||||
.borrow()
|
.borrow()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(&cnum, data)| {
|
.filter_map(|(&cnum, data)| {
|
||||||
(cnum,
|
if data.dep_kind.get() == DepKind::MacrosOnly { return None; }
|
||||||
match prefer {
|
let path = match prefer {
|
||||||
LinkagePreference::RequireDynamic => data.source.dylib.clone().map(|p| p.0),
|
LinkagePreference::RequireDynamic => data.source.dylib.clone().map(|p| p.0),
|
||||||
LinkagePreference::RequireStatic => data.source.rlib.clone().map(|p| p.0),
|
LinkagePreference::RequireStatic => data.source.rlib.clone().map(|p| p.0),
|
||||||
})
|
};
|
||||||
|
Some((cnum, path))
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
libs.sort_by(|&(a, _), &(b, _)| {
|
libs.sort_by(|&(a, _), &(b, _)| {
|
||||||
|
@ -21,7 +21,7 @@ use rustc::util::nodemap::FxHashMap;
|
|||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
use rustc::hir::intravisit::IdRange;
|
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::{self, Def, CtorKind};
|
||||||
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE};
|
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE};
|
||||||
use rustc::middle::lang_items;
|
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)
|
pub fn each_child_of_item<F>(&self, id: DefIndex, mut callback: F)
|
||||||
where F: FnMut(def::Export)
|
where F: FnMut(def::Export)
|
||||||
{
|
{
|
||||||
|
if self.dep_kind.get() == DepKind::MacrosOnly {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Find the item.
|
// Find the item.
|
||||||
let item = match self.maybe_entry(id) {
|
let item = match self.maybe_entry(id) {
|
||||||
None => return,
|
None => return,
|
||||||
|
@ -22,7 +22,7 @@ use {NameBinding, NameBindingKind, ToNameBinding};
|
|||||||
use Resolver;
|
use Resolver;
|
||||||
use {resolve_error, resolve_struct_error, ResolutionError};
|
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::*;
|
||||||
use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId};
|
use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId};
|
||||||
use rustc::ty;
|
use rustc::ty;
|
||||||
@ -499,8 +499,9 @@ impl<'b> Resolver<'b> {
|
|||||||
|
|
||||||
fn get_extern_crate_root(&mut self, cnum: CrateNum) -> Module<'b> {
|
fn get_extern_crate_root(&mut self, cnum: CrateNum) -> Module<'b> {
|
||||||
let def_id = DefId { krate: cnum, index: CRATE_DEF_INDEX };
|
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;
|
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 {
|
arenas.alloc_module(ModuleS {
|
||||||
populated: Cell::new(false),
|
populated: Cell::new(false),
|
||||||
..ModuleS::new(None, ModuleKind::Def(Def::Mod(def_id), keywords::Invalid.name()))
|
..ModuleS::new(None, ModuleKind::Def(Def::Mod(def_id), keywords::Invalid.name()))
|
||||||
|
@ -1083,7 +1083,7 @@ pub struct Resolver<'a> {
|
|||||||
// There will be an anonymous module created around `g` with the ID of the
|
// There will be an anonymous module created around `g` with the ID of the
|
||||||
// entry block for `f`.
|
// entry block for `f`.
|
||||||
module_map: NodeMap<Module<'a>>,
|
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
|
// Whether or not to print error messages. Can be set to true
|
||||||
// when getting additional info for error message suggestions,
|
// when getting additional info for error message suggestions,
|
||||||
|
@ -8,11 +8,11 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
|
// aux-build:empty-struct.rs
|
||||||
|
|
||||||
#[no_link]
|
#[no_link]
|
||||||
extern crate libc;
|
extern crate empty_struct;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
unsafe {
|
empty_struct::XEmpty1; //~ ERROR unresolved name
|
||||||
libc::abs(0); //~ ERROR unresolved name
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user