Skip to content

Commit 7cc3ce3

Browse files
committed
Combine 'Extern' and 'ExternPrivate'
1 parent 21491dc commit 7cc3ce3

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
@@ -283,33 +283,24 @@ impl OutputTypes {
283283
// DO NOT switch BTreeMap or BTreeSet out for an unsorted container type! That
284284
// would break dependency tracking for command-line arguments.
285285
#[derive(Clone, Hash)]
286-
pub struct Externs(BTreeMap<String, BTreeSet<Option<String>>>);
286+
pub struct Externs(BTreeMap<String, BTreeSet<ExternEntry>>);
287287

288+
#[derive(Clone, Hash, Eq, PartialEq, Ord, PartialOrd, Debug)]
289+
pub struct ExternEntry {
290+
pub location: Option<String>,
291+
pub public: bool
292+
}
288293

289294
impl Externs {
290-
pub fn new(data: BTreeMap<String, BTreeSet<Option<String>>>) -> Externs {
295+
pub fn new(data: BTreeMap<String, BTreeSet<ExternEntry>>) -> Externs {
291296
Externs(data)
292297
}
293298

294-
pub fn get(&self, key: &str) -> Option<&BTreeSet<Option<String>>> {
295-
self.0.get(key)
296-
}
297-
298-
pub fn iter<'a>(&'a self) -> BTreeMapIter<'a, String, BTreeSet<Option<String>>> {
299-
self.0.iter()
300-
}
301-
}
302-
303-
// Similar to 'Externs', but used for the '--extern-private' option
304-
#[derive(Clone, Hash)]
305-
pub struct ExternPrivates(BTreeMap<String, BTreeSet<String>>);
306-
307-
impl ExternPrivates {
308-
pub fn get(&self, key: &str) -> Option<&BTreeSet<String>> {
299+
pub fn get(&self, key: &str) -> Option<&BTreeSet<ExternEntry>> {
309300
self.0.get(key)
310301
}
311302

312-
pub fn iter<'a>(&'a self) -> BTreeMapIter<'a, String, BTreeSet<String>> {
303+
pub fn iter<'a>(&'a self) -> BTreeMapIter<'a, String, BTreeSet<ExternEntry>> {
313304
self.0.iter()
314305
}
315306
}
@@ -446,7 +437,7 @@ top_level_options!(
446437

447438
// The crates to consider private when
448439
// checking leaked private dependency types in public interfaces
449-
extern_private: ExternPrivates [UNTRACKED],
440+
//extern_private: ExternPrivates [UNTRACKED],
450441
}
451442
);
452443

@@ -649,7 +640,7 @@ impl Default for Options {
649640
cli_forced_thinlto_off: false,
650641
remap_path_prefix: Vec::new(),
651642
edition: DEFAULT_EDITION,
652-
extern_private: ExternPrivates(BTreeMap::new())
643+
//extern_private: ExternPrivates(BTreeMap::new())
653644
}
654645
}
655646
}
@@ -2331,7 +2322,7 @@ pub fn build_session_options_and_crate_config(
23312322
)
23322323
}
23332324

2334-
let mut extern_private: BTreeMap<_, BTreeSet<_>> = BTreeMap::new();
2325+
/*let mut extern_private: BTreeMap<_, BTreeSet<_>> = BTreeMap::new();
23352326
23362327
for arg in matches.opt_strs("extern-private").into_iter() {
23372328
let mut parts = arg.splitn(2, '=');
@@ -2346,10 +2337,16 @@ pub fn build_session_options_and_crate_config(
23462337
.or_default()
23472338
.insert(location);
23482339
2349-
}
2340+
}*/
2341+
2342+
// We start out with a Vec<(Option<String>, bool)>>,
2343+
// and later convert it into a BTreeSet<(Option<String>, bool)>
2344+
// This allows to modify entries in-place to set their correct
2345+
// 'public' value
2346+
let mut externs: BTreeMap<_, BTreeMap<Option<String>, bool>> = BTreeMap::new();
2347+
for (arg, public) in matches.opt_strs("extern").into_iter().map(|v| (v, true))
2348+
.chain(matches.opt_strs("extern-private").into_iter().map(|v| (v, false))) {
23502349

2351-
let mut externs: BTreeMap<_, BTreeSet<_>> = BTreeMap::new();
2352-
for arg in matches.opt_strs("extern").into_iter() {
23532350
let mut parts = arg.splitn(2, '=');
23542351
let name = parts.next().unwrap_or_else(||
23552352
early_error(error_format, "--extern value must not be empty"));
@@ -2362,11 +2359,37 @@ pub fn build_session_options_and_crate_config(
23622359
);
23632360
};
23642361

2362+
2363+
// Externsl crates start out public,
2364+
// and become private if we later see
2365+
// an '--extern-private' key. They never
2366+
// go back to being public once we've seen
2367+
// '--extern-private', so we logical-AND
2368+
// their current and new 'public' value together
2369+
23652370
externs
23662371
.entry(name.to_owned())
23672372
.or_default()
2368-
.insert(location);
2369-
}
2373+
.entry(location)
2374+
.and_modify(|e| *e &= public)
2375+
.or_insert(public);
2376+
}
2377+
2378+
// Now that we've determined the 'public' status of each extern,
2379+
// collect them into a set of ExternEntry
2380+
let externs: BTreeMap<String, BTreeSet<ExternEntry>> = externs.into_iter()
2381+
.map(|(k, v)| {
2382+
let values =v.into_iter().map(|(location, public)| {
2383+
ExternEntry {
2384+
location,
2385+
public
2386+
}
2387+
}).collect::<BTreeSet<ExternEntry>>();
2388+
(k, values)
2389+
})
2390+
.collect();
2391+
2392+
23702393

23712394
let crate_name = matches.opt_str("crate-name");
23722395

@@ -2417,7 +2440,7 @@ pub fn build_session_options_and_crate_config(
24172440
cli_forced_thinlto_off: disable_thinlto,
24182441
remap_path_prefix,
24192442
edition,
2420-
extern_private: ExternPrivates(extern_private)
2443+
//extern_private: ExternPrivates(extern_private)
24212444
},
24222445
cfg,
24232446
)

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)