Combine 'Extern' and 'ExternPrivate'
This commit is contained in:
parent
21491dc701
commit
7cc3ce3bbd
4 changed files with 60 additions and 35 deletions
|
@ -283,33 +283,24 @@ impl OutputTypes {
|
|||
// DO NOT switch BTreeMap or BTreeSet out for an unsorted container type! That
|
||||
// would break dependency tracking for command-line arguments.
|
||||
#[derive(Clone, Hash)]
|
||||
pub struct Externs(BTreeMap<String, BTreeSet<Option<String>>>);
|
||||
pub struct Externs(BTreeMap<String, BTreeSet<ExternEntry>>);
|
||||
|
||||
#[derive(Clone, Hash, Eq, PartialEq, Ord, PartialOrd, Debug)]
|
||||
pub struct ExternEntry {
|
||||
pub location: Option<String>,
|
||||
pub public: bool
|
||||
}
|
||||
|
||||
impl Externs {
|
||||
pub fn new(data: BTreeMap<String, BTreeSet<Option<String>>>) -> Externs {
|
||||
pub fn new(data: BTreeMap<String, BTreeSet<ExternEntry>>) -> Externs {
|
||||
Externs(data)
|
||||
}
|
||||
|
||||
pub fn get(&self, key: &str) -> Option<&BTreeSet<Option<String>>> {
|
||||
pub fn get(&self, key: &str) -> Option<&BTreeSet<ExternEntry>> {
|
||||
self.0.get(key)
|
||||
}
|
||||
|
||||
pub fn iter<'a>(&'a self) -> BTreeMapIter<'a, String, BTreeSet<Option<String>>> {
|
||||
self.0.iter()
|
||||
}
|
||||
}
|
||||
|
||||
// Similar to 'Externs', but used for the '--extern-private' option
|
||||
#[derive(Clone, Hash)]
|
||||
pub struct ExternPrivates(BTreeMap<String, BTreeSet<String>>);
|
||||
|
||||
impl ExternPrivates {
|
||||
pub fn get(&self, key: &str) -> Option<&BTreeSet<String>> {
|
||||
self.0.get(key)
|
||||
}
|
||||
|
||||
pub fn iter<'a>(&'a self) -> BTreeMapIter<'a, String, BTreeSet<String>> {
|
||||
pub fn iter<'a>(&'a self) -> BTreeMapIter<'a, String, BTreeSet<ExternEntry>> {
|
||||
self.0.iter()
|
||||
}
|
||||
}
|
||||
|
@ -446,7 +437,7 @@ top_level_options!(
|
|||
|
||||
// The crates to consider private when
|
||||
// checking leaked private dependency types in public interfaces
|
||||
extern_private: ExternPrivates [UNTRACKED],
|
||||
//extern_private: ExternPrivates [UNTRACKED],
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -649,7 +640,7 @@ impl Default for Options {
|
|||
cli_forced_thinlto_off: false,
|
||||
remap_path_prefix: Vec::new(),
|
||||
edition: DEFAULT_EDITION,
|
||||
extern_private: ExternPrivates(BTreeMap::new())
|
||||
//extern_private: ExternPrivates(BTreeMap::new())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2331,7 +2322,7 @@ pub fn build_session_options_and_crate_config(
|
|||
)
|
||||
}
|
||||
|
||||
let mut extern_private: BTreeMap<_, BTreeSet<_>> = BTreeMap::new();
|
||||
/*let mut extern_private: BTreeMap<_, BTreeSet<_>> = BTreeMap::new();
|
||||
|
||||
for arg in matches.opt_strs("extern-private").into_iter() {
|
||||
let mut parts = arg.splitn(2, '=');
|
||||
|
@ -2346,10 +2337,16 @@ pub fn build_session_options_and_crate_config(
|
|||
.or_default()
|
||||
.insert(location);
|
||||
|
||||
}
|
||||
}*/
|
||||
|
||||
// We start out with a Vec<(Option<String>, bool)>>,
|
||||
// and later convert it into a BTreeSet<(Option<String>, bool)>
|
||||
// This allows to modify entries in-place to set their correct
|
||||
// 'public' value
|
||||
let mut externs: BTreeMap<_, BTreeMap<Option<String>, bool>> = BTreeMap::new();
|
||||
for (arg, public) in matches.opt_strs("extern").into_iter().map(|v| (v, true))
|
||||
.chain(matches.opt_strs("extern-private").into_iter().map(|v| (v, false))) {
|
||||
|
||||
let mut externs: BTreeMap<_, BTreeSet<_>> = BTreeMap::new();
|
||||
for arg in matches.opt_strs("extern").into_iter() {
|
||||
let mut parts = arg.splitn(2, '=');
|
||||
let name = parts.next().unwrap_or_else(||
|
||||
early_error(error_format, "--extern value must not be empty"));
|
||||
|
@ -2362,12 +2359,38 @@ pub fn build_session_options_and_crate_config(
|
|||
);
|
||||
};
|
||||
|
||||
|
||||
// Externsl crates start out public,
|
||||
// and become private if we later see
|
||||
// an '--extern-private' key. They never
|
||||
// go back to being public once we've seen
|
||||
// '--extern-private', so we logical-AND
|
||||
// their current and new 'public' value together
|
||||
|
||||
externs
|
||||
.entry(name.to_owned())
|
||||
.or_default()
|
||||
.insert(location);
|
||||
.entry(location)
|
||||
.and_modify(|e| *e &= public)
|
||||
.or_insert(public);
|
||||
}
|
||||
|
||||
// Now that we've determined the 'public' status of each extern,
|
||||
// collect them into a set of ExternEntry
|
||||
let externs: BTreeMap<String, BTreeSet<ExternEntry>> = externs.into_iter()
|
||||
.map(|(k, v)| {
|
||||
let values =v.into_iter().map(|(location, public)| {
|
||||
ExternEntry {
|
||||
location,
|
||||
public
|
||||
}
|
||||
}).collect::<BTreeSet<ExternEntry>>();
|
||||
(k, values)
|
||||
})
|
||||
.collect();
|
||||
|
||||
|
||||
|
||||
let crate_name = matches.opt_str("crate-name");
|
||||
|
||||
let remap_path_prefix = matches
|
||||
|
@ -2417,7 +2440,7 @@ pub fn build_session_options_and_crate_config(
|
|||
cli_forced_thinlto_off: disable_thinlto,
|
||||
remap_path_prefix,
|
||||
edition,
|
||||
extern_private: ExternPrivates(extern_private)
|
||||
//extern_private: ExternPrivates(extern_private)
|
||||
},
|
||||
cfg,
|
||||
)
|
||||
|
|
|
@ -133,7 +133,7 @@ impl<'a> CrateLoader<'a> {
|
|||
let source = &self.cstore.get_crate_data(cnum).source;
|
||||
if let Some(locs) = self.sess.opts.externs.get(&*name.as_str()) {
|
||||
// Only use `--extern crate_name=path` here, not `--extern crate_name`.
|
||||
let found = locs.iter().filter_map(|l| l.as_ref()).any(|l| {
|
||||
let found = locs.iter().filter_map(|l| l.location.as_ref()).any(|l| {
|
||||
let l = fs::canonicalize(l).ok();
|
||||
source.dylib.as_ref().map(|p| &p.0) == l.as_ref() ||
|
||||
source.rlib.as_ref().map(|p| &p.0) == l.as_ref()
|
||||
|
@ -202,13 +202,14 @@ impl<'a> CrateLoader<'a> {
|
|||
self.verify_no_symbol_conflicts(span, &crate_root);
|
||||
|
||||
let mut private_dep = false;
|
||||
if let Some(s) = self.sess.opts.extern_private.get(&name.as_str()) {
|
||||
for path in s {
|
||||
let p = Some(path.as_str());
|
||||
if let Some(s) = self.sess.opts.externs.get(&name.as_str()) {
|
||||
for entry in s {
|
||||
let p = entry.location.as_ref().map(|s| s.as_str());
|
||||
if p == lib.dylib.as_ref().and_then(|r| r.0.to_str()) ||
|
||||
p == lib.rlib.as_ref().and_then(|r| r.0.to_str()) {
|
||||
|
||||
private_dep = true;
|
||||
private_dep = !entry.public;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -444,9 +444,9 @@ impl<'a> Context<'a> {
|
|||
self.should_match_name = false;
|
||||
if let Some(s) = self.sess.opts.externs.get(&self.crate_name.as_str()) {
|
||||
// Only use `--extern crate_name=path` here, not `--extern crate_name`.
|
||||
if s.iter().any(|l| l.is_some()) {
|
||||
if s.iter().any(|l| l.location.is_some()) {
|
||||
return self.find_commandline_library(
|
||||
s.iter().filter_map(|l| l.as_ref()),
|
||||
s.iter().filter_map(|l| l.location.as_ref()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ use errors::emitter::ColorConfig;
|
|||
use getopts;
|
||||
use rustc::lint::Level;
|
||||
use rustc::session::early_error;
|
||||
use rustc::session::config::{CodegenOptions, DebuggingOptions, ErrorOutputType, Externs};
|
||||
use rustc::session::config::{CodegenOptions, DebuggingOptions, ErrorOutputType, Externs, ExternEntry};
|
||||
use rustc::session::config::{nightly_options, build_codegen_options, build_debugging_options,
|
||||
get_cmd_lint_options};
|
||||
use rustc::session::search_paths::SearchPath;
|
||||
|
@ -588,7 +588,8 @@ fn parse_externs(matches: &getopts::Matches) -> Result<Externs, String> {
|
|||
enable `--extern crate_name` without `=path`".to_string());
|
||||
}
|
||||
let name = name.to_string();
|
||||
externs.entry(name).or_default().insert(location);
|
||||
// For Rustdoc purposes, we can treat all externs as public
|
||||
externs.entry(name).or_default().insert(ExternEntry { location, public: true });
|
||||
}
|
||||
Ok(Externs::new(externs))
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue