Merge remote-tracking branch 'origin/master' into subtree_sync_with_1.77.0_nightly_2023_12_27

This commit is contained in:
Yacin Tmimi 2023-12-28 16:50:17 -05:00
commit 6cc513f5e5
21 changed files with 286 additions and 36 deletions

View File

@ -1098,7 +1098,7 @@ See also [`format_macro_bodies`](#format_macro_bodies).
## `format_macro_bodies`
Format the bodies of macros.
Format the bodies of declarative macro definitions.
- **Default value**: `true`
- **Possible values**: `true`, `false`
@ -1248,12 +1248,20 @@ Control the case of the letters in hexadecimal literal values
## `hide_parse_errors`
Do not show parse errors if the parser failed to parse files.
This option is deprecated and has been renamed to `show_parse_errors` to avoid confusion around the double negative default of `hide_parse_errors=false`.
- **Default value**: `false`
- **Possible values**: `true`, `false`
- **Stable**: No (tracking issue: [#3390](https://github.com/rust-lang/rustfmt/issues/3390))
## `show_parse_errors`
Show parse errors if the parser failed to parse files.
- **Default value**: `true`
- **Possible values**: `true`, `false`
- **Stable**: No (tracking issue: [#5977](https://github.com/rust-lang/rustfmt/issues/5977))
## `ignore`
Skip formatting files and directories that match the specified pattern.

View File

@ -2,9 +2,6 @@
set -e
# https://github.com/rust-lang/rustfmt/issues/5675
export LD_LIBRARY_PATH=$(rustc --print sysroot)/lib:$LD_LIBRARY_PATH
function print_usage() {
echo "usage check_diff REMOTE_REPO FEATURE_BRANCH [COMMIT_HASH] [OPTIONAL_RUSTFMT_CONFIGS]"
}
@ -114,15 +111,42 @@ function compile_rustfmt() {
git remote add feature $REMOTE_REPO
git fetch feature $FEATURE_BRANCH
cargo build --release --bin rustfmt && cp target/release/rustfmt $1/rustfmt
CARGO_VERSON=$(cargo --version)
echo -e "\ncompiling with $CARGO_VERSON\n"
# Because we're building standalone binaries we need to set `LD_LIBRARY_PATH` so each
# binary can find it's runtime dependencies. See https://github.com/rust-lang/rustfmt/issues/5675
# This will prepend the `LD_LIBRARY_PATH` for the master rustfmt binary
export LD_LIBRARY_PATH=$(rustc --print sysroot)/lib:$LD_LIBRARY_PATH
echo "Building rustfmt from src"
cargo build -q --release --bin rustfmt && cp target/release/rustfmt $1/rustfmt
if [ -z "$OPTIONAL_COMMIT_HASH" ] || [ "$FEATURE_BRANCH" = "$OPTIONAL_COMMIT_HASH" ]; then
git switch $FEATURE_BRANCH
else
git switch $OPTIONAL_COMMIT_HASH --detach
fi
cargo build --release --bin rustfmt && cp target/release/rustfmt $1/feature_rustfmt
# This will prepend the `LD_LIBRARY_PATH` for the feature branch rustfmt binary.
# In most cases the `LD_LIBRARY_PATH` should be the same for both rustfmt binaries that we build
# in `compile_rustfmt`, however, there are scenarios where each binary has different runtime
# dependencies. For example, during subtree syncs we bump the nightly toolchain required to build
# rustfmt, and therefore the feature branch relies on a newer set of runtime dependencies.
export LD_LIBRARY_PATH=$(rustc --print sysroot)/lib:$LD_LIBRARY_PATH
echo "Building feature rustfmt from src"
cargo build -q --release --bin rustfmt && cp target/release/rustfmt $1/feature_rustfmt
echo -e "\nRuntime dependencies for rustfmt -- LD_LIBRARY_PATH: $LD_LIBRARY_PATH"
RUSFMT_BIN=$1/rustfmt
RUSTFMT_VERSION=$($RUSFMT_BIN --version)
echo -e "\nRUSFMT_BIN $RUSTFMT_VERSION\n"
FEATURE_BIN=$1/feature_rustfmt
FEATURE_VERSION=$($FEATURE_BIN --version)
echo -e "FEATURE_BIN $FEATURE_VERSION\n"
}
# Check the diff for running rustfmt and the feature branch on all the .rs files in the repo.
@ -155,7 +179,7 @@ function check_repo() {
STATUSES+=($?)
set -e
echo "removing tmp_dir $tmp_dir"
echo -e "removing tmp_dir $tmp_dir\n\n"
rm -rf $tmp_dir
cd $WORKDIR
}

View File

@ -1,3 +1,3 @@
[toolchain]
channel = "nightly-2023-10-22"
channel = "nightly-2023-12-12"
components = ["llvm-tools", "rustc-dev"]

View File

@ -173,10 +173,7 @@ pub(crate) fn combine_strs_with_missing_comments(
) -> Option<String> {
trace!(
"combine_strs_with_missing_comments `{}` `{}` {:?} {:?}",
prev_str,
next_str,
span,
shape
prev_str, next_str, span, shape
);
let mut result =

View File

@ -129,6 +129,7 @@ macro_rules! create_config {
| "chain_width" => self.0.set_heuristics(),
"merge_imports" => self.0.set_merge_imports(),
"fn_args_layout" => self.0.set_fn_args_layout(),
"hide_parse_errors" => self.0.set_hide_parse_errors(),
&_ => (),
}
}
@ -184,6 +185,7 @@ macro_rules! create_config {
self.set_ignore(dir);
self.set_merge_imports();
self.set_fn_args_layout();
self.set_hide_parse_errors();
self
}
@ -278,19 +280,21 @@ macro_rules! create_config {
| "chain_width" => self.set_heuristics(),
"merge_imports" => self.set_merge_imports(),
"fn_args_layout" => self.set_fn_args_layout(),
"hide_parse_errors" => self.set_hide_parse_errors(),
&_ => (),
}
}
#[allow(unreachable_pub)]
pub fn is_hidden_option(name: &str) -> bool {
const HIDE_OPTIONS: [&str; 6] = [
const HIDE_OPTIONS: [&str; 7] = [
"verbose",
"verbose_diff",
"file_lines",
"width_heuristics",
"merge_imports",
"fn_args_layout"
"fn_args_layout",
"hide_parse_errors"
];
HIDE_OPTIONS.contains(&name)
}
@ -461,6 +465,18 @@ macro_rules! create_config {
}
}
fn set_hide_parse_errors(&mut self) {
if self.was_set().hide_parse_errors() {
eprintln!(
"Warning: the `hide_parse_errors` option is deprecated. \
Use `show_parse_errors` instead"
);
if !self.was_set().show_parse_errors() {
self.show_parse_errors.2 = self.hide_parse_errors();
}
}
}
#[allow(unreachable_pub)]
/// Returns `true` if the config key was explicitly set and is the default value.
pub fn is_default(&self, key: &str) -> bool {

View File

@ -26,6 +26,7 @@ pub(crate) mod file_lines;
#[allow(unreachable_pub)]
pub(crate) mod lists;
pub(crate) mod macro_names;
pub(crate) mod style_edition;
// This macro defines configuration options used in rustfmt. Each option
// is defined as follows:
@ -73,7 +74,7 @@ create_config! {
format_strings: bool, false, false, "Format string literals where necessary";
format_macro_matchers: bool, false, false,
"Format the metavariable matching patterns in macros";
format_macro_bodies: bool, true, false, "Format the bodies of macros";
format_macro_bodies: bool, true, false, "Format the bodies of declarative macro definitions";
skip_macro_invocations: MacroSelectors, MacroSelectors::default(), false,
"Skip formatting the bodies of macros invoked with the following names.";
hex_literal_case: HexLiteralCase, HexLiteralCase::Preserve, false,
@ -168,7 +169,8 @@ create_config! {
"Enables unstable features. Only available on nightly channel";
disable_all_formatting: bool, false, true, "Don't reformat anything";
skip_children: bool, false, false, "Don't reformat out of line modules";
hide_parse_errors: bool, false, false, "Hide errors from the parser";
hide_parse_errors: bool, false, false, "(deprecated: use show_parse_errors instead)";
show_parse_errors: bool, true, false, "Show errors from the parser (unstable)";
error_on_line_overflow: bool, false, false, "Error if unable to get all lines within max_width";
error_on_unformatted: bool, false, false,
"Error if unable to get comments or string literals within max_width, \
@ -203,6 +205,7 @@ impl PartialConfig {
cloned.print_misformatted_file_names = None;
cloned.merge_imports = None;
cloned.fn_args_layout = None;
cloned.hide_parse_errors = None;
::toml::to_string(&cloned).map_err(ToTomlError)
}
@ -455,6 +458,13 @@ mod test {
fn_params_layout: Density, Density::Tall, true,
"Control the layout of parameters in a function signatures.";
// hide_parse_errors renamed to show_parse_errors
hide_parse_errors: bool, false, false,
"(deprecated: use show_parse_errors instead)";
show_parse_errors: bool, true, false,
"Show errors from the parser (unstable)";
// Width Heuristics
use_small_heuristics: Heuristics, Heuristics::Default, true,
"Whether to use different formatting for items and \
@ -680,7 +690,7 @@ required_version = "{}"
unstable_features = false
disable_all_formatting = false
skip_children = false
hide_parse_errors = false
show_parse_errors = true
error_on_line_overflow = false
error_on_unformatted = false
ignore = []

View File

@ -470,3 +470,27 @@ pub enum MatchArmLeadingPipe {
/// Preserve any existing leading pipes
Preserve,
}
/// Defines the default values for each config according to [the style guide].
/// rustfmt output may differ between style editions.
///
/// [the style guide]: https://doc.rust-lang.org/nightly/style-guide/
#[config_type]
pub enum StyleEdition {
#[value = "2015"]
#[doc_hint = "2015"]
/// [Edition 2015]()
Edition2015,
#[value = "2018"]
#[doc_hint = "2018"]
/// [Edition 2018]()
Edition2018,
#[value = "2021"]
#[doc_hint = "2021"]
/// [Edition 2021]()
Edition2021,
#[value = "2024"]
#[doc_hint = "2024"]
/// [Edition 2024]().
Edition2024,
}

View File

@ -0,0 +1,69 @@
use crate::config::StyleEdition;
/// Defines the default value for the given style edition
pub(crate) trait StyleEditionDefault {
type ConfigType;
fn style_edition_default(style_edition: StyleEdition) -> Self::ConfigType;
}
/// macro to help implement `StyleEditionDefault` for config options
#[macro_export]
macro_rules! style_edition_default {
($ty:ident, $config_ty:ty, _ => $default:expr) => {
impl $crate::config::style_edition::StyleEditionDefault for $ty {
type ConfigType = $config_ty;
fn style_edition_default(_: $crate::config::StyleEdition) -> Self::ConfigType {
$default
}
}
};
($ty:ident, $config_ty:ty, Edition2024 => $default_2024:expr, _ => $default_2015:expr) => {
impl $crate::config::style_edition::StyleEditionDefault for $ty {
type ConfigType = $config_ty;
fn style_edition_default(
style_edition: $crate::config::StyleEdition,
) -> Self::ConfigType {
match style_edition {
$crate::config::StyleEdition::Edition2015
| $crate::config::StyleEdition::Edition2018
| $crate::config::StyleEdition::Edition2021 => $default_2015,
$crate::config::StyleEdition::Edition2024 => $default_2024,
}
}
}
};
}
#[cfg(test)]
mod test {
use super::*;
use crate::config::StyleEdition;
#[test]
fn test_impl_default_style_edition_struct_for_all_editions() {
struct Unit;
style_edition_default!(Unit, usize, _ => 100);
// regardless of the style edition used the value will always return 100
assert_eq!(Unit::style_edition_default(StyleEdition::Edition2015), 100);
assert_eq!(Unit::style_edition_default(StyleEdition::Edition2018), 100);
assert_eq!(Unit::style_edition_default(StyleEdition::Edition2021), 100);
assert_eq!(Unit::style_edition_default(StyleEdition::Edition2024), 100);
}
#[test]
fn test_impl_default_style_edition_for_old_and_new_editions() {
struct Unit;
style_edition_default!(Unit, usize, Edition2024 => 50, _ => 100);
// style edition 2015-2021 are all the same
assert_eq!(Unit::style_edition_default(StyleEdition::Edition2015), 100);
assert_eq!(Unit::style_edition_default(StyleEdition::Edition2018), 100);
assert_eq!(Unit::style_edition_default(StyleEdition::Edition2021), 100);
// style edition 2024
assert_eq!(Unit::style_edition_default(StyleEdition::Edition2024), 50);
}
}

View File

@ -832,13 +832,15 @@ pub(crate) fn format_impl(
if is_impl_single_line(context, items.as_slice(), &result, &where_clause_str, item)? {
result.push_str(&where_clause_str);
if where_clause_str.contains('\n') || last_line_contains_single_line_comment(&result) {
// if the where_clause contains extra comments AND
// there is only one where-clause predicate
// recover the suppressed comma in single line where_clause formatting
if where_clause_str.contains('\n') {
// If there is only one where-clause predicate
// and the where-clause spans multiple lines,
// then recover the suppressed comma in single line where-clause formatting
if generics.where_clause.predicates.len() == 1 {
result.push(',');
}
}
if where_clause_str.contains('\n') || last_line_contains_single_line_comment(&result) {
result.push_str(&format!("{sep}{{{sep}}}"));
} else {
result.push_str(" {}");

View File

@ -3,7 +3,6 @@
#![warn(unreachable_pub)]
#![recursion_limit = "256"]
#![allow(clippy::match_like_matches_macro)]
#![allow(unreachable_pub)]
#[cfg(test)]
#[macro_use]
@ -305,7 +304,7 @@ fn format_snippet(snippet: &str, config: &Config, is_macro_def: bool) -> Option<
let mut out: Vec<u8> = Vec::with_capacity(snippet.len() * 2);
config.set().emit_mode(config::EmitMode::Stdout);
config.set().verbose(Verbosity::Quiet);
config.set().hide_parse_errors(true);
config.set().show_parse_errors(false);
if is_macro_def {
config.set().error_on_unformatted(true);
}

View File

@ -1269,7 +1269,7 @@ impl MacroBranch {
let has_block_body = old_body.starts_with('{');
let mut config = context.config.clone();
config.set().hide_parse_errors(true);
config.set().show_parse_errors(false);
result += " {";

View File

@ -451,8 +451,8 @@ fn rewrite_match_body(
};
let block_sep = match context.config.control_brace_style() {
ControlBraceStyle::AlwaysNextLine => format!("{}{}", alt_block_sep, body_prefix),
_ if body_prefix.is_empty() => "".to_owned(),
ControlBraceStyle::AlwaysNextLine => format!("{}{}", alt_block_sep, body_prefix),
_ if forbid_same_line || !arrow_comment.is_empty() => {
format!("{}{}", alt_block_sep, body_prefix)
}

View File

@ -8,8 +8,8 @@ use rustc_ast::{ast, ptr};
use rustc_span::Span;
use crate::closures;
use crate::config::lists::*;
use crate::config::Version;
use crate::config::{lists::*, Config};
use crate::expr::{
can_be_overflowed_expr, is_every_expr_simple, is_method_call, is_nested_call, is_simple_expr,
rewrite_cond,
@ -60,6 +60,13 @@ const SPECIAL_CASE_MACROS: &[(&str, usize)] = &[
("debug_assert_ne!", 2),
];
/// Additional special case macros for version 2; these are separated to avoid breaking changes in
/// version 1.
const SPECIAL_CASE_MACROS_V2: &[(&str, usize)] = &[
// From the `log` crate.
("trace!", 0),
];
const SPECIAL_CASE_ATTR: &[(&str, usize)] = &[
// From the `failure` crate.
("fail", 0),
@ -182,12 +189,17 @@ impl<'a> OverflowableItem<'a> {
}
}
fn special_cases(&self) -> &'static [(&'static str, usize)] {
match self {
fn special_cases(&self, config: &Config) -> impl Iterator<Item = &(&'static str, usize)> {
let base_cases = match self {
OverflowableItem::MacroArg(..) => SPECIAL_CASE_MACROS,
OverflowableItem::NestedMetaItem(..) => SPECIAL_CASE_ATTR,
_ => &[],
}
};
let additional_cases = match (self, config.version()) {
(OverflowableItem::MacroArg(..), Version::Two) => SPECIAL_CASE_MACROS_V2,
_ => &[],
};
base_cases.iter().chain(additional_cases)
}
}
@ -551,7 +563,7 @@ impl<'a> Context<'a> {
if tactic == DefinitiveListTactic::Vertical {
if let Some((all_simple, num_args_before)) =
maybe_get_args_offset(self.ident, &self.items)
maybe_get_args_offset(self.ident, &self.items, &self.context.config)
{
let one_line = all_simple
&& definitive_tactic(
@ -771,11 +783,11 @@ fn no_long_items(list: &[ListItem], short_array_element_width_threshold: usize)
pub(crate) fn maybe_get_args_offset(
callee_str: &str,
args: &[OverflowableItem<'_>],
config: &Config,
) -> Option<(bool, usize)> {
if let Some(&(_, num_args_before)) = args
.get(0)?
.special_cases()
.iter()
.special_cases(config)
.find(|&&(s, _)| s == callee_str)
{
let all_simple = args.len() > num_args_before

View File

@ -122,7 +122,7 @@ fn default_dcx(
source_map: Lrc<SourceMap>,
ignore_path_set: Lrc<IgnorePathSet>,
can_reset: Lrc<AtomicBool>,
hide_parse_errors: bool,
show_parse_errors: bool,
color: Color,
) -> DiagCtxt {
let supports_color = term::stderr().map_or(false, |term| term.supports_color());
@ -132,7 +132,7 @@ fn default_dcx(
ColorConfig::Never
};
let emitter = if hide_parse_errors {
let emitter = if !show_parse_errors {
silent_emitter()
} else {
let fallback_bundle = rustc_errors::fallback_fluent_bundle(
@ -163,7 +163,7 @@ impl ParseSess {
Lrc::clone(&source_map),
Lrc::clone(&ignore_path_set),
Lrc::clone(&can_reset_errors),
config.hide_parse_errors(),
config.show_parse_errors(),
config.color(),
);
let parse_sess = RawParseSess::with_dcx(dcx, source_map);

View File

@ -184,3 +184,19 @@ fn dont_emit_ICE() {
assert!(!stderr.contains("thread 'main' panicked"));
}
}
#[test]
fn rustfmt_emits_error_when_control_brace_style_is_always_next_line() {
// See also https://github.com/rust-lang/rustfmt/issues/5912
let args = [
"--config=color=Never",
"--config",
"control_brace_style=AlwaysNextLine",
"--config",
"match_arm_blocks=false",
"tests/target/issue_5912.rs",
];
let (_stdout, stderr) = rustfmt(&args);
assert!(!stderr.contains("error[internal]: left behind trailing whitespace"))
}

View File

@ -0,0 +1,13 @@
// rustfmt-version: Two
fn main() {
trace!(
"get some longer length in here yes yes {} {}",
"hello",
"world"
);
debug!(
"get some longer length in here yes yes {} {}",
"hello", "world"
);
}

View File

@ -0,0 +1,15 @@
// rustfmt-match_arm_blocks: false
// rustfmt-control_brace_style: AlwaysNextLine
fn foo() {
match 0 {
0 => {
aaaaaaaaaaaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbbbbb
+ bbbbbbbbbbbbbbbbbbbbbbbbb
+ bbbbbbbbbbbbbbbbbbbbbbbbb
+ bbbbbbbbbbbbbbbbbbbbbbbbb
}
_ => 2,
}
}

View File

@ -32,6 +32,11 @@ where
{
}
// #5941
impl T where (): Clone // Should not add comma to comment
{
}
// #1823
default impl Trait for X {}
default unsafe impl Trait for Y {}

View File

@ -0,0 +1,13 @@
// rustfmt-version: One
fn main() {
trace!(
"get some longer length in here yes yes {} {}",
"hello",
"world"
);
debug!(
"get some longer length in here yes yes {} {}",
"hello", "world"
);
}

View File

@ -0,0 +1,12 @@
// rustfmt-version: Two
fn main() {
trace!(
"get some longer length in here yes yes {} {}",
"hello", "world"
);
debug!(
"get some longer length in here yes yes {} {}",
"hello", "world"
);
}

View File

@ -0,0 +1,15 @@
// rustfmt-match_arm_blocks: false
// rustfmt-control_brace_style: AlwaysNextLine
fn foo() {
match 0
{
0 =>
aaaaaaaaaaaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbbbbb
+ bbbbbbbbbbbbbbbbbbbbbbbbb
+ bbbbbbbbbbbbbbbbbbbbbbbbb
+ bbbbbbbbbbbbbbbbbbbbbbbbb,
_ => 2,
}
}