Skip to content

Rollup of 7 pull requests #140869

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

Merged
merged 17 commits into from
May 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
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
152 changes: 76 additions & 76 deletions RELEASES.md

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions compiler/rustc_parse/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -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]

Expand Down
2 changes: 1 addition & 1 deletion src/doc/edition-guide
6 changes: 3 additions & 3 deletions src/librustdoc/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -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,
Expand Down
44 changes: 1 addition & 43 deletions src/librustdoc/doctest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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:?}"))?;
Expand Down Expand Up @@ -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");

Expand Down
22 changes: 0 additions & 22 deletions src/librustdoc/doctest/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
25 changes: 22 additions & 3 deletions src/librustdoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand All @@ -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}"));
}
}
6 changes: 6 additions & 0 deletions src/tools/run-make-support/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
4 changes: 2 additions & 2 deletions src/tools/run-make-support/src/external_deps/rustdoc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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();
Expand Down
12 changes: 12 additions & 0 deletions src/tools/run-make-support/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 5 additions & 3 deletions tests/run-make/broken-pipe-no-ice/rmake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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);
}
5 changes: 3 additions & 2 deletions tests/run-make/rustdoc-default-output/output-default.stdout
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
7 changes: 3 additions & 4 deletions tests/rustdoc-ui/doctest/rustflags-multiple-args.rs
Original file line number Diff line number Diff line change
@@ -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"

Expand Down
2 changes: 1 addition & 1 deletion tests/rustdoc-ui/doctest/rustflags-multiple-args.stdout
Original file line number Diff line number Diff line change
@@ -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

2 changes: 1 addition & 1 deletion tests/rustdoc-ui/doctest/rustflags.rs
Original file line number Diff line number Diff line change
@@ -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"

Expand Down
2 changes: 1 addition & 1 deletion tests/ui/or-patterns/fn-param-wrap-parens.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion tests/ui/or-patterns/fn-param-wrap-parens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion tests/ui/or-patterns/fn-param-wrap-parens.stderr
Original file line number Diff line number Diff line change
@@ -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) {}
Expand Down
10 changes: 5 additions & 5 deletions tests/ui/or-patterns/nested-undelimited-precedence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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() {}
10 changes: 5 additions & 5 deletions tests/ui/or-patterns/nested-undelimited-precedence.stderr
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand Down
Loading
Loading