Skip to content
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

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