about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/doc/rustc/src/codegen-options/index.md6
-rw-r--r--src/doc/rustc/src/command-line-arguments.md30
-rw-r--r--src/librustc/session/config.rs17
-rw-r--r--src/librustdoc/config.rs4
-rw-r--r--src/librustdoc/lib.rs2
-rw-r--r--src/test/run-make-fulldeps/extern-flag-fun/Makefile4
-rw-r--r--src/test/run-make-fulldeps/extern-flag-fun/gated_unstable.rs3
-rw-r--r--src/test/run-make-fulldeps/extern-flag-fun/rustc.rs1
-rw-r--r--src/test/run-make-fulldeps/extern-flag-pathless/Makefile18
-rw-r--r--src/test/run-make-fulldeps/extern-flag-pathless/bar-dynamic.rs3
-rw-r--r--src/test/run-make-fulldeps/extern-flag-pathless/bar-static.rs3
-rw-r--r--src/test/run-make-fulldeps/extern-flag-pathless/foo.rs3
-rw-r--r--src/test/run-make-fulldeps/save-analysis-rfc2126/Makefile3
-rw-r--r--src/test/rustdoc/inline_cross/use_crate.rs2
-rw-r--r--src/test/ui-fulldeps/pathless-extern-unstable.rs10
-rw-r--r--src/test/ui-fulldeps/pathless-extern-unstable.stderr12
-rw-r--r--src/test/ui/pathless-extern-ok.rs9
17 files changed, 101 insertions, 29 deletions
diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md
index 70c7acccd36..0dc81378e05 100644
--- a/src/doc/rustc/src/codegen-options/index.md
+++ b/src/doc/rustc/src/codegen-options/index.md
@@ -197,7 +197,11 @@ in software.
 ## prefer-dynamic
 
 By default, `rustc` prefers to statically link dependencies. This option will
-make it use dynamic linking instead.
+indicate that dynamic linking should be used if possible if both a static and
+dynamic versions of a library are available. There is an internal algorithm
+for determining whether or not it is possible to statically or dynamically
+link with a dependency. For example, `cdylib` crate types may only use static
+linkage.
 
 ## no-integrated-as
 
diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md
index 79b4f7542f9..577d03d1038 100644
--- a/src/doc/rustc/src/command-line-arguments.md
+++ b/src/doc/rustc/src/command-line-arguments.md
@@ -21,8 +21,7 @@ to `#[cfg(verbose)]` and `#[cfg(feature = "serde")]` respectively.
 <a id="option-l-search-path"></a>
 ## `-L`: add a directory to the library search path
 
-When looking for external crates or libraries, a directory passed to this flag
-will be searched.
+The `-L` flag adds a path to search for external crates and libraries.
 
 The kind of search path can optionally be specified with the form `-L
 KIND=PATH` where `KIND` may be one of:
@@ -262,9 +261,30 @@ This flag, when combined with other flags, makes them produce extra output.
 <a id="option-extern"></a>
 ## `--extern`: specify where an external library is located
 
