Skip to content

Commit 26b1ed1

Browse files
committed
rustc: add unstable support for --extern crate_name without a path.
1 parent afc2149 commit 26b1ed1

File tree

4 files changed

+37
-27
lines changed

4 files changed

+37
-27
lines changed

src/librustc/session/config.rs

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -275,18 +275,18 @@ impl OutputTypes {
275275
// DO NOT switch BTreeMap or BTreeSet out for an unsorted container type! That
276276
// would break dependency tracking for commandline arguments.
277277
#[derive(Clone, Hash)]
278-
pub struct Externs(BTreeMap<String, BTreeSet<String>>);
278+
pub struct Externs(BTreeMap<String, BTreeSet<Option<String>>>);
279279

280280
impl Externs {
281-
pub fn new(data: BTreeMap<String, BTreeSet<String>>) -> Externs {
281+
pub fn new(data: BTreeMap<String, BTreeSet<Option<String>>>) -> Externs {
282282
Externs(data)
283283
}
284284

285-
pub fn get(&self, key: &str) -> Option<&BTreeSet<String>> {
285+
pub fn get(&self, key: &str) -> Option<&BTreeSet<Option<String>>> {
286286
self.0.get(key)
287287
}
288288

289-
pub fn iter<'a>(&'a self) -> BTreeMapIter<'a, String, BTreeSet<String>> {
289+
pub fn iter<'a>(&'a self) -> BTreeMapIter<'a, String, BTreeSet<Option<String>>> {
290290
self.0.iter()
291291
}
292292
}
@@ -2169,6 +2169,8 @@ pub fn build_session_options_and_crate_config(
21692169
let cfg = parse_cfgspecs(matches.opt_strs("cfg"));
21702170
let test = matches.opt_present("test");
21712171

2172+
let is_unstable_enabled = nightly_options::is_unstable_enabled(matches);
2173+
21722174
prints.extend(matches.opt_strs("print").into_iter().map(|s| match &*s {
21732175
"crate-name" => PrintRequest::CrateName,
21742176
"file-names" => PrintRequest::FileNames,
@@ -2182,15 +2184,13 @@ pub fn build_session_options_and_crate_config(
21822184
"tls-models" => PrintRequest::TlsModels,
21832185
"native-static-libs" => PrintRequest::NativeStaticLibs,
21842186
"target-spec-json" => {
2185-
if nightly_options::is_unstable_enabled(matches) {
2187+
if is_unstable_enabled {
21862188
PrintRequest::TargetSpec
21872189
} else {
21882190
early_error(
21892191
error_format,
2190-
&format!(
2191-
"the `-Z unstable-options` flag must also be passed to \
2192-
enable the target-spec-json print option"
2193-
),
2192+
"the `-Z unstable-options` flag must also be passed to \
2193+
enable the target-spec-json print option",
21942194
);
21952195
}
21962196
}
@@ -2220,18 +2220,19 @@ pub fn build_session_options_and_crate_config(
22202220
Some(s) => s,
22212221
None => early_error(error_format, "--extern value must not be empty"),
22222222
};
2223-
let location = match parts.next() {
2224-
Some(s) => s,
2225-
None => early_error(
2223+
let location = parts.next().map(|s| s.to_string());
2224+
if location.is_none() && !is_unstable_enabled {
2225+
early_error(
22262226
error_format,
2227-
"--extern value must be of the format `foo=bar`",
2228-
),
2227+
"the `-Z unstable-options` flag must also be passed to \
2228+
enable `--extern crate_name` without `=path`",
2229+
);
22292230
};
22302231

22312232
externs
22322233
.entry(name.to_string())
22332234
.or_default()
2234-
.insert(location.to_string());
2235+
.insert(location);
22352236
}
22362237

22372238
let crate_name = matches.opt_str("crate-name");
@@ -2687,33 +2688,33 @@ mod tests {
26872688
v1.externs = Externs::new(mk_map(vec![
26882689
(
26892690
String::from("a"),
2690-
mk_set(vec![String::from("b"), String::from("c")]),
2691+
mk_set(vec![Some(String::from("b")), Some(String::from("c"))]),
26912692
),
26922693
(
26932694
String::from("d"),
2694-
mk_set(vec![String::from("e"), String::from("f")]),
2695+
mk_set(vec![Some(String::from("e")), Some(String::from("f"))]),
26952696
),
26962697
]));
26972698

26982699
v2.externs = Externs::new(mk_map(vec![
26992700
(
27002701
String::from("d"),
2701-
mk_set(vec![String::from("e"), String::from("f")]),
2702+
mk_set(vec![Some(String::from("e")), Some(String::from("f"))]),
27022703
),
27032704
(
27042705
String::from("a"),
2705-
mk_set(vec![String::from("b"), String::from("c")]),
2706+
mk_set(vec![Some(String::from("b")), Some(String::from("c"))]),
27062707
),
27072708
]));
27082709

27092710
v3.externs = Externs::new(mk_map(vec![
27102711
(
27112712
String::from("a"),
2712-
mk_set(vec![String::from("b"), String::from("c")]),
2713+
mk_set(vec![Some(String::from("b")), Some(String::from("c"))]),
27132714
),
27142715
(
27152716
String::from("d"),
2716-
mk_set(vec![String::from("f"), String::from("e")]),
2717+
mk_set(vec![Some(String::from("f")), Some(String::from("e"))]),
27172718
),
27182719
]));
27192720

src/librustc_metadata/creader.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,8 @@ impl<'a> CrateLoader<'a> {
132132
// from the strings on the command line.
133133
let source = &self.cstore.get_crate_data(cnum).source;
134134
if let Some(locs) = self.sess.opts.externs.get(&*name.as_str()) {
135-
let found = locs.iter().any(|l| {
135+
// Only use `--extern crate_name=path` here, not `--extern crate_name`.
136+
let found = locs.iter().filter_map(|l| l.as_ref()).any(|l| {
136137
let l = fs::canonicalize(l).ok();
137138
source.dylib.as_ref().map(|p| &p.0) == l.as_ref() ||
138139
source.rlib.as_ref().map(|p| &p.0) == l.as_ref()

src/librustc_metadata/locator.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,12 @@ impl<'a> Context<'a> {
438438
if self.hash.is_none() {
439439
self.should_match_name = false;
440440
if let Some(s) = self.sess.opts.externs.get(&self.crate_name.as_str()) {
441-
return self.find_commandline_library(s.iter());
441+
// Only use `--extern crate_name=path` here, not `--extern crate_name`.
442+
if s.iter().any(|l| l.is_some()) {
443+
return self.find_commandline_library(
444+
s.iter().filter_map(|l| l.as_ref()),
445+
);
446+
}
442447
}
443448
self.should_match_name = true;
444449
}

src/librustdoc/lib.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -609,16 +609,19 @@ where R: 'static + Send, F: 'static + Send + FnOnce(Output) -> R {
609609
/// Extracts `--extern CRATE=PATH` arguments from `matches` and
610610
/// returns a map mapping crate names to their paths or else an
611611
/// error message.
612+
// FIXME(eddyb) This shouldn't be duplicated with `rustc::session`.
612613
fn parse_externs(matches: &getopts::Matches) -> Result<Externs, String> {
613614
let mut externs: BTreeMap<_, BTreeSet<_>> = BTreeMap::new();
614615
for arg in &matches.opt_strs("extern") {
615616
let mut parts = arg.splitn(2, '=');
616617
let name = parts.next().ok_or("--extern value must not be empty".to_string())?;
617-
let location = parts.next()
618-
.ok_or("--extern value must be of the format `foo=bar`"
619-
.to_string())?;
618+
let location = parts.next().map(|s| s.to_string());
619+
if location.is_none() && !nightly_options::is_unstable_enabled(matches) {
620+
return Err("the `-Z unstable-options` flag must also be passed to \
621+
enable `--extern crate_name` without `=path`".to_string());
622+
}
620623
let name = name.to_string();
621-
externs.entry(name).or_default().insert(location.to_string());
624+
externs.entry(name).or_default().insert(location);
622625
}
623626
Ok(Externs::new(externs))
624627
}

0 commit comments

Comments
 (0)