Skip to content

Commit 3344ca7

Browse files
committed
Combine 'Extern' and 'ExternPrivate'
1 parent e65c0ed commit 3344ca7

File tree

4 files changed

+61
-36
lines changed

4 files changed

+61
-36
lines changed

src/librustc/session/config.rs

Lines changed: 50 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -268,33 +268,24 @@ impl OutputTypes {
268268
// DO NOT switch BTreeMap or BTreeSet out for an unsorted container type! That
269269
// would break dependency tracking for command-line arguments.
270270
#[derive(Clone, Hash)]
271-
pub struct Externs(BTreeMap<String, BTreeSet<Option<String>>>);
271+
pub struct Externs(BTreeMap<String, BTreeSet<ExternEntry>>);
272272

273+
#[derive(Clone, Hash, Eq, PartialEq, Ord, PartialOrd, Debug)]
274+
pub struct ExternEntry {
275+
pub location: Option<String>,
276+
pub public: bool
277+
}
273278

274279
impl Externs {
275-
pub fn new(data: BTreeMap<String, BTreeSet<Option<String>>>) -> Externs {
280+
pub fn new(data: BTreeMap<String, BTreeSet<ExternEntry>>) -> Externs {
276281
Externs(data)
277282
}
278283

279-
pub fn get(&self, key: &str) -> Option<&BTreeSet<Option<String>>> {
280-
self.0.get(key)
281-
}
282-
283-
pub fn iter<'a>(&'a self) -> BTreeMapIter<'a, String, BTreeSet<Option<String>>> {
284-
self.0.iter()
285-
}
286-
}
287-
288-
// Similar to 'Externs', but used for the '--extern-private' option
289-
#[derive(Clone, Hash)]
290-
pub struct ExternPrivates(BTreeMap<String, BTreeSet<String>>);
291-
292-
impl ExternPrivates {
293-
pub fn get(&self, key: &str) -> Option<&BTreeSet<String>> {
284+
pub fn get(&self, key: &str) -> Option<&BTreeSet<ExternEntry>> {
294285
self.0.get(key)
295286
}
296287

297-
pub fn iter<'a>(&'a self) -> BTreeMapIter<'a, String, BTreeSet<String>> {
288+
pub fn iter<'a>(&'a self) -> BTreeMapIter<'a, String, BTreeSet<ExternEntry>> {
298289
self.0.iter()
299290
}
300291
}
@@ -431,7 +422,7 @@ top_level_options!(
431422

432423
// The crates to consider private when
433424
// checking leaked private dependency types in public interfaces
434-
extern_private: ExternPrivates [UNTRACKED],
425+
//extern_private: ExternPrivates [UNTRACKED],
435426
}
436427
);
437428

@@ -634,7 +625,7 @@ impl Default for Options {
634625
cli_forced_thinlto_off: false,
635626
remap_path_prefix: Vec::new(),
636627
edition: DEFAULT_EDITION,
637-
extern_private: ExternPrivates(BTreeMap::new())
628+
//extern_private: ExternPrivates(BTreeMap::new())
638629
}
639630
}
640631
}
@@ -2304,7 +2295,7 @@ pub fn build_session_options_and_crate_config(
23042295
)
23052296
}
23062297

2307-
let mut extern_private: BTreeMap<_, BTreeSet<_>> = BTreeMap::new();
2298+
/*let mut extern_private: BTreeMap<_, BTreeSet<_>> = BTreeMap::new();
23082299
23092300
for arg in matches.opt_strs("extern-private").into_iter() {
23102301
let mut parts = arg.splitn(2, '=');
@@ -2319,10 +2310,16 @@ pub fn build_session_options_and_crate_config(
23192310
.or_default()
23202311
.insert(location);
23212312
2322-
}
2313+
}*/
2314+
2315+
// We start out with a Vec<(Option<String>, bool)>>,
2316+
// and later convert it into a BTreeSet<(Option<String>, bool)>
2317+
// This allows to modify entries in-place to set their correct
2318+
// 'public' value
2319+
let mut externs: BTreeMap<_, BTreeMap<Option<String>, bool>> = BTreeMap::new();
2320+
for (arg, public) in matches.opt_strs("extern").into_iter().map(|v| (v, true))
2321+
.chain(matches.opt_strs("extern-private").into_iter().map(|v| (v, false))) {
23232322

2324-
let mut externs: BTreeMap<_, BTreeSet<_>> = BTreeMap::new();
2325-
for arg in matches.opt_strs("extern").into_iter() {
23262323
let mut parts = arg.splitn(2, '=');
23272324
let name = parts.next().unwrap_or_else(||
23282325
early_error(error_format, "--extern value must not be empty"));
@@ -2335,11 +2332,37 @@ pub fn build_session_options_and_crate_config(
23352332
);
23362333
};
23372334

2335+
2336+
// Externsl crates start out public,
2337+
// and become private if we later see
2338+
// an '--extern-private' key. They never
2339+
// go back to being public once we've seen
2340+
// '--extern-private', so we logical-AND
2341+
// their current and new 'public' value together
2342+
23382343
externs
23392344
.entry(name.to_owned())
23402345
.or_default()
2341-
.insert(location);
2342-
}
2346+
.entry(location)
2347+
.and_modify(|e| *e &= public)
2348+
.or_insert(public);
2349+
}
2350+
2351+
// Now that we've determined the 'public' status of each extern,
2352+
// collect them into a set of ExternEntry
2353+
let externs: BTreeMap<String, BTreeSet<ExternEntry>> = externs.into_iter()
2354+
.map(|(k, v)| {
2355+
let values =v.into_iter().map(|(location, public)| {
2356+
ExternEntry {
2357+
location,
2358+
public
2359+
}
2360+
}).collect::<BTreeSet<ExternEntry>>();
2361+
(k, values)
2362+
})
2363+
.collect();
2364+
2365+
23432366

