]> git.lizzy.rs Git - rust.git/commitdiff
Add options to --extern flag.
authorEric Huss <eric@huss.org>
Thu, 5 Dec 2019 22:43:53 +0000 (14:43 -0800)
committerEric Huss <eric@huss.org>
Mon, 9 Dec 2019 16:08:13 +0000 (08:08 -0800)
18 files changed:
src/librustc_interface/tests.rs
src/librustc_metadata/creader.rs
src/librustc_metadata/locator.rs
src/librustc_resolve/lib.rs
src/librustc_session/config.rs
src/librustdoc/config.rs
src/librustdoc/core.rs
src/librustdoc/lib.rs
src/test/run-make-fulldeps/extern-flag-noprelude/Makefile [new file with mode: 0644]
src/test/run-make-fulldeps/extern-flag-noprelude/dep.rs [new file with mode: 0644]
src/test/run-make-fulldeps/extern-flag-noprelude/foo.rs [new file with mode: 0644]
src/test/ui/extern-flag/multiple-opts.rs [new file with mode: 0644]
src/test/ui/extern-flag/multiple-opts.stderr [new file with mode: 0644]
src/test/ui/extern-flag/noprelude-and-prelude.rs [new file with mode: 0644]
src/test/ui/extern-flag/public-and-private.rs [new file with mode: 0644]
src/test/ui/extern-flag/public-and-private.stderr [new file with mode: 0644]
src/tools/compiletest/src/header.rs
src/tools/compiletest/src/runtest.rs

index 4c630b56cb4ce36a1b02bac73b31b57b673b1a4f..d4b5e833dfb23df34cf3304089b6df867c008b6a 100644 (file)
@@ -7,7 +7,7 @@
 use rustc::session::config::{build_configuration, build_session_options, to_crate_config};
 use rustc::session::config::{LtoCli, LinkerPluginLto, SwitchWithOptPath, ExternEntry};
 use rustc::session::config::{Externs, OutputType, OutputTypes, SymbolManglingVersion};
-use rustc::session::config::{rustc_optgroups, Options, ErrorOutputType, Passes};
+use rustc::session::config::{rustc_optgroups, Options, ErrorOutputType, Passes, ExternLocation};
 use rustc::session::{build_session, Session};
 use rustc::session::search_paths::SearchPath;
 use std::collections::{BTreeMap, BTreeSet};
@@ -38,14 +38,15 @@ fn mk_session(matches: getopts::Matches) -> (Session, CfgSpecs) {
 fn new_public_extern_entry<S, I>(locations: I) -> ExternEntry
 where
     S: Into<String>,
-    I: IntoIterator<Item = Option<S>>,
+    I: IntoIterator<Item = S>,
 {
-    let locations: BTreeSet<_> = locations.into_iter().map(|o| o.map(|s| s.into()))
+    let locations: BTreeSet<_> = locations.into_iter().map(|s| s.into())
         .collect();
 
     ExternEntry {
-        locations,
-        is_private_dep: false
+        location: ExternLocation::ExactPaths(locations),
+        is_private_dep: false,
+        add_prelude: true,
     }
 }
 
@@ -160,33 +161,33 @@ fn test_externs_tracking_hash_different_construction_order() {
     v1.externs = Externs::new(mk_map(vec![
         (
             String::from("a"),
-            new_public_extern_entry(vec![Some("b"), Some("c")])
+            new_public_extern_entry(vec!["b", "c"])
         ),
         (
             String::from("d"),
-            new_public_extern_entry(vec![Some("e"), Some("f")])
+            new_public_extern_entry(vec!["e", "f"])
         ),
     ]));
 
     v2.externs = Externs::new(mk_map(vec![
         (
             String::from("d"),
-            new_public_extern_entry(vec![Some("e"), Some("f")])
+            new_public_extern_entry(vec!["e", "f"])
         ),
         (
             String::from("a"),
-            new_public_extern_entry(vec![Some("b"), Some("c")])
+            new_public_extern_entry(vec!["b", "c"])
         ),
     ]));
 
     v3.externs = Externs::new(mk_map(vec![
         (
             String::from("a"),
-            new_public_extern_entry(vec![Some("b"), Some("c")])
+            new_public_extern_entry(vec!["b", "c"])
         ),
         (
             String::from("d"),
-            new_public_extern_entry(vec![Some("f"), Some("e")])
+            new_public_extern_entry(vec!["f", "e"])
         ),
     ]));
 
index dbf2dcf1c0aea461d6be050c33deaf806f453dc5..71871373e35e94d6841622ac548aa83d827568f6 100644 (file)
@@ -218,13 +218,14 @@ fn existing_match(&self, name: Symbol, hash: Option<Svh>, kind: PathKind) -> Opt
             let source = self.cstore.get_crate_data(cnum).source();
             if let Some(entry) = self.sess.opts.externs.get(&name.as_str()) {
                 // Only use `--extern crate_name=path` here, not `--extern crate_name`.
-                let found = entry.locations.iter().filter_map(|l| l.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()
-                });
-                if found {
-                    ret = Some(cnum);
+                if let Some(mut files) = entry.files() {
+                    if files.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()
+                    }) {
+                        ret = Some(cnum);
+                    }
                 }
                 return
             }
