Skip to content

Commit 64a7034

Browse files
committed
rustc: Remove a number of mutable fields in cstore
This commit started by moving methods from `CrateStore` to queries, but it ended up necessitating some deeper refactorings to move more items in general to queries. Before this commit the *resolver* would walk over the AST and process foreign modules (`extern { .. }` blocks) and collect `#[link]` annotations. It would then also process the command line `-l` directives and such. This information was then stored as precalculated lists in the `CrateStore` object for iterating over later. After this, commit, however, this pass no longer happens during resolution but now instead happens through queries. A query for the linked libraries of a crate will crawl the crate for `extern` blocks and then process the linkage annotations at that time.
1 parent 87ea0a1 commit 64a7034

File tree

19 files changed

+366
-309
lines changed

19 files changed

+366
-309
lines changed

src/librustc/dep_graph/dep_node.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,11 @@ define_dep_nodes!( <'tcx>
545545

546546
[] ImplementationsOfTrait { krate: CrateNum, trait_id: DefId },
547547
[] AllTraitImplementations(CrateNum),
548+
549+
[] IsDllimportForeignItem(DefId),
550+
[] IsStaticallyIncludedForeignItem(DefId),
551+
[] NativeLibraryKind(DefId),
552+
[] LinkArgs,
548553
);
549554

