Skip to content

Rollup of 4 pull requests #66184

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 18 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/doc/rustc/src/codegen-options/index.md
Original file line number Diff line number Diff line change
@@ -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

31 changes: 26 additions & 5 deletions src/doc/rustc/src/command-line-arguments.md
Original file line number Diff line number Diff line change
@@ -20,9 +20,9 @@ to `#[cfg(verbose)]` and `#[cfg(feature = "serde")]` respectively.

<a id="option-l-search-path"></a>
## `-L`: add a directory to the library search path
<a id="option-l-search-path"></a>

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 +262,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
63 changes: 63 additions & 0 deletions src/libcore/mem/maybe_uninit.rs
Original file line number Diff line number Diff line change
@@ -258,6 +258,43 @@ impl<T> MaybeUninit<T> {
MaybeUninit { uninit: () }
}

/// Create a new array of `MaybeUninit<T>` items, in an uninitialized state.
///
/// Note: in a future Rust version this method may become unnecessary
/// when array literal syntax allows
/// [repeating const expressions](https://github.com/rust-lang/rust/issues/49147).
/// The example below could then use `let mut buf = [MaybeUninit::<u8>::uninit(); 32];`.
///
/// # Examples
///
/// ```no_run
/// #![feature(maybe_uninit_uninit_array, maybe_uninit_extra, maybe_uninit_slice_assume_init)]
///
/// use std::mem::MaybeUninit;
///
/// extern "C" {
/// fn read_into_buffer(ptr: *mut u8, max_len: usize) -> usize;
/// }
///
/// /// Returns a (possibly smaller) slice of data that was actually read
/// fn read(buf: &mut [MaybeUninit<u8>]) -> &[u8] {
/// unsafe {
/// let len = read_into_buffer(buf.as_mut_ptr() as *mut u8, buf.len());
/// MaybeUninit::slice_get_ref(&buf[..len])
/// }
/// }
///
/// let mut buf: [MaybeUninit<u8>; 32] = MaybeUninit::uninit_array();
/// let data = read(&mut buf);
/// ```
#[unstable(feature = "maybe_uninit_uninit_array", issue = "0")]
#[inline(always)]
pub fn uninit_array<const LEN: usize>() -> [Self; LEN] {
unsafe {
MaybeUninit::<[MaybeUninit<T>; LEN]>::uninit().assume_init()
}
}

/// A promotable constant, equivalent to `uninit()`.
#[unstable(feature = "internal_uninit_const", issue = "0",
reason = "hack to work around promotability")]
@@ -690,6 +727,32 @@ impl<T> MaybeUninit<T> {
&mut *self.value
}

/// Assuming all the elements are initialized, get a slice to them.
///
/// # Safety
///
/// It is up to the caller to guarantee that the `MaybeUninit<T>` elements
/// really are in an initialized state.
/// Calling this when the content is not yet fully initialized causes undefined behavior.
#[unstable(feature = "maybe_uninit_slice_assume_init", issue = "0")]
#[inline(always)]
pub unsafe fn slice_get_ref(slice: &[Self]) -> &[T] {
&*(slice as *const [Self] as *const [T])
}

/// Assuming all the elements are initialized, get a mutable slice to them.
///
/// # Safety
///
/// It is up to the caller to guarantee that the `MaybeUninit<T>` elements
/// really are in an initialized state.
/// Calling this when the content is not yet fully initialized causes undefined behavior.
#[unstable(feature = "maybe_uninit_slice_assume_init", issue = "0")]
#[inline(always)]
pub unsafe fn slice_get_mut(slice: &mut [Self]) -> &mut [T] {
&mut *(slice as *mut [Self] as *mut [T])
}

/// Gets a pointer to the first element of the array.
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
#[inline(always)]
17 changes: 3 additions & 14 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
@@ -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");

3 changes: 2 additions & 1 deletion src/librustc_lint/builtin.rs
Original file line number Diff line number Diff line change
@@ -2052,7 +2052,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidValue {
);
err.span_label(expr.span,
"this code causes undefined behavior when executed");
err.span_label(expr.span, "help: use `MaybeUninit<T>` instead");
err.span_label(expr.span, "help: use `MaybeUninit<T>` instead, \
and only call `assume_init` after initialization is done");
if let Some(span) = span {
err.span_note(span, &msg);
} else {
4 changes: 0 additions & 4 deletions src/librustdoc/config.rs
Original file line number Diff line number Diff line change
@@ -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)
99 changes: 79 additions & 20 deletions src/librustdoc/html/render.rs
Original file line number Diff line number Diff line change
@@ -1230,36 +1230,95 @@ impl AllTypes {
}
}

