From 7175da59d3ce56ededb142385dbbf95a2f6ad1ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 28 Dec 2024 18:37:16 +0000 Subject: [PATCH] Structured suggestion for "missing `feature` intrinsic" ``` error: `size_of_val` is not yet stable as a const intrinsic --> $DIR/const-unstable-intrinsic.rs:17:9 | LL | unstable_intrinsic::size_of_val(&x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: add `#![feature(unstable)]` to the crate attributes to enable help: add `#![feature(unstable)]` to the crate attributes to enable | LL + #![feature("unstable")] | ``` --- compiler/rustc_const_eval/messages.ftl | 2 +- compiler/rustc_const_eval/src/check_consts/check.rs | 7 +++++++ compiler/rustc_const_eval/src/check_consts/ops.rs | 3 +++ compiler/rustc_const_eval/src/errors.rs | 9 ++++++++- tests/ui/consts/const-unstable-intrinsic.stderr | 10 ++++++++-- 5 files changed, 27 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl index 4861b7a4430f..d4bfb781320d 100644 --- a/compiler/rustc_const_eval/messages.ftl +++ b/compiler/rustc_const_eval/messages.ftl @@ -424,7 +424,7 @@ const_eval_unstable_in_stable_exposed = .bypass_sugg = otherwise, as a last resort `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (this requires team approval) const_eval_unstable_intrinsic = `{$name}` is not yet stable as a const intrinsic - .help = add `#![feature({$feature})]` to the crate attributes to enable +const_eval_unstable_intrinsic_suggestion = add `#![feature({$feature})]` to the crate attributes to enable const_eval_unterminated_c_string = reading a null-terminated string starting at {$pointer} with no null found before end of allocation diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index 94fb039512a6..844dc2aa5933 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -819,10 +819,17 @@ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location feature, .. }) => { + let suggestion = + tcx.hir_crate_items(()).definitions().next().and_then(|id| { + tcx.crate_level_attribute_injection_span( + tcx.local_def_id_to_hir_id(id), + ) + }); self.check_op(ops::IntrinsicUnstable { name: intrinsic.name, feature, const_stable_indirect: is_const_stable, + suggestion, }); } Some(ConstStability { level: StabilityLevel::Stable { .. }, .. }) => { diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs index 6a7da13b3039..3c83a7b92cdc 100644 --- a/compiler/rustc_const_eval/src/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/check_consts/ops.rs @@ -447,6 +447,7 @@ pub(crate) struct IntrinsicUnstable { pub name: Symbol, pub feature: Symbol, pub const_stable_indirect: bool, + pub suggestion: Option, } impl<'tcx> NonConstOp<'tcx> for IntrinsicUnstable { @@ -466,6 +467,8 @@ fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> { span, name: self.name, feature: self.feature, + suggestion: self.suggestion, + help: self.suggestion.is_none(), }) } } diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index 3fe78171cd94..1ee9214c4b2a 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -123,12 +123,19 @@ pub(crate) struct UnstableConstFn { #[derive(Diagnostic)] #[diag(const_eval_unstable_intrinsic)] -#[help] pub(crate) struct UnstableIntrinsic { #[primary_span] pub span: Span, pub name: Symbol, pub feature: Symbol, + #[suggestion( + const_eval_unstable_intrinsic_suggestion, + code = "#![feature({feature})]\n", + applicability = "machine-applicable" + )] + pub suggestion: Option, + #[help(const_eval_unstable_intrinsic_suggestion)] + pub help: bool, } #[derive(Diagnostic)] diff --git a/tests/ui/consts/const-unstable-intrinsic.stderr b/tests/ui/consts/const-unstable-intrinsic.stderr index 601c8647eeef..308b02386f5c 100644 --- a/tests/ui/consts/const-unstable-intrinsic.stderr +++ b/tests/ui/consts/const-unstable-intrinsic.stderr @@ -24,7 +24,10 @@ error: `size_of_val` is not yet stable as a const intrinsic LL | unstable_intrinsic::size_of_val(&x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add `#![feature(unstable)]` to the crate attributes to enable +help: add `#![feature(unstable)]` to the crate attributes to enable + | +LL + #![feature(unstable)] + | error: `min_align_of_val` is not yet stable as a const intrinsic --> $DIR/const-unstable-intrinsic.rs:20:9 @@ -32,7 +35,10 @@ error: `min_align_of_val` is not yet stable as a const intrinsic LL | unstable_intrinsic::min_align_of_val(&x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add `#![feature(unstable)]` to the crate attributes to enable +help: add `#![feature(unstable)]` to the crate attributes to enable + | +LL + #![feature(unstable)] + | error: const function that might be (indirectly) exposed to stable cannot use `#[feature(local)]` --> $DIR/const-unstable-intrinsic.rs:24:9