index c6fb80eca055ad98cce36d9faa0cbc2028b4c4ff..8a1eeea02512e89f30693a62a075f4d79d1a6c25 100644 (file)
@@ -328,8 +328,9 @@ impl<'a> CrateLocator<'a> {
             crate_name,
             exact_paths: if hash.is_none() {
                 sess.opts.externs.get(&crate_name.as_str()).into_iter()
-                    .flat_map(|entry| entry.locations.iter())
-                    .filter_map(|location| location.clone().map(PathBuf::from)).collect()
+                    .filter_map(|entry| entry.files())
+                    .flatten()
+                    .map(|location| PathBuf::from(location)).collect()
             } else {
                 // SVH being specified means this is a transitive dependency,
                 // so `--extern` options do not apply.
index be36e02f5b5b1e17fc8659c2d5092a98890f3b91..2aa79d7b0da50420563e8ccde8ca145a58d30bd2 100644 (file)
@@ -1126,8 +1126,10 @@ pub fn new(session: &'a Session,
         definitions.create_root_def(crate_name, session.local_crate_disambiguator());
 
         let mut extern_prelude: FxHashMap<Ident, ExternPreludeEntry<'_>> =
-            session.opts.externs.iter().map(|kv| (Ident::from_str(kv.0), Default::default()))
-                                       .collect();
+            session.opts.externs.iter()
+                .filter(|(_, entry)| entry.add_prelude)
+                .map(|(name, _)| (Ident::from_str(name), Default::default()))
+                .collect();
 
         if !attr::contains_name(&krate.attrs, sym::no_core) {
             extern_prelude.insert(Ident::with_dummy_span(sym::core), Default::default());
index 58113bb8cd6cb430a202d7d9c0a3559b4fa8ad1e..7f3bab8f23299b0041127dadd3fddcb0f7a57a6e 100644 (file)
@@ -1,3 +1,5 @@
+// ignore-tidy-filelength
+
 //! Contains infrastructure for configuring the compiler, including parsing
 //! command-line options.
 
@@ -31,7 +33,7 @@
 use std::str::{self, FromStr};
 use std::hash::Hasher;
 use std::collections::hash_map::DefaultHasher;
-use std::iter::FromIterator;
+use std::iter::{self, FromIterator};
 use std::path::{Path, PathBuf};
 
 pub struct Config {
@@ -322,10 +324,35 @@ pub fn should_codegen(&self) -> bool {
 #[derive(Clone)]
 pub struct Externs(BTreeMap<String, ExternEntry>);
 
-#[derive(Clone, Debug, Default)]
+#[derive(Clone, Debug)]
 pub struct ExternEntry {
-    pub locations: BTreeSet<Option<String>>,
-    pub is_private_dep: bool
+    pub location: ExternLocation,
+    /// Indicates this is a "private" dependency for the
+    /// `exported_private_dependencies` lint.
+    ///
+    /// This can be set with the `priv` option like
+    /// `--extern priv:name=foo.rlib`.
+    pub is_private_dep: bool,
+    /// Add the extern entry to the extern prelude.
+    ///
+    /// This can be disabled with the `noprelude` option like
+    /// `--extern noprelude:name`.
+    pub add_prelude: bool,
+}
+
+#[derive(Clone, Debug)]
+pub enum ExternLocation {
+    /// Indicates to look for the library in the search paths.
+    ///
+    /// Added via `--extern name`.
+    FoundInLibrarySearchDirectories,
+    /// The locations where this extern entry must be found.
+    ///
+    /// The `CrateLoader` is responsible for loading these and figuring out
+    /// which one to use.
+    ///
+    /// Added via `--extern prelude_name=some_file.rlib`
+    ExactPaths(BTreeSet<String>),
 }
 
 impl Externs {
@@ -342,6 +369,18 @@ pub fn iter(&self) -> BTreeMapIter<'_, String, ExternEntry> {
     }
 }
 
+impl ExternEntry {
+    fn new(location: ExternLocation) -> ExternEntry {
+        ExternEntry { location, is_private_dep: false, add_prelude: false }
+    }
+
+    pub fn files(&self) -> Option<impl Iterator<Item = &String>> {
+        match &self.location {
+            ExternLocation::ExactPaths(set) => Some(set.iter()),
+            _ => None,
+        }
+    }
+}
 
 macro_rules! hash_option {
     ($opt_name:ident, $opt_expr:expr, $sub_hashes:expr, [UNTRACKED]) => ({});
@@ -1869,12 +1908,6 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
             "Specify where an external rust library is located",
             "NAME[=PATH]",
         ),
-        opt::multi_s(
-            "",
-            "extern-private",
-            "Specify where an extern rust library is located, marking it as a private dependency",
-            "NAME=PATH",
-        ),
         opt::opt_s("", "sysroot", "Override the system root", "PATH"),
         opt::multi("Z", "", "Set internal debugging options", "FLAG"),
         opt::opt_s(
@@ -2435,43 +2468,105 @@ fn parse_borrowck_mode(dopts: &DebuggingOptions, error_format: ErrorOutputType)
     }
 }
 
-fn parse_externs(
+pub fn parse_externs(
     matches: &getopts::Matches,
     debugging_opts: &DebuggingOptions,
     error_format: ErrorOutputType,
 ) -> Externs {
-    if matches.opt_present("extern-private") && !debugging_opts.unstable_options {
-        early_error(
-            ErrorOutputType::default(),
-            "'--extern-private' is unstable and only \
-            available for nightly builds of rustc."
-        )
-    }
-
-    // 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 is_unstable_enabled = debugging_opts.unstable_options;
     let mut externs: BTreeMap<String, ExternEntry> = BTreeMap::new();
-    for (arg, private) in matches.opt_strs("extern").into_iter().map(|v| (v, false))
-        .chain(matches.opt_strs("extern-private").into_iter().map(|v| (v, true))) {
-
+    for arg in matches.opt_strs("extern") {
         let mut parts = arg.splitn(2, '=');
-        let name = parts.next().unwrap_or_else(||
-            early_error(error_format, "--extern value must not be empty"));
-        let location = parts.next().map(|s| s.to_string());
+        let name = parts
+            .next()
+            .unwrap_or_else(|| early_error(error_format, "--extern value must not be empty"));
+        let path = parts.next().map(|s| s.to_string());
+
+        let mut name_parts = name.splitn(2, ':');
+        let first_part = name_parts.next();
+        let second_part = name_parts.next();
+        let (options, name) = match (first_part, second_part) {
+            (Some(opts), Some(name)) => (Some(opts), name),
+            (Some(name), None) => (None, name),
+            (None, None) => early_error(error_format, "--extern name must not be empty"),
+            _ => unreachable!(),
+        };
+
+        let entry = externs.entry(name.to_owned());
 
-        let entry = externs
-            .entry(name.to_owned())
-            .or_default();
+        use std::collections::btree_map::Entry;
 
+        let entry = if let Some(path) = path {
+            // --extern prelude_name=some_file.rlib
+            match entry {
+                Entry::Vacant(vacant) => {
+                    let files = BTreeSet::from_iter(iter::once(path));
+                    vacant.insert(ExternEntry::new(ExternLocation::ExactPaths(files)))
+                }
+                Entry::Occupied(occupied) => {
+                    let ext_ent = occupied.into_mut();
+                    match ext_ent {
+                        ExternEntry { location: ExternLocation::ExactPaths(files), .. } => {
+                            files.insert(path);
+                        }
+                        ExternEntry {
+                            location: location @ ExternLocation::FoundInLibrarySearchDirectories,
+                            ..
+                        } => {
+                            // Exact paths take precedence over search directories.
+                            let files = BTreeSet::from_iter(iter::once(path));
+                            *location = ExternLocation::ExactPaths(files);
+                        }
+                    }
+                    ext_ent
+                }
+            }
+        } else {
+            // --extern prelude_name
+            match entry {
+                Entry::Vacant(vacant) => {
+                    vacant.insert(ExternEntry::new(ExternLocation::FoundInLibrarySearchDirectories))
+                }
+                Entry::Occupied(occupied) => {
+                    // Ignore if already specified.
+                    occupied.into_mut()
+                }
+            }
+        };
 
-        entry.locations.insert(location.clone());
+        let mut is_private_dep = false;
+        let mut add_prelude = true;
+        if let Some(opts) = options {
+            if !is_unstable_enabled {
+                early_error(
+                    error_format,
+                    "the `-Z unstable-options` flag must also be passed to \
+                     enable `--extern options",
+                );
+            }
+            for opt in opts.split(',') {
+                match opt {
+                    "priv" => is_private_dep = true,
+                    "noprelude" => {
+                        if let ExternLocation::ExactPaths(_) = &entry.location {
+                            add_prelude = false;
+                        } else {
+                            early_error(
+                                error_format,
+                                "the `noprelude` --extern option requires a file path",
+                            );
+                        }
+                    }
+                    _ => early_error(error_format, &format!("unknown --extern option `{}`", opt)),
+                }
+            }
+        }
 
-        // Crates start out being not private,
-        // and go to being private if we see an '--extern-private'
-        // flag
-        entry.is_private_dep |= private;
+        // Crates start out being not private, and go to being private `priv`
+        // is specified.
+        entry.is_private_dep |= is_private_dep;
+        // If any flag is missing `noprelude`, then add to the prelude.
+        entry.add_prelude |= add_prelude;
     }
     Externs(externs)
 }
index cdb1a1f6997c9f80024e9e34c5fc6bd69b7aa294..0db3d28bf0e3782d989cd785b2b3c9994a331734 100644 (file)
@@ -7,10 +7,10 @@
 use getopts;
 use rustc::lint::Level;
 use rustc::session;
-use rustc::session::config::{CrateType, parse_crate_types_from_list};
+use rustc::session::config::{CrateType, parse_crate_types_from_list, parse_externs};
 use rustc::session::config::{CodegenOptions, DebuggingOptions, ErrorOutputType, Externs};
 use rustc::session::config::{nightly_options, build_codegen_options, build_debugging_options,
-                             get_cmd_lint_options, host_triple, ExternEntry};
+                             get_cmd_lint_options, host_triple};
 use rustc::session::search_paths::SearchPath;
 use rustc_driver;
 use rustc_target::spec::TargetTriple;
@@ -320,13 +320,7 @@ pub fn from_matches(matches: &getopts::Matches) -> Result<Options, i32> {
         let libs = matches.opt_strs("L").iter()
             .map(|s| SearchPath::from_cli_opt(s, error_format))
             .collect();
-        let externs = match parse_externs(&matches) {
-            Ok(ex) => ex,
-            Err(err) => {
-                diag.struct_err(&err).emit();
-                return Err(1);
-            }
-        };
+        let externs = parse_externs(&matches, &debugging_options, error_format);
         let extern_html_root_urls = match parse_extern_html_roots(&matches) {
             Ok(ex) => ex,
             Err(err) => {
@@ -617,24 +611,3 @@ fn parse_extern_html_roots(
 
     Ok(externs)
 }
-
-/// Extracts `--extern CRATE=PATH` arguments from `matches` and
-/// returns a map mapping crate names to their paths or else an
-/// error message.
-/// Also handles `--extern-private` which for the purposes of rustdoc
-/// we can treat as `--extern`
-// FIXME(eddyb) This shouldn't be duplicated with `rustc::session`.
-fn parse_externs(matches: &getopts::Matches) -> Result<Externs, String> {
-    let mut externs: BTreeMap<_, ExternEntry> = BTreeMap::new();
-    for arg in matches.opt_strs("extern").iter().chain(matches.opt_strs("extern-private").iter()) {
-        let mut parts = arg.splitn(2, '=');
-        let name = parts.next().ok_or("--extern value must not be empty".to_string())?;
-        let location = parts.next().map(|s| s.to_string());
-        let name = name.to_string();
-        // For Rustdoc purposes, we can treat all externs as public
-        externs.entry(name)
-            .or_default()
-            .locations.insert(location.clone());
-    }
-    Ok(Externs::new(externs))
-}
index b77b1c720cfdffa0186a4f67c2386958c53c869e..a524801bea6bf27b47dabb96fe13097a52b33f79 100644 (file)
@@ -248,7 +248,9 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
         ..
     } = options;
 
-    let extern_names: Vec<String> = externs.iter().map(|(s,_)| s).cloned().collect();
+    let extern_names: Vec<String> = externs.iter()
+        .filter(|(_, entry)| entry.add_prelude)
+        .map(|(name, _)| name).cloned().collect();
 
     // Add the doc cfg into the doc build.
     cfgs.push("doc".to_string());
index be3644ecf96a7ad1436d23a45a9d5fff00ac1925..a4be3dee938ed307ec4d5241f03659eba52590ec 100644 (file)
@@ -145,10 +145,6 @@ fn opts() -> Vec<RustcOptGroup> {
         stable("extern", |o| {
             o.optmulti("", "extern", "pass an --extern to rustc", "NAME[=PATH]")
         }),
-        unstable("extern-private", |o| {
-            o.optmulti("", "extern-private",
-                       "pass an --extern to rustc (compatibility only)", "NAME=PATH")
-        }),
         unstable("extern-html-root-url", |o| {
             o.optmulti("", "extern-html-root-url",
                        "base URL to use for dependencies", "NAME=URL")
diff --git a/src/test/run-make-fulldeps/extern-flag-noprelude/Makefile b/src/test/run-make-fulldeps/extern-flag-noprelude/Makefile
new file mode 100644 (file)
index 0000000..18f9d8b
--- /dev/null
@@ -0,0 +1,11 @@
+-include ../tools.mk
+
+# Test --extern noprelude
+
+all:
+       $(RUSTC) dep.rs --crate-name=dep --crate-type=rlib
+       $(RUSTC) foo.rs --edition=2018 -Zunstable-options \
+               --extern noprelude:dep=$(TMPDIR)/libdep.rlib 2>&1 | \
+               $(CGREP) -e 'failed to resolve.*`dep`'
+       $(RUSTC) foo.rs --edition=2018 -Zunstable-options \
+               --extern dep=$(TMPDIR)/libdep.rlib
diff --git a/src/test/run-make-fulldeps/extern-flag-noprelude/dep.rs b/src/test/run-make-fulldeps/extern-flag-noprelude/dep.rs
new file mode 100644 (file)
index 0000000..dd2f373
--- /dev/null
@@ -0,0 +1,3 @@
+pub fn somefun() {}
+
+pub struct S;
diff --git a/src/test/run-make-fulldeps/extern-flag-noprelude/foo.rs b/src/test/run-make-fulldeps/extern-flag-noprelude/foo.rs
new file mode 100644 (file)
index 0000000..9bb1b78
--- /dev/null
@@ -0,0 +1,3 @@
+fn main() {
+    dep::somefun();
+}
diff --git a/src/test/ui/extern-flag/multiple-opts.rs b/src/test/ui/extern-flag/multiple-opts.rs
new file mode 100644 (file)
index 0000000..3dc2f1d
--- /dev/null
@@ -0,0 +1,20 @@
+// aux-crate:priv,noprelude:somedep=somedep.rs
+// compile-flags: -Zunstable-options
+// edition:2018
+
+// Test for multiple options to --extern. Can't test for errors from both
+// options at the same time, so this only checks that noprelude is honored.
+
+#![warn(exported_private_dependencies)]
+
+// Module to avoid adding to prelude.
+pub mod m {
+    extern crate somedep;
+    pub struct PublicType {
+        pub field: somedep::S,
+    }
+}
+
+fn main() {
+    somedep::somefun();  //~ ERROR failed to resolve
+}
diff --git a/src/test/ui/extern-flag/multiple-opts.stderr b/src/test/ui/extern-flag/multiple-opts.stderr
new file mode 100644 (file)
index 0000000..3bf73d1
--- /dev/null
@@ -0,0 +1,9 @@
+error[E0433]: failed to resolve: use of undeclared type or module `somedep`
+  --> $DIR/multiple-opts.rs:19:5
+   |
+LL |     somedep::somefun();
+   |     ^^^^^^^ use of undeclared type or module `somedep`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0433`.
diff --git a/src/test/ui/extern-flag/noprelude-and-prelude.rs b/src/test/ui/extern-flag/noprelude-and-prelude.rs
new file mode 100644 (file)
index 0000000..e6a150b
--- /dev/null
@@ -0,0 +1,10 @@
+// check-pass
+// aux-crate:noprelude:somedep=somedep.rs
+// compile-flags: -Zunstable-options --extern somedep
+// edition:2018
+
+// Having a flag with `noprelude` and one without, will add to the prelude.
+
+fn main() {
+    somedep::somefun();
+}
diff --git a/src/test/ui/extern-flag/public-and-private.rs b/src/test/ui/extern-flag/public-and-private.rs
new file mode 100644 (file)
index 0000000..a3a81cb
--- /dev/null
@@ -0,0 +1,13 @@
+// aux-crate:priv:somedep=somedep.rs
+// compile-flags: -Zunstable-options --extern somedep
+// edition:2018
+
+#![deny(exported_private_dependencies)]
+
+// Having a flag with `priv` and one without, will remain private (it is sticky).
+
+pub struct PublicType {
+    pub field: somedep::S, //~ ERROR from private dependency
+}
+
+fn main() {}
diff --git a/src/test/ui/extern-flag/public-and-private.stderr b/src/test/ui/extern-flag/public-and-private.stderr
new file mode 100644 (file)
index 0000000..72f1bb2
--- /dev/null
@@ -0,0 +1,14 @@
+error: type `somedep::S` from private dependency 'somedep' in public interface
+  --> $DIR/public-and-private.rs:10:5
+   |
+LL |     pub field: somedep::S,
+   |     ^^^^^^^^^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/public-and-private.rs:5:9
+   |
+LL | #![deny(exported_private_dependencies)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
index dc4811e5d24ce96d422eabbd573fbd8a9cffb441..ca30e782c505654ad20c088e560e215c838b32f3 100644 (file)
@@ -311,7 +311,7 @@ pub struct TestProps {
     // directory as the test, but for backwards compatibility reasons
     // we also check the auxiliary directory)
     pub aux_builds: Vec<String>,
-    // A list of crates to pass '--extern-private name:PATH' flags for
+    // A list of crates to pass '--extern priv:name=PATH' flags for
     // This should be a subset of 'aux_build'
     // FIXME: Replace this with a better solution: https://github.com/rust-lang/rust/pull/54020
     pub extern_private: Vec<String>,
index 15ae67fb12c516a0484e84ab59c7d9424d83944d..ca68fe3e39b96fc71c3a1b4e396753b2c1b0f23a 100644 (file)
@@ -1782,8 +1782,8 @@ fn compose_and_run_compiler(&self, mut rustc: Command, input: Option<String>) ->
         let mut add_extern_priv = |priv_dep: &str, dylib: bool| {
             let lib_name = get_lib_name(priv_dep, dylib);
             rustc
-                .arg("--extern-private")
-                .arg(format!("{}={}", priv_dep, aux_dir.join(lib_name).to_str().unwrap()));
+                .arg("--extern")
+                .arg(format!("priv:{}={}", priv_dep, aux_dir.join(lib_name).to_str().unwrap()));
         };
 
         for rel_ab in &self.props.aux_builds {
@@ -1829,9 +1829,9 @@ fn compose_and_run_compiler(&self, mut rustc: Command, input: Option<String>) ->
 
             let trimmed = rel_ab.trim_end_matches(".rs").to_string();
 
-            // Normally, every 'extern-private' has a correspodning 'aux-build'
+            // Normally, every 'extern-private' has a corresponding 'aux-build'
             // entry. If so, we remove it from our list of private crates,
-            // and add an '--extern-private' flag to rustc
+            // and add an '--extern priv:NAME=PATH' flag to rustc
             if extern_priv.remove_item(&trimmed).is_some() {
                 add_extern_priv(&trimmed, dylib);
             }
@@ -1859,7 +1859,7 @@ fn compose_and_run_compiler(&self, mut rustc: Command, input: Option<String>) ->
             }
         }
 
-        // Add any '--extern-private' entries without a matching
+        // Add any '--extern' private entries without a matching
         // 'aux-build'
         for private_lib in extern_priv {
             add_extern_priv(&private_lib, true);