From 9ccf4f22c91bbe9ce295d274d86820597be76c37 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 28 Sep 2019 12:04:06 -0700 Subject: [PATCH 1/8] Stabilize --extern flag without a path. --- src/doc/rustc/src/command-line-arguments.md | 7 ++++++- src/librustc/session/config.rs | 7 ------- src/librustdoc/config.rs | 4 ---- src/test/run-make-fulldeps/extern-flag-fun/Makefile | 1 - src/test/run-make-fulldeps/save-analysis-rfc2126/Makefile | 3 +-- 5 files changed, 7 insertions(+), 15 deletions(-) diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md index 5eea9c8687900..8ff3b463ae2b9 100644 --- a/src/doc/rustc/src/command-line-arguments.md +++ b/src/doc/rustc/src/command-line-arguments.md @@ -233,7 +233,12 @@ This flag, when combined with other flags, makes them produce extra output. 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`. +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. ## `--sysroot`: Override the system root diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 675e3bbd002b0..19e618e9fcac6 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -2449,13 +2449,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()) diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 1c0d1b3273731..1f37db574dcec 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -611,10 +611,6 @@ fn parse_externs(matches: &getopts::Matches) -> Result { 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/test/run-make-fulldeps/extern-flag-fun/Makefile b/src/test/run-make-fulldeps/extern-flag-fun/Makefile index a9f2585335003..7f54d6ea3bc6c 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 \ diff --git a/src/test/run-make-fulldeps/save-analysis-rfc2126/Makefile b/src/test/run-make-fulldeps/save-analysis-rfc2126/Makefile index bf98fcd10cfde..36288c4b870e7 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 From 04c2c6083958c7c4b2f96685410f50c3442768ff Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sun, 29 Sep 2019 18:17:27 -0700 Subject: [PATCH 2/8] Add more --extern tests. --- .../extern-flag-pathless/Makefile | 18 ++++++++++++++++++ .../extern-flag-pathless/bar-dynamic.rs | 3 +++ .../extern-flag-pathless/bar-static.rs | 3 +++ .../extern-flag-pathless/foo.rs | 3 +++ src/test/rustdoc/inline_cross/use_crate.rs | 2 +- .../ui-fulldeps/pathless-extern-unstable.rs | 10 ++++++++++ .../pathless-extern-unstable.stderr | 12 ++++++++++++ src/test/ui/pathless-extern-ok.rs | 9 +++++++++ 8 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 src/test/run-make-fulldeps/extern-flag-pathless/Makefile create mode 100644 src/test/run-make-fulldeps/extern-flag-pathless/bar-dynamic.rs create mode 100644 src/test/run-make-fulldeps/extern-flag-pathless/bar-static.rs create mode 100644 src/test/run-make-fulldeps/extern-flag-pathless/foo.rs create mode 100644 src/test/ui-fulldeps/pathless-extern-unstable.rs create mode 100644 src/test/ui-fulldeps/pathless-extern-unstable.stderr create mode 100644 src/test/ui/pathless-extern-ok.rs 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 0000000000000..4849fc62f4a95 --- /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 0000000000000..e2d68d517ff97 --- /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 0000000000000..240d8bde4d186 --- /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 0000000000000..1ea64da7dad26 --- /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/rustdoc/inline_cross/use_crate.rs b/src/test/rustdoc/inline_cross/use_crate.rs index f678ba0a46c0d..00e0f041c56fe 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 0000000000000..a5a31816c9572 --- /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; +//~^ 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 0000000000000..edc3b1c58be22 --- /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 0000000000000..0ffa5eb894040 --- /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 = alloc::vec::Vec::new(); +} From 8e62a016e4605e3e3aca77e04d21095a3812493c Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sun, 29 Sep 2019 18:17:48 -0700 Subject: [PATCH 3/8] Update built-in help for --extern. --- src/librustc/session/config.rs | 2 +- src/librustdoc/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 19e618e9fcac6..07fd71632d167 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1804,7 +1804,7 @@ pub fn rustc_optgroups() -> Vec { "", "extern", "Specify where an external rust library is located", - "NAME=PATH", + "NAME[=PATH]", ), opt::multi_s( "", diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 6bcb4a817d78e..c0b665dc64a20 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -139,7 +139,7 @@ fn opts() -> Vec { }), 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", From 414d7cf4a28197d9ac622ce76a6e9ea085da0858 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sun, 29 Sep 2019 18:20:03 -0700 Subject: [PATCH 4/8] Update extern linking documentation. --- src/doc/rustc/src/codegen-options/index.md | 6 ++++- src/doc/rustc/src/command-line-arguments.md | 29 ++++++++++++++++----- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index e73fd43f19a51..2026e36e34a05 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -119,7 +119,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 8ff3b463ae2b9..7e9b4833ef0a4 100644 --- a/src/doc/rustc/src/command-line-arguments.md +++ b/src/doc/rustc/src/command-line-arguments.md @@ -16,9 +16,9 @@ For examples, `--cfg 'verbose'` or `--cfg 'feature="serde"'`. These correspond to `#[cfg(verbose)]` and `#[cfg(feature = "serde")]` respectively. ## `-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: @@ -231,15 +231,32 @@ This flag, when combined with other flags, makes them produce extra output. ## `--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. This flag takes an argument with either of the following -formats: +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. +For loading metadata, `rlib` takes precedence over `rmeta`, which takes +precedence over `dylib`. 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 + ## `--sysroot`: Override the system root The "sysroot" is where `rustc` looks for the crates that come with the Rust From 6d4776693d478c2f298139676b691bae9d50f899 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 7 Oct 2019 07:58:28 -0700 Subject: [PATCH 5/8] Update src/test/ui-fulldeps/pathless-extern-unstable.rs Add ERROR Co-Authored-By: Mazdak Farrokhzad --- src/test/ui-fulldeps/pathless-extern-unstable.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui-fulldeps/pathless-extern-unstable.rs b/src/test/ui-fulldeps/pathless-extern-unstable.rs index a5a31816c9572..00b3ec5409ff0 100644 --- a/src/test/ui-fulldeps/pathless-extern-unstable.rs +++ b/src/test/ui-fulldeps/pathless-extern-unstable.rs @@ -5,6 +5,6 @@ // Test that `--extern rustc` fails with `rustc_private`. pub use rustc; -//~^ use of unstable library feature 'rustc_private' +//~^ ERROR use of unstable library feature 'rustc_private' fn main() {} From 5e678cfb2931ce04bc7d5b66308bdbf0a5d46db2 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 8 Oct 2019 09:45:24 -0700 Subject: [PATCH 6/8] Add test for --extern alloc=librustc.rlib --- src/test/run-make-fulldeps/extern-flag-fun/Makefile | 3 +++ src/test/run-make-fulldeps/extern-flag-fun/gated_unstable.rs | 3 +++ src/test/run-make-fulldeps/extern-flag-fun/rustc.rs | 1 + 3 files changed, 7 insertions(+) create mode 100644 src/test/run-make-fulldeps/extern-flag-fun/gated_unstable.rs create mode 100644 src/test/run-make-fulldeps/extern-flag-fun/rustc.rs diff --git a/src/test/run-make-fulldeps/extern-flag-fun/Makefile b/src/test/run-make-fulldeps/extern-flag-fun/Makefile index 7f54d6ea3bc6c..38d1d5bb8488a 100644 --- a/src/test/run-make-fulldeps/extern-flag-fun/Makefile +++ b/src/test/run-make-fulldeps/extern-flag-fun/Makefile @@ -14,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 0000000000000..03600c830fff6 --- /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 0000000000000..b76b4321d62aa --- /dev/null +++ b/src/test/run-make-fulldeps/extern-flag-fun/rustc.rs @@ -0,0 +1 @@ +pub fn foo() {} From 40282a19cd802fdaf952f4b469120df1d876f95b Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 16 Oct 2019 07:37:53 -0700 Subject: [PATCH 7/8] Remove docs on --extern metadata precedence. --- src/doc/rustc/src/command-line-arguments.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md index 7e9b4833ef0a4..c7e802ef156ad 100644 --- a/src/doc/rustc/src/command-line-arguments.md +++ b/src/doc/rustc/src/command-line-arguments.md @@ -246,9 +246,8 @@ either of the following formats: such as within the sysroot or via the `-L` flag. The same crate name may be specified multiple times for different crate types. -For loading metadata, `rlib` takes precedence over `rmeta`, which takes -precedence over `dylib`. If both an `rlib` and `dylib` are found, an internal -algorithm is used to decide which to use for linking. The [`-C prefer-dynamic` +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 From 098ffd9aa23638d2ccfc00c7574b8863ef3dd111 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 16 Oct 2019 09:55:40 -0700 Subject: [PATCH 8/8] Update for unstable option refactoring. --- src/librustc/session/config.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 07fd71632d167..259b24cac8b48 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -2221,7 +2221,6 @@ fn collect_print_requests( cg: &mut CodegenOptions, dopts: &mut DebuggingOptions, matches: &getopts::Matches, - is_unstable_enabled: bool, error_format: ErrorOutputType, ) -> Vec { let mut prints = Vec::::new(); @@ -2263,7 +2262,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( @@ -2427,7 +2426,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( @@ -2533,12 +2531,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, ); @@ -2571,7 +2567,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");