550555
trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {

src/librustc/middle/cstore.rs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -236,10 +236,6 @@ pub trait CrateStore {
236236
// trait/impl-item info
237237
fn associated_item_cloned(&self, def: DefId) -> ty::AssociatedItem;
238238

239-
// flags
240-
fn is_dllimport_foreign_item(&self, def: DefId) -> bool;
241-
fn is_statically_included_foreign_item(&self, def_id: DefId) -> bool;
242-
243239
// crate metadata
244240
fn dep_kind(&self, cnum: CrateNum) -> DepKind;
245241
fn export_macros(&self, cnum: CrateNum);
@@ -265,8 +261,6 @@ pub trait CrateStore {
265261
// This is basically a 1-based range of ints, which is a little
266262
// silly - I may fix that.
267263
fn crates(&self) -> Vec<CrateNum>;
268-
fn used_libraries(&self) -> Vec<NativeLibrary>;
269-
fn used_link_args(&self) -> Vec<String>;
270264

271265
// utility functions
272266
fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)>;
@@ -329,10 +323,6 @@ impl CrateStore for DummyCrateStore {
329323
fn associated_item_cloned(&self, def: DefId) -> ty::AssociatedItem
330324
{ bug!("associated_item_cloned") }
331325

332-
// flags
333-
fn is_dllimport_foreign_item(&self, id: DefId) -> bool { false }
334-
fn is_statically_included_foreign_item(&self, def_id: DefId) -> bool { false }
335-
336326
// crate metadata
337327
fn lang_items(&self, cnum: CrateNum) -> Vec<(DefIndex, usize)>
338328
{ bug!("lang_items") }
@@ -368,8 +358,6 @@ impl CrateStore for DummyCrateStore {
368358
// This is basically a 1-based range of ints, which is a little
369359
// silly - I may fix that.
370360
fn crates(&self) -> Vec<CrateNum> { vec![] }
371-
fn used_libraries(&self) -> Vec<NativeLibrary> { vec![] }
372-
fn used_link_args(&self) -> Vec<String> { vec![] }
373361

374362
// utility functions
375363
fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)>

src/librustc/ty/maps.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use hir::svh::Svh;
1717
use lint;
1818
use middle::const_val;
1919
use middle::cstore::{ExternCrate, LinkagePreference, NativeLibrary};
20+
use middle::cstore::NativeLibraryKind;
2021
use middle::privacy::AccessLevels;
2122
use middle::region;
2223
use mir;
@@ -642,6 +643,12 @@ impl<'tcx> QueryDescription for queries::all_trait_implementations<'tcx> {
642643
}
643644
}
644645

646+
impl<'tcx> QueryDescription for queries::link_args<'tcx> {
647+
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
648+
format!("looking up link arguments for a crate")
649+
}
650+
}
651+
645652
// If enabled, send a message to the profile-queries thread
646653
macro_rules! profq_msg {
647654
($tcx:expr, $msg:expr) => {
@@ -1230,6 +1237,12 @@ define_maps! { <'tcx>
12301237
-> Rc<Vec<DefId>>,
12311238
[] fn all_trait_implementations: AllTraitImplementations(CrateNum)
12321239
-> Rc<Vec<DefId>>,
1240+
1241+
[] is_dllimport_foreign_item: IsDllimportForeignItem(DefId) -> bool,
1242+
[] is_statically_included_foreign_item: IsStaticallyIncludedForeignItem(DefId) -> bool,
1243+
[] native_library_kind: NativeLibraryKind(DefId)
1244+
-> Option<NativeLibraryKind>,
1245+
[] link_args: link_args_node(CrateNum) -> Rc<Vec<String>>,
12331246
}
12341247

12351248
fn type_param_predicates<'tcx>((item_id, param_id): (DefId, DefId)) -> DepConstructor<'tcx> {
@@ -1315,3 +1328,7 @@ fn implementations_of_trait_node<'tcx>((krate, trait_id): (CrateNum, DefId))
13151328
{
13161329
DepConstructor::ImplementationsOfTrait { krate, trait_id }
13171330
}
1331+
1332+
fn link_args_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
1333+
DepConstructor::LinkArgs
1334+
}

src/librustc_driver/driver.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -694,7 +694,6 @@ pub fn phase_2_configure_and_expand<F>(sess: &Session,
694694
// this back at some point.
695695
let _ignore = sess.dep_graph.in_ignore();
696696
let mut crate_loader = CrateLoader::new(sess, &cstore, crate_name);
697-
crate_loader.preprocess(&krate);
698697
let resolver_arenas = Resolver::arenas();
699698
let mut resolver = Resolver::new(sess,
700699
&krate,

src/librustc_metadata/creader.rs

Lines changed: 1 addition & 220 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
1313
use cstore::{self, CStore, CrateSource, MetadataBlob};
1414
use locator::{self, CratePaths};
15+
use native_libs::relevant_lib;
1516
use schema::{CrateRoot, Tracked};
1617

1718
use rustc::hir::def_id::{CrateNum, DefIndex};
@@ -26,7 +27,6 @@ use rustc::middle;
2627
use rustc::middle::cstore::{CrateStore, validate_crate_name, ExternCrate};
2728
use rustc::util::common::record_time;
2829
use rustc::util::nodemap::FxHashSet;
29-
use rustc::middle::cstore::NativeLibrary;
3030
use rustc::hir::map::Definitions;
3131

3232
use std::cell::{RefCell, Cell};
@@ -36,10 +36,8 @@ use std::rc::Rc;
3636
use std::{cmp, fs};
3737

3838
use syntax::ast;
39-
use syntax::abi::Abi;
4039
use syntax::attr;
4140
use syntax::ext::base::SyntaxExtension;
42-
use syntax::feature_gate::{self, GateIssue};
4341
use syntax::symbol::Symbol;
4442
use syntax::visit;
4543
use syntax_pos::{Span, DUMMY_SP};
@@ -81,56 +79,6 @@ struct ExternCrateInfo {
8179
dep_kind: DepKind,
8280
}
8381

84-
fn register_native_lib(sess: &Session,
85-
cstore: &CStore,
86-
span: Option<Span>,
87-
lib: NativeLibrary) {
88-
if lib.name.as_str().is_empty() {
89-
match span {
90-
Some(span) => {
91-
struct_span_err!(sess, span, E0454,
92-
"#[link(name = \"\")] given with empty name")
93-
.span_label(span, "empty name given")
94-
.emit();
95-
}
96-
None => {
97-
sess.err("empty library name given via `-l`");
98-
}
99-
}
100-
return
101-
}
102-
let is_osx = sess.target.target.options.is_like_osx;
103-
if lib.kind == cstore::NativeFramework && !is_osx {
104-
let msg = "native frameworks are only available on macOS targets";
105-
match span {
106-
Some(span) => span_err!(sess, span, E0455, "{}", msg),
107-
None => sess.err(msg),
108-
}
109-
}
110-
if lib.cfg.is_some() && !sess.features.borrow().link_cfg {
111-
feature_gate::emit_feature_err(&sess.parse_sess,
112-
"link_cfg",
113-
span.unwrap(),
114-
GateIssue::Language,
115-
"is feature gated");
116-
}
117-
if lib.kind == cstore::NativeStaticNobundle && !sess.features.borrow().static_nobundle {
118-
feature_gate::emit_feature_err(&sess.parse_sess,
119-
"static_nobundle",
120-
span.unwrap(),
121-
GateIssue::Language,
122-
"kind=\"static-nobundle\" is feature gated");
123-
}
124-
cstore.add_used_library(lib);
125-
}
126-
127-
fn relevant_lib(sess: &Session, lib: &NativeLibrary) -> bool {
128-
match lib.cfg {
129-
Some(ref cfg) => attr::cfg_matches(cfg, &sess.parse_sess, None),
130-
None => true,
131-
}
132-
}
133-
13482
// Extra info about a crate loaded for plugins or exported macros.
13583
struct ExtensionCrate {
13684
metadata: PMDSource,
@@ -721,33 +669,6 @@ impl<'a> CrateLoader<'a> {
721669
}
722670
}
723671

724-
fn get_foreign_items_of_kind(&self, kind: cstore::NativeLibraryKind) -> Vec<DefIndex> {
725-
let mut items = vec![];
726-
let libs = self.cstore.get_used_libraries();
727-
for lib in libs.borrow().iter() {
728-
if relevant_lib(self.sess, lib) && lib.kind == kind {
729-
items.extend(&lib.foreign_items);
730-
}
731-
}
732-
items
733-
}
734-
735-
fn register_statically_included_foreign_items(&mut self) {
736-
for id in self.get_foreign_items_of_kind(cstore::NativeStatic) {
737-
self.cstore.add_statically_included_foreign_item(id);
738-
}
739-
for id in self.get_foreign_items_of_kind(cstore::NativeStaticNobundle) {
740-
self.cstore.add_statically_included_foreign_item(id);
741-
}
742-
}
743-
744-
fn register_dllimport_foreign_items(&mut self) {
745-
let mut dllimports = self.cstore.dllimport_foreign_items.borrow_mut();
746-
for id in self.get_foreign_items_of_kind(cstore::NativeUnknown) {
747-
dllimports.insert(id);
748-
}
749-
}
750-
751672
fn inject_panic_runtime(&mut self, krate: &ast::Crate) {
752673
// If we're only compiling an rlib, then there's no need to select a
753674
// panic runtime, so we just skip this section entirely.
@@ -1152,84 +1073,6 @@ impl<'a> CrateLoader<'a> {
11521073
}
11531074
}
11541075

1155-
impl<'a> CrateLoader<'a> {
1156-
pub fn preprocess(&mut self, krate: &ast::Crate) {
1157-
for attr in &krate.attrs {
1158-
if attr.path == "link_args" {
1159-
if let Some(linkarg) = attr.value_str() {
1160-
self.cstore.add_used_link_args(&linkarg.as_str());
1161-
}
1162-
}
1163-
}
1164-
}
1165-
1166-
fn process_foreign_mod(&mut self, i: &ast::Item, fm: &ast::ForeignMod,
1167-
definitions: &Definitions) {
1168-
if fm.abi == Abi::Rust || fm.abi == Abi::RustIntrinsic || fm.abi == Abi::PlatformIntrinsic {
1169-
return;
1170-
}
1171-
1172-
// First, add all of the custom #[link_args] attributes
1173-
for m in i.attrs.iter().filter(|a| a.check_name("link_args")) {
1174-
if let Some(linkarg) = m.value_str() {
1175-
self.cstore.add_used_link_args(&linkarg.as_str());
1176-
}
1177-
}
1178-
1179-
// Next, process all of the #[link(..)]-style arguments
1180-
for m in i.attrs.iter().filter(|a| a.check_name("link")) {
1181-
let items = match m.meta_item_list() {
1182-
Some(item) => item,
1183-
None => continue,
1184-
};
1185-
let kind = items.iter().find(|k| {
1186-
k.check_name("kind")
1187-
}).and_then(|a| a.value_str()).map(Symbol::as_str);
1188-
let kind = match kind.as_ref().map(|s| &s[..]) {
1189-
Some("static") => cstore::NativeStatic,
1190-
Some("static-nobundle") => cstore::NativeStaticNobundle,
1191-
Some("dylib") => cstore::NativeUnknown,
1192-
Some("framework") => cstore::NativeFramework,
1193-
Some(k) => {
1194-
struct_span_err!(self.sess, m.span, E0458,
1195-
"unknown kind: `{}`", k)
1196-
.span_label(m.span, "unknown kind").emit();
1197-
cstore::NativeUnknown
1198-
}
1199-
None => cstore::NativeUnknown
1200-
};
1201-
let n = items.iter().find(|n| {
1202-
n.check_name("name")
1203-
}).and_then(|a| a.value_str());
1204-
let n = match n {
1205-
Some(n) => n,
1206-
None => {
1207-
struct_span_err!(self.sess, m.span, E0459,
1208-
"#[link(...)] specified without `name = \"foo\"`")
1209-
.span_label(m.span, "missing `name` argument").emit();
1210-
Symbol::intern("foo")
1211-
}
1212-
};
1213-
let cfg = items.iter().find(|k| {
1214-
k.check_name("cfg")
1215-
}).and_then(|a| a.meta_item_list());
1216-
let cfg = cfg.map(|list| {
1217-
list[0].meta_item().unwrap().clone()
1218-
});
1219-
let foreign_items = fm.items.iter()
1220-
.map(|it| definitions.opt_def_index(it.id).unwrap())
1221-
.collect();
1222-
let lib = NativeLibrary {
1223-
name: n,
1224-
kind,
1225-
cfg,
1226-
foreign_items,
1227-
};
1228-
register_native_lib(self.sess, self.cstore, Some(m.span), lib);
1229-
}
1230-
}
1231-
}
1232-
12331076
impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> {
12341077
fn postprocess(&mut self, krate: &ast::Crate) {
12351078
// inject the sanitizer runtime before the allocator runtime because all
@@ -1242,72 +1085,10 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> {
12421085
if log_enabled!(log::LogLevel::Info) {
12431086
dump_crates(&self.cstore);
12441087
}
1245-
1246-
// Process libs passed on the command line
1247-
// First, check for errors
1248-
let mut renames = FxHashSet();
1249-
for &(ref name, ref new_name, _) in &self.sess.opts.libs {
1250-
if let &Some(ref new_name) = new_name {
1251-
if new_name.is_empty() {
1252-
self.sess.err(
1253-
&format!("an empty renaming target was specified for library `{}`",name));
1254-
} else if !self.cstore.get_used_libraries().borrow().iter()
1255-
.any(|lib| lib.name == name as &str) {
1256-
self.sess.err(&format!("renaming of the library `{}` was specified, \
1257-
however this crate contains no #[link(...)] \
1258-
attributes referencing this library.", name));
1259-
} else if renames.contains(name) {
1260-
self.sess.err(&format!("multiple renamings were specified for library `{}` .",
1261-
name));
1262-
} else {
1263-
renames.insert(name);
1264-
}
1265-
}
1266-
}
1267-
// Update kind and, optionally, the name of all native libaries
1268-
// (there may be more than one) with the specified name.
1269-
for &(ref name, ref new_name, kind) in &self.sess.opts.libs {
1270-
let mut found = false;
1271-
for lib in self.cstore.get_used_libraries().borrow_mut().iter_mut() {
1272-
if lib.name == name as &str {
1273-
let mut changed = false;
1274-
if let Some(k) = kind {
1275-
lib.kind = k;
1276-
changed = true;
1277-
}
1278-
if let &Some(ref new_name) = new_name {
1279-
lib.name = Symbol::intern(new_name);
1280-
changed = true;
1281-
}
1282-
if !changed {
1283-
self.sess.warn(&format!("redundant linker flag specified for library `{}`",
1284-
name));
1285-
}
1286-
1287-
found = true;
1288-
}
1289-
}
1290-
if !found {
1291-
// Add if not found
1292-
let new_name = new_name.as_ref().map(|s| &**s); // &Option<String> -> Option<&str>
1293-
let lib = NativeLibrary {
1294-
name: Symbol::intern(new_name.unwrap_or(name)),
1295-
kind: if let Some(k) = kind { k } else { cstore::NativeUnknown },
1296-
cfg: None,
1297-
foreign_items: Vec::new(),
1298-
};
1299-
register_native_lib(self.sess, self.cstore, None, lib);
1300-
}
1301-
}
1302-
self.register_statically_included_foreign_items();
1303-
self.register_dllimport_foreign_items();
13041088
}
13051089

13061090
fn process_item(&mut self, item: &ast::Item, definitions: &Definitions) {
13071091
match item.node {
1308-
ast::ItemKind::ForeignMod(ref fm) => {
1309-
self.process_foreign_mod(item, fm, definitions)
1310-
},
13111092
ast::ItemKind::ExternCrate(_) => {
13121093
let info = self.extract_crate_info(item).unwrap();
13131094
let (cnum, ..) = self.resolve_crate(

0 commit comments

Comments
 (0)