#[derive(Debug)]
enum Setting {
Section {
description: &'static str,
sub_settings: Vec<Setting>,
},
Entry {
js_data_name: &'static str,
description: &'static str,
default_value: bool,
}
}

impl Setting {
fn display(&self) -> String {
match *self {
Setting::Section { ref description, ref sub_settings } => {
format!(
"<div class='setting-line'>\
<div class='title'>{}</div>\
<div class='sub-settings'>{}</div>
</div>",
description,
sub_settings.iter().map(|s| s.display()).collect::<String>()
)
}
Setting::Entry { ref js_data_name, ref description, ref default_value } => {
format!(
"<div class='setting-line'>\
<label class='toggle'>\
<input type='checkbox' id='{}' {}>\
<span class='slider'></span>\
</label>\
<div>{}</div>\
</div>",
js_data_name,
if *default_value { " checked" } else { "" },
description,
)
}
}
}
}

impl From<(&'static str, &'static str, bool)> for Setting {
fn from(values: (&'static str, &'static str, bool)) -> Setting {
Setting::Entry {
js_data_name: values.0,
description: values.1,
default_value: values.2,
}
}
}

impl<T: Into<Setting>> From<(&'static str, Vec<T>)> for Setting {
fn from(values: (&'static str, Vec<T>)) -> Setting {
Setting::Section {
description: values.0,
sub_settings: values.1.into_iter().map(|v| v.into()).collect::<Vec<_>>(),
}
}
}

fn settings(root_path: &str, suffix: &str) -> String {
// (id, explanation, default value)
let settings = [
("item-declarations", "Auto-hide item declarations.", true),
("item-attributes", "Auto-hide item attributes.", true),
("trait-implementations", "Auto-hide trait implementations documentation",
true),
("method-docs", "Auto-hide item methods' documentation", false),
let settings: &[Setting] = &[
("Auto-hide item declarations", vec![
("auto-hide-struct", "Auto-hide structs declaration", true),
("auto-hide-enum", "Auto-hide enums declaration", false),
("auto-hide-union", "Auto-hide unions declaration", true),
("auto-hide-trait", "Auto-hide traits declaration", true),
("auto-hide-macro", "Auto-hide macros declaration", false),
]).into(),
("auto-hide-attributes", "Auto-hide item attributes.", true).into(),
("auto-hide-method-docs", "Auto-hide item methods' documentation", false).into(),
("auto-hide-trait-implementations", "Auto-hide trait implementations documentation",
true).into(),
("go-to-only-result", "Directly go to item in search if there is only one result",
false),
("line-numbers", "Show line numbers on code examples", false),
("disable-shortcuts", "Disable keyboard shortcuts", false),
false).into(),
("line-numbers", "Show line numbers on code examples", false).into(),
("disable-shortcuts", "Disable keyboard shortcuts", false).into(),
];
format!(
"<h1 class='fqn'>\
<span class='in-band'>Rustdoc settings</span>\
</h1>\
<div class='settings'>{}</div>\
<script src='{}settings{}.js'></script>",
settings.iter()
.map(|(id, text, enabled)| {
format!("<div class='setting-line'>\
<label class='toggle'>\
<input type='checkbox' id='{}' {}>\
<span class='slider'></span>\
</label>\
<div>{}</div>\
</div>", id, if *enabled { " checked" } else { "" }, text)
})
.collect::<String>(),
settings.iter().map(|s| s.display()).collect::<String>(),
root_path,
suffix)
}
32 changes: 28 additions & 4 deletions src/librustdoc/html/static/main.js
Original file line number Diff line number Diff line change
@@ -2118,7 +2118,7 @@ function getSearchElement() {
function autoCollapse(pageId, collapse) {
if (collapse) {
toggleAllDocs(pageId, true);
} else if (getCurrentValue("rustdoc-trait-implementations") !== "false") {
} else if (getCurrentValue("rustdoc-auto-hide-trait-implementations") !== "false") {
var impl_list = document.getElementById("implementations-list");

if (impl_list !== null) {
@@ -2156,7 +2156,7 @@ function getSearchElement() {
}

var toggle = createSimpleToggle(false);
var hideMethodDocs = getCurrentValue("rustdoc-method-docs") === "true";
var hideMethodDocs = getCurrentValue("rustdoc-auto-hide-method-docs") === "true";
var pageId = getPageId();

var func = function(e) {
@@ -2286,7 +2286,31 @@ function getSearchElement() {
return wrapper;
}

var showItemDeclarations = getCurrentValue("rustdoc-item-declarations") === "false";
var currentType = document.getElementsByClassName("type-decl")[0];
var className = null;
if (currentType) {
currentType = currentType.getElementsByClassName("rust")[0];
if (currentType) {
currentType.classList.forEach(function(item) {
if (item !== "main") {
className = item;
return true;
}
});
}
}
var showItemDeclarations = getCurrentValue("rustdoc-auto-hide-" + className);
if (showItemDeclarations === null) {
if (className === "enum" || className === "macro") {
showItemDeclarations = "false";
} else if (className === "struct" || className === "union" || className === "trait") {
showItemDeclarations = "true";
} else {
// In case we found an unknown type, we just use the "parent" value.
showItemDeclarations = getCurrentValue("rustdoc-auto-hide-declarations");
}
}
showItemDeclarations = showItemDeclarations === "false";
function buildToggleWrapper(e) {
if (hasClass(e, "autohide")) {
var wrap = e.previousElementSibling;
@@ -2369,7 +2393,7 @@ function getSearchElement() {

// To avoid checking on "rustdoc-item-attributes" value on every loop...
var itemAttributesFunc = function() {};
if (getCurrentValue("rustdoc-item-attributes") !== "false") {
if (getCurrentValue("rustdoc-auto-hide-attributes") !== "false") {
itemAttributesFunc = function(x) {
collapseDocs(x.previousSibling.childNodes[0], "toggle");
};
14 changes: 14 additions & 0 deletions src/librustdoc/html/static/settings.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.setting-line {
padding: 5px;
position: relative;
}

.setting-line > div {
@@ -10,6 +11,13 @@
padding-top: 2px;
}

.setting-line > .title {
font-size: 19px;
width: 100%;
max-width: none;
border-bottom: 1px solid;
}

.toggle {
position: relative;
display: inline-block;
@@ -59,3 +67,9 @@ input:checked + .slider:before {
-ms-transform: translateX(19px);
transform: translateX(19px);
}

.setting-line > .sub-settings {
padding-left: 42px;
width: 100%;
display: block;
}
3 changes: 3 additions & 0 deletions src/librustdoc/html/static/themes/dark.css
Original file line number Diff line number Diff line change
@@ -425,3 +425,6 @@ div.files > a:hover, div.name:hover {
div.files > .selected {
background-color: #333;
}
.setting-line > .title {
border-bottom-color: #ddd;
}
3 changes: 3 additions & 0 deletions src/librustdoc/html/static/themes/light.css
Original file line number Diff line number Diff line change
@@ -419,3 +419,6 @@ div.files > a:hover, div.name:hover {
div.files > .selected {
background-color: #fff;
}
.setting-line > .title {
border-bottom-color: #D5D5D5;
}
2 changes: 1 addition & 1 deletion src/librustdoc/lib.rs
Original file line number Diff line number Diff line change
@@ -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",
4 changes: 3 additions & 1 deletion src/test/run-make-fulldeps/extern-flag-fun/Makefile
Original file line number Diff line number Diff line change
@@ -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'
3 changes: 3 additions & 0 deletions src/test/run-make-fulldeps/extern-flag-fun/gated_unstable.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
extern crate alloc;

fn main() {}
1 change: 1 addition & 0 deletions src/test/run-make-fulldeps/extern-flag-fun/rustc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub fn foo() {}
18 changes: 18 additions & 0 deletions src/test/run-make-fulldeps/extern-flag-pathless/Makefile
Original file line number Diff line number Diff line change
@@ -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'
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub fn f() {
println!("dynamic");
}
3 changes: 3 additions & 0 deletions src/test/run-make-fulldeps/extern-flag-pathless/bar-static.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub fn f() {
println!("static");
}
3 changes: 3 additions & 0 deletions src/test/run-make-fulldeps/extern-flag-pathless/foo.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
bar::f();
}
3 changes: 1 addition & 2 deletions src/test/run-make-fulldeps/save-analysis-rfc2126/Makefile
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion src/test/rustdoc/inline_cross/use_crate.rs
Original file line number Diff line number Diff line change
@@ -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
10 changes: 10 additions & 0 deletions src/test/ui-fulldeps/pathless-extern-unstable.rs
Original file line number Diff line number Diff line change
@@ -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() {}
12 changes: 12 additions & 0 deletions src/test/ui-fulldeps/pathless-extern-unstable.stderr
Original file line number Diff line number Diff line change
@@ -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`.
70 changes: 35 additions & 35 deletions src/test/ui/lint/uninitialized-zeroed.stderr

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions src/test/ui/pathless-extern-ok.rs
Original file line number Diff line number Diff line change
@@ -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();
}