-This flag allows you to pass the name and location of an external crate that
-will be linked into the crate you are building. This flag may be specified
-multiple times. The format of the value should be `CRATENAME=PATH`.
+This flag allows you to pass the name and location for an external crate of a
+direct dependency. Indirect dependencies (dependencies of dependencies) are
+located using the [`-L` flag](#option-l-search-path). The given crate name is
+added to the [extern prelude], which is the same as specifying `extern crate`
+within the root module. The given crate name does not need to match the name
+the library was built with.
+
+This flag may be specified multiple times. This flag takes an argument with
+either of the following formats:
+
+* `CRATENAME=PATH` — Indicates the given crate is found at the given path.
+* `CRATENAME` — Indicates the given crate may be found in the search path,
+  such as within the sysroot or via the `-L` flag.
+
+The same crate name may be specified multiple times for different crate types.
+If both an `rlib` and `dylib` are found, an internal algorithm is used to
+decide which to use for linking. The [`-C prefer-dynamic`
+flag][prefer-dynamic] may be used to influence which is used.
+
+If the same crate name is specified with and without a path, the one with the
+path is used and the pathless flag has no effect.
+
+[extern prelude]: ../reference/items/extern-crates.html#extern-prelude
+[prefer-dynamic]: codegen-options/index.md#prefer-dynamic
 
 <a id="option-sysroot"></a>
 ## `--sysroot`: Override the system root
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 2bcddeaf196..eb5654e80a8 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -1800,7 +1800,7 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
             "",
             "extern",
             "Specify where an external rust library is located",
-            "NAME=PATH",
+            "NAME[=PATH]",
         ),
         opt::multi_s(
             "",
@@ -2164,7 +2164,6 @@ fn collect_print_requests(
     cg: &mut CodegenOptions,
     dopts: &mut DebuggingOptions,
     matches: &getopts::Matches,
-    is_unstable_enabled: bool,
     error_format: ErrorOutputType,
 ) -> Vec<PrintRequest> {
     let mut prints = Vec::<PrintRequest>::new();
@@ -2206,7 +2205,7 @@ fn collect_print_requests(
         "tls-models" => PrintRequest::TlsModels,
         "native-static-libs" => PrintRequest::NativeStaticLibs,
         "target-spec-json" => {
-            if is_unstable_enabled {
+            if dopts.unstable_options {
                 PrintRequest::TargetSpec
             } else {
                 early_error(
@@ -2370,7 +2369,6 @@ fn parse_externs(
     matches: &getopts::Matches,
     debugging_opts: &DebuggingOptions,
     error_format: ErrorOutputType,
-    is_unstable_enabled: bool,
 ) -> Externs {
     if matches.opt_present("extern-private") && !debugging_opts.unstable_options {
         early_error(
@@ -2392,13 +2390,6 @@ fn parse_externs(
         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());
-        if location.is_none() && !is_unstable_enabled {
-            early_error(
-                error_format,
-                "the `-Z unstable-options` flag must also be passed to \
-                 enable `--extern crate_name` without `=path`",
-            );
-        };
 
         let entry = externs
             .entry(name.to_owned())
@@ -2483,12 +2474,10 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         );
     }
 
-    let is_unstable_enabled = nightly_options::is_unstable_enabled(matches);
     let prints = collect_print_requests(
         &mut cg,
         &mut debugging_opts,
         matches,
-        is_unstable_enabled,
         error_format,
     );
 
@@ -2521,7 +2510,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         );
     }
 
-    let externs = parse_externs(matches, &debugging_opts, error_format, is_unstable_enabled);
+    let externs = parse_externs(matches, &debugging_opts, error_format);
 
     let crate_name = matches.opt_str("crate-name");
 
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index 0b8d4d6c302..255d5f9f35d 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -615,10 +615,6 @@ fn parse_externs(matches: &getopts::Matches) -> Result<Externs, String> {
         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());
-        if location.is_none() && !nightly_options::is_unstable_enabled(matches) {
-            return Err("the `-Z unstable-options` flag must also be passed to \
-                        enable `--extern crate_name` without `=path`".to_string());
-        }
         let name = name.to_string();
         // For Rustdoc purposes, we can treat all externs as public
         externs.entry(name)
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 8cd32a3d1b5..13b8809e23e 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -140,7 +140,7 @@ fn opts() -> Vec<RustcOptGroup> {
         }),
         stable("cfg", |o| o.optmulti("", "cfg", "pass a --cfg to rustc", "")),
         stable("extern", |o| {
-            o.optmulti("", "extern", "pass an --extern to rustc", "NAME=PATH")
+            o.optmulti("", "extern", "pass an --extern to rustc", "NAME[=PATH]")
         }),
         unstable("extern-html-root-url", |o| {
             o.optmulti("", "extern-html-root-url",
diff --git a/src/test/run-make-fulldeps/extern-flag-fun/Makefile b/src/test/run-make-fulldeps/extern-flag-fun/Makefile
index a9f25853350..38d1d5bb848 100644
--- a/src/test/run-make-fulldeps/extern-flag-fun/Makefile
+++ b/src/test/run-make-fulldeps/extern-flag-fun/Makefile
@@ -4,7 +4,6 @@ all:
 	$(RUSTC) bar.rs --crate-type=rlib
 	$(RUSTC) bar.rs --crate-type=rlib -C extra-filename=-a
 	$(RUSTC) bar-alt.rs --crate-type=rlib
-	$(RUSTC) foo.rs --extern hello && exit 1 || exit 0
 	$(RUSTC) foo.rs --extern bar=no-exist && exit 1 || exit 0
 	$(RUSTC) foo.rs --extern bar=foo.rs && exit 1 || exit 0
 	$(RUSTC) foo.rs \
@@ -15,3 +14,6 @@ all:
 		--extern bar=$(TMPDIR)/libbar.rlib \
 		--extern bar=$(TMPDIR)/libbar-a.rlib
 	$(RUSTC) foo.rs --extern bar=$(TMPDIR)/libbar.rlib
+	# Try to be sneaky and load a private crate from with a non-private name.
+	$(RUSTC) rustc.rs -Zforce-unstable-if-unmarked --crate-type=rlib
+	$(RUSTC) gated_unstable.rs --extern alloc=$(TMPDIR)/librustc.rlib 2>&1 | $(CGREP) 'rustc_private'
diff --git a/src/test/run-make-fulldeps/extern-flag-fun/gated_unstable.rs b/src/test/run-make-fulldeps/extern-flag-fun/gated_unstable.rs
new file mode 100644
index 00000000000..03600c830ff
--- /dev/null
+++ b/src/test/run-make-fulldeps/extern-flag-fun/gated_unstable.rs
@@ -0,0 +1,3 @@
+extern crate alloc;
+
+fn main() {}
diff --git a/src/test/run-make-fulldeps/extern-flag-fun/rustc.rs b/src/test/run-make-fulldeps/extern-flag-fun/rustc.rs
new file mode 100644
index 00000000000..b76b4321d62
--- /dev/null
+++ b/src/test/run-make-fulldeps/extern-flag-fun/rustc.rs
@@ -0,0 +1 @@
+pub fn foo() {}
diff --git a/src/test/run-make-fulldeps/extern-flag-pathless/Makefile b/src/test/run-make-fulldeps/extern-flag-pathless/Makefile
new file mode 100644
index 00000000000..4849fc62f4a
--- /dev/null
+++ b/src/test/run-make-fulldeps/extern-flag-pathless/Makefile
@@ -0,0 +1,18 @@
+-include ../tools.mk
+
+# Test mixing pathless --extern with paths.
+
+all:
+	$(RUSTC) bar-static.rs --crate-name=bar --crate-type=rlib
+	$(RUSTC) bar-dynamic.rs --crate-name=bar --crate-type=dylib -C prefer-dynamic
+	# rlib preferred over dylib
+	$(RUSTC) foo.rs --extern bar
+	$(call RUN,foo) | $(CGREP) 'static'
+	$(RUSTC) foo.rs --extern bar=$(TMPDIR)/libbar.rlib --extern bar
+	$(call RUN,foo) | $(CGREP) 'static'
+	# explicit --extern overrides pathless
+	$(RUSTC) foo.rs --extern bar=$(call DYLIB,bar) --extern bar
+	$(call RUN,foo) | $(CGREP) 'dynamic'
+	# prefer-dynamic does what it says
+	$(RUSTC) foo.rs --extern bar -C prefer-dynamic
+	$(call RUN,foo) | $(CGREP) 'dynamic'
diff --git a/src/test/run-make-fulldeps/extern-flag-pathless/bar-dynamic.rs b/src/test/run-make-fulldeps/extern-flag-pathless/bar-dynamic.rs
new file mode 100644
index 00000000000..e2d68d517ff
--- /dev/null
+++ b/src/test/run-make-fulldeps/extern-flag-pathless/bar-dynamic.rs
@@ -0,0 +1,3 @@
+pub fn f() {
+    println!("dynamic");
+}
diff --git a/src/test/run-make-fulldeps/extern-flag-pathless/bar-static.rs b/src/test/run-make-fulldeps/extern-flag-pathless/bar-static.rs
new file mode 100644
index 00000000000..240d8bde4d1
--- /dev/null
+++ b/src/test/run-make-fulldeps/extern-flag-pathless/bar-static.rs
@@ -0,0 +1,3 @@
+pub fn f() {
+    println!("static");
+}
diff --git a/src/test/run-make-fulldeps/extern-flag-pathless/foo.rs b/src/test/run-make-fulldeps/extern-flag-pathless/foo.rs
new file mode 100644
index 00000000000..1ea64da7dad
--- /dev/null
+++ b/src/test/run-make-fulldeps/extern-flag-pathless/foo.rs
@@ -0,0 +1,3 @@
+fn main() {
+    bar::f();
+}
diff --git a/src/test/run-make-fulldeps/save-analysis-rfc2126/Makefile b/src/test/run-make-fulldeps/save-analysis-rfc2126/Makefile
index bf98fcd10cf..36288c4b870 100644
--- a/src/test/run-make-fulldeps/save-analysis-rfc2126/Makefile
+++ b/src/test/run-make-fulldeps/save-analysis-rfc2126/Makefile
@@ -1,8 +1,7 @@
 -include ../tools.mk
 
 all: extern_absolute_paths.rs krate2
-	$(RUSTC) extern_absolute_paths.rs -Zsave-analysis --edition=2018 \
-		-Z unstable-options --extern krate2
+	$(RUSTC) extern_absolute_paths.rs -Zsave-analysis --edition=2018 --extern krate2
 	cat $(TMPDIR)/save-analysis/extern_absolute_paths.json | "$(PYTHON)" validate_json.py
 
 krate2: krate2.rs
diff --git a/src/test/rustdoc/inline_cross/use_crate.rs b/src/test/rustdoc/inline_cross/use_crate.rs
index f678ba0a46c..00e0f041c56 100644
--- a/src/test/rustdoc/inline_cross/use_crate.rs
+++ b/src/test/rustdoc/inline_cross/use_crate.rs
@@ -2,7 +2,7 @@
 // aux-build:use_crate_2.rs
 // build-aux-docs
 // edition:2018
-// compile-flags:--extern use_crate --extern use_crate_2 -Z unstable-options
+// compile-flags:--extern use_crate --extern use_crate_2
 
 // During the buildup to Rust 2018, rustdoc would eagerly inline `pub use some_crate;` as if it
 // were a module, so we changed it to make `pub use`ing crate roots remain as a `pub use` statement
diff --git a/src/test/ui-fulldeps/pathless-extern-unstable.rs b/src/test/ui-fulldeps/pathless-extern-unstable.rs
new file mode 100644
index 00000000000..00b3ec5409f
--- /dev/null
+++ b/src/test/ui-fulldeps/pathless-extern-unstable.rs
@@ -0,0 +1,10 @@
+// ignore-stage1
+// edition:2018
+// compile-flags:--extern rustc
+
+// Test that `--extern rustc` fails with `rustc_private`.
+
+pub use rustc;
+//~^ ERROR use of unstable library feature 'rustc_private'
+
+fn main() {}
diff --git a/src/test/ui-fulldeps/pathless-extern-unstable.stderr b/src/test/ui-fulldeps/pathless-extern-unstable.stderr
new file mode 100644
index 00000000000..edc3b1c58be
--- /dev/null
+++ b/src/test/ui-fulldeps/pathless-extern-unstable.stderr
@@ -0,0 +1,12 @@
+error[E0658]: use of unstable library feature 'rustc_private': this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead?
+  --> $DIR/pathless-extern-unstable.rs:7:9
+   |
+LL | pub use rustc;
+   |         ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/27812
+   = help: add `#![feature(rustc_private)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/pathless-extern-ok.rs b/src/test/ui/pathless-extern-ok.rs
new file mode 100644
index 00000000000..0ffa5eb8940
--- /dev/null
+++ b/src/test/ui/pathless-extern-ok.rs
@@ -0,0 +1,9 @@
+// edition:2018
+// compile-flags:--extern alloc
+// build-pass
+
+// Test that `--extern alloc` will load from the sysroot without error.
+
+fn main() {
+    let _: Vec<i32> = alloc::vec::Vec::new();
+}