From e71ee500d1d9f63b2de99daed7b83165d0fc921b Mon Sep 17 00:00:00 2001 From: apekros Date: Fri, 29 Sep 2023 11:02:17 +1000 Subject: [PATCH 01/29] Add test for rust-lang#114912 --- ...ebug-ice-attempted-to-add-with-overflow.rs | 10 ++++++++ ...-ice-attempted-to-add-with-overflow.stderr | 23 +++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 tests/ui/async-await/debug-ice-attempted-to-add-with-overflow.rs create mode 100644 tests/ui/async-await/debug-ice-attempted-to-add-with-overflow.stderr diff --git a/tests/ui/async-await/debug-ice-attempted-to-add-with-overflow.rs b/tests/ui/async-await/debug-ice-attempted-to-add-with-overflow.rs new file mode 100644 index 00000000000..ced4434a7a7 --- /dev/null +++ b/tests/ui/async-await/debug-ice-attempted-to-add-with-overflow.rs @@ -0,0 +1,10 @@ +// check-fail +// edition:2021 + +// test for issue-114912 - debug ice: attempted to add with overflow + +async fn main() { + //~^ ERROR `main` function is not allowed to be `async` + [0usize; 0xffff_ffff_ffff_ffff].await; + //~^ ERROR `[usize; usize::MAX]` is not a future +} diff --git a/tests/ui/async-await/debug-ice-attempted-to-add-with-overflow.stderr b/tests/ui/async-await/debug-ice-attempted-to-add-with-overflow.stderr new file mode 100644 index 00000000000..8c9d06c79ca --- /dev/null +++ b/tests/ui/async-await/debug-ice-attempted-to-add-with-overflow.stderr @@ -0,0 +1,23 @@ +error[E0277]: `[usize; usize::MAX]` is not a future + --> $DIR/debug-ice-attempted-to-add-with-overflow.rs:8:37 + | +LL | [0usize; 0xffff_ffff_ffff_ffff].await; + | -^^^^^ + | || + | |`[usize; usize::MAX]` is not a future + | help: remove the `.await` + | + = help: the trait `Future` is not implemented for `[usize; usize::MAX]` + = note: [usize; usize::MAX] must be a future or must implement `IntoFuture` to be awaited + = note: required for `[usize; usize::MAX]` to implement `IntoFuture` + +error[E0752]: `main` function is not allowed to be `async` + --> $DIR/debug-ice-attempted-to-add-with-overflow.rs:6:1 + | +LL | async fn main() { + | ^^^^^^^^^^^^^^^ `main` function is not allowed to be `async` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0277, E0752. +For more information about an error, try `rustc --explain E0277`. From 93df9e6d7d54160cfd4870339b5ae6568918af66 Mon Sep 17 00:00:00 2001 From: francorbacho Date: Mon, 28 Aug 2023 18:37:03 +0200 Subject: [PATCH 02/29] Suggest removing redundant arguments in format!() --- compiler/rustc_builtin_macros/src/format.rs | 84 ++++++++++++++++++++- tests/ui/did_you_mean/issue-105225.rs | 19 +++++ tests/ui/did_you_mean/issue-105225.stderr | 81 ++++++++++++++++++++ 3 files changed, 180 insertions(+), 4 deletions(-) create mode 100644 tests/ui/did_you_mean/issue-105225.rs create mode 100644 tests/ui/did_you_mean/issue-105225.stderr diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 8397b5e4221..fd286391437 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -1,3 +1,4 @@ +use parse::Position::ArgumentNamed; use rustc_ast::ptr::P; use rustc_ast::tokenstream::TokenStream; use rustc_ast::{token, StmtKind}; @@ -6,7 +7,7 @@ use rustc_ast::{ FormatArgsPiece, FormatArgument, FormatArgumentKind, FormatArguments, FormatCount, FormatDebugHex, FormatOptions, FormatPlaceholder, FormatSign, FormatTrait, }; -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_errors::{Applicability, MultiSpan, PResult, SingleLabelManySpans}; use rustc_expand::base::{self, *}; use rustc_parse_format as parse; @@ -357,8 +358,8 @@ fn make_format_args( let mut unfinished_literal = String::new(); let mut placeholder_index = 0; - for piece in pieces { - match piece { + for piece in &pieces { + match *piece { parse::Piece::String(s) => { unfinished_literal.push_str(s); } @@ -506,7 +507,17 @@ fn make_format_args( // If there's a lot of unused arguments, // let's check if this format arguments looks like another syntax (printf / shell). let detect_foreign_fmt = unused.len() > args.explicit_args().len() / 2; - report_missing_placeholders(ecx, unused, detect_foreign_fmt, str_style, fmt_str, fmt_span); + report_missing_placeholders( + ecx, + unused, + &used, + &args, + &pieces, + detect_foreign_fmt, + str_style, + fmt_str, + fmt_span, + ); } // Only check for unused named argument names if there are no other errors to avoid causing @@ -573,6 +584,9 @@ fn invalid_placeholder_type_error( fn report_missing_placeholders( ecx: &mut ExtCtxt<'_>, unused: Vec<(Span, bool)>, + used: &[bool], + args: &FormatArguments, + pieces: &[parse::Piece<'_>], detect_foreign_fmt: bool, str_style: Option, fmt_str: &str, @@ -591,6 +605,68 @@ fn report_missing_placeholders( }) }; + let placeholders = pieces + .iter() + .filter_map(|piece| { + if let parse::Piece::NextArgument(argument) = piece && let ArgumentNamed(binding) = argument.position { + let span = fmt_span.from_inner(InnerSpan::new(argument.position_span.start, argument.position_span.end)); + Some((span, binding)) + } else { None } + }) + .collect::>(); + + let mut args_spans = vec![]; + let mut fmt_spans = FxIndexSet::default(); + + for (i, unnamed_arg) in args.unnamed_args().iter().enumerate().rev() { + let Some(ty) = unnamed_arg.expr.to_ty() else { continue }; + let Some(argument_binding) = ty.kind.is_simple_path() else { continue }; + let argument_binding = argument_binding.as_str(); + + if used[i] { + continue; + } + + let matching_placeholders = placeholders + .iter() + .filter(|(_, inline_binding)| argument_binding == *inline_binding) + .collect::>(); + + if !matching_placeholders.is_empty() { + args_spans.push(unnamed_arg.expr.span); + for placeholder in &matching_placeholders { + fmt_spans.insert(*placeholder); + } + } + } + + if !args_spans.is_empty() { + let mut multispan = MultiSpan::from(args_spans.clone()); + + let msg = if fmt_spans.len() > 1 { + "the formatting strings already captures the bindings \ + directly, they don't need to be included in the argument list" + } else { + "the formatting string already captures the binding \ + directly, it doesn't need to be included in the argument list" + }; + + for (span, binding) in fmt_spans { + multispan.push_span_label( + *span, + format!("this formatting specifier is referencing the `{binding}` binding"), + ); + } + + for span in &args_spans { + multispan.push_span_label(*span, "this can be removed"); + } + + diag.span_help(multispan, msg); + diag.emit(); + return; + } + // Used to ensure we only report translations for *one* kind of foreign format. let mut found_foreign = false; diff --git a/tests/ui/did_you_mean/issue-105225.rs b/tests/ui/did_you_mean/issue-105225.rs new file mode 100644 index 00000000000..5d288c7eb24 --- /dev/null +++ b/tests/ui/did_you_mean/issue-105225.rs @@ -0,0 +1,19 @@ +fn main() { + let x = 0; + println!("{x}", x); + //~^ ERROR: argument never used + + println!("{x} {}", x, x); + //~^ ERROR: argument never used + + println!("{} {x}", x, x); + //~^ ERROR: argument never used + + let y = 0; + println!("{x} {y}", x, y); + //~^ ERROR: multiple unused formatting arguments + + let y = 0; + println!("{} {} {x} {y} {}", x, x, x, y, y); + //~^ ERROR: multiple unused formatting arguments +} diff --git a/tests/ui/did_you_mean/issue-105225.stderr b/tests/ui/did_you_mean/issue-105225.stderr new file mode 100644 index 00000000000..c067d396367 --- /dev/null +++ b/tests/ui/did_you_mean/issue-105225.stderr @@ -0,0 +1,81 @@ +error: argument never used + --> $DIR/issue-105225.rs:3:21 + | +LL | println!("{x}", x); + | ^ argument never used + | +help: the formatting string already captures the binding directly, it doesn't need to be included in the argument list + --> $DIR/issue-105225.rs:3:21 + | +LL | println!("{x}", x); + | - ^ this can be removed + | | + | this formatting specifier is referencing the `x` binding + +error: argument never used + --> $DIR/issue-105225.rs:6:27 + | +LL | println!("{x} {}", x, x); + | ^ argument never used + | +help: the formatting string already captures the binding directly, it doesn't need to be included in the argument list + --> $DIR/issue-105225.rs:6:27 + | +LL | println!("{x} {}", x, x); + | - ^ this can be removed + | | + | this formatting specifier is referencing the `x` binding + +error: argument never used + --> $DIR/issue-105225.rs:9:27 + | +LL | println!("{} {x}", x, x); + | ^ argument never used + | +help: the formatting string already captures the binding directly, it doesn't need to be included in the argument list + --> $DIR/issue-105225.rs:9:27 + | +LL | println!("{} {x}", x, x); + | - ^ this can be removed + | | + | this formatting specifier is referencing the `x` binding + +error: multiple unused formatting arguments + --> $DIR/issue-105225.rs:13:25 + | +LL | println!("{x} {y}", x, y); + | --------- ^ ^ argument never used + | | | + | | argument never used + | multiple missing formatting specifiers + | +help: the formatting strings already captures the bindings directly, they don't need to be included in the argument list + --> $DIR/issue-105225.rs:13:25 + | +LL | println!("{x} {y}", x, y); + | - - ^ ^ this can be removed + | | | | + | | | this can be removed + | | this formatting specifier is referencing the `y` binding + | this formatting specifier is referencing the `x` binding + +error: multiple unused formatting arguments + --> $DIR/issue-105225.rs:17:43 + | +LL | println!("{} {} {x} {y} {}", x, x, x, y, y); + | ------------------ ^ ^ argument never used + | | | + | | argument never used + | multiple missing formatting specifiers + | +help: the formatting string already captures the binding directly, it doesn't need to be included in the argument list + --> $DIR/issue-105225.rs:17:43 + | +LL | println!("{} {} {x} {y} {}", x, x, x, y, y); + | - ^ ^ this can be removed + | | | + | | this can be removed + | this formatting specifier is referencing the `y` binding + +error: aborting due to 5 previous errors + From 4cc2d0bd6569bc684892905af22c7492ecd1f91a Mon Sep 17 00:00:00 2001 From: francorbacho Date: Mon, 25 Sep 2023 16:50:17 +0200 Subject: [PATCH 03/29] Separate report_redundant_placeholders() into its own function --- compiler/rustc_builtin_macros/src/format.rs | 114 +++++++++++--------- 1 file changed, 62 insertions(+), 52 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index fd286391437..6db551aef35 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -8,11 +8,11 @@ use rustc_ast::{ FormatDebugHex, FormatOptions, FormatPlaceholder, FormatSign, FormatTrait, }; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; -use rustc_errors::{Applicability, MultiSpan, PResult, SingleLabelManySpans}; +use rustc_errors::{Applicability, DiagnosticBuilder, MultiSpan, PResult, SingleLabelManySpans}; use rustc_expand::base::{self, *}; use rustc_parse_format as parse; use rustc_span::symbol::{Ident, Symbol}; -use rustc_span::{BytePos, InnerSpan, Span}; +use rustc_span::{BytePos, ErrorGuaranteed, InnerSpan, Span}; use rustc_lint_defs::builtin::NAMED_ARGUMENTS_USED_POSITIONALLY; use rustc_lint_defs::{BufferedEarlyLint, BuiltinLintDiagnostics, LintId}; @@ -615,56 +615,8 @@ fn report_missing_placeholders( }) .collect::>(); - let mut args_spans = vec![]; - let mut fmt_spans = FxIndexSet::default(); - - for (i, unnamed_arg) in args.unnamed_args().iter().enumerate().rev() { - let Some(ty) = unnamed_arg.expr.to_ty() else { continue }; - let Some(argument_binding) = ty.kind.is_simple_path() else { continue }; - let argument_binding = argument_binding.as_str(); - - if used[i] { - continue; - } - - let matching_placeholders = placeholders - .iter() - .filter(|(_, inline_binding)| argument_binding == *inline_binding) - .collect::>(); - - if !matching_placeholders.is_empty() { - args_spans.push(unnamed_arg.expr.span); - for placeholder in &matching_placeholders { - fmt_spans.insert(*placeholder); - } - } - } - - if !args_spans.is_empty() { - let mut multispan = MultiSpan::from(args_spans.clone()); - - let msg = if fmt_spans.len() > 1 { - "the formatting strings already captures the bindings \ - directly, they don't need to be included in the argument list" - } else { - "the formatting string already captures the binding \ - directly, it doesn't need to be included in the argument list" - }; - - for (span, binding) in fmt_spans { - multispan.push_span_label( - *span, - format!("this formatting specifier is referencing the `{binding}` binding"), - ); - } - - for span in &args_spans { - multispan.push_span_label(*span, "this can be removed"); - } - - diag.span_help(multispan, msg); - diag.emit(); - return; + if !placeholders.is_empty() { + report_redundant_placeholders(&mut diag, &args, used, placeholders); } // Used to ensure we only report translations for *one* kind of foreign format. @@ -754,6 +706,64 @@ fn report_missing_placeholders( diag.emit(); } +fn report_redundant_placeholders( + diag: &mut DiagnosticBuilder<'_, ErrorGuaranteed>, + args: &FormatArguments, + used: &[bool], + placeholders: Vec<(Span, &str)>, +) { + let mut args_spans = vec![]; + let mut fmt_spans = FxIndexSet::default(); + + for (i, unnamed_arg) in args.unnamed_args().iter().enumerate().rev() { + let Some(ty) = unnamed_arg.expr.to_ty() else { continue }; + let Some(argument_binding) = ty.kind.is_simple_path() else { continue }; + let argument_binding = argument_binding.as_str(); + + if used[i] { + continue; + } + + let matching_placeholders = placeholders + .iter() + .filter(|(_, inline_binding)| argument_binding == *inline_binding) + .collect::>(); + + if !matching_placeholders.is_empty() { + args_spans.push(unnamed_arg.expr.span); + for placeholder in &matching_placeholders { + fmt_spans.insert(*placeholder); + } + } + } + + if !args_spans.is_empty() { + let mut multispan = MultiSpan::from(args_spans.clone()); + + let msg = if fmt_spans.len() > 1 { + "the formatting strings already captures the bindings \ + directly, they don't need to be included in the argument list" + } else { + "the formatting string already captures the binding \ + directly, it doesn't need to be included in the argument list" + }; + + for (span, binding) in fmt_spans { + multispan.push_span_label( + *span, + format!("this formatting specifier is referencing the `{binding}` binding"), + ); + } + + for span in &args_spans { + multispan.push_span_label(*span, "this can be removed"); + } + + diag.span_help(multispan, msg); + diag.emit(); + } +} + /// Handle invalid references to positional arguments. Output different /// errors for the case where all arguments are positional and for when /// there are named arguments or numbered positional arguments in the From 04fc051a345c861efe8b2053d62cc1313824731a Mon Sep 17 00:00:00 2001 From: francorbacho Date: Wed, 4 Oct 2023 15:47:53 +0200 Subject: [PATCH 04/29] Use diagnostic impls and add suggestions in redundant format!() args --- compiler/rustc_builtin_macros/messages.ftl | 11 +++ compiler/rustc_builtin_macros/src/errors.rs | 21 +++++ compiler/rustc_builtin_macros/src/format.rs | 58 ++++++++------ tests/ui/did_you_mean/issue-105225.rs | 10 +-- tests/ui/did_you_mean/issue-105225.stderr | 89 +++++++++------------ 5 files changed, 110 insertions(+), 79 deletions(-) diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl index 207ae8ad844..ce3d07c59de 100644 --- a/compiler/rustc_builtin_macros/messages.ftl +++ b/compiler/rustc_builtin_macros/messages.ftl @@ -139,6 +139,17 @@ builtin_macros_format_positional_after_named = positional arguments cannot follo builtin_macros_format_remove_raw_ident = remove the `r#` +builtin_macros_format_redundant_args = redundant argument + .help = {$n -> + [one] the formatting string already captures the binding directly, it doesn't need to be included in the argument list + *[more] the formatting strings already captures the bindings directly, they don't need to be included in the argument list + } + .note = {$n -> + [one] the formatting specifier is referencing the binding already + *[more] the formatting specifiers are referencing the bindings already + } + .suggestion = this can be removed + builtin_macros_format_requires_string = requires at least a format string argument builtin_macros_format_string_invalid = invalid format string: {$desc} diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index 1238773d58b..c2097f0bc47 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -646,6 +646,27 @@ pub(crate) struct FormatPositionalMismatch { pub(crate) highlight: SingleLabelManySpans, } +#[derive(Diagnostic)] +#[diag(builtin_macros_format_redundant_args)] +pub(crate) struct FormatRedundantArgs { + #[primary_span] + pub(crate) fmt_span: Span, + pub(crate) n: usize, + + #[note] + pub(crate) note: MultiSpan, + + #[subdiagnostic] + pub(crate) sugg: FormatRedundantArgsSugg, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion(builtin_macros_suggestion, applicability = "machine-applicable")] +pub(crate) struct FormatRedundantArgsSugg { + #[suggestion_part(code = "")] + pub(crate) spans: Vec, +} + #[derive(Diagnostic)] #[diag(builtin_macros_test_case_non_item)] pub(crate) struct TestCaseNonItem { diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 6db551aef35..32a90b307ef 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -7,12 +7,12 @@ use rustc_ast::{ FormatArgsPiece, FormatArgument, FormatArgumentKind, FormatArguments, FormatCount, FormatDebugHex, FormatOptions, FormatPlaceholder, FormatSign, FormatTrait, }; -use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; -use rustc_errors::{Applicability, DiagnosticBuilder, MultiSpan, PResult, SingleLabelManySpans}; +use rustc_data_structures::fx::FxHashSet; +use rustc_errors::{Applicability, MultiSpan, PResult, SingleLabelManySpans}; use rustc_expand::base::{self, *}; use rustc_parse_format as parse; use rustc_span::symbol::{Ident, Symbol}; -use rustc_span::{BytePos, ErrorGuaranteed, InnerSpan, Span}; +use rustc_span::{BytePos, InnerSpan, Span}; use rustc_lint_defs::builtin::NAMED_ARGUMENTS_USED_POSITIONALLY; use rustc_lint_defs::{BufferedEarlyLint, BuiltinLintDiagnostics, LintId}; @@ -616,7 +616,9 @@ fn report_missing_placeholders( .collect::>(); if !placeholders.is_empty() { - report_redundant_placeholders(&mut diag, &args, used, placeholders); + report_redundant_placeholders(ecx, fmt_span, &args, used, placeholders); + diag.cancel(); + return; } // Used to ensure we only report translations for *one* kind of foreign format. @@ -707,13 +709,16 @@ fn report_missing_placeholders( } fn report_redundant_placeholders( - diag: &mut DiagnosticBuilder<'_, ErrorGuaranteed>, + ecx: &mut ExtCtxt<'_>, + fmt_span: Span, args: &FormatArguments, used: &[bool], placeholders: Vec<(Span, &str)>, ) { + let mut fmt_arg_indices = vec![]; let mut args_spans = vec![]; - let mut fmt_spans = FxIndexSet::default(); + let mut fmt_spans = vec![]; + let mut bindings = vec![]; for (i, unnamed_arg) in args.unnamed_args().iter().enumerate().rev() { let Some(ty) = unnamed_arg.expr.to_ty() else { continue }; @@ -730,36 +735,39 @@ fn report_redundant_placeholders( .collect::>(); if !matching_placeholders.is_empty() { + fmt_arg_indices.push(i); args_spans.push(unnamed_arg.expr.span); - for placeholder in &matching_placeholders { - fmt_spans.insert(*placeholder); + for (span, binding) in &matching_placeholders { + if fmt_spans.contains(span) { + continue; + } + fmt_spans.push(*span); + bindings.push(binding); } } } if !args_spans.is_empty() { - let mut multispan = MultiSpan::from(args_spans.clone()); + let multispan = MultiSpan::from(fmt_spans); + let mut suggestion_spans = vec![]; - let msg = if fmt_spans.len() > 1 { - "the formatting strings already captures the bindings \ - directly, they don't need to be included in the argument list" - } else { - "the formatting string already captures the binding \ - directly, it doesn't need to be included in the argument list" - }; + for (arg_span, fmt_arg_idx) in args_spans.iter().zip(fmt_arg_indices.iter()) { + let span = if fmt_arg_idx + 1 == args.explicit_args().len() { + *arg_span + } else { + arg_span.until(args.explicit_args()[*fmt_arg_idx + 1].expr.span) + }; - for (span, binding) in fmt_spans { - multispan.push_span_label( - *span, - format!("this formatting specifier is referencing the `{binding}` binding"), - ); + suggestion_spans.push(span); } - for span in &args_spans { - multispan.push_span_label(*span, "this can be removed"); - } + let mut diag = ecx.create_err(errors::FormatRedundantArgs { + fmt_span, + note: multispan, + n: args_spans.len(), + sugg: errors::FormatRedundantArgsSugg { spans: suggestion_spans }, + }); - diag.span_help(multispan, msg); diag.emit(); } } diff --git a/tests/ui/did_you_mean/issue-105225.rs b/tests/ui/did_you_mean/issue-105225.rs index 5d288c7eb24..49070b52dd0 100644 --- a/tests/ui/did_you_mean/issue-105225.rs +++ b/tests/ui/did_you_mean/issue-105225.rs @@ -1,19 +1,19 @@ fn main() { let x = 0; println!("{x}", x); - //~^ ERROR: argument never used + //~^ ERROR: redundant argument println!("{x} {}", x, x); - //~^ ERROR: argument never used + //~^ ERROR: redundant argument println!("{} {x}", x, x); - //~^ ERROR: argument never used + //~^ ERROR: redundant argument let y = 0; println!("{x} {y}", x, y); - //~^ ERROR: multiple unused formatting arguments + //~^ ERROR: redundant argument let y = 0; println!("{} {} {x} {y} {}", x, x, x, y, y); - //~^ ERROR: multiple unused formatting arguments + //~^ ERROR: redundant argument } diff --git a/tests/ui/did_you_mean/issue-105225.stderr b/tests/ui/did_you_mean/issue-105225.stderr index c067d396367..8c366f31311 100644 --- a/tests/ui/did_you_mean/issue-105225.stderr +++ b/tests/ui/did_you_mean/issue-105225.stderr @@ -1,81 +1,72 @@ -error: argument never used - --> $DIR/issue-105225.rs:3:21 +error: redundant argument + --> $DIR/issue-105225.rs:3:14 | LL | println!("{x}", x); - | ^ argument never used + | ^^^^^ - help: this can be removed | -help: the formatting string already captures the binding directly, it doesn't need to be included in the argument list - --> $DIR/issue-105225.rs:3:21 +note: the formatting specifier is referencing the binding already + --> $DIR/issue-105225.rs:3:16 | LL | println!("{x}", x); - | - ^ this can be removed - | | - | this formatting specifier is referencing the `x` binding + | ^ -error: argument never used - --> $DIR/issue-105225.rs:6:27 +error: redundant argument + --> $DIR/issue-105225.rs:6:14 | LL | println!("{x} {}", x, x); - | ^ argument never used + | ^^^^^^^^ - help: this can be removed | -help: the formatting string already captures the binding directly, it doesn't need to be included in the argument list - --> $DIR/issue-105225.rs:6:27 +note: the formatting specifier is referencing the binding already + --> $DIR/issue-105225.rs:6:16 | LL | println!("{x} {}", x, x); - | - ^ this can be removed - | | - | this formatting specifier is referencing the `x` binding + | ^ -error: argument never used - --> $DIR/issue-105225.rs:9:27 +error: redundant argument + --> $DIR/issue-105225.rs:9:14 | LL | println!("{} {x}", x, x); - | ^ argument never used + | ^^^^^^^^ - help: this can be removed | -help: the formatting string already captures the binding directly, it doesn't need to be included in the argument list - --> $DIR/issue-105225.rs:9:27 +note: the formatting specifier is referencing the binding already + --> $DIR/issue-105225.rs:9:19 | LL | println!("{} {x}", x, x); - | - ^ this can be removed - | | - | this formatting specifier is referencing the `x` binding + | ^ -error: multiple unused formatting arguments - --> $DIR/issue-105225.rs:13:25 +error: redundant argument + --> $DIR/issue-105225.rs:13:14 | LL | println!("{x} {y}", x, y); - | --------- ^ ^ argument never used - | | | - | | argument never used - | multiple missing formatting specifiers + | ^^^^^^^^^ | -help: the formatting strings already captures the bindings directly, they don't need to be included in the argument list - --> $DIR/issue-105225.rs:13:25 +note: the formatting specifiers are referencing the bindings already + --> $DIR/issue-105225.rs:13:16 | LL | println!("{x} {y}", x, y); - | - - ^ ^ this can be removed - | | | | - | | | this can be removed - | | this formatting specifier is referencing the `y` binding - | this formatting specifier is referencing the `x` binding + | ^ ^ +help: this can be removed + | +LL - println!("{x} {y}", x, y); +LL + println!("{x} {y}", ); + | -error: multiple unused formatting arguments - --> $DIR/issue-105225.rs:17:43 +error: redundant argument + --> $DIR/issue-105225.rs:17:14 | LL | println!("{} {} {x} {y} {}", x, x, x, y, y); - | ------------------ ^ ^ argument never used - | | | - | | argument never used - | multiple missing formatting specifiers + | ^^^^^^^^^^^^^^^^^^ | -help: the formatting string already captures the binding directly, it doesn't need to be included in the argument list - --> $DIR/issue-105225.rs:17:43 +note: the formatting specifiers are referencing the bindings already + --> $DIR/issue-105225.rs:17:26 | LL | println!("{} {} {x} {y} {}", x, x, x, y, y); - | - ^ ^ this can be removed - | | | - | | this can be removed - | this formatting specifier is referencing the `y` binding + | ^ +help: this can be removed + | +LL - println!("{} {} {x} {y} {}", x, x, x, y, y); +LL + println!("{} {} {x} {y} {}", x, x, x, ); + | error: aborting due to 5 previous errors From 9c921f843c78a98b8b0eaa40f2b20b60543ebf53 Mon Sep 17 00:00:00 2001 From: francorbacho Date: Wed, 4 Oct 2023 17:35:39 +0200 Subject: [PATCH 05/29] Rename report_redundant_placeholders() to report_redundant_format_arguments() --- compiler/rustc_builtin_macros/src/format.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 32a90b307ef..8cdab65b6b3 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -616,7 +616,7 @@ fn report_missing_placeholders( .collect::>(); if !placeholders.is_empty() { - report_redundant_placeholders(ecx, fmt_span, &args, used, placeholders); + report_redundant_format_arguments(ecx, fmt_span, &args, used, placeholders); diag.cancel(); return; } @@ -708,7 +708,7 @@ fn report_missing_placeholders( diag.emit(); } -fn report_redundant_placeholders( +fn report_redundant_format_arguments( ecx: &mut ExtCtxt<'_>, fmt_span: Span, args: &FormatArguments, From e1c18f4d9de902ad615035bfed4e173d72f7ff09 Mon Sep 17 00:00:00 2001 From: francorbacho Date: Wed, 4 Oct 2023 17:38:46 +0200 Subject: [PATCH 06/29] Document report_redundant_format_arguments() --- compiler/rustc_builtin_macros/src/format.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 8cdab65b6b3..2d91de105cd 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -708,6 +708,8 @@ fn report_missing_placeholders( diag.emit(); } +/// This function detects and reports unused format!() arguments that are +/// redundant due to implicit captures (e.g. `format!("{x}", x)`). fn report_redundant_format_arguments( ecx: &mut ExtCtxt<'_>, fmt_span: Span, From dc75c99226f948c3459f9970dbd6fe0b5d2bbef2 Mon Sep 17 00:00:00 2001 From: francorbacho Date: Wed, 4 Oct 2023 17:46:48 +0200 Subject: [PATCH 07/29] Remove unused variable --- compiler/rustc_builtin_macros/src/format.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 2d91de105cd..cdd5e7225bb 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -720,7 +720,6 @@ fn report_redundant_format_arguments( let mut fmt_arg_indices = vec![]; let mut args_spans = vec![]; let mut fmt_spans = vec![]; - let mut bindings = vec![]; for (i, unnamed_arg) in args.unnamed_args().iter().enumerate().rev() { let Some(ty) = unnamed_arg.expr.to_ty() else { continue }; @@ -734,17 +733,17 @@ fn report_redundant_format_arguments( let matching_placeholders = placeholders .iter() .filter(|(_, inline_binding)| argument_binding == *inline_binding) + .map(|(span, _)| span) .collect::>(); if !matching_placeholders.is_empty() { fmt_arg_indices.push(i); args_spans.push(unnamed_arg.expr.span); - for (span, binding) in &matching_placeholders { - if fmt_spans.contains(span) { + for span in &matching_placeholders { + if fmt_spans.contains(*span) { continue; } - fmt_spans.push(*span); - bindings.push(binding); + fmt_spans.push(**span); } } } From 4a7a98cf3058f68f94c3cac1e6dfaa2f3282680c Mon Sep 17 00:00:00 2001 From: francorbacho Date: Thu, 5 Oct 2023 14:23:02 +0200 Subject: [PATCH 08/29] Fix diagnostics being cancelled even with unused arguments --- compiler/rustc_builtin_macros/src/format.rs | 28 +++++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index cdd5e7225bb..d7fc48026cb 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -8,7 +8,9 @@ use rustc_ast::{ FormatDebugHex, FormatOptions, FormatPlaceholder, FormatSign, FormatTrait, }; use rustc_data_structures::fx::FxHashSet; -use rustc_errors::{Applicability, MultiSpan, PResult, SingleLabelManySpans}; +use rustc_errors::{ + Applicability, DiagnosticBuilder, ErrorGuaranteed, MultiSpan, PResult, SingleLabelManySpans, +}; use rustc_expand::base::{self, *}; use rustc_parse_format as parse; use rustc_span::symbol::{Ident, Symbol}; @@ -616,9 +618,13 @@ fn report_missing_placeholders( .collect::>(); if !placeholders.is_empty() { - report_redundant_format_arguments(ecx, fmt_span, &args, used, placeholders); - diag.cancel(); - return; + if let Some(mut new_diag) = + report_redundant_format_arguments(ecx, fmt_span, &args, used, placeholders) + { + diag.cancel(); + new_diag.emit(); + return; + } } // Used to ensure we only report translations for *one* kind of foreign format. @@ -710,13 +716,13 @@ fn report_missing_placeholders( /// This function detects and reports unused format!() arguments that are /// redundant due to implicit captures (e.g. `format!("{x}", x)`). -fn report_redundant_format_arguments( - ecx: &mut ExtCtxt<'_>, +fn report_redundant_format_arguments<'a>( + ecx: &mut ExtCtxt<'a>, fmt_span: Span, args: &FormatArguments, used: &[bool], placeholders: Vec<(Span, &str)>, -) { +) -> Option> { let mut fmt_arg_indices = vec![]; let mut args_spans = vec![]; let mut fmt_spans = vec![]; @@ -762,15 +768,15 @@ fn report_redundant_format_arguments( suggestion_spans.push(span); } - let mut diag = ecx.create_err(errors::FormatRedundantArgs { + return Some(ecx.create_err(errors::FormatRedundantArgs { fmt_span, note: multispan, n: args_spans.len(), sugg: errors::FormatRedundantArgsSugg { spans: suggestion_spans }, - }); - - diag.emit(); + })); } + + None } /// Handle invalid references to positional arguments. Output different From fcdd5c0b2d754c513241d62c5692be2197458b08 Mon Sep 17 00:00:00 2001 From: francorbacho Date: Thu, 5 Oct 2023 14:32:56 +0200 Subject: [PATCH 09/29] Plurals in format redundant arguments suggestion --- compiler/rustc_builtin_macros/messages.ftl | 5 ++++- tests/ui/did_you_mean/issue-105225.stderr | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl index ce3d07c59de..8f158fb17da 100644 --- a/compiler/rustc_builtin_macros/messages.ftl +++ b/compiler/rustc_builtin_macros/messages.ftl @@ -139,7 +139,10 @@ builtin_macros_format_positional_after_named = positional arguments cannot follo builtin_macros_format_remove_raw_ident = remove the `r#` -builtin_macros_format_redundant_args = redundant argument +builtin_macros_format_redundant_args = redundant {$n -> + [one] argument + *[more] arguments + } .help = {$n -> [one] the formatting string already captures the binding directly, it doesn't need to be included in the argument list *[more] the formatting strings already captures the bindings directly, they don't need to be included in the argument list diff --git a/tests/ui/did_you_mean/issue-105225.stderr b/tests/ui/did_you_mean/issue-105225.stderr index 8c366f31311..dc18e7268b4 100644 --- a/tests/ui/did_you_mean/issue-105225.stderr +++ b/tests/ui/did_you_mean/issue-105225.stderr @@ -34,7 +34,7 @@ note: the formatting specifier is referencing the binding already LL | println!("{} {x}", x, x); | ^ -error: redundant argument +error: redundant arguments --> $DIR/issue-105225.rs:13:14 | LL | println!("{x} {y}", x, y); @@ -51,7 +51,7 @@ LL - println!("{x} {y}", x, y); LL + println!("{x} {y}", ); | -error: redundant argument +error: redundant arguments --> $DIR/issue-105225.rs:17:14 | LL | println!("{} {} {x} {y} {}", x, x, x, y, y); From 905bace904ded95ef6996684ede37486313b640f Mon Sep 17 00:00:00 2001 From: francorbacho Date: Thu, 5 Oct 2023 14:36:50 +0200 Subject: [PATCH 10/29] Highlight redundant arguments instead of the whole format string --- compiler/rustc_builtin_macros/src/errors.rs | 2 +- compiler/rustc_builtin_macros/src/format.rs | 7 +++--- tests/ui/did_you_mean/issue-105225.rs | 8 +++--- tests/ui/did_you_mean/issue-105225.stderr | 28 ++++++++++----------- 4 files changed, 22 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index c2097f0bc47..7a8ec5cfdf3 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -650,7 +650,7 @@ pub(crate) struct FormatPositionalMismatch { #[diag(builtin_macros_format_redundant_args)] pub(crate) struct FormatRedundantArgs { #[primary_span] - pub(crate) fmt_span: Span, + pub(crate) span: MultiSpan, pub(crate) n: usize, #[note] diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index d7fc48026cb..e08fded01fb 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -619,7 +619,7 @@ fn report_missing_placeholders( if !placeholders.is_empty() { if let Some(mut new_diag) = - report_redundant_format_arguments(ecx, fmt_span, &args, used, placeholders) + report_redundant_format_arguments(ecx, &args, used, placeholders) { diag.cancel(); new_diag.emit(); @@ -718,7 +718,6 @@ fn report_missing_placeholders( /// redundant due to implicit captures (e.g. `format!("{x}", x)`). fn report_redundant_format_arguments<'a>( ecx: &mut ExtCtxt<'a>, - fmt_span: Span, args: &FormatArguments, used: &[bool], placeholders: Vec<(Span, &str)>, @@ -769,9 +768,9 @@ fn report_redundant_format_arguments<'a>( } return Some(ecx.create_err(errors::FormatRedundantArgs { - fmt_span, - note: multispan, n: args_spans.len(), + span: MultiSpan::from(args_spans), + note: multispan, sugg: errors::FormatRedundantArgsSugg { spans: suggestion_spans }, })); } diff --git a/tests/ui/did_you_mean/issue-105225.rs b/tests/ui/did_you_mean/issue-105225.rs index 49070b52dd0..5c0d17f5839 100644 --- a/tests/ui/did_you_mean/issue-105225.rs +++ b/tests/ui/did_you_mean/issue-105225.rs @@ -1,5 +1,7 @@ fn main() { let x = 0; + let y = 0; + println!("{x}", x); //~^ ERROR: redundant argument @@ -9,11 +11,9 @@ fn main() { println!("{} {x}", x, x); //~^ ERROR: redundant argument - let y = 0; println!("{x} {y}", x, y); - //~^ ERROR: redundant argument + //~^ ERROR: redundant arguments - let y = 0; println!("{} {} {x} {y} {}", x, x, x, y, y); - //~^ ERROR: redundant argument + //~^ ERROR: redundant arguments } diff --git a/tests/ui/did_you_mean/issue-105225.stderr b/tests/ui/did_you_mean/issue-105225.stderr index dc18e7268b4..b9b04a0fe2e 100644 --- a/tests/ui/did_you_mean/issue-105225.stderr +++ b/tests/ui/did_you_mean/issue-105225.stderr @@ -1,47 +1,47 @@ error: redundant argument - --> $DIR/issue-105225.rs:3:14 + --> $DIR/issue-105225.rs:5:21 | LL | println!("{x}", x); - | ^^^^^ - help: this can be removed + | ^ help: this can be removed | note: the formatting specifier is referencing the binding already - --> $DIR/issue-105225.rs:3:16 + --> $DIR/issue-105225.rs:5:16 | LL | println!("{x}", x); | ^ error: redundant argument - --> $DIR/issue-105225.rs:6:14 + --> $DIR/issue-105225.rs:8:27 | LL | println!("{x} {}", x, x); - | ^^^^^^^^ - help: this can be removed + | ^ help: this can be removed | note: the formatting specifier is referencing the binding already - --> $DIR/issue-105225.rs:6:16 + --> $DIR/issue-105225.rs:8:16 | LL | println!("{x} {}", x, x); | ^ error: redundant argument - --> $DIR/issue-105225.rs:9:14 + --> $DIR/issue-105225.rs:11:27 | LL | println!("{} {x}", x, x); - | ^^^^^^^^ - help: this can be removed + | ^ help: this can be removed | note: the formatting specifier is referencing the binding already - --> $DIR/issue-105225.rs:9:19 + --> $DIR/issue-105225.rs:11:19 | LL | println!("{} {x}", x, x); | ^ error: redundant arguments - --> $DIR/issue-105225.rs:13:14 + --> $DIR/issue-105225.rs:14:25 | LL | println!("{x} {y}", x, y); - | ^^^^^^^^^ + | ^ ^ | note: the formatting specifiers are referencing the bindings already - --> $DIR/issue-105225.rs:13:16 + --> $DIR/issue-105225.rs:14:16 | LL | println!("{x} {y}", x, y); | ^ ^ @@ -52,10 +52,10 @@ LL + println!("{x} {y}", ); | error: redundant arguments - --> $DIR/issue-105225.rs:17:14 + --> $DIR/issue-105225.rs:17:43 | LL | println!("{} {} {x} {y} {}", x, x, x, y, y); - | ^^^^^^^^^^^^^^^^^^ + | ^ ^ | note: the formatting specifiers are referencing the bindings already --> $DIR/issue-105225.rs:17:26 From 38b01828328014708feb48f9cdc065460e651098 Mon Sep 17 00:00:00 2001 From: francorbacho Date: Thu, 5 Oct 2023 14:59:15 +0200 Subject: [PATCH 11/29] Add suggestion test --- tests/ui/did_you_mean/issue-105225.fixed | 21 +++++++++++++++++++++ tests/ui/did_you_mean/issue-105225.rs | 2 ++ tests/ui/did_you_mean/issue-105225.stderr | 20 ++++++++++---------- 3 files changed, 33 insertions(+), 10 deletions(-) create mode 100644 tests/ui/did_you_mean/issue-105225.fixed diff --git a/tests/ui/did_you_mean/issue-105225.fixed b/tests/ui/did_you_mean/issue-105225.fixed new file mode 100644 index 00000000000..30c99221912 --- /dev/null +++ b/tests/ui/did_you_mean/issue-105225.fixed @@ -0,0 +1,21 @@ +// run-rustfix + +fn main() { + let x = 0; + let y = 0; + + println!("{x}", ); + //~^ ERROR: redundant argument + + println!("{x} {}", x, ); + //~^ ERROR: redundant argument + + println!("{} {x}", x, ); + //~^ ERROR: redundant argument + + println!("{x} {y}", ); + //~^ ERROR: redundant arguments + + println!("{} {} {x} {y} {}", x, x, x, ); + //~^ ERROR: redundant arguments +} diff --git a/tests/ui/did_you_mean/issue-105225.rs b/tests/ui/did_you_mean/issue-105225.rs index 5c0d17f5839..a69c90a6490 100644 --- a/tests/ui/did_you_mean/issue-105225.rs +++ b/tests/ui/did_you_mean/issue-105225.rs @@ -1,3 +1,5 @@ +// run-rustfix + fn main() { let x = 0; let y = 0; diff --git a/tests/ui/did_you_mean/issue-105225.stderr b/tests/ui/did_you_mean/issue-105225.stderr index b9b04a0fe2e..5fb46222bee 100644 --- a/tests/ui/did_you_mean/issue-105225.stderr +++ b/tests/ui/did_you_mean/issue-105225.stderr @@ -1,47 +1,47 @@ error: redundant argument - --> $DIR/issue-105225.rs:5:21 + --> $DIR/issue-105225.rs:7:21 | LL | println!("{x}", x); | ^ help: this can be removed | note: the formatting specifier is referencing the binding already - --> $DIR/issue-105225.rs:5:16 + --> $DIR/issue-105225.rs:7:16 | LL | println!("{x}", x); | ^ error: redundant argument - --> $DIR/issue-105225.rs:8:27 + --> $DIR/issue-105225.rs:10:27 | LL | println!("{x} {}", x, x); | ^ help: this can be removed | note: the formatting specifier is referencing the binding already - --> $DIR/issue-105225.rs:8:16 + --> $DIR/issue-105225.rs:10:16 | LL | println!("{x} {}", x, x); | ^ error: redundant argument - --> $DIR/issue-105225.rs:11:27 + --> $DIR/issue-105225.rs:13:27 | LL | println!("{} {x}", x, x); | ^ help: this can be removed | note: the formatting specifier is referencing the binding already - --> $DIR/issue-105225.rs:11:19 + --> $DIR/issue-105225.rs:13:19 | LL | println!("{} {x}", x, x); | ^ error: redundant arguments - --> $DIR/issue-105225.rs:14:25 + --> $DIR/issue-105225.rs:16:25 | LL | println!("{x} {y}", x, y); | ^ ^ | note: the formatting specifiers are referencing the bindings already - --> $DIR/issue-105225.rs:14:16 + --> $DIR/issue-105225.rs:16:16 | LL | println!("{x} {y}", x, y); | ^ ^ @@ -52,13 +52,13 @@ LL + println!("{x} {y}", ); | error: redundant arguments - --> $DIR/issue-105225.rs:17:43 + --> $DIR/issue-105225.rs:19:43 | LL | println!("{} {} {x} {y} {}", x, x, x, y, y); | ^ ^ | note: the formatting specifiers are referencing the bindings already - --> $DIR/issue-105225.rs:17:26 + --> $DIR/issue-105225.rs:19:26 | LL | println!("{} {} {x} {y} {}", x, x, x, y, y); | ^ From c8ee7db6ea272b42e90602007807be6c2191f96b Mon Sep 17 00:00:00 2001 From: francorbacho Date: Thu, 5 Oct 2023 15:46:34 +0200 Subject: [PATCH 12/29] Only give autofix suggestion when no named args are present --- compiler/rustc_builtin_macros/src/errors.rs | 2 +- compiler/rustc_builtin_macros/src/format.rs | 8 ++++++- .../did_you_mean/issue-105225-named-args.rs | 10 +++++++++ .../issue-105225-named-args.stderr | 22 +++++++++++++++++++ tests/ui/did_you_mean/issue-105225.fixed | 4 ++-- tests/ui/did_you_mean/issue-105225.rs | 4 ++-- 6 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 tests/ui/did_you_mean/issue-105225-named-args.rs create mode 100644 tests/ui/did_you_mean/issue-105225-named-args.stderr diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index 7a8ec5cfdf3..fde4270334b 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -657,7 +657,7 @@ pub(crate) struct FormatRedundantArgs { pub(crate) note: MultiSpan, #[subdiagnostic] - pub(crate) sugg: FormatRedundantArgsSugg, + pub(crate) sugg: Option, } #[derive(Subdiagnostic)] diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index e08fded01fb..7c78be17653 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -767,11 +767,17 @@ fn report_redundant_format_arguments<'a>( suggestion_spans.push(span); } + let sugg = if args.named_args().len() == 0 { + Some(errors::FormatRedundantArgsSugg { spans: suggestion_spans }) + } else { + None + }; + return Some(ecx.create_err(errors::FormatRedundantArgs { n: args_spans.len(), span: MultiSpan::from(args_spans), note: multispan, - sugg: errors::FormatRedundantArgsSugg { spans: suggestion_spans }, + sugg, })); } diff --git a/tests/ui/did_you_mean/issue-105225-named-args.rs b/tests/ui/did_you_mean/issue-105225-named-args.rs new file mode 100644 index 00000000000..38e81776576 --- /dev/null +++ b/tests/ui/did_you_mean/issue-105225-named-args.rs @@ -0,0 +1,10 @@ +fn main() { + let x = "x"; + let y = "y"; + + println!("{x}", x, x = y); + //~^ ERROR: redundant argument + + println!("{x}", x = y, x = y); + //~^ ERROR: duplicate argument named `x` +} diff --git a/tests/ui/did_you_mean/issue-105225-named-args.stderr b/tests/ui/did_you_mean/issue-105225-named-args.stderr new file mode 100644 index 00000000000..72204102ef6 --- /dev/null +++ b/tests/ui/did_you_mean/issue-105225-named-args.stderr @@ -0,0 +1,22 @@ +error: redundant argument + --> $DIR/issue-105225-named-args.rs:5:21 + | +LL | println!("{x}", x, x = y); + | ^ + | +note: the formatting specifier is referencing the binding already + --> $DIR/issue-105225-named-args.rs:5:16 + | +LL | println!("{x}", x, x = y); + | ^ + +error: duplicate argument named `x` + --> $DIR/issue-105225-named-args.rs:8:28 + | +LL | println!("{x}", x = y, x = y); + | - ^ duplicate argument + | | + | previously here + +error: aborting due to 2 previous errors + diff --git a/tests/ui/did_you_mean/issue-105225.fixed b/tests/ui/did_you_mean/issue-105225.fixed index 30c99221912..f756be615a1 100644 --- a/tests/ui/did_you_mean/issue-105225.fixed +++ b/tests/ui/did_you_mean/issue-105225.fixed @@ -1,8 +1,8 @@ // run-rustfix fn main() { - let x = 0; - let y = 0; + let x = "x"; + let y = "y"; println!("{x}", ); //~^ ERROR: redundant argument diff --git a/tests/ui/did_you_mean/issue-105225.rs b/tests/ui/did_you_mean/issue-105225.rs index a69c90a6490..91cdf0eb28f 100644 --- a/tests/ui/did_you_mean/issue-105225.rs +++ b/tests/ui/did_you_mean/issue-105225.rs @@ -1,8 +1,8 @@ // run-rustfix fn main() { - let x = 0; - let y = 0; + let x = "x"; + let y = "y"; println!("{x}", x); //~^ ERROR: redundant argument From cbc6b65d9a4a404392a928dfc200a7616cfc2c98 Mon Sep 17 00:00:00 2001 From: francorbacho Date: Thu, 5 Oct 2023 16:16:31 +0200 Subject: [PATCH 13/29] Keep fluent slugs in alphabetical order --- compiler/rustc_builtin_macros/messages.ftl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl index 8f158fb17da..dda466b026d 100644 --- a/compiler/rustc_builtin_macros/messages.ftl +++ b/compiler/rustc_builtin_macros/messages.ftl @@ -137,8 +137,6 @@ builtin_macros_format_positional_after_named = positional arguments cannot follo .label = positional arguments must be before named arguments .named_args = named argument -builtin_macros_format_remove_raw_ident = remove the `r#` - builtin_macros_format_redundant_args = redundant {$n -> [one] argument *[more] arguments @@ -153,6 +151,8 @@ builtin_macros_format_redundant_args = redundant {$n -> } .suggestion = this can be removed +builtin_macros_format_remove_raw_ident = remove the `r#` + builtin_macros_format_requires_string = requires at least a format string argument builtin_macros_format_string_invalid = invalid format string: {$desc} From 5f86fe96d8de12ffc6d88a8a7e3df7a15b38c298 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 19 Oct 2023 10:47:18 -0700 Subject: [PATCH 14/29] ci: add a runner for vanilla LLVM 17 --- .github/workflows/ci.yml | 4 ++ .../host-x86_64/x86_64-gnu-llvm-17/Dockerfile | 50 +++++++++++++++++++ src/ci/github-actions/ci.yml | 5 ++ 3 files changed, 59 insertions(+) create mode 100644 src/ci/docker/host-x86_64/x86_64-gnu-llvm-17/Dockerfile diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8c207e7ea11..41b4797e705 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -283,6 +283,10 @@ jobs: - name: x86_64-gnu-distcheck os: ubuntu-20.04-8core-32gb env: {} + - name: x86_64-gnu-llvm-17 + env: + RUST_BACKTRACE: 1 + os: ubuntu-20.04-8core-32gb - name: x86_64-gnu-llvm-16 env: RUST_BACKTRACE: 1 diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-17/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-17/Dockerfile new file mode 100644 index 00000000000..76846f1fed7 --- /dev/null +++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-17/Dockerfile @@ -0,0 +1,50 @@ +FROM ubuntu:23.10 + +ARG DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && apt-get install -y --no-install-recommends \ + g++ \ + gcc-multilib \ + make \ + ninja-build \ + file \ + curl \ + ca-certificates \ + python3 \ + git \ + cmake \ + sudo \ + gdb \ + llvm-17-tools \ + llvm-17-dev \ + libedit-dev \ + libssl-dev \ + pkg-config \ + zlib1g-dev \ + xz-utils \ + nodejs \ + mingw-w64 \ + && rm -rf /var/lib/apt/lists/* + +# Install powershell (universal package) so we can test x.ps1 on Linux +RUN curl -sL "https://github.com/PowerShell/PowerShell/releases/download/v7.3.1/powershell_7.3.1-1.deb_amd64.deb" > powershell.deb && \ + dpkg -i powershell.deb && \ + rm -f powershell.deb + +COPY scripts/sccache.sh /scripts/ +RUN sh /scripts/sccache.sh + +# We are disabling CI LLVM since this builder is intentionally using a host +# LLVM, rather than the typical src/llvm-project LLVM. +ENV NO_DOWNLOAD_CI_LLVM 1 + +# Using llvm-link-shared due to libffi issues -- see #34486 +ENV RUST_CONFIGURE_ARGS \ + --build=x86_64-unknown-linux-gnu \ + --llvm-root=/usr/lib/llvm-17 \ + --enable-llvm-link-shared \ + --set rust.thin-lto-import-instr-limit=10 + +COPY host-x86_64/x86_64-gnu-llvm-15/script.sh /tmp/ + +ENV SCRIPT /tmp/script.sh diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index 93b07350ac1..cb164eecc90 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -455,6 +455,11 @@ jobs: - name: x86_64-gnu-distcheck <<: *job-linux-8c + - name: x86_64-gnu-llvm-17 + env: + RUST_BACKTRACE: 1 + <<: *job-linux-8c + - name: x86_64-gnu-llvm-16 env: RUST_BACKTRACE: 1 From 048e54658a3e9485b2876052a3a5b8392f9f944a Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 19 Oct 2023 10:49:38 -0700 Subject: [PATCH 15/29] ci: set IS_NOT_LATEST_LLVM for llvm-16 --- src/ci/docker/host-x86_64/x86_64-gnu-llvm-16/Dockerfile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-16/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-16/Dockerfile index 1e2b802e64e..c177e7387fc 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-16/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-16/Dockerfile @@ -38,6 +38,10 @@ RUN sh /scripts/sccache.sh # LLVM, rather than the typical src/llvm-project LLVM. ENV NO_DOWNLOAD_CI_LLVM 1 +# This is not the latest LLVM version, so some components required by tests may +# be missing. +ENV IS_NOT_LATEST_LLVM 1 + # Using llvm-link-shared due to libffi issues -- see #34486 ENV RUST_CONFIGURE_ARGS \ --build=x86_64-unknown-linux-gnu \ From eeea74785d6a81796dce5125eb62672c1ba8c21d Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Thu, 19 Oct 2023 21:44:23 +0100 Subject: [PATCH 16/29] Update hashbrown to 0.14.2 Fixes #116880 --- Cargo.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aa2f9c4147e..44cf900521e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1641,9 +1641,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.14.0" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" dependencies = [ "ahash", "allocator-api2", @@ -1960,7 +1960,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" dependencies = [ "equivalent", - "hashbrown 0.14.0", + "hashbrown 0.14.2", "rustc-rayon", "serde", ] @@ -2589,7 +2589,7 @@ dependencies = [ "compiler_builtins", "crc32fast", "flate2", - "hashbrown 0.14.0", + "hashbrown 0.14.2", "indexmap 2.0.0", "memchr", "rustc-std-workspace-alloc", @@ -5064,7 +5064,7 @@ dependencies = [ "core", "dlmalloc", "fortanix-sgx-abi", - "hashbrown 0.14.0", + "hashbrown 0.14.2", "hermit-abi 0.3.2", "libc", "miniz_oxide", @@ -5384,7 +5384,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4db52ee8fec06e119b692ef3dd2c4cf621a99204c1b8c47407870ed050305b9b" dependencies = [ "gimli", - "hashbrown 0.14.0", + "hashbrown 0.14.2", "object", "tracing", ] From 7eee62c9beac6ea63ef26ce0ef14c3757f42468b Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Fri, 20 Oct 2023 10:49:40 -0600 Subject: [PATCH 17/29] Use gdb.ValuePrinter tag class GDB 14 has a "gdb.ValuePrinter" tag class that was introduced to let GDB evolve the pretty-printer API. Users of this tag are required to hide any local attributes or methods. This patch makes this change to the Rust pretty-printers. At present this is just a cleanup, providing the basis for any future changes. --- src/etc/gdb_providers.py | 299 ++++++++++++++++++++------------------- 1 file changed, 154 insertions(+), 145 deletions(-) diff --git a/src/etc/gdb_providers.py b/src/etc/gdb_providers.py index 32b8d8e24c6..e851aa62634 100644 --- a/src/etc/gdb_providers.py +++ b/src/etc/gdb_providers.py @@ -18,70 +18,79 @@ def unwrap_unique_or_non_null(unique_or_nonnull): return ptr if ptr.type.code == gdb.TYPE_CODE_PTR else ptr[ptr.type.fields()[0]] -class EnumProvider: +# GDB 14 has a tag class that indicates that extension methods are ok +# to call. Use of this tag only requires that printers hide local +# attributes and methods by prefixing them with "_". +if hasattr(gdb, 'ValuePrinter'): + printer_base = gdb.ValuePrinter +else: + printer_base = object + + +class EnumProvider(printer_base): def __init__(self, valobj): content = valobj[valobj.type.fields()[0]] fields = content.type.fields() - self.empty = len(fields) == 0 - if not self.empty: + self._empty = len(fields) == 0 + if not self._empty: if len(fields) == 1: discriminant = 0 else: discriminant = int(content[fields[0]]) + 1 - self.active_variant = content[fields[discriminant]] - self.name = fields[discriminant].name - self.full_name = "{}::{}".format(valobj.type.name, self.name) + self._active_variant = content[fields[discriminant]] + self._name = fields[discriminant].name + self._full_name = "{}::{}".format(valobj.type.name, self._name) else: - self.full_name = valobj.type.name + self._full_name = valobj.type.name def to_string(self): - return self.full_name + return self._full_name def children(self): - if not self.empty: - yield self.name, self.active_variant + if not self._empty: + yield self._name, self._active_variant -class StdStringProvider: +class StdStringProvider(printer_base): def __init__(self, valobj): - self.valobj = valobj + self._valobj = valobj vec = valobj["vec"] - self.length = int(vec["len"]) - self.data_ptr = unwrap_unique_or_non_null(vec["buf"]["ptr"]) + self._length = int(vec["len"]) + self._data_ptr = unwrap_unique_or_non_null(vec["buf"]["ptr"]) def to_string(self): - return self.data_ptr.lazy_string(encoding="utf-8", length=self.length) + return self._data_ptr.lazy_string(encoding="utf-8", length=self._length) @staticmethod def display_hint(): return "string" -class StdOsStringProvider: +class StdOsStringProvider(printer_base): def __init__(self, valobj): - self.valobj = valobj - buf = self.valobj["inner"]["inner"] + self._valobj = valobj + buf = self._valobj["inner"]["inner"] is_windows = "Wtf8Buf" in buf.type.name vec = buf[ZERO_FIELD] if is_windows else buf - self.length = int(vec["len"]) - self.data_ptr = unwrap_unique_or_non_null(vec["buf"]["ptr"]) + self._length = int(vec["len"]) + self._data_ptr = unwrap_unique_or_non_null(vec["buf"]["ptr"]) def to_string(self): - return self.data_ptr.lazy_string(encoding="utf-8", length=self.length) + return self._data_ptr.lazy_string(encoding="utf-8", length=self._length) def display_hint(self): return "string" -class StdStrProvider: +class StdStrProvider(printer_base): def __init__(self, valobj): - self.valobj = valobj - self.length = int(valobj["length"]) - self.data_ptr = valobj["data_ptr"] + self._valobj = valobj + self._length = int(valobj["length"]) + self._data_ptr = valobj["data_ptr"] def to_string(self): - return self.data_ptr.lazy_string(encoding="utf-8", length=self.length) + return self._data_ptr.lazy_string(encoding="utf-8", length=self._length) @staticmethod def display_hint(): @@ -103,36 +112,36 @@ def _enumerate_array_elements(element_ptrs): yield key, element -class StdSliceProvider: +class StdSliceProvider(printer_base): def __init__(self, valobj): - self.valobj = valobj - self.length = int(valobj["length"]) - self.data_ptr = valobj["data_ptr"] + self._valobj = valobj + self._length = int(valobj["length"]) + self._data_ptr = valobj["data_ptr"] def to_string(self): - return "{}(size={})".format(self.valobj.type, self.length) + return "{}(size={})".format(self._valobj.type, self._length) def children(self): return _enumerate_array_elements( - self.data_ptr + index for index in xrange(self.length) + self._data_ptr + index for index in xrange(self._length) ) @staticmethod def display_hint(): return "array" -class StdVecProvider: +class StdVecProvider(printer_base): def __init__(self, valobj): - self.valobj = valobj - self.length = int(valobj["len"]) - self.data_ptr = unwrap_unique_or_non_null(valobj["buf"]["ptr"]) + self._valobj = valobj + self._length = int(valobj["len"]) + self._data_ptr = unwrap_unique_or_non_null(valobj["buf"]["ptr"]) def to_string(self): - return "Vec(size={})".format(self.length) + return "Vec(size={})".format(self._length) def children(self): return _enumerate_array_elements( - self.data_ptr + index for index in xrange(self.length) + self._data_ptr + index for index in xrange(self._length) ) @staticmethod @@ -140,20 +149,20 @@ class StdVecProvider: return "array" -class StdVecDequeProvider: +class StdVecDequeProvider(printer_base): def __init__(self, valobj): - self.valobj = valobj - self.head = int(valobj["head"]) - self.size = int(valobj["len"]) - self.cap = int(valobj["buf"]["cap"]) - self.data_ptr = unwrap_unique_or_non_null(valobj["buf"]["ptr"]) + self._valobj = valobj + self._head = int(valobj["head"]) + self._size = int(valobj["len"]) + self._cap = int(valobj["buf"]["cap"]) + self._data_ptr = unwrap_unique_or_non_null(valobj["buf"]["ptr"]) def to_string(self): - return "VecDeque(size={})".format(self.size) + return "VecDeque(size={})".format(self._size) def children(self): return _enumerate_array_elements( - (self.data_ptr + ((self.head + index) % self.cap)) for index in xrange(self.size) + (self._data_ptr + ((self._head + index) % self._cap)) for index in xrange(self._size) ) @staticmethod @@ -161,81 +170,81 @@ class StdVecDequeProvider: return "array" -class StdRcProvider: +class StdRcProvider(printer_base): def __init__(self, valobj, is_atomic=False): - self.valobj = valobj - self.is_atomic = is_atomic - self.ptr = unwrap_unique_or_non_null(valobj["ptr"]) - self.value = self.ptr["data" if is_atomic else "value"] - self.strong = self.ptr["strong"]["v" if is_atomic else "value"]["value"] - self.weak = self.ptr["weak"]["v" if is_atomic else "value"]["value"] - 1 + self._valobj = valobj + self._is_atomic = is_atomic + self._ptr = unwrap_unique_or_non_null(valobj["ptr"]) + self._value = self._ptr["data" if is_atomic else "value"] + self._strong = self._ptr["strong"]["v" if is_atomic else "value"]["value"] + self._weak = self._ptr["weak"]["v" if is_atomic else "value"]["value"] - 1 def to_string(self): - if self.is_atomic: - return "Arc(strong={}, weak={})".format(int(self.strong), int(self.weak)) + if self._is_atomic: + return "Arc(strong={}, weak={})".format(int(self._strong), int(self._weak)) else: - return "Rc(strong={}, weak={})".format(int(self.strong), int(self.weak)) + return "Rc(strong={}, weak={})".format(int(self._strong), int(self._weak)) def children(self): - yield "value", self.value - yield "strong", self.strong - yield "weak", self.weak + yield "value", self._value + yield "strong", self._strong + yield "weak", self._weak -class StdCellProvider: +class StdCellProvider(printer_base): def __init__(self, valobj): - self.value = valobj["value"]["value"] + self._value = valobj["value"]["value"] def to_string(self): return "Cell" def children(self): - yield "value", self.value + yield "value", self._value -class StdRefProvider: +class StdRefProvider(printer_base): def __init__(self, valobj): - self.value = valobj["value"].dereference() - self.borrow = valobj["borrow"]["borrow"]["value"]["value"] + self._value = valobj["value"].dereference() + self._borrow = valobj["borrow"]["borrow"]["value"]["value"] def to_string(self): - borrow = int(self.borrow) + borrow = int(self._borrow) if borrow >= 0: return "Ref(borrow={})".format(borrow) else: return "Ref(borrow_mut={})".format(-borrow) def children(self): - yield "*value", self.value - yield "borrow", self.borrow + yield "*value", self._value + yield "borrow", self._borrow -class StdRefCellProvider: +class StdRefCellProvider(printer_base): def __init__(self, valobj): - self.value = valobj["value"]["value"] - self.borrow = valobj["borrow"]["value"]["value"] + self._value = valobj["value"]["value"] + self._borrow = valobj["borrow"]["value"]["value"] def to_string(self): - borrow = int(self.borrow) + borrow = int(self._borrow) if borrow >= 0: return "RefCell(borrow={})".format(borrow) else: return "RefCell(borrow_mut={})".format(-borrow) def children(self): - yield "value", self.value - yield "borrow", self.borrow + yield "value", self._value + yield "borrow", self._borrow -class StdNonZeroNumberProvider: +class StdNonZeroNumberProvider(printer_base): def __init__(self, valobj): fields = valobj.type.fields() assert len(fields) == 1 field = list(fields)[0] - self.value = str(valobj[field.name]) + self._value = str(valobj[field.name]) def to_string(self): - return self.value + return self._value # Yields children (in a provider's sense of the word) for a BTreeMap. @@ -280,15 +289,15 @@ def children_of_btree_map(map): yield child -class StdBTreeSetProvider: +class StdBTreeSetProvider(printer_base): def __init__(self, valobj): - self.valobj = valobj + self._valobj = valobj def to_string(self): - return "BTreeSet(size={})".format(self.valobj["map"]["length"]) + return "BTreeSet(size={})".format(self._valobj["map"]["length"]) def children(self): - inner_map = self.valobj["map"] + inner_map = self._valobj["map"] for i, (child, _) in enumerate(children_of_btree_map(inner_map)): yield "[{}]".format(i), child @@ -297,15 +306,15 @@ class StdBTreeSetProvider: return "array" -class StdBTreeMapProvider: +class StdBTreeMapProvider(printer_base): def __init__(self, valobj): - self.valobj = valobj + self._valobj = valobj def to_string(self): - return "BTreeMap(size={})".format(self.valobj["length"]) + return "BTreeMap(size={})".format(self._valobj["length"]) def children(self): - for i, (key, val) in enumerate(children_of_btree_map(self.valobj)): + for i, (key, val) in enumerate(children_of_btree_map(self._valobj)): yield "key{}".format(i), key yield "val{}".format(i), val @@ -315,124 +324,124 @@ class StdBTreeMapProvider: # BACKCOMPAT: rust 1.35 -class StdOldHashMapProvider: +class StdOldHashMapProvider(printer_base): def __init__(self, valobj, show_values=True): - self.valobj = valobj - self.show_values = show_values + self._valobj = valobj + self._show_values = show_values - self.table = self.valobj["table"] - self.size = int(self.table["size"]) - self.hashes = self.table["hashes"] - self.hash_uint_type = self.hashes.type - self.hash_uint_size = self.hashes.type.sizeof - self.modulo = 2 ** self.hash_uint_size - self.data_ptr = self.hashes[ZERO_FIELD]["pointer"] + self._table = self._valobj["table"] + self._size = int(self._table["size"]) + self._hashes = self._table["hashes"] + self._hash_uint_type = self._hashes.type + self._hash_uint_size = self._hashes.type.sizeof + self._modulo = 2 ** self._hash_uint_size + self._data_ptr = self._hashes[ZERO_FIELD]["pointer"] - self.capacity_mask = int(self.table["capacity_mask"]) - self.capacity = (self.capacity_mask + 1) % self.modulo + self._capacity_mask = int(self._table["capacity_mask"]) + self._capacity = (self._capacity_mask + 1) % self._modulo - marker = self.table["marker"].type - self.pair_type = marker.template_argument(0) - self.pair_type_size = self.pair_type.sizeof + marker = self._table["marker"].type + self._pair_type = marker.template_argument(0) + self._pair_type_size = self._pair_type.sizeof - self.valid_indices = [] - for idx in range(self.capacity): - data_ptr = self.data_ptr.cast(self.hash_uint_type.pointer()) + self._valid_indices = [] + for idx in range(self._capacity): + data_ptr = self._data_ptr.cast(self._hash_uint_type.pointer()) address = data_ptr + idx hash_uint = address.dereference() hash_ptr = hash_uint[ZERO_FIELD]["pointer"] if int(hash_ptr) != 0: - self.valid_indices.append(idx) + self._valid_indices.append(idx) def to_string(self): - if self.show_values: - return "HashMap(size={})".format(self.size) + if self._show_values: + return "HashMap(size={})".format(self._size) else: - return "HashSet(size={})".format(self.size) + return "HashSet(size={})".format(self._size) def children(self): - start = int(self.data_ptr) & ~1 + start = int(self._data_ptr) & ~1 - hashes = self.hash_uint_size * self.capacity - align = self.pair_type_size - len_rounded_up = (((((hashes + align) % self.modulo - 1) % self.modulo) & ~( - (align - 1) % self.modulo)) % self.modulo - hashes) % self.modulo + hashes = self._hash_uint_size * self._capacity + align = self._pair_type_size + len_rounded_up = (((((hashes + align) % self._modulo - 1) % self._modulo) & ~( + (align - 1) % self._modulo)) % self._modulo - hashes) % self._modulo pairs_offset = hashes + len_rounded_up - pairs_start = gdb.Value(start + pairs_offset).cast(self.pair_type.pointer()) + pairs_start = gdb.Value(start + pairs_offset).cast(self._pair_type.pointer()) - for index in range(self.size): - table_index = self.valid_indices[index] - idx = table_index & self.capacity_mask + for index in range(self._size): + table_index = self._valid_indices[index] + idx = table_index & self._capacity_mask element = (pairs_start + idx).dereference() - if self.show_values: + if self._show_values: yield "key{}".format(index), element[ZERO_FIELD] yield "val{}".format(index), element[FIRST_FIELD] else: yield "[{}]".format(index), element[ZERO_FIELD] def display_hint(self): - return "map" if self.show_values else "array" + return "map" if self._show_values else "array" -class StdHashMapProvider: +class StdHashMapProvider(printer_base): def __init__(self, valobj, show_values=True): - self.valobj = valobj - self.show_values = show_values + self._valobj = valobj + self._show_values = show_values - table = self.table() + table = self._table() table_inner = table["table"] capacity = int(table_inner["bucket_mask"]) + 1 ctrl = table_inner["ctrl"]["pointer"] - self.size = int(table_inner["items"]) - self.pair_type = table.type.template_argument(0).strip_typedefs() + self._size = int(table_inner["items"]) + self._pair_type = table.type.template_argument(0).strip_typedefs() - self.new_layout = not table_inner.type.has_key("data") - if self.new_layout: - self.data_ptr = ctrl.cast(self.pair_type.pointer()) + self._new_layout = not table_inner.type.has_key("data") + if self._new_layout: + self._data_ptr = ctrl.cast(self._pair_type.pointer()) else: - self.data_ptr = table_inner["data"]["pointer"] + self._data_ptr = table_inner["data"]["pointer"] - self.valid_indices = [] + self._valid_indices = [] for idx in range(capacity): address = ctrl + idx value = address.dereference() is_presented = value & 128 == 0 if is_presented: - self.valid_indices.append(idx) + self._valid_indices.append(idx) - def table(self): - if self.show_values: - hashbrown_hashmap = self.valobj["base"] - elif self.valobj.type.fields()[0].name == "map": + def _table(self): + if self._show_values: + hashbrown_hashmap = self._valobj["base"] + elif self._valobj.type.fields()[0].name == "map": # BACKCOMPAT: rust 1.47 # HashSet wraps std::collections::HashMap, which wraps hashbrown::HashMap - hashbrown_hashmap = self.valobj["map"]["base"] + hashbrown_hashmap = self._valobj["map"]["base"] else: # HashSet wraps hashbrown::HashSet, which wraps hashbrown::HashMap - hashbrown_hashmap = self.valobj["base"]["map"] + hashbrown_hashmap = self._valobj["base"]["map"] return hashbrown_hashmap["table"] def to_string(self): - if self.show_values: - return "HashMap(size={})".format(self.size) + if self._show_values: + return "HashMap(size={})".format(self._size) else: - return "HashSet(size={})".format(self.size) + return "HashSet(size={})".format(self._size) def children(self): - pairs_start = self.data_ptr + pairs_start = self._data_ptr - for index in range(self.size): - idx = self.valid_indices[index] - if self.new_layout: + for index in range(self._size): + idx = self._valid_indices[index] + if self._new_layout: idx = -(idx + 1) element = (pairs_start + idx).dereference() - if self.show_values: + if self._show_values: yield "key{}".format(index), element[ZERO_FIELD] yield "val{}".format(index), element[FIRST_FIELD] else: yield "[{}]".format(index), element[ZERO_FIELD] def display_hint(self): - return "map" if self.show_values else "array" + return "map" if self._show_values else "array" From 46f68ccb8b88c77edc5ed3d5d5cfb6189910af37 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Fri, 20 Oct 2023 18:10:34 +0100 Subject: [PATCH 18/29] Skip test if Unix sockets are unsupported --- library/std/src/fs/tests.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index f0c4be2327c..736b495343e 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -1717,7 +1717,7 @@ fn windows_unix_socket_exists() { let tmp = tmpdir(); let socket_path = tmp.join("socket"); - // std doesn't current support Unix sockets on Windows so manually create one here. + // std doesn't currently support Unix sockets on Windows so manually create one here. net::init(); unsafe { let socket = c::WSASocketW( @@ -1728,7 +1728,16 @@ fn windows_unix_socket_exists() { 0, c::WSA_FLAG_OVERLAPPED | c::WSA_FLAG_NO_HANDLE_INHERIT, ); - assert_ne!(socket, c::INVALID_SOCKET); + // AF_UNIX is not supported on earlier versions of Windows, + // so skip this test if it's unsupported and we're not in CI. + if socket == c::INVALID_SOCKET { + let error = c::WSAGetLastError(); + if env::var_os("CI").is_none() && error == c::WSAEAFNOSUPPORT { + return; + } else { + panic!("Creating AF_UNIX socket failed (OS error {error})"); + } + } let mut addr = c::SOCKADDR_UN { sun_family: c::AF_UNIX, sun_path: mem::zeroed() }; let bytes = socket_path.as_os_str().as_encoded_bytes(); addr.sun_path[..bytes.len()].copy_from_slice(bytes); From 45e74236aaae1187949de3ec76c4363d497bd4c7 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Fri, 20 Oct 2023 18:56:53 -0400 Subject: [PATCH 19/29] Update cargo --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index 8eb8acbb116..d2f6a048529 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 8eb8acbb116e7923ea2ce33a50109933ed5ab375 +Subproject commit d2f6a048529eb8e9ebc55d793abd63456c98fac2 From 4851cc938023d8eac9b9e36a0f8e6e8abc6d9b0e Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 20 Oct 2023 18:26:20 -0700 Subject: [PATCH 20/29] rustdoc: avoid allocating strings primitive link printing This is aimed at hitting the allocator less in a function that gets called a lot. --- src/librustdoc/html/format.rs | 77 +++++++++++++++++++++++------------ 1 file changed, 51 insertions(+), 26 deletions(-) diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index aa3f7184b4e..29fd880af50 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -847,7 +847,7 @@ fn resolved_path<'cx>( fn primitive_link( f: &mut fmt::Formatter<'_>, prim: clean::PrimitiveType, - name: &str, + name: fmt::Arguments<'_>, cx: &Context<'_>, ) -> fmt::Result { primitive_link_fragment(f, prim, name, "", cx) @@ -856,7 +856,7 @@ fn primitive_link( fn primitive_link_fragment( f: &mut fmt::Formatter<'_>, prim: clean::PrimitiveType, - name: &str, + name: fmt::Arguments<'_>, fragment: &str, cx: &Context<'_>, ) -> fmt::Result { @@ -907,7 +907,7 @@ fn primitive_link_fragment( None => {} } } - f.write_str(name)?; + std::fmt::Display::fmt(&name, f)?; if needs_termination { write!(f, "")?; } @@ -977,9 +977,11 @@ fn fmt_type<'cx>( } clean::Infer => write!(f, "_"), clean::Primitive(clean::PrimitiveType::Never) => { - primitive_link(f, PrimitiveType::Never, "!", cx) + primitive_link(f, PrimitiveType::Never, format_args!("!"), cx) + } + clean::Primitive(prim) => { + primitive_link(f, prim, format_args!("{}", prim.as_sym().as_str()), cx) } - clean::Primitive(prim) => primitive_link(f, prim, prim.as_sym().as_str(), cx), clean::BareFunction(ref decl) => { if f.alternate() { write!( @@ -998,16 +1000,16 @@ fn fmt_type<'cx>( decl.unsafety.print_with_space(), print_abi_with_space(decl.abi) )?; - primitive_link(f, PrimitiveType::Fn, "fn", cx)?; + primitive_link(f, PrimitiveType::Fn, format_args!("fn"), cx)?; write!(f, "{}", decl.decl.print(cx)) } } clean::Tuple(ref typs) => { match &typs[..] { - &[] => primitive_link(f, PrimitiveType::Unit, "()", cx), + &[] => primitive_link(f, PrimitiveType::Unit, format_args!("()"), cx), [one] => { if let clean::Generic(name) = one { - primitive_link(f, PrimitiveType::Tuple, &format!("({name},)"), cx) + primitive_link(f, PrimitiveType::Tuple, format_args!("({name},)"), cx) } else { write!(f, "(")?; // Carry `f.alternate()` into this display w/o branching manually. @@ -1028,7 +1030,10 @@ fn fmt_type<'cx>( primitive_link( f, PrimitiveType::Tuple, - &format!("({})", generic_names.iter().map(|s| s.as_str()).join(", ")), + format_args!( + "({})", + generic_names.iter().map(|s| s.as_str()).join(", ") + ), cx, ) } else { @@ -1047,7 +1052,7 @@ fn fmt_type<'cx>( } clean::Slice(ref t) => match **t { clean::Generic(name) => { - primitive_link(f, PrimitiveType::Slice, &format!("[{name}]"), cx) + primitive_link(f, PrimitiveType::Slice, format_args!("[{name}]"), cx) } _ => { write!(f, "[")?; @@ -1059,7 +1064,7 @@ fn fmt_type<'cx>( clean::Generic(name) if !f.alternate() => primitive_link( f, PrimitiveType::Array, - &format!("[{name}; {n}]", n = Escape(n)), + format_args!("[{name}; {n}]", n = Escape(n)), cx, ), _ => { @@ -1069,7 +1074,12 @@ fn fmt_type<'cx>( write!(f, "; {n}")?; } else { write!(f, "; ")?; - primitive_link(f, PrimitiveType::Array, &format!("{n}", n = Escape(n)), cx)?; + primitive_link( + f, + PrimitiveType::Array, + format_args!("{n}", n = Escape(n)), + cx, + )?; } write!(f, "]") } @@ -1081,22 +1091,32 @@ fn fmt_type<'cx>( }; if matches!(**t, clean::Generic(_)) || t.is_assoc_ty() { - let text = if f.alternate() { - format!("*{m} {ty:#}", ty = t.print(cx)) + let ty = t.print(cx); + if f.alternate() { + primitive_link( + f, + clean::PrimitiveType::RawPointer, + format_args!("*{m} {ty:#}"), + cx, + ) } else { - format!("*{m} {ty}", ty = t.print(cx)) - }; - primitive_link(f, clean::PrimitiveType::RawPointer, &text, cx) + primitive_link( + f, + clean::PrimitiveType::RawPointer, + format_args!("*{m} {ty}"), + cx, + ) + } } else { - primitive_link(f, clean::PrimitiveType::RawPointer, &format!("*{m} "), cx)?; + primitive_link(f, clean::PrimitiveType::RawPointer, format_args!("*{m} "), cx)?; fmt::Display::fmt(&t.print(cx), f) } } clean::BorrowedRef { lifetime: ref l, mutability, type_: ref ty } => { - let lt = match l { - Some(l) => format!("{} ", l.print()), - _ => String::new(), - }; + let lt = display_fn(|f| match l { + Some(l) => write!(f, "{} ", l.print()), + _ => Ok(()), + }); let m = mutability.print_with_space(); let amp = if f.alternate() { "&" } else { "&" }; @@ -1104,7 +1124,7 @@ fn fmt_type<'cx>( return primitive_link( f, PrimitiveType::Reference, - &format!("{amp}{lt}{m}{name}"), + format_args!("{amp}{lt}{m}{name}"), cx, ); } @@ -1254,7 +1274,7 @@ impl clean::Impl { { // Hardcoded anchor library/core/src/primitive_docs.rs // Link should match `# Trait implementations` - primitive_link_fragment(f, PrimitiveType::Tuple, &format!("({name}₁, {name}₂, …, {name}ₙ)"), "#trait-implementations-1", cx)?; + primitive_link_fragment(f, PrimitiveType::Tuple, format_args!("({name}₁, {name}₂, …, {name}ₙ)"), "#trait-implementations-1", cx)?; } else if let clean::BareFunction(bare_fn) = &self.for_ && let [clean::Argument { type_: clean::Type::Generic(name), .. }] = &bare_fn.decl.inputs.values[..] && (self.kind.is_fake_variadic() || self.kind.is_auto()) @@ -1281,7 +1301,7 @@ impl clean::Impl { } else { "" }; - primitive_link_fragment(f, PrimitiveType::Tuple, &format!("fn ({name}₁, {name}₂, …, {name}ₙ{ellipsis})"), "#trait-implementations-1", cx)?; + primitive_link_fragment(f, PrimitiveType::Tuple, format_args!("fn ({name}₁, {name}₂, …, {name}ₙ{ellipsis})"), "#trait-implementations-1", cx)?; // Write output. if !bare_fn.decl.output.is_unit() { write!(f, " -> ")?; @@ -1665,7 +1685,12 @@ impl clean::ImportSource { } let name = self.path.last(); if let hir::def::Res::PrimTy(p) = self.path.res { - primitive_link(f, PrimitiveType::from(p), name.as_str(), cx)?; + primitive_link( + f, + PrimitiveType::from(p), + format_args!("{}", name.as_str()), + cx, + )?; } else { f.write_str(name.as_str())?; } From a134f1624cd011703378f5f7597854375d74e135 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sat, 21 Oct 2023 23:04:17 +0200 Subject: [PATCH 21/29] Fix #117033 --- compiler/rustc_mir_build/src/thir/pattern/usefulness.rs | 3 +++ tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.rs | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs index a8cee5a61ed..5218f772484 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs @@ -884,6 +884,9 @@ fn collect_nonexhaustive_missing_variants<'p, 'tcx>( cx: &MatchCheckCtxt<'p, 'tcx>, column: &[&DeconstructedPat<'p, 'tcx>], ) -> Vec> { + if column.is_empty() { + return Vec::new(); + } let ty = column[0].ty(); let pcx = &PatCtxt { cx, ty, span: DUMMY_SP, is_top_level: false }; diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.rs b/tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.rs index ecfeb3f9b98..e0a6051a81f 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.rs +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.rs @@ -251,3 +251,10 @@ fn main() { pub fn takes_non_exhaustive(_: NonExhaustiveEnum) { let _closure = |_: NonExhaustiveEnum| {}; } + +// ICE #117033 +enum Void {} +#[deny(non_exhaustive_omitted_patterns)] +pub fn void(v: Void) -> ! { + match v {} +} From 65962708f801afefd0d04a77ad171788df0918e6 Mon Sep 17 00:00:00 2001 From: Cameron Ditchfield <26909787+csditchfield@users.noreply.github.com> Date: Sat, 21 Oct 2023 19:40:08 -0500 Subject: [PATCH 22/29] fix what-to-include doc example Fixes the second example in the Examples section of what-to-include.md by marking main as a function. --- src/doc/rustdoc/src/write-documentation/what-to-include.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustdoc/src/write-documentation/what-to-include.md b/src/doc/rustdoc/src/write-documentation/what-to-include.md index 4bcae4d222c..75d3b7dae61 100644 --- a/src/doc/rustdoc/src/write-documentation/what-to-include.md +++ b/src/doc/rustdoc/src/write-documentation/what-to-include.md @@ -73,7 +73,7 @@ and your test suite, this example needs some additional code: ``````text /// Example /// ```rust -/// # main() -> Result<(), std::num::ParseIntError> { +/// # fn main() -> Result<(), std::num::ParseIntError> { /// let fortytwo = "42".parse::()?; /// println!("{} + 10 = {}", fortytwo, fortytwo+10); /// # Ok(()) From a836fd65f9d615343a52ffb6bb3f9799ae4683ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 21 Oct 2023 12:12:47 +0200 Subject: [PATCH 23/29] Use beta cargo in opt-dist Using the new cargo caused issues when a backwards-incompatible change was made to cargo. --- src/tools/opt-dist/src/tests.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/tools/opt-dist/src/tests.rs b/src/tools/opt-dist/src/tests.rs index 8000c9e7fdd..f8a26f99319 100644 --- a/src/tools/opt-dist/src/tests.rs +++ b/src/tools/opt-dist/src/tests.rs @@ -24,11 +24,10 @@ pub fn run_tests(env: &Environment) -> anyhow::Result<()> { let host_triple = env.host_triple(); let version = find_dist_version(&dist_dir)?; - // Extract rustc, libstd, cargo and src archives to create the optimized sysroot + // Extract rustc, libstd and src archives to create the optimized sysroot let rustc_dir = extract_dist_dir(&format!("rustc-{version}-{host_triple}"))?.join("rustc"); let libstd_dir = extract_dist_dir(&format!("rust-std-{version}-{host_triple}"))? .join(format!("rust-std-{host_triple}")); - let cargo_dir = extract_dist_dir(&format!("cargo-{version}-{host_triple}"))?.join("cargo"); let extracted_src_dir = extract_dist_dir(&format!("rust-src-{version}"))?.join("rust-src"); // We need to manually copy libstd to the extracted rustc sysroot @@ -47,8 +46,6 @@ pub fn run_tests(env: &Environment) -> anyhow::Result<()> { let rustc_path = rustc_dir.join("bin").join(format!("rustc{}", executable_extension())); assert!(rustc_path.is_file()); - let cargo_path = cargo_dir.join("bin").join(format!("cargo{}", executable_extension())); - assert!(cargo_path.is_file()); // Specify path to a LLVM config so that LLVM is not rebuilt. // It doesn't really matter which LLVM config we choose, because no sysroot will be compiled. @@ -65,13 +62,11 @@ change-id = 115898 [build] rustc = "{rustc}" -cargo = "{cargo}" [target.{host_triple}] llvm-config = "{llvm_config}" "#, rustc = rustc_path.to_string().replace('\\', "/"), - cargo = cargo_path.to_string().replace('\\', "/"), llvm_config = llvm_config.to_string().replace('\\', "/") ); log::info!("Using following `config.toml` for running tests:\n{config_content}"); From 823d72abde2ddbd67441d4a873f1f76ef8c21e74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sun, 22 Oct 2023 11:13:12 +0200 Subject: [PATCH 24/29] Pass host triple when running tests in `opt-dist` --- src/tools/opt-dist/src/tests.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tools/opt-dist/src/tests.rs b/src/tools/opt-dist/src/tests.rs index f8a26f99319..3c33cfe985d 100644 --- a/src/tools/opt-dist/src/tests.rs +++ b/src/tools/opt-dist/src/tests.rs @@ -79,6 +79,8 @@ llvm-config = "{llvm_config}" env.python_binary(), x_py.as_str(), "test", + "--build", + env.host_triple(), "--stage", "0", "tests/assembly", From 41dfebbd177b05f85ad3f737dda1fef56936c203 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sun, 22 Oct 2023 20:04:20 +0200 Subject: [PATCH 25/29] Update rustc-perf version --- src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile | 4 ++-- src/tools/opt-dist/src/main.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile index c04121a8bee..9a2fcb0ce0a 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile @@ -57,9 +57,9 @@ COPY host-x86_64/dist-x86_64-linux/build-clang.sh /tmp/ RUN ./build-clang.sh ENV CC=clang CXX=clang++ -# rustc-perf version from 2023-05-30 +# rustc-perf version from 2023-10-22 # Should also be changed in the opt-dist tool for other environments. -ENV PERF_COMMIT 8b2ac3042e1ff2c0074455a0a3618adef97156b1 +ENV PERF_COMMIT 4f313add609f43e928e98132358e8426ed3969ae RUN curl -LS -o perf.zip https://ci-mirrors.rust-lang.org/rustc/rustc-perf-$PERF_COMMIT.zip && \ unzip perf.zip && \ mv rustc-perf-$PERF_COMMIT rustc-perf && \ diff --git a/src/tools/opt-dist/src/main.rs b/src/tools/opt-dist/src/main.rs index 9cdff84676e..f9ff1a0a486 100644 --- a/src/tools/opt-dist/src/main.rs +++ b/src/tools/opt-dist/src/main.rs @@ -408,8 +408,8 @@ fn download_rustc_perf(env: &Environment) -> anyhow::Result<()> { // FIXME: add some mechanism for synchronization of this commit SHA with // Linux (which builds rustc-perf in a Dockerfile) - // rustc-perf version from 2023-05-30 - const PERF_COMMIT: &str = "8b2ac3042e1ff2c0074455a0a3618adef97156b1"; + // rustc-perf version from 2023-10-22 + const PERF_COMMIT: &str = "4f313add609f43e928e98132358e8426ed3969ae"; let url = format!("https://ci-mirrors.rust-lang.org/rustc/rustc-perf-{PERF_COMMIT}.zip"); let client = reqwest::blocking::Client::builder() From a80b5c00b64a6ec8175a3153b174f59a237434a7 Mon Sep 17 00:00:00 2001 From: The Miri Conjob Bot Date: Mon, 23 Oct 2023 05:30:20 +0000 Subject: [PATCH 26/29] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 0335ad3c1d8..9e9f2bad7c3 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -9e3f784eb2c7c847b6c3578b373c0e0bc9233ca3 +62fae2305e5f3a959bd6ad6c20608c118e93648a From b67985e1132806c6451b9924aab67e2da8d73885 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sun, 22 Oct 2023 22:50:25 -0700 Subject: [PATCH 27/29] rustdoc: wrap Type with Box instead of Generics When these `Box` types were introduced, `Generics` was made with `Vec` and much larger. Now that it's made with `ThinVec`, `Type` is bigger and should be boxed instead. --- src/librustdoc/clean/inline.rs | 6 +++--- src/librustdoc/clean/mod.rs | 30 +++++++++++++++--------------- src/librustdoc/clean/types.rs | 10 +++++----- src/librustdoc/json/conversions.rs | 6 +++--- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index eb18ecf662c..89796761126 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -641,13 +641,13 @@ fn build_const(cx: &mut DocContext<'_>, def_id: DefId) -> clean::Constant { clean::simplify::move_bounds_to_generic_parameters(&mut generics); clean::Constant { - type_: clean_middle_ty( + type_: Box::new(clean_middle_ty( ty::Binder::dummy(cx.tcx.type_of(def_id).instantiate_identity()), cx, Some(def_id), None, - ), - generics: Box::new(generics), + )), + generics, kind: clean::ConstantKind::Extern { def_id }, } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 7becc156142..125b1fecf18 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -259,13 +259,13 @@ fn clean_lifetime<'tcx>(lifetime: &hir::Lifetime, cx: &mut DocContext<'tcx>) -> pub(crate) fn clean_const<'tcx>(constant: &hir::ConstArg, cx: &mut DocContext<'tcx>) -> Constant { let def_id = cx.tcx.hir().body_owner_def_id(constant.value.body).to_def_id(); Constant { - type_: clean_middle_ty( + type_: Box::new(clean_middle_ty( ty::Binder::dummy(cx.tcx.type_of(def_id).instantiate_identity()), cx, Some(def_id), None, - ), - generics: Box::new(Generics::default()), + )), + generics: Generics::default(), kind: ConstantKind::Anonymous { body: constant.value.body }, } } @@ -276,8 +276,8 @@ pub(crate) fn clean_middle_const<'tcx>( ) -> Constant { // FIXME: instead of storing the stringified expression, store `self` directly instead. Constant { - type_: clean_middle_ty(constant.map_bound(|c| c.ty()), cx, None, None), - generics: Box::new(Generics::default()), + type_: Box::new(clean_middle_ty(constant.map_bound(|c| c.ty()), cx, None, None)), + generics: Generics::default(), kind: ConstantKind::TyConst { expr: constant.skip_binder().to_string().into() }, } } @@ -1216,14 +1216,14 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext hir::TraitItemKind::Const(ty, Some(default)) => { let generics = enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx)); AssocConstItem( - Box::new(generics), - clean_ty(ty, cx), + generics, + Box::new(clean_ty(ty, cx)), ConstantKind::Local { def_id: local_did, body: default }, ) } hir::TraitItemKind::Const(ty, None) => { let generics = enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx)); - TyAssocConstItem(Box::new(generics), clean_ty(ty, cx)) + TyAssocConstItem(generics, Box::new(clean_ty(ty, cx))) } hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => { let m = clean_function(cx, sig, trait_item.generics, FunctionArgs::Body(body)); @@ -1272,7 +1272,7 @@ pub(crate) fn clean_impl_item<'tcx>( hir::ImplItemKind::Const(ty, expr) => { let generics = clean_generics(impl_.generics, cx); let default = ConstantKind::Local { def_id: local_did, body: expr }; - AssocConstItem(Box::new(generics), clean_ty(ty, cx), default) + AssocConstItem(generics, Box::new(clean_ty(ty, cx)), default) } hir::ImplItemKind::Fn(ref sig, body) => { let m = clean_function(cx, sig, impl_.generics, FunctionArgs::Body(body)); @@ -1311,18 +1311,18 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( let tcx = cx.tcx; let kind = match assoc_item.kind { ty::AssocKind::Const => { - let ty = clean_middle_ty( + let ty = Box::new(clean_middle_ty( ty::Binder::dummy(tcx.type_of(assoc_item.def_id).instantiate_identity()), cx, Some(assoc_item.def_id), None, - ); + )); - let mut generics = Box::new(clean_ty_generics( + let mut generics = clean_ty_generics( cx, tcx.generics_of(assoc_item.def_id), tcx.explicit_predicates_of(assoc_item.def_id), - )); + ); simplify::move_bounds_to_generic_parameters(&mut generics); let provided = match assoc_item.container { @@ -2718,8 +2718,8 @@ fn clean_maybe_renamed_item<'tcx>( StaticItem(Static { type_: clean_ty(ty, cx), mutability, expr: Some(body_id) }) } ItemKind::Const(ty, generics, body_id) => ConstantItem(Constant { - type_: clean_ty(ty, cx), - generics: Box::new(clean_generics(generics, cx)), + type_: Box::new(clean_ty(ty, cx)), + generics: clean_generics(generics, cx), kind: ConstantKind::Local { body: body_id, def_id }, }), ItemKind::OpaqueTy(ref ty) => OpaqueTyItem(OpaqueTy { diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 2a54266676d..1f34306f8ba 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -852,9 +852,9 @@ pub(crate) enum ItemKind { ProcMacroItem(ProcMacro), PrimitiveItem(PrimitiveType), /// A required associated constant in a trait declaration. - TyAssocConstItem(Box, Type), + TyAssocConstItem(Generics, Box), /// An associated constant in a trait impl or a provided one in a trait declaration. - AssocConstItem(Box, Type, ConstantKind), + AssocConstItem(Generics, Box, ConstantKind), /// A required associated type in a trait declaration. /// /// The bounds may be non-empty if there is a `where` clause. @@ -2282,8 +2282,8 @@ pub(crate) struct Static { #[derive(Clone, PartialEq, Eq, Hash, Debug)] pub(crate) struct Constant { - pub(crate) type_: Type, - pub(crate) generics: Box, + pub(crate) type_: Box, + pub(crate) generics: Generics, pub(crate) kind: ConstantKind, } @@ -2525,7 +2525,7 @@ mod size_asserts { static_assert_size!(Generics, 16); static_assert_size!(Item, 56); // FIXME(generic_const_items): Further reduce the size. - static_assert_size!(ItemKind, 72); + static_assert_size!(ItemKind, 56); static_assert_size!(PathSegment, 40); static_assert_size!(Type, 32); // tidy-alphabetical-end diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 17e2172a270..563e0cffddd 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -177,7 +177,7 @@ impl FromWithTcx for Constant { let expr = constant.expr(tcx); let value = constant.value(tcx); let is_literal = constant.is_literal(tcx); - Constant { type_: constant.type_.into_tcx(tcx), expr, value, is_literal } + Constant { type_: (*constant.type_).into_tcx(tcx), expr, value, is_literal } } } @@ -325,11 +325,11 @@ fn from_clean_item(item: clean::Item, tcx: TyCtxt<'_>) -> ItemEnum { } // FIXME(generic_const_items): Add support for generic associated consts. TyAssocConstItem(_generics, ty) => { - ItemEnum::AssocConst { type_: ty.into_tcx(tcx), default: None } + ItemEnum::AssocConst { type_: (*ty).into_tcx(tcx), default: None } } // FIXME(generic_const_items): Add support for generic associated consts. AssocConstItem(_generics, ty, default) => { - ItemEnum::AssocConst { type_: ty.into_tcx(tcx), default: Some(default.expr(tcx)) } + ItemEnum::AssocConst { type_: (*ty).into_tcx(tcx), default: Some(default.expr(tcx)) } } TyAssocTypeItem(g, b) => ItemEnum::AssocType { generics: g.into_tcx(tcx), From f1a1ef68c7a6d588ba9faa20f3b2ecac4ef607c5 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Mon, 23 Oct 2023 06:52:29 -0700 Subject: [PATCH 28/29] Remove FIXME after fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: León Orell Valerian Liehr --- src/librustdoc/clean/types.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 1f34306f8ba..6a7410144fd 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -2524,7 +2524,6 @@ mod size_asserts { static_assert_size!(GenericParamDef, 56); static_assert_size!(Generics, 16); static_assert_size!(Item, 56); - // FIXME(generic_const_items): Further reduce the size. static_assert_size!(ItemKind, 56); static_assert_size!(PathSegment, 40); static_assert_size!(Type, 32); From dd683dd12e0a969554a2073febe14ad061f6d3b1 Mon Sep 17 00:00:00 2001 From: The Miri Conjob Bot Date: Mon, 23 Oct 2023 05:39:23 +0000 Subject: [PATCH 29/29] fmt --- .../miri/src/borrow_tracker/tree_borrows/tree.rs | 12 +++++------- src/tools/miri/src/concurrency/data_race.rs | 1 + src/tools/miri/src/shims/windows/foreign_items.rs | 4 +++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs index b63b0bdff12..4232cd396c9 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs @@ -661,13 +661,11 @@ impl<'tcx> Tree { for (perms_range, perms) in self.rperms.iter_mut_all() { let idx = self.tag_mapping.get(&tag).unwrap(); // Only visit initialized permissions - if let Some(p) = perms.get(idx) && p.initialized { - TreeVisitor { - nodes: &mut self.nodes, - tag_mapping: &self.tag_mapping, - perms, - } - .traverse_nonchildren( + if let Some(p) = perms.get(idx) + && p.initialized + { + TreeVisitor { nodes: &mut self.nodes, tag_mapping: &self.tag_mapping, perms } + .traverse_nonchildren( tag, |args| node_app(perms_range.clone(), args), |args| err_handler(perms_range.clone(), args), diff --git a/src/tools/miri/src/concurrency/data_race.rs b/src/tools/miri/src/concurrency/data_race.rs index bec2972c50d..e49d62177c5 100644 --- a/src/tools/miri/src/concurrency/data_race.rs +++ b/src/tools/miri/src/concurrency/data_race.rs @@ -563,6 +563,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> { let old = this.allow_data_races_mut(|this| this.read_immediate(place))?; let lt = this.wrapping_binary_op(mir::BinOp::Lt, &old, &rhs)?.to_scalar().to_bool()?; + #[rustfmt::skip] // rustfmt makes this unreadable let new_val = if min { if lt { &old } else { &rhs } } else { diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs index 759a412c16a..4ad44adff04 100644 --- a/src/tools/miri/src/shims/windows/foreign_items.rs +++ b/src/tools/miri/src/shims/windows/foreign_items.rs @@ -351,7 +351,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; this.read_target_isize(hModule)?; let name = this.read_c_str(this.read_pointer(lpProcName)?)?; - if let Ok(name) = str::from_utf8(name) && is_dyn_sym(name) { + if let Ok(name) = str::from_utf8(name) + && is_dyn_sym(name) + { let ptr = this.fn_ptr(FnVal::Other(DynSym::from_str(name))); this.write_pointer(ptr, dest)?; } else {