From ba5ec1fc5c68dc727e5f68cd804829c4f9eb9b81 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Mon, 24 Jun 2024 15:30:24 +0300 Subject: [PATCH] Suggest inline const blocks for array initialization --- .../src/traits/error_reporting/suggestions.rs | 40 ++++--------------- .../const-blocks/fn-call-in-non-const.stderr | 8 ++-- .../ui/consts/const-blocks/trait-error.stderr | 11 ++--- tests/ui/consts/const-fn-in-vec.stderr | 33 ++++++--------- 4 files changed, 26 insertions(+), 66 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index b2fa3489dda2b..f9cdca6360e91 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2915,38 +2915,21 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } ObligationCauseCode::RepeatElementCopy { is_constable, - elt_type, + elt_type: _, elt_span, - elt_stmt_span, + elt_stmt_span: _, } => { err.note( "the `Copy` trait is required because this value will be copied for each element of the array", ); - let value_kind = match is_constable { - IsConstable::Fn => Some("the result of the function call"), - IsConstable::Ctor => Some("the result of the constructor"), - _ => None, - }; let sm = tcx.sess.source_map(); - if let Some(value_kind) = value_kind + if matches!(is_constable, IsConstable::Fn | IsConstable::Ctor) && let Ok(snip) = sm.span_to_snippet(elt_span) { - let help_msg = format!( - "consider creating a new `const` item and initializing it with {value_kind} \ - to be used in the repeat position" - ); - let indentation = sm.indentation_before(elt_stmt_span).unwrap_or_default(); - err.multipart_suggestion( - help_msg, - vec![ - ( - elt_stmt_span.shrink_to_lo(), - format!( - "const ARRAY_REPEAT_VALUE: {elt_type} = {snip};\n{indentation}" - ), - ), - (elt_span, "ARRAY_REPEAT_VALUE".to_string()), - ], + err.span_suggestion( + elt_span, + "create an inline `const` block", + format!("const {{ {snip} }}"), Applicability::MachineApplicable, ); } else { @@ -2954,15 +2937,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { err.help("consider using `core::array::from_fn` to initialize the array"); err.help("see https://doc.rust-lang.org/stable/std/array/fn.from_fn.html for more information"); } - - if tcx.sess.is_nightly_build() - && matches!(is_constable, IsConstable::Fn | IsConstable::Ctor) - { - err.help( - "create an inline `const` block, see RFC #2920 \ - for more information", - ); - } } ObligationCauseCode::VariableType(hir_id) => { if let Some(typeck_results) = &self.typeck_results diff --git a/tests/ui/consts/const-blocks/fn-call-in-non-const.stderr b/tests/ui/consts/const-blocks/fn-call-in-non-const.stderr index 14bce10f78744..9dce29732ac80 100644 --- a/tests/ui/consts/const-blocks/fn-call-in-non-const.stderr +++ b/tests/ui/consts/const-blocks/fn-call-in-non-const.stderr @@ -6,17 +6,15 @@ LL | let _: [Option; 2] = [no_copy(); 2]; | = note: required for `Option` to implement `Copy` = note: the `Copy` trait is required because this value will be copied for each element of the array - = help: create an inline `const` block, see RFC #2920 for more information help: consider annotating `Bar` with `#[derive(Copy)]` | LL + #[derive(Copy)] LL | struct Bar; | -help: consider creating a new `const` item and initializing it with the result of the function call to be used in the repeat position - | -LL ~ const ARRAY_REPEAT_VALUE: Option = no_copy(); -LL ~ let _: [Option; 2] = [ARRAY_REPEAT_VALUE; 2]; +help: create an inline `const` block | +LL | let _: [Option; 2] = [const { no_copy() }; 2]; + | ~~~~~~~~~~~~~~~~~~~ error: aborting due to 1 previous error diff --git a/tests/ui/consts/const-blocks/trait-error.stderr b/tests/ui/consts/const-blocks/trait-error.stderr index b0b1378bb7de0..8f00f14dfb900 100644 --- a/tests/ui/consts/const-blocks/trait-error.stderr +++ b/tests/ui/consts/const-blocks/trait-error.stderr @@ -2,7 +2,10 @@ error[E0277]: the trait bound `String: Copy` is not satisfied --> $DIR/trait-error.rs:5:6 | LL | [Foo(String::new()); 4]; - | ^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`, which is required by `Foo: Copy` + | ^^^^^^^^^^^^^^^^^^ + | | + | the trait `Copy` is not implemented for `String`, which is required by `Foo: Copy` + | help: create an inline `const` block: `const { Foo(String::new()) }` | note: required for `Foo` to implement `Copy` --> $DIR/trait-error.rs:1:10 @@ -10,13 +13,7 @@ note: required for `Foo` to implement `Copy` LL | #[derive(Copy, Clone)] | ^^^^ unsatisfied trait bound introduced in this `derive` macro = note: the `Copy` trait is required because this value will be copied for each element of the array - = help: create an inline `const` block, see RFC #2920 for more information = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info) -help: consider creating a new `const` item and initializing it with the result of the function call to be used in the repeat position - | -LL ~ const ARRAY_REPEAT_VALUE: Foo = Foo(String::new()); -LL ~ [ARRAY_REPEAT_VALUE; 4]; - | error: aborting due to 1 previous error diff --git a/tests/ui/consts/const-fn-in-vec.stderr b/tests/ui/consts/const-fn-in-vec.stderr index 12098e8199cd7..7c6b3bee9404b 100644 --- a/tests/ui/consts/const-fn-in-vec.stderr +++ b/tests/ui/consts/const-fn-in-vec.stderr @@ -2,45 +2,36 @@ error[E0277]: the trait bound `String: Copy` is not satisfied --> $DIR/const-fn-in-vec.rs:1:47 | LL | static _MAYBE_STRINGS: [Option; 5] = [None; 5]; - | ^^^^ the trait `Copy` is not implemented for `String`, which is required by `Option: Copy` + | ^^^^ + | | + | the trait `Copy` is not implemented for `String`, which is required by `Option: Copy` + | help: create an inline `const` block: `const { None }` | = note: required for `Option` to implement `Copy` = note: the `Copy` trait is required because this value will be copied for each element of the array - = help: create an inline `const` block, see RFC #2920 for more information -help: consider creating a new `const` item and initializing it with the result of the constructor to be used in the repeat position - | -LL + const ARRAY_REPEAT_VALUE: Option = None; -LL ~ static _MAYBE_STRINGS: [Option; 5] = [ARRAY_REPEAT_VALUE; 5]; - | error[E0277]: the trait bound `String: Copy` is not satisfied --> $DIR/const-fn-in-vec.rs:7:34 | LL | let _strings: [String; 5] = [String::new(); 5]; - | ^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` + | ^^^^^^^^^^^^^ + | | + | the trait `Copy` is not implemented for `String` + | help: create an inline `const` block: `const { String::new() }` | = note: the `Copy` trait is required because this value will be copied for each element of the array - = help: create an inline `const` block, see RFC #2920 for more information -help: consider creating a new `const` item and initializing it with the result of the function call to be used in the repeat position - | -LL ~ const ARRAY_REPEAT_VALUE: String = String::new(); -LL ~ let _strings: [String; 5] = [ARRAY_REPEAT_VALUE; 5]; - | error[E0277]: the trait bound `String: Copy` is not satisfied --> $DIR/const-fn-in-vec.rs:9:48 | LL | let _maybe_strings: [Option; 5] = [None; 5]; - | ^^^^ the trait `Copy` is not implemented for `String`, which is required by `Option: Copy` + | ^^^^ + | | + | the trait `Copy` is not implemented for `String`, which is required by `Option: Copy` + | help: create an inline `const` block: `const { None }` | = note: required for `Option` to implement `Copy` = note: the `Copy` trait is required because this value will be copied for each element of the array - = help: create an inline `const` block, see RFC #2920 for more information -help: consider creating a new `const` item and initializing it with the result of the constructor to be used in the repeat position - | -LL ~ const ARRAY_REPEAT_VALUE: Option = None; -LL ~ let _maybe_strings: [Option; 5] = [ARRAY_REPEAT_VALUE; 5]; - | error: aborting due to 3 previous errors