Auto merge of #140869 - matthiaskrgr:rollup-r5k19w6, r=matthiaskrgr

Rollup of 7 pull requests

Successful merges:

 - #139863 (rustdoc: Replace unstable flag `--doctest-compilation-args` with a simpler one: `--doctest-build-arg`)
 - #140815 (also export metrics from librustdoc)
 - #140819 (Add regression test for 125877)
 - #140843 (Fix `broken-pipe-no-ice` run-make test for rpath-less builds)
 - #140848 (Improved error message for top-level or-patterns)
 - #140852 (Update the edition guide for let chains)
 - #140864 (Last minute relnotes fix)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2025-05-09 23:48:54 +00:00
commit fd9fad6dbc
29 changed files with 215 additions and 187 deletions

View file

@ -45,83 +45,83 @@ Libraries
Stabilized APIs
---------------
- [`Vec::extract_if`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.extract_if)
- [`vec::ExtractIf`](https://doc.rust-lang.org/nightly/std/vec/struct.ExtractIf.html)
- [`LinkedList::extract_if`](https://doc.rust-lang.org/nightly/std/collections/struct.LinkedList.html#method.extract_if)
- [`linked_list::ExtractIf`](https://doc.rust-lang.org/nightly/std/collections/linked_list/struct.ExtractIf.html)
- [`<[T]>::split_off`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_off)
- [`<[T]>::split_off_mut`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_off_mut)
- [`<[T]>::split_off_first`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_off_first)
- [`<[T]>::split_off_first_mut`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_off_first_mut)
- [`<[T]>::split_off_last`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_off_last)
- [`<[T]>::split_off_last_mut`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_off_last_mut)
- [`Vec::extract_if`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.extract_if)
- [`vec::ExtractIf`](https://doc.rust-lang.org/stable/std/vec/struct.ExtractIf.html)
- [`LinkedList::extract_if`](https://doc.rust-lang.org/stable/std/collections/struct.LinkedList.html#method.extract_if)
- [`linked_list::ExtractIf`](https://doc.rust-lang.org/stable/std/collections/linked_list/struct.ExtractIf.html)
- [`<[T]>::split_off`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_off)
- [`<[T]>::split_off_mut`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_off_mut)
- [`<[T]>::split_off_first`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_off_first)
- [`<[T]>::split_off_first_mut`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_off_first_mut)
- [`<[T]>::split_off_last`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_off_last)
- [`<[T]>::split_off_last_mut`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_off_last_mut)
- [`String::extend_from_within`](https://doc.rust-lang.org/stable/alloc/string/struct.String.html#method.extend_from_within)
- [`os_str::Display`](https://doc.rust-lang.org/nightly/std/ffi/os_str/struct.Display.html)
- [`OsString::display`](https://doc.rust-lang.org/nightly/std/ffi/struct.OsString.html#method.display)
- [`OsStr::display`](https://doc.rust-lang.org/nightly/std/ffi/struct.OsStr.html#method.display)
- [`io::pipe`](https://doc.rust-lang.org/nightly/std/io/fn.pipe.html)
- [`io::PipeReader`](https://doc.rust-lang.org/nightly/std/io/struct.PipeReader.html)
- [`io::PipeWriter`](https://doc.rust-lang.org/nightly/std/io/struct.PipeWriter.html)
- [`impl From<PipeReader> for OwnedHandle`](https://doc.rust-lang.org/nightly/std/os/windows/io/struct.OwnedHandle.html#impl-From%3CPipeReader%3E-for-OwnedHandle)
- [`impl From<PipeWriter> for OwnedHandle`](https://doc.rust-lang.org/nightly/std/os/windows/io/struct.OwnedHandle.html#impl-From%3CPipeWriter%3E-for-OwnedHandle)
- [`impl From<PipeReader> for Stdio`](https://doc.rust-lang.org/nightly/std/process/struct.Stdio.html)
- [`impl From<PipeWriter> for Stdio`](https://doc.rust-lang.org/nightly/std/process/struct.Stdio.html#impl-From%3CPipeWriter%3E-for-Stdio)
- [`impl From<PipeReader> for OwnedFd`](https://doc.rust-lang.org/nightly/std/os/fd/struct.OwnedFd.html#impl-From%3CPipeReader%3E-for-OwnedFd)
- [`impl From<PipeWriter> for OwnedFd`](https://doc.rust-lang.org/nightly/std/os/fd/struct.OwnedFd.html#impl-From%3CPipeWriter%3E-for-OwnedFd)
- [`Box<MaybeUninit<T>>::write`](https://doc.rust-lang.org/nightly/std/boxed/struct.Box.html#method.write)
- [`impl TryFrom<Vec<u8>> for String`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#impl-TryFrom%3CVec%3Cu8%3E%3E-for-String)
- [`os_str::Display`](https://doc.rust-lang.org/stable/std/ffi/os_str/struct.Display.html)
- [`OsString::display`](https://doc.rust-lang.org/stable/std/ffi/struct.OsString.html#method.display)
- [`OsStr::display`](https://doc.rust-lang.org/stable/std/ffi/struct.OsStr.html#method.display)
- [`io::pipe`](https://doc.rust-lang.org/stable/std/io/fn.pipe.html)
- [`io::PipeReader`](https://doc.rust-lang.org/stable/std/io/struct.PipeReader.html)
- [`io::PipeWriter`](https://doc.rust-lang.org/stable/std/io/struct.PipeWriter.html)
- [`impl From<PipeReader> for OwnedHandle`](https://doc.rust-lang.org/stable/std/os/windows/io/struct.OwnedHandle.html#impl-From%3CPipeReader%3E-for-OwnedHandle)
- [`impl From<PipeWriter> for OwnedHandle`](https://doc.rust-lang.org/stable/std/os/windows/io/struct.OwnedHandle.html#impl-From%3CPipeWriter%3E-for-OwnedHandle)
- [`impl From<PipeReader> for Stdio`](https://doc.rust-lang.org/stable/std/process/struct.Stdio.html)
- [`impl From<PipeWriter> for Stdio`](https://doc.rust-lang.org/stable/std/process/struct.Stdio.html#impl-From%3CPipeWriter%3E-for-Stdio)
- [`impl From<PipeReader> for OwnedFd`](https://doc.rust-lang.org/stable/std/os/fd/struct.OwnedFd.html#impl-From%3CPipeReader%3E-for-OwnedFd)
- [`impl From<PipeWriter> for OwnedFd`](https://doc.rust-lang.org/stable/std/os/fd/struct.OwnedFd.html#impl-From%3CPipeWriter%3E-for-OwnedFd)
- [`Box<MaybeUninit<T>>::write`](https://doc.rust-lang.org/stable/std/boxed/struct.Box.html#method.write)
- [`impl TryFrom<Vec<u8>> for String`](https://doc.rust-lang.org/stable/std/string/struct.String.html#impl-TryFrom%3CVec%3Cu8%3E%3E-for-String)
- [`<*const T>::offset_from_unsigned`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.offset_from_unsigned)
- [`<*const T>::byte_offset_from_unsigned`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.byte_offset_from_unsigned)
- [`<*mut T>::offset_from_unsigned`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.offset_from_unsigned-1)
- [`<*mut T>::byte_offset_from_unsigned`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.byte_offset_from_unsigned-1)
- [`NonNull::offset_from_unsigned`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.offset_from_unsigned)
- [`NonNull::byte_offset_from_unsigned`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.byte_offset_from_unsigned)
- [`<uN>::cast_signed`](https://doc.rust-lang.org/stable/std/primitive.usize.html#method.cast_signed)
- [`NonZero::<uN>::cast_signed`](https://doc.rust-lang.org/stable/std/num/struct.NonZero.html#method.cast_signed-5).
- [`<iN>::cast_unsigned`](https://doc.rust-lang.org/stable/std/primitive.isize.html#method.cast_unsigned).
- [`NonZero::<iN>::cast_unsigned`](https://doc.rust-lang.org/stable/std/num/struct.NonZero.html#method.cast_unsigned-5).
- [`<uN>::is_multiple_of`](https://doc.rust-lang.org/stable/std/primitive.usize.html#method.is_multiple_of)
- [`<uN>::unbounded_shl`](https://doc.rust-lang.org/stable/std/primitive.usize.html#method.unbounded_shl)
- [`<uN>::unbounded_shr`](https://doc.rust-lang.org/stable/std/primitive.usize.html#method.unbounded_shr)
- [`<iN>::unbounded_shl`](https://doc.rust-lang.org/stable/std/primitive.isize.html#method.unbounded_shl)
- [`<iN>::unbounded_shr`](https://doc.rust-lang.org/stable/std/primitive.isize.html#method.unbounded_shr)
- [`<iN>::midpoint`](https://doc.rust-lang.org/stable/std/primitive.isize.html#method.midpoint)
- [`<str>::from_utf8`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.from_utf8)
- [`<str>::from_utf8_mut`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.from_utf8_mut)
- [`<str>::from_utf8_unchecked`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.from_utf8_unchecked)
- [`<str>::from_utf8_unchecked_mut`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.from_utf8_unchecked_mut)
These APIs are now stable in const contexts:
These previously stable APIs are now stable in const contexts:
- [`<*const T>::offset_from_unsigned`](https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.offset_from_unsigned)
- [`<*const T>::byte_offset_from_unsigned`](https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.byte_offset_from_unsigned)
- [`<*mut T>::offset_from_unsigned`](https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.offset_from_unsigned-1)
- [`<*mut T>::byte_offset_from_unsigned`](https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.byte_offset_from_unsigned-1)
- [`NonNull::offset_from_unsigned`](https://doc.rust-lang.org/nightly/std/ptr/struct.NonNull.html#method.offset_from_unsigned)
- [`NonNull::byte_offset_from_unsigned`](https://doc.rust-lang.org/nightly/std/ptr/struct.NonNull.html#method.byte_offset_from_unsigned)
- [`<uN>::cast_signed`](https://doc.rust-lang.org/nightly/std/primitive.usize.html#method.cast_signed)
- [`NonZero::<uN>::cast_signed`](https://doc.rust-lang.org/nightly/std/num/struct.NonZero.html#method.cast_signed-5).
- [`<iN>::cast_signed`](https://doc.rust-lang.org/nightly/std/primitive.isize.html#method.cast_signed).
- [`NonZero::<iN>::cast_unsigned`](https://doc.rust-lang.org/nightly/std/num/struct.NonZero.html#method.cast_unsigned-5).
- [`<uN>::is_multiple_of`](https://doc.rust-lang.org/nightly/std/primitive.usize.html#method.is_multiple_of)
- [`<uN>::unbounded_shl`](https://doc.rust-lang.org/nightly/std/primitive.usize.html#method.unbounded_shl)
- [`<uN>::unbounded_shr`](https://doc.rust-lang.org/nightly/std/primitive.usize.html#method.unbounded_shr)
- [`<iN>::unbounded_shl`](https://doc.rust-lang.org/nightly/std/primitive.isize.html#method.unbounded_shl)
- [`<iN>::unbounded_shr`](https://doc.rust-lang.org/nightly/std/primitive.isize.html#method.unbounded_shr)
- [`<str>::from_utf8`](https://doc.rust-lang.org/nightly/std/primitive.str.html#method.from_utf8)
- [`<str>::from_utf8_mut`](https://doc.rust-lang.org/nightly/std/primitive.str.html#method.from_utf8_mut)
- [`<str>::from_utf8_unchecked`](https://doc.rust-lang.org/nightly/std/primitive.str.html#method.from_utf8_unchecked)
- [`<str>::from_utf8_unchecked_mut`](https://doc.rust-lang.org/nightly/std/primitive.str.html#method.from_utf8_unchecked_mut)
- [`core::str::from_utf8_mut`](https://doc.rust-lang.org/nightly/std/str/fn.from_utf8_mut.html)
- [`<[T]>::copy_from_slice`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.copy_from_slice)
- [`SocketAddr::set_ip`](https://doc.rust-lang.org/nightly/std/net/enum.SocketAddr.html#method.set_ip)
- [`SocketAddr::set_port`](https://doc.rust-lang.org/nightly/std/net/enum.SocketAddr.html#method.set_port),
- [`SocketAddrV4::set_ip`](https://doc.rust-lang.org/nightly/std/net/struct.SocketAddrV4.html#method.set_ip)
- [`SocketAddrV4::set_port`](https://doc.rust-lang.org/nightly/std/net/struct.SocketAddrV4.html#method.set_port),
- [`SocketAddrV6::set_ip`](https://doc.rust-lang.org/nightly/std/net/struct.SocketAddrV6.html#method.set_ip)
- [`SocketAddrV6::set_port`](https://doc.rust-lang.org/nightly/std/net/struct.SocketAddrV6.html#method.set_port)
- [`SocketAddrV6::set_flowinfo`](https://doc.rust-lang.org/nightly/std/net/struct.SocketAddrV6.html#method.set_flowinfo)
- [`SocketAddrV6::set_scope_id`](https://doc.rust-lang.org/nightly/std/net/struct.SocketAddrV6.html#method.set_scope_id)
- [`char::is_digit`](https://doc.rust-lang.org/nightly/std/primitive.char.html#method.is_digit)
- [`char::is_whitespace`](https://doc.rust-lang.org/nightly/std/primitive.char.html#method.is_whitespace)
- [`<iN>::midpoint`](https://doc.rust-lang.org/std/primitive.isize.html#method.midpoint)
- [`<[[T; N]]>::as_flattened`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.as_flattened)
- [`<[[T; N]]>::as_flattened_mut`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.as_flattened_mut)
- [`String::into_bytes`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.into_bytes)
- [`String::as_str`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.as_str)
- [`String::capacity`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.capacity)
- [`String::as_bytes`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.as_bytes)
- [`String::len`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.len)
- [`String::is_empty`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.is_empty)
- [`String::as_mut_str`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.as_mut_str)
- [`String::as_mut_vec`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.as_mut_vec)
- [`Vec::as_ptr`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.as_ptr)
- [`Vec::as_slice`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.as_slice)
- [`Vec::capacity`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.capacity)
- [`Vec::len`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.len)
- [`Vec::is_empty`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.is_empty)
- [`Vec::as_mut_slice`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.as_mut_slice)
- [`Vec::as_mut_ptr`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.as_mut_ptr)
- [`core::str::from_utf8_mut`](https://doc.rust-lang.org/stable/std/str/fn.from_utf8_mut.html)
- [`<[T]>::copy_from_slice`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.copy_from_slice)
- [`SocketAddr::set_ip`](https://doc.rust-lang.org/stable/std/net/enum.SocketAddr.html#method.set_ip)
- [`SocketAddr::set_port`](https://doc.rust-lang.org/stable/std/net/enum.SocketAddr.html#method.set_port),
- [`SocketAddrV4::set_ip`](https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV4.html#method.set_ip)
- [`SocketAddrV4::set_port`](https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV4.html#method.set_port),
- [`SocketAddrV6::set_ip`](https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV6.html#method.set_ip)
- [`SocketAddrV6::set_port`](https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV6.html#method.set_port)
- [`SocketAddrV6::set_flowinfo`](https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV6.html#method.set_flowinfo)
- [`SocketAddrV6::set_scope_id`](https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV6.html#method.set_scope_id)
- [`char::is_digit`](https://doc.rust-lang.org/stable/std/primitive.char.html#method.is_digit)
- [`char::is_whitespace`](https://doc.rust-lang.org/stable/std/primitive.char.html#method.is_whitespace)
- [`<[[T; N]]>::as_flattened`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.as_flattened)
- [`<[[T; N]]>::as_flattened_mut`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.as_flattened_mut)
- [`String::into_bytes`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.into_bytes)
- [`String::as_str`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.as_str)
- [`String::capacity`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.capacity)
- [`String::as_bytes`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.as_bytes)
- [`String::len`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.len)
- [`String::is_empty`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.is_empty)
- [`String::as_mut_str`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.as_mut_str)
- [`String::as_mut_vec`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.as_mut_vec)
- [`Vec::as_ptr`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.as_ptr)
- [`Vec::as_slice`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.as_slice)
- [`Vec::capacity`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.capacity)
- [`Vec::len`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.len)
- [`Vec::is_empty`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.is_empty)
- [`Vec::as_mut_slice`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.as_mut_slice)
- [`Vec::as_mut_ptr`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.as_mut_ptr)
<a id="1.87.0-Cargo"></a>

View file

@ -690,8 +690,8 @@ parse_nul_in_c_str = null characters in C string literals are not supported
parse_or_in_let_chain = `||` operators are not supported in let chain conditions
parse_or_pattern_not_allowed_in_fn_parameters = top-level or-patterns are not allowed in function parameters
parse_or_pattern_not_allowed_in_let_binding = top-level or-patterns are not allowed in `let` bindings
parse_or_pattern_not_allowed_in_fn_parameters = function parameters require top-level or-patterns in parentheses
parse_or_pattern_not_allowed_in_let_binding = `let` bindings require top-level or-patterns in parentheses
parse_out_of_range_hex_escape = out of range hex escape
.label = must be a character in the range [\x00-\x7f]

@ -1 +1 @@
Subproject commit 467f45637b73ec6aa70fb36bc3054bb50b8967ea
Subproject commit 1b1bb49babd65c732468cfa515b0c009bd1d26bc

View file

@ -174,7 +174,7 @@ pub(crate) struct Options {
pub(crate) expanded_args: Vec<String>,
/// Arguments to be used when compiling doctests.
pub(crate) doctest_compilation_args: Vec<String>,
pub(crate) doctest_build_args: Vec<String>,
}
impl fmt::Debug for Options {
@ -802,7 +802,7 @@ impl Options {
let scrape_examples_options = ScrapeExamplesOptions::new(matches, dcx);
let with_examples = matches.opt_strs("with-examples");
let call_locations = crate::scrape_examples::load_call_locations(with_examples, dcx);
let doctest_compilation_args = matches.opt_strs("doctest-compilation-args");
let doctest_build_args = matches.opt_strs("doctest-build-arg");
let unstable_features =
rustc_feature::UnstableFeatures::from_environment(crate_name.as_deref());
@ -851,7 +851,7 @@ impl Options {
scrape_examples_options,
unstable_features,
expanded_args: args,
doctest_compilation_args,
doctest_build_args,
};
let render_options = RenderOptions {
output,

View file

@ -51,46 +51,6 @@ pub(crate) struct GlobalTestOptions {
pub(crate) args_file: PathBuf,
}
/// Function used to split command line arguments just like a shell would.
fn split_args(args: &str) -> Vec<String> {
let mut out = Vec::new();
let mut iter = args.chars();
let mut current = String::new();
while let Some(c) = iter.next() {
if c == '\\' {
if let Some(c) = iter.next() {
// If it's escaped, even a quote or a whitespace will be ignored.
current.push(c);
}
} else if c == '"' || c == '\'' {
while let Some(new_c) = iter.next() {
if new_c == c {
break;
} else if new_c == '\\' {
if let Some(c) = iter.next() {
// If it's escaped, even a quote will be ignored.
current.push(c);
}
} else {
current.push(new_c);
}
}
} else if " \n\t\r".contains(c) {
if !current.is_empty() {
out.push(current.clone());
current.clear();
}
} else {
current.push(c);
}
}
if !current.is_empty() {
out.push(current);
}
out
}
pub(crate) fn generate_args_file(file_path: &Path, options: &RustdocOptions) -> Result<(), String> {
let mut file = File::create(file_path)
.map_err(|error| format!("failed to create args file: {error:?}"))?;
@ -119,9 +79,7 @@ pub(crate) fn generate_args_file(file_path: &Path, options: &RustdocOptions) ->
content.push(format!("-Z{unstable_option_str}"));
}
for compilation_args in &options.doctest_compilation_args {
content.extend(split_args(compilation_args));
}
content.extend(options.doctest_build_args.clone());
let content = content.join("\n");

View file

@ -381,28 +381,6 @@ fn main() {
assert_eq!((output, len), (expected, 1));
}
#[test]
fn check_split_args() {
fn compare(input: &str, expected: &[&str]) {
let output = super::split_args(input);
let expected = expected.iter().map(|s| s.to_string()).collect::<Vec<_>>();
assert_eq!(expected, output, "test failed for {input:?}");
}
compare("'a' \"b\"c", &["a", "bc"]);
compare("'a' \"b \"c d", &["a", "b c", "d"]);
compare("'a' \"b\\\"c\"", &["a", "b\"c"]);
compare("'a\"'", &["a\""]);
compare("\"a'\"", &["a'"]);
compare("\\ a", &[" a"]);
compare("\\\\", &["\\"]);
compare("a'", &["a"]);
compare("a ", &["a"]);
compare("a b", &["a", "b"]);
compare("a\n\t \rb", &["a", "b"]);
compare("a\n\t1 \rb", &["a", "1", "b"]);
}
#[test]
fn comment_in_attrs() {
// If there is an inline code comment after attributes, we need to ensure that

View file

@ -73,9 +73,11 @@ extern crate tikv_jemalloc_sys as jemalloc_sys;
use std::env::{self, VarError};
use std::io::{self, IsTerminal};
use std::path::Path;
use std::process;
use rustc_errors::DiagCtxtHandle;
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_interface::interface;
use rustc_middle::ty::TyCtxt;
use rustc_session::config::{ErrorOutputType, RustcOptGroup, make_crate_type_option};
@ -654,9 +656,9 @@ fn opts() -> Vec<RustcOptGroup> {
Unstable,
Multi,
"",
"doctest-compilation-args",
"",
"add arguments to be used when compiling doctests",
"doctest-build-arg",
"One argument (of possibly many) to be used when compiling doctests",
"ARG",
),
opt(
Unstable,
@ -904,6 +906,10 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) {
rustc_interface::passes::write_dep_info(tcx);
}
if let Some(metrics_dir) = &sess.opts.unstable_opts.metrics_dir {
dump_feature_usage_metrics(tcx, metrics_dir);
}
if run_check {
// Since we're in "check" mode, no need to generate anything beyond this point.
return;
@ -923,3 +929,16 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) {
})
})
}
fn dump_feature_usage_metrics(tcxt: TyCtxt<'_>, metrics_dir: &Path) {
let hash = tcxt.crate_hash(LOCAL_CRATE);
let crate_name = tcxt.crate_name(LOCAL_CRATE);
let metrics_file_name = format!("unstable_feature_usage_metrics-{crate_name}-{hash}.json");
let metrics_path = metrics_dir.join(metrics_file_name);
if let Err(error) = tcxt.features().dump_feature_usage_metrics(metrics_path) {
// FIXME(yaahc): once metrics can be enabled by default we will want "failure to emit
// default metrics" to only produce a warning when metrics are enabled by default and emit
// an error only when the user manually enables metrics
tcxt.dcx().err(format!("cannot emit feature usage metrics: {error}"));
}
}

View file

@ -63,6 +63,12 @@ impl Command {
}
}
// Internal-only.
pub(crate) fn into_raw_command(mut self) -> std::process::Command {
self.drop_bomb.defuse();
self.cmd
}
/// Specify a stdin input buffer. This is a convenience helper,
pub fn stdin_buf<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
self.stdin_buf = Some(input.as_ref().to_vec().into_boxed_slice());

View file

@ -5,7 +5,7 @@ use crate::command::Command;
use crate::env::env_var;
use crate::util::set_host_compiler_dylib_path;
/// Construct a new `rustdoc` invocation.
/// Construct a new `rustdoc` invocation. This will configure the host compiler runtime libs.
#[track_caller]
pub fn rustdoc() -> Rustdoc {
Rustdoc::new()
@ -28,7 +28,7 @@ fn setup_common() -> Command {
}
impl Rustdoc {
/// Construct a bare `rustdoc` invocation.
/// Construct a bare `rustdoc` invocation. This will configure the host compiler runtime libs.
#[track_caller]
pub fn new() -> Self {
let cmd = setup_common();

View file

@ -28,6 +28,18 @@
macro_rules! impl_common_helpers {
($wrapper: ident) => {
impl $wrapper {
/// In very rare circumstances, you may need a e.g. `bare_rustc()` or `bare_rustdoc()`
/// with host runtime libs configured, but want the underlying raw
/// [`std::process::Command`] (e.g. for manipulating pipes or whatever). This function
/// will consume the command wrapper and extract the underlying
/// [`std::process::Command`].
///
/// Caution: this will mean that you can no longer use the convenience methods on the
/// command wrapper. Use as a last resort.
pub fn into_raw_command(self) -> ::std::process::Command {
self.cmd.into_raw_command()
}
/// Specify an environment variable.
pub fn env<K, V>(&mut self, key: K, value: V) -> &mut Self
where

View file

@ -14,7 +14,7 @@
use std::io::Read;
use std::process::{Command, Stdio};
use run_make_support::env_var;
use run_make_support::{bare_rustc, rustdoc};
#[derive(Debug, PartialEq)]
enum Binary {
@ -67,11 +67,13 @@ fn check_broken_pipe_handled_gracefully(bin: Binary, mut cmd: Command) {
}
fn main() {
let mut rustc = Command::new(env_var("RUSTC"));
let mut rustc = bare_rustc();
rustc.arg("--print=sysroot");
let rustc = rustc.into_raw_command();
check_broken_pipe_handled_gracefully(Binary::Rustc, rustc);
let mut rustdoc = Command::new(env_var("RUSTDOC"));
let mut rustdoc = rustdoc();
rustdoc.arg("--version");
let rustdoc = rustdoc.into_raw_command();
check_broken_pipe_handled_gracefully(Binary::Rustdoc, rustdoc);
}

View file

@ -188,8 +188,9 @@ Options:
from provided path. Only use with --merge=finalize
--html-no-source
Disable HTML source code pages generation
--doctest-compilation-args add arguments to be used when compiling doctests
--doctest-build-arg ARG
One argument (of possibly many) to be used when
compiling doctests
--disable-minification
disable the minification of CSS/JS files
(perma-unstable, do not use with cached files)

View file

@ -1,9 +1,8 @@
// This test checks that the test behave when `--doctest-compilation-args` is passed
// multiple times.
// This test checks that the test behave when `--doctest-build-arg` is passed multiple times.
//@ check-pass
//@ compile-flags: --test -Zunstable-options --doctest-compilation-args=--cfg=testcase_must_be_present
//@ compile-flags: --doctest-compilation-args=--cfg=another
//@ compile-flags: --test -Zunstable-options --doctest-build-arg=--cfg=testcase_must_be_present
//@ compile-flags: --doctest-build-arg=--cfg=another
//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR"
//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"

View file

@ -1,6 +1,6 @@
running 1 test
test $DIR/rustflags-multiple-args.rs - Bar (line 10) ... ok
test $DIR/rustflags-multiple-args.rs - Bar (line 9) ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME

View file

@ -1,5 +1,5 @@
//@ check-pass
//@ compile-flags: --test -Zunstable-options --doctest-compilation-args=--cfg=testcase_must_be_present
//@ compile-flags: --test -Zunstable-options --doctest-build-arg=--cfg=testcase_must_be_present
//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR"
//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"

View file

@ -10,4 +10,4 @@ enum E { A, B }
use E::*;
#[cfg(false)]
fn fun1((A | B): E) {} //~ ERROR top-level or-patterns are not allowed
fn fun1((A | B): E) {} //~ ERROR function parameters require top-level or-patterns in parentheses

View file

@ -10,4 +10,4 @@ enum E { A, B }
use E::*;
#[cfg(false)]
fn fun1(A | B: E) {} //~ ERROR top-level or-patterns are not allowed
fn fun1(A | B: E) {} //~ ERROR function parameters require top-level or-patterns in parentheses

View file

@ -1,4 +1,4 @@
error: top-level or-patterns are not allowed in function parameters
error: function parameters require top-level or-patterns in parentheses
--> $DIR/fn-param-wrap-parens.rs:13:9
|
LL | fn fun1(A | B: E) {}

View file

@ -17,7 +17,7 @@ fn foo() {
let b @ (A | B): E = A;
let b @ A | B: E = A; //~ERROR `b` is not bound in all patterns
//~^ ERROR top-level or-patterns are not allowed
//~^ ERROR `let` bindings require top-level or-patterns in parentheses
}
enum F {
@ -32,13 +32,13 @@ fn bar() {
let (A(x) | B(x)): F = A(3);
let &A(_) | B(_): F = A(3); //~ERROR mismatched types
//~^ ERROR top-level or-patterns are not allowed
//~^ ERROR `let` bindings require top-level or-patterns in parentheses
let &&A(_) | B(_): F = A(3); //~ERROR mismatched types
//~^ ERROR top-level or-patterns are not allowed
//~^ ERROR `let` bindings require top-level or-patterns in parentheses
let &mut A(_) | B(_): F = A(3); //~ERROR mismatched types
//~^ ERROR top-level or-patterns are not allowed
//~^ ERROR `let` bindings require top-level or-patterns in parentheses
let &&mut A(_) | B(_): F = A(3); //~ERROR mismatched types
//~^ ERROR top-level or-patterns are not allowed
//~^ ERROR `let` bindings require top-level or-patterns in parentheses
}
fn main() {}

View file

@ -1,4 +1,4 @@
error: top-level or-patterns are not allowed in `let` bindings
error: `let` bindings require top-level or-patterns in parentheses
--> $DIR/nested-undelimited-precedence.rs:19:9
|
LL | let b @ A | B: E = A;
@ -9,7 +9,7 @@ help: wrap the pattern in parentheses
LL | let (b @ A | B): E = A;
| + +
error: top-level or-patterns are not allowed in `let` bindings
error: `let` bindings require top-level or-patterns in parentheses
--> $DIR/nested-undelimited-precedence.rs:34:9
|
LL | let &A(_) | B(_): F = A(3);
@ -20,7 +20,7 @@ help: wrap the pattern in parentheses
LL | let (&A(_) | B(_)): F = A(3);
| + +
error: top-level or-patterns are not allowed in `let` bindings
error: `let` bindings require top-level or-patterns in parentheses
--> $DIR/nested-undelimited-precedence.rs:36:9
|
LL | let &&A(_) | B(_): F = A(3);
@ -31,7 +31,7 @@ help: wrap the pattern in parentheses
LL | let (&&A(_) | B(_)): F = A(3);
| + +
error: top-level or-patterns are not allowed in `let` bindings
error: `let` bindings require top-level or-patterns in parentheses
--> $DIR/nested-undelimited-precedence.rs:38:9
|
LL | let &mut A(_) | B(_): F = A(3);
@ -42,7 +42,7 @@ help: wrap the pattern in parentheses
LL | let (&mut A(_) | B(_)): F = A(3);
| + +
error: top-level or-patterns are not allowed in `let` bindings
error: `let` bindings require top-level or-patterns in parentheses
--> $DIR/nested-undelimited-precedence.rs:40:9
|
LL | let &&mut A(_) | B(_): F = A(3);

View file

@ -16,18 +16,18 @@ fn no_top_level_or_patterns() {
fn no_top_level_or_patterns_2() {
// ...and for now neither do we allow or-patterns at the top level of functions.
fn fun1(A | B: E) {}
//~^ ERROR top-level or-patterns are not allowed
//~^ ERROR function parameters require top-level or-patterns in parentheses
fn fun2(| A | B: E) {}
//~^ ERROR top-level or-patterns are not allowed
//~^ ERROR function parameters require top-level or-patterns in parentheses
// We don't allow top-level or-patterns before type annotation in let-statements because we
// want to reserve this syntactic space for possible future type ascription.
let A | B: E = A;
//~^ ERROR top-level or-patterns are not allowed
//~^ ERROR `let` bindings require top-level or-patterns in parentheses
let | A | B: E = A;
//~^ ERROR top-level or-patterns are not allowed
//~^ ERROR `let` bindings require top-level or-patterns in parentheses
let (A | B): E = A; // ok -- wrapped in parens
}

View file

@ -11,7 +11,7 @@ help: you might have meant to open the body of the closure
LL | let _ = |A | { B: E| ();
| +
error: top-level or-patterns are not allowed in function parameters
error: function parameters require top-level or-patterns in parentheses
--> $DIR/or-patterns-syntactic-fail.rs:18:13
|
LL | fn fun1(A | B: E) {}
@ -22,7 +22,7 @@ help: wrap the pattern in parentheses
LL | fn fun1((A | B): E) {}
| + +
error: top-level or-patterns are not allowed in function parameters
error: function parameters require top-level or-patterns in parentheses
--> $DIR/or-patterns-syntactic-fail.rs:21:13
|
LL | fn fun2(| A | B: E) {}
@ -33,7 +33,7 @@ help: wrap the pattern in parentheses
LL | fn fun2((| A | B): E) {}
| + +
error: top-level or-patterns are not allowed in `let` bindings
error: `let` bindings require top-level or-patterns in parentheses
--> $DIR/or-patterns-syntactic-fail.rs:26:9
|
LL | let A | B: E = A;
@ -44,7 +44,7 @@ help: wrap the pattern in parentheses
LL | let (A | B): E = A;
| + +
error: top-level or-patterns are not allowed in `let` bindings
error: `let` bindings require top-level or-patterns in parentheses
--> $DIR/or-patterns-syntactic-fail.rs:29:9
|
LL | let | A | B: E = A;

View file

@ -8,7 +8,7 @@ fn main() {}
#[cfg(false)]
fn leading() {
fn fun1( A: E) {} //~ ERROR top-level or-patterns are not allowed
fn fun1( A: E) {} //~ ERROR function parameters require top-level or-patterns in parentheses
fn fun2( A: E) {} //~ ERROR unexpected `||` before function parameter
let ( | A): E;
let ( | A): (E); //~ ERROR unexpected token `||` in pattern

View file

@ -8,7 +8,7 @@ fn main() {}
#[cfg(false)]
fn leading() {
fn fun1( | A: E) {} //~ ERROR top-level or-patterns are not allowed
fn fun1( | A: E) {} //~ ERROR function parameters require top-level or-patterns in parentheses
fn fun2( || A: E) {} //~ ERROR unexpected `||` before function parameter
let ( | A): E;
let ( || A): (E); //~ ERROR unexpected token `||` in pattern

View file

@ -1,4 +1,4 @@
error: top-level or-patterns are not allowed in function parameters
error: function parameters require top-level or-patterns in parentheses
--> $DIR/remove-leading-vert.rs:11:14
|
LL | fn fun1( | A: E) {}

View file

@ -65,7 +65,7 @@ fn parse(x: Void) {
let res: Result<bool, Void> = Ok(false);
let Ok(_) = res;
let Ok(_) | Err(!) = &res; // Disallowed; see #82048.
//~^ ERROR top-level or-patterns are not allowed in `let` bindings
//~^ ERROR `let` bindings require top-level or-patterns in parentheses
let (Ok(_) | Err(!)) = &res;
let (Ok(_) | Err(&!)) = res.as_ref();

View file

@ -26,7 +26,7 @@ error: expected one of `,`, `=>`, `if`, `|`, or `}`, found `<=`
LL | Some(!) <=
| ^^ expected one of `,`, `=>`, `if`, `|`, or `}`
error: top-level or-patterns are not allowed in `let` bindings
error: `let` bindings require top-level or-patterns in parentheses
--> $DIR/parse.rs:67:9
|
LL | let Ok(_) | Err(!) = &res; // Disallowed; see #82048.

View file

@ -0,0 +1,32 @@
// This test demonstrates an ICE that may occur when we try to resolve the instance
// of a impl that has different generics than the trait it's implementing. This ensures
// we first check that the args are compatible before resolving the body, just like
// we do in projection before substituting a GAT.
//
// Regression test for issue #125877.
//@ compile-flags: -Znext-solver
#![feature(const_trait_impl, effects)]
//~^ ERROR feature has been removed
#[const_trait]
trait Main {
fn compute<T: ~const Aux>() -> u32;
}
impl const Main for () {
fn compute<'x>() -> u32 {
//~^ ERROR associated function `compute` has 0 type parameters but its trait declaration has 1 type parameter
0
}
}
#[const_trait]
trait Aux {}
impl const Aux for () {}
fn main() {
const _: u32 = <()>::compute::<()>();
}

View file

@ -0,0 +1,21 @@
error[E0557]: feature has been removed
--> $DIR/const-trait-impl-parameter-mismatch.rs:10:30
|
LL | #![feature(const_trait_impl, effects)]
| ^^^^^^^ feature has been removed
|
= note: removed, redundant with `#![feature(const_trait_impl)]`
error[E0049]: associated function `compute` has 0 type parameters but its trait declaration has 1 type parameter
--> $DIR/const-trait-impl-parameter-mismatch.rs:19:16
|
LL | fn compute<T: ~const Aux>() -> u32;
| - expected 1 type parameter
...
LL | fn compute<'x>() -> u32 {
| ^^ found 0 type parameters
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0049, E0557.
For more information about an error, try `rustc --explain E0049`.