23442367
let crate_name = matches.opt_str("crate-name");
23452368

@@ -2390,7 +2413,7 @@ pub fn build_session_options_and_crate_config(
23902413
cli_forced_thinlto_off: disable_thinlto,
23912414
remap_path_prefix,
23922415
edition,
2393-
extern_private: ExternPrivates(extern_private)
2416+
//extern_private: ExternPrivates(extern_private)
23942417
},
23952418
cfg,
23962419
)

src/librustc_metadata/creader.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ impl<'a> CrateLoader<'a> {
133133
let source = &self.cstore.get_crate_data(cnum).source;
134134
if let Some(locs) = self.sess.opts.externs.get(&*name.as_str()) {
135135
// Only use `--extern crate_name=path` here, not `--extern crate_name`.
136-
let found = locs.iter().filter_map(|l| l.as_ref()).any(|l| {
136+
let found = locs.iter().filter_map(|l| l.location.as_ref()).any(|l| {
137137
let l = fs::canonicalize(l).ok();
138138
source.dylib.as_ref().map(|p| &p.0) == l.as_ref() ||
139139
source.rlib.as_ref().map(|p| &p.0) == l.as_ref()
@@ -202,13 +202,14 @@ impl<'a> CrateLoader<'a> {
202202
self.verify_no_symbol_conflicts(span, &crate_root);
203203

204204
let mut private_dep = false;
205-
if let Some(s) = self.sess.opts.extern_private.get(&name.as_str()) {
206-
for path in s {
207-
let p = Some(path.as_str());
205+
if let Some(s) = self.sess.opts.externs.get(&name.as_str()) {
206+
for entry in s {
207+
let p = entry.location.as_ref().map(|s| s.as_str());
208208
if p == lib.dylib.as_ref().and_then(|r| r.0.to_str()) ||
209209
p == lib.rlib.as_ref().and_then(|r| r.0.to_str()) {
210210

211-
private_dep = true;
211+
private_dep = !entry.public;
212+
break;
212213
}
213214
}
214215
}

src/librustc_metadata/locator.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -444,9 +444,9 @@ impl<'a> Context<'a> {
444444
self.should_match_name = false;
445445
if let Some(s) = self.sess.opts.externs.get(&self.crate_name.as_str()) {
446446
// Only use `--extern crate_name=path` here, not `--extern crate_name`.
447-
if s.iter().any(|l| l.is_some()) {
447+
if s.iter().any(|l| l.location.is_some()) {
448448
return self.find_commandline_library(
449-
s.iter().filter_map(|l| l.as_ref()),
449+
s.iter().filter_map(|l| l.location.as_ref()),
450450
);
451451
}
452452
}

src/librustdoc/config.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use errors::emitter::ColorConfig;
77
use getopts;
88
use rustc::lint::Level;
99
use rustc::session::early_error;
10-
use rustc::session::config::{CodegenOptions, DebuggingOptions, ErrorOutputType, Externs};
10+
use rustc::session::config::{CodegenOptions, DebuggingOptions, ErrorOutputType, Externs, ExternEntry};
1111
use rustc::session::config::{nightly_options, build_codegen_options, build_debugging_options,
1212
get_cmd_lint_options};
1313
use rustc::session::search_paths::SearchPath;
@@ -588,7 +588,8 @@ fn parse_externs(matches: &getopts::Matches) -> Result<Externs, String> {
588588
enable `--extern crate_name` without `=path`".to_string());
589589
}
590590
let name = name.to_string();
591-
externs.entry(name).or_default().insert(location);
591+
// For Rustdoc purposes, we can treat all externs as public
592+
externs.entry(name).or_default().insert(ExternEntry { location, public: true });
592593
}
593594
Ok(Externs::new(externs))
594595
}

0 commit comments

Comments
 (0)