From 13703b52bf7634a3cb71b971e8e26aea733f0518 Mon Sep 17 00:00:00 2001 From: mejrs <59372212+mejrs@users.noreply.github.com> Date: Thu, 8 Oct 2026 14:04:32 +0200 Subject: [PATCH] comptime fn error: suggest wrapping in const block It won't always be correct, since all values captured by a const block must also be determined at compile time, but it should usually work or be a step in the right direction --- compiler/rustc_hir_typeck/src/callee.rs | 8 ++++++- compiler/rustc_hir_typeck/src/diagnostics.rs | 21 +++++++++++++++++++ .../doc_examples/rustc_comptime.stderr | 14 +++++++++++-- tests/ui/comptime/comptime_method.rs | 2 +- tests/ui/comptime/comptime_method.stderr | 7 ++++++- tests/ui/comptime/not_callable.rs | 4 ++-- tests/ui/comptime/not_callable.stderr | 14 +++++++++++-- .../reflection_methods_in_runtime_code.rs | 2 +- .../reflection_methods_in_runtime_code.stderr | 7 ++++++- 9 files changed, 68 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 025c64896edb7..998351e3f2825 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -1115,7 +1115,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match const_context { Some(hir::ConstContext::Const { .. } | hir::ConstContext::Static(_)) => {} Some(hir::ConstContext::ConstFn) | None => { - self.dcx().span_err(span, "comptime fns can only be called at compile time"); + self.dcx().emit_err(diagnostics::ComptimeFnCalledOutsideConstContext { + span, + const_block: diagnostics::WrapConstBlock { + left: span.shrink_to_lo(), + right: span.shrink_to_hi(), + }, + }); } } } diff --git a/compiler/rustc_hir_typeck/src/diagnostics.rs b/compiler/rustc_hir_typeck/src/diagnostics.rs index 12e1006cc734f..5522ce033ee9c 100644 --- a/compiler/rustc_hir_typeck/src/diagnostics.rs +++ b/compiler/rustc_hir_typeck/src/diagnostics.rs @@ -1349,3 +1349,24 @@ impl ExprParenthesesNeeded { #[derive(Diagnostic)] #[diag("`#[panic_handler]` functions can't be `unsafe`")] pub(crate) struct UnsafePanicHandlers; + +#[derive(Diagnostic)] +#[diag("comptime functions can only be called at compile time")] +pub(crate) struct ComptimeFnCalledOutsideConstContext { + #[primary_span] + pub span: Span, + #[subdiagnostic] + pub const_block: WrapConstBlock, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion( + "wrap the call in a const block to force compile time evaluation", + applicability = "maybe-incorrect" +)] +pub(crate) struct WrapConstBlock { + #[suggestion_part(code = "const {{ ")] + pub left: Span, + #[suggestion_part(code = " }}")] + pub right: Span, +} diff --git a/tests/ui/attributes/doc_examples/rustc_comptime.stderr b/tests/ui/attributes/doc_examples/rustc_comptime.stderr index 20dd2597d929e..6ace103fdcfa5 100644 --- a/tests/ui/attributes/doc_examples/rustc_comptime.stderr +++ b/tests/ui/attributes/doc_examples/rustc_comptime.stderr @@ -1,14 +1,24 @@ -error: comptime fns can only be called at compile time +error: comptime functions can only be called at compile time --> $DIR/rustc_comptime.rs:10:5 | 10 | comptime(); // ERROR | ^^^^^^^^^^ + | +help: wrap the call in a const block to force compile time evaluation + | +10 | const { comptime() }; // ERROR + | +++++++ + -error: comptime fns can only be called at compile time +error: comptime functions can only be called at compile time --> $DIR/rustc_comptime.rs:18:5 | 18 | comptime(); | ^^^^^^^^^^ + | +help: wrap the call in a const block to force compile time evaluation + | +18 | const { comptime() }; + | +++++++ + error: aborting due to 2 previous errors diff --git a/tests/ui/comptime/comptime_method.rs b/tests/ui/comptime/comptime_method.rs index a55c950b01680..e5bd403d6168e 100644 --- a/tests/ui/comptime/comptime_method.rs +++ b/tests/ui/comptime/comptime_method.rs @@ -13,5 +13,5 @@ const _: () = { fn main() { Bar.boo(); - //~^ ERROR: comptime fns can only be called at compile time + //~^ ERROR: comptime functions can only be called at compile time } diff --git a/tests/ui/comptime/comptime_method.stderr b/tests/ui/comptime/comptime_method.stderr index f188ab7e4be58..0838a68168d8d 100644 --- a/tests/ui/comptime/comptime_method.stderr +++ b/tests/ui/comptime/comptime_method.stderr @@ -1,8 +1,13 @@ -error: comptime fns can only be called at compile time +error: comptime functions can only be called at compile time --> $DIR/comptime_method.rs:15:5 | LL | Bar.boo(); | ^^^^^^^^^ + | +help: wrap the call in a const block to force compile time evaluation + | +LL | const { Bar.boo() }; + | +++++++ + error: aborting due to 1 previous error diff --git a/tests/ui/comptime/not_callable.rs b/tests/ui/comptime/not_callable.rs index c06e643d5403e..be533c1118ed3 100644 --- a/tests/ui/comptime/not_callable.rs +++ b/tests/ui/comptime/not_callable.rs @@ -7,12 +7,12 @@ fn main() { // Ok const { foo() }; // Not Ok - foo(); //~ ERROR: comptime fns can only be called at compile time + foo(); //~ ERROR: comptime functions can only be called at compile time } const fn bar() { // Not Ok - foo(); //~ ERROR: comptime fns can only be called at compile time + foo(); //~ ERROR: comptime functions can only be called at compile time } #[rustc_comptime] diff --git a/tests/ui/comptime/not_callable.stderr b/tests/ui/comptime/not_callable.stderr index 8a2c3fb2bf00f..a53aa5bf12b3a 100644 --- a/tests/ui/comptime/not_callable.stderr +++ b/tests/ui/comptime/not_callable.stderr @@ -1,14 +1,24 @@ -error: comptime fns can only be called at compile time +error: comptime functions can only be called at compile time --> $DIR/not_callable.rs:10:5 | LL | foo(); | ^^^^^ + | +help: wrap the call in a const block to force compile time evaluation + | +LL | const { foo() }; + | +++++++ + -error: comptime fns can only be called at compile time +error: comptime functions can only be called at compile time --> $DIR/not_callable.rs:15:5 | LL | foo(); | ^^^^^ + | +help: wrap the call in a const block to force compile time evaluation + | +LL | const { foo() }; + | +++++++ + error: aborting due to 2 previous errors diff --git a/tests/ui/reflection/reflection_methods_in_runtime_code.rs b/tests/ui/reflection/reflection_methods_in_runtime_code.rs index 4204fb3ad16f4..0f1fcd1768e27 100644 --- a/tests/ui/reflection/reflection_methods_in_runtime_code.rs +++ b/tests/ui/reflection/reflection_methods_in_runtime_code.rs @@ -5,5 +5,5 @@ trait Trait {} fn main() { // Test the (lack of) usability of comptime fns in runtime code. std::any::TypeId::of::<[u8; usize::MAX]>().trait_info_of::(); - //~^ ERROR: comptime fns can only be called at compile time + //~^ ERROR: comptime functions can only be called at compile time } diff --git a/tests/ui/reflection/reflection_methods_in_runtime_code.stderr b/tests/ui/reflection/reflection_methods_in_runtime_code.stderr index ff83c50754254..05e87ec2a69aa 100644 --- a/tests/ui/reflection/reflection_methods_in_runtime_code.stderr +++ b/tests/ui/reflection/reflection_methods_in_runtime_code.stderr @@ -1,8 +1,13 @@ -error: comptime fns can only be called at compile time +error: comptime functions can only be called at compile time --> $DIR/reflection_methods_in_runtime_code.rs:7:5 | LL | std::any::TypeId::of::<[u8; usize::MAX]>().trait_info_of::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: wrap the call in a const block to force compile time evaluation + | +LL | const { std::any::TypeId::of::<[u8; usize::MAX]>().trait_info_of::() }; + | +++++++ + error: aborting due to 1 previous error