From ca150644d7a28f7f37d6d85db020e3236a9568ce Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 12 Jun 2026 11:19:25 +0200 Subject: [PATCH 1/3] Add regression test --- tests/ui/comptime/comptime_method.rs | 16 ++++++++++++++++ tests/ui/comptime/comptime_method.stderr | 19 +++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 tests/ui/comptime/comptime_method.rs create mode 100644 tests/ui/comptime/comptime_method.stderr diff --git a/tests/ui/comptime/comptime_method.rs b/tests/ui/comptime/comptime_method.rs new file mode 100644 index 0000000000000..a0618f97e0ea8 --- /dev/null +++ b/tests/ui/comptime/comptime_method.rs @@ -0,0 +1,16 @@ +#![feature(rustc_attrs)] + +struct Bar; + +#[rustc_comptime] +//~^ ERROR: cannot be used on inherent impl +impl Bar { + fn boo(&self) {} +} + +const _: () = { + Bar.boo(); + //~^ ERROR: cannot call non-const method `Bar::boo` in constants +}; + +fn main() {} diff --git a/tests/ui/comptime/comptime_method.stderr b/tests/ui/comptime/comptime_method.stderr new file mode 100644 index 0000000000000..682e0c364e43c --- /dev/null +++ b/tests/ui/comptime/comptime_method.stderr @@ -0,0 +1,19 @@ +error: `#[rustc_comptime]` attribute cannot be used on inherent impl blocks + --> $DIR/comptime_method.rs:5:1 + | +LL | #[rustc_comptime] + | ^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_comptime]` can only be applied to functions + +error[E0015]: cannot call non-const method `Bar::boo` in constants + --> $DIR/comptime_method.rs:12:9 + | +LL | Bar.boo(); + | ^^^^^ + | + = note: calls in constants are limited to constant functions, tuple structs and tuple variants + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0015`. From 5b3e95d537e399b65a2fcb89e821b69e7efb6ccb Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 12 Jun 2026 11:19:25 +0200 Subject: [PATCH 2/3] Add regression test --- tests/ui/comptime/comptime_impl.rs | 37 ++++++++++++++++++++ tests/ui/comptime/comptime_impl.stderr | 47 ++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 tests/ui/comptime/comptime_impl.rs create mode 100644 tests/ui/comptime/comptime_impl.stderr diff --git a/tests/ui/comptime/comptime_impl.rs b/tests/ui/comptime/comptime_impl.rs new file mode 100644 index 0000000000000..84b08ded12b5c --- /dev/null +++ b/tests/ui/comptime/comptime_impl.rs @@ -0,0 +1,37 @@ +#![feature(rustc_attrs, const_trait_impl)] + +const trait Foo { + fn foo(&self); + + fn bar(&self) {} +} + +struct Bar; + +#[rustc_comptime] +//~^ ERROR: cannot be used on inherent impl +impl Bar { + fn boo(&self) {} +} + +#[rustc_comptime] +//~^ ERROR: cannot be used on trait impl +impl Foo for Bar { + fn foo(&self) { + comptime_fn(); + //~^ ERROR: comptime fns can only be called at compile time + } +} + +#[rustc_comptime] +fn comptime_fn() {} + +const _: () = { + Bar.boo(); + Bar.foo(); + //~^ ERROR: `Bar: const Foo` is not satisfied + Bar.bar(); + //~^ ERROR: `Bar: const Foo` is not satisfied +}; + +fn main() {} diff --git a/tests/ui/comptime/comptime_impl.stderr b/tests/ui/comptime/comptime_impl.stderr new file mode 100644 index 0000000000000..75ad46d60cbea --- /dev/null +++ b/tests/ui/comptime/comptime_impl.stderr @@ -0,0 +1,47 @@ +error: `#[rustc_comptime]` attribute cannot be used on inherent impl blocks + --> $DIR/comptime_impl.rs:11:1 + | +LL | #[rustc_comptime] + | ^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_comptime]` can only be applied to functions + +error: `#[rustc_comptime]` attribute cannot be used on trait impl blocks + --> $DIR/comptime_impl.rs:17:1 + | +LL | #[rustc_comptime] + | ^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_comptime]` can only be applied to functions + +error: comptime fns can only be called at compile time + --> $DIR/comptime_impl.rs:21:9 + | +LL | comptime_fn(); + | ^^^^^^^^^^^^^ + +error[E0277]: the trait bound `Bar: const Foo` is not satisfied + --> $DIR/comptime_impl.rs:31:9 + | +LL | Bar.foo(); + | ^^^ + | +help: make the `impl` of trait `Foo` `const` + | +LL | impl const Foo for Bar { + | +++++ + +error[E0277]: the trait bound `Bar: const Foo` is not satisfied + --> $DIR/comptime_impl.rs:33:9 + | +LL | Bar.bar(); + | ^^^ + | +help: make the `impl` of trait `Foo` `const` + | +LL | impl const Foo for Bar { + | +++++ + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0277`. From 6741f56b0277b37f468a68fa89f61f2f5c3adf7e Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 12 Jun 2026 11:35:19 +0200 Subject: [PATCH 3/3] =?UTF-8?q?Add=20=C2=B4#[rustc=5Fcomptime]`=20inherent?= =?UTF-8?q?=20impls?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../rustc_ast_lowering/src/expr/closure.rs | 6 ++- compiler/rustc_ast_lowering/src/item.rs | 45 ++++++++++--------- .../src/attributes/semantics.rs | 1 + .../src/traits/effects.rs | 3 +- tests/ui/comptime/comptime_closure.rs | 13 ++++++ tests/ui/comptime/comptime_closure.stderr | 20 +++++++++ tests/ui/comptime/comptime_impl.rs | 2 - tests/ui/comptime/comptime_impl.stderr | 24 +++------- tests/ui/comptime/comptime_method.rs | 7 +-- tests/ui/comptime/comptime_method.stderr | 19 ++------ tests/ui/comptime/comptime_method_bounds.rs | 24 ++++++++++ tests/ui/comptime/comptime_trait.rs | 32 +++++++++++++ tests/ui/comptime/comptime_trait.stderr | 35 +++++++++++++++ tests/ui/comptime/trait_comptime.stderr | 6 +-- 14 files changed, 172 insertions(+), 65 deletions(-) create mode 100644 tests/ui/comptime/comptime_closure.rs create mode 100644 tests/ui/comptime/comptime_closure.stderr create mode 100644 tests/ui/comptime/comptime_method_bounds.rs create mode 100644 tests/ui/comptime/comptime_trait.rs create mode 100644 tests/ui/comptime/comptime_trait.stderr diff --git a/compiler/rustc_ast_lowering/src/expr/closure.rs b/compiler/rustc_ast_lowering/src/expr/closure.rs index cc2c6ae2879c1..32e2e5d40d132 100644 --- a/compiler/rustc_ast_lowering/src/expr/closure.rs +++ b/compiler/rustc_ast_lowering/src/expr/closure.rs @@ -38,6 +38,7 @@ impl<'hir> LoweringContext<'_, 'hir> { &closure.body, closure.fn_decl_span, closure.fn_arg_span, + attrs, ), span: self.lower_span(e.span), }, @@ -240,7 +241,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn_decl_span: self.lower_span(fn_decl_span), fn_arg_span: Some(self.lower_span(fn_arg_span)), kind: closure_kind, - constness: self.lower_constness(constness), + constness: self.lower_constness(attrs, constness), explicit_captures, }); @@ -308,6 +309,7 @@ impl<'hir> LoweringContext<'_, 'hir> { body: &Expr, fn_decl_span: Span, fn_arg_span: Span, + attrs: &[hir::Attribute], ) -> hir::ExprKind<'hir> { let closure_def_id = self.local_def_id(closure_id); let (binder_clause, generic_params) = self.lower_closure_binder(binder); @@ -369,7 +371,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // knows that a `FnDecl` output type like `-> &str` actually means // "coroutine that returns &str", rather than directly returning a `&str`. kind: hir::ClosureKind::CoroutineClosure(coroutine_desugaring), - constness: self.lower_constness(constness), + constness: self.lower_constness(attrs, constness), explicit_captures: &[], }); hir::ExprKind::Closure(c) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 692c178a6875c..8d5bd34f13444 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -479,7 +479,7 @@ impl<'hir> LoweringContext<'_, 'hir> { .arena .alloc_from_iter(impl_items.iter().map(|item| self.lower_impl_item_ref(item))); - let constness = self.lower_constness(*constness); + let constness = self.lower_constness(attrs, *constness); hir::ItemKind::Impl(hir::Impl { generics, @@ -499,7 +499,7 @@ impl<'hir> LoweringContext<'_, 'hir> { bounds, items, }) => { - let constness = self.lower_constness(*constness); + let constness = self.lower_constness(attrs, *constness); let impl_restriction = self.lower_impl_restriction(impl_restriction); let ident = self.lower_ident(*ident); let (generics, (safety, items, bounds)) = self.lower_generics( @@ -530,7 +530,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } } ItemKind::TraitAlias(TraitAlias { constness, ident, generics, bounds }) => { - let constness = self.lower_constness(*constness); + let constness = self.lower_constness(attrs, *constness); let ident = self.lower_ident(*ident); let (generics, bounds) = self.lower_generics( generics, @@ -1702,21 +1702,7 @@ impl<'hir> LoweringContext<'_, 'hir> { safety.into() }; - let mut constness = self.lower_constness(h.constness); - if let Some(&attr_span) = find_attr!(attrs, RustcComptime(span) => span) { - match std::mem::replace(&mut constness, rustc_hir::Constness::Const { always: true }) { - rustc_hir::Constness::Const { always: true } => { - unreachable!("lower_constness cannot produce comptime") - } - // A function can't be `const` and `comptime` at the same time - rustc_hir::Constness::Const { always: false } => { - let Const::Yes(span) = h.constness else { unreachable!() }; - self.dcx().emit_err(ConstComptimeFn { span, attr_span }); - } - // Good - rustc_hir::Constness::NotConst => {} - } - } + let constness = self.lower_constness(attrs, h.constness); hir::FnHeader { safety, asyncness, constness, abi: self.lower_extern(h.ext) } } @@ -1778,11 +1764,30 @@ impl<'hir> LoweringContext<'_, 'hir> { }); } - pub(super) fn lower_constness(&mut self, c: Const) -> hir::Constness { - match c { + /// Lowers constness or comptime attribute. + /// Whether `const` is allowed here is checked by ast validation. + /// Whether `comptime` is allowed here is checked by the `comptime` attribute parser. + pub(super) fn lower_constness(&mut self, attrs: &[hir::Attribute], c: Const) -> hir::Constness { + let mut constness = match c { Const::Yes(_) => hir::Constness::Const { always: false }, Const::No => hir::Constness::NotConst, + }; + + if let Some(&attr_span) = find_attr!(attrs, RustcComptime(span) => span) { + match std::mem::replace(&mut constness, hir::Constness::Const { always: true }) { + hir::Constness::Const { always: true } => { + unreachable!("lower_constness cannot produce comptime") + } + // A function can't be `const` and `comptime` at the same time + hir::Constness::Const { always: false } => { + let Const::Yes(span) = c else { unreachable!() }; + self.dcx().emit_err(ConstComptimeFn { span, attr_span }); + } + // Good + hir::Constness::NotConst => {} + } } + constness } pub(super) fn lower_safety(&self, s: Safety, default: hir::Safety) -> hir::Safety { diff --git a/compiler/rustc_attr_parsing/src/attributes/semantics.rs b/compiler/rustc_attr_parsing/src/attributes/semantics.rs index cdcb8e95da726..fa19d51c397eb 100644 --- a/compiler/rustc_attr_parsing/src/attributes/semantics.rs +++ b/compiler/rustc_attr_parsing/src/attributes/semantics.rs @@ -23,6 +23,7 @@ impl NoArgsAttributeParser for ComptimeParser { const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Fn), + Allow(Target::Impl { of_trait: false }), ]); const STABILITY: AttributeStability = unstable!(rustc_attrs); const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcComptime; diff --git a/compiler/rustc_trait_selection/src/traits/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs index fb44b3b9a9988..1d5c657cb6723 100644 --- a/compiler/rustc_trait_selection/src/traits/effects.rs +++ b/compiler/rustc_trait_selection/src/traits/effects.rs @@ -601,7 +601,8 @@ fn evaluate_host_effect_from_selection_candidate<'tcx>( match tcx.impl_trait_header(impl_.impl_def_id).constness { rustc_hir::Constness::Const { always } => { if always { - unimplemented!() + // FIXME(comptime): just bailing for now to avoid an ICE in a test. + return Err(EvaluationFailure::NoSolution); } } rustc_hir::Constness::NotConst => { diff --git a/tests/ui/comptime/comptime_closure.rs b/tests/ui/comptime/comptime_closure.rs new file mode 100644 index 0000000000000..bc3d58104cbc6 --- /dev/null +++ b/tests/ui/comptime/comptime_closure.rs @@ -0,0 +1,13 @@ +#![feature(rustc_attrs, stmt_expr_attributes)] + +const _: () = { + let f = #[rustc_comptime] + //~^ ERROR: `#[rustc_comptime]` attribute cannot be used on closures + || (); + + // FIXME(comptime): closures should work, too. + f(); + //~^ ERROR: cannot call non-const closure in constants +}; + +fn main() {} diff --git a/tests/ui/comptime/comptime_closure.stderr b/tests/ui/comptime/comptime_closure.stderr new file mode 100644 index 0000000000000..602f88e64b7ad --- /dev/null +++ b/tests/ui/comptime/comptime_closure.stderr @@ -0,0 +1,20 @@ +error: `#[rustc_comptime]` attribute cannot be used on closures + --> $DIR/comptime_closure.rs:4:13 + | +LL | let f = #[rustc_comptime] + | ^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_comptime]` can be applied to functions, inherent impl blocks, and inherent methods + +error[E0015]: cannot call non-const closure in constants + --> $DIR/comptime_closure.rs:9:5 + | +LL | f(); + | ^^^ + | + = note: closures need an RFC before allowed to be called in constants + = note: calls in constants are limited to constant functions, tuple structs and tuple variants + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/comptime/comptime_impl.rs b/tests/ui/comptime/comptime_impl.rs index 84b08ded12b5c..6e8768aaed109 100644 --- a/tests/ui/comptime/comptime_impl.rs +++ b/tests/ui/comptime/comptime_impl.rs @@ -9,7 +9,6 @@ const trait Foo { struct Bar; #[rustc_comptime] -//~^ ERROR: cannot be used on inherent impl impl Bar { fn boo(&self) {} } @@ -19,7 +18,6 @@ impl Bar { impl Foo for Bar { fn foo(&self) { comptime_fn(); - //~^ ERROR: comptime fns can only be called at compile time } } diff --git a/tests/ui/comptime/comptime_impl.stderr b/tests/ui/comptime/comptime_impl.stderr index 75ad46d60cbea..25f5e878b57f6 100644 --- a/tests/ui/comptime/comptime_impl.stderr +++ b/tests/ui/comptime/comptime_impl.stderr @@ -1,27 +1,13 @@ -error: `#[rustc_comptime]` attribute cannot be used on inherent impl blocks - --> $DIR/comptime_impl.rs:11:1 - | -LL | #[rustc_comptime] - | ^^^^^^^^^^^^^^^^^ - | - = help: `#[rustc_comptime]` can only be applied to functions - error: `#[rustc_comptime]` attribute cannot be used on trait impl blocks - --> $DIR/comptime_impl.rs:17:1 + --> $DIR/comptime_impl.rs:16:1 | LL | #[rustc_comptime] | ^^^^^^^^^^^^^^^^^ | - = help: `#[rustc_comptime]` can only be applied to functions - -error: comptime fns can only be called at compile time - --> $DIR/comptime_impl.rs:21:9 - | -LL | comptime_fn(); - | ^^^^^^^^^^^^^ + = help: `#[rustc_comptime]` can be applied to functions and inherent impl blocks error[E0277]: the trait bound `Bar: const Foo` is not satisfied - --> $DIR/comptime_impl.rs:31:9 + --> $DIR/comptime_impl.rs:29:9 | LL | Bar.foo(); | ^^^ @@ -32,7 +18,7 @@ LL | impl const Foo for Bar { | +++++ error[E0277]: the trait bound `Bar: const Foo` is not satisfied - --> $DIR/comptime_impl.rs:33:9 + --> $DIR/comptime_impl.rs:31:9 | LL | Bar.bar(); | ^^^ @@ -42,6 +28,6 @@ help: make the `impl` of trait `Foo` `const` LL | impl const Foo for Bar { | +++++ -error: aborting due to 5 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/comptime/comptime_method.rs b/tests/ui/comptime/comptime_method.rs index a0618f97e0ea8..a55c950b01680 100644 --- a/tests/ui/comptime/comptime_method.rs +++ b/tests/ui/comptime/comptime_method.rs @@ -3,14 +3,15 @@ struct Bar; #[rustc_comptime] -//~^ ERROR: cannot be used on inherent impl impl Bar { fn boo(&self) {} } const _: () = { Bar.boo(); - //~^ ERROR: cannot call non-const method `Bar::boo` in constants }; -fn main() {} +fn main() { + Bar.boo(); + //~^ ERROR: comptime fns can only be called at compile time +} diff --git a/tests/ui/comptime/comptime_method.stderr b/tests/ui/comptime/comptime_method.stderr index 682e0c364e43c..f188ab7e4be58 100644 --- a/tests/ui/comptime/comptime_method.stderr +++ b/tests/ui/comptime/comptime_method.stderr @@ -1,19 +1,8 @@ -error: `#[rustc_comptime]` attribute cannot be used on inherent impl blocks - --> $DIR/comptime_method.rs:5:1 - | -LL | #[rustc_comptime] - | ^^^^^^^^^^^^^^^^^ - | - = help: `#[rustc_comptime]` can only be applied to functions - -error[E0015]: cannot call non-const method `Bar::boo` in constants - --> $DIR/comptime_method.rs:12:9 +error: comptime fns can only be called at compile time + --> $DIR/comptime_method.rs:15:5 | LL | Bar.boo(); - | ^^^^^ - | - = note: calls in constants are limited to constant functions, tuple structs and tuple variants + | ^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/comptime/comptime_method_bounds.rs b/tests/ui/comptime/comptime_method_bounds.rs new file mode 100644 index 0000000000000..993fd28abd1f1 --- /dev/null +++ b/tests/ui/comptime/comptime_method_bounds.rs @@ -0,0 +1,24 @@ +//@check-pass + +#![feature(rustc_attrs, const_trait_impl)] + +struct Bar(T); + +const trait Trait { + fn method(&self) {} +} + +#[rustc_comptime] +impl Bar { + fn boo(&self) { + self.0.method() + } +} + +const impl Trait for () {} + +const _: () = { + Bar(()).boo(); +}; + +fn main() {} diff --git a/tests/ui/comptime/comptime_trait.rs b/tests/ui/comptime/comptime_trait.rs new file mode 100644 index 0000000000000..6f7b601149191 --- /dev/null +++ b/tests/ui/comptime/comptime_trait.rs @@ -0,0 +1,32 @@ +#![feature(rustc_attrs, const_trait_impl, trait_alias)] + +#[rustc_comptime] +//~^ ERROR: `#[rustc_comptime]` attribute cannot be used on traits +trait Trait { + fn method(&self) {} +} + +const impl Trait for () {} + +#[rustc_comptime] +//~^ ERROR: `#[rustc_comptime]` attribute cannot be used on trait impl +impl Trait for u32 { + fn method(&self) { + comptime_fn(); + } +} + +#[rustc_comptime] +fn comptime_fn() {} + +#[rustc_comptime] +//~^ ERROR: `#[rustc_comptime]` attribute cannot be used on trait aliases +trait TraitAlias = const Trait; + +#[rustc_comptime] +fn func(t: &T) { + t.method() + //~^ ERROR: cannot call non-const method `::method` in constants +} + +fn main() {} diff --git a/tests/ui/comptime/comptime_trait.stderr b/tests/ui/comptime/comptime_trait.stderr new file mode 100644 index 0000000000000..8e9272e238fe1 --- /dev/null +++ b/tests/ui/comptime/comptime_trait.stderr @@ -0,0 +1,35 @@ +error: `#[rustc_comptime]` attribute cannot be used on traits + --> $DIR/comptime_trait.rs:3:1 + | +LL | #[rustc_comptime] + | ^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_comptime]` can be applied to functions and inherent impl blocks + +error: `#[rustc_comptime]` attribute cannot be used on trait impl blocks + --> $DIR/comptime_trait.rs:11:1 + | +LL | #[rustc_comptime] + | ^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_comptime]` can be applied to functions and inherent impl blocks + +error: `#[rustc_comptime]` attribute cannot be used on trait aliases + --> $DIR/comptime_trait.rs:22:1 + | +LL | #[rustc_comptime] + | ^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_comptime]` can be applied to functions and inherent impl blocks + +error[E0015]: cannot call non-const method `::method` in constants + --> $DIR/comptime_trait.rs:28:7 + | +LL | t.method() + | ^^^^^^^^ + | + = note: calls in constants are limited to constant functions, tuple structs and tuple variants + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/comptime/trait_comptime.stderr b/tests/ui/comptime/trait_comptime.stderr index 06e982288471d..0ff981e290b17 100644 --- a/tests/ui/comptime/trait_comptime.stderr +++ b/tests/ui/comptime/trait_comptime.stderr @@ -4,7 +4,7 @@ error: `#[rustc_comptime]` attribute cannot be used on required trait methods LL | #[rustc_comptime] | ^^^^^^^^^^^^^^^^^ | - = help: `#[rustc_comptime]` can only be applied to functions with a body + = help: `#[rustc_comptime]` can be applied to functions with a body and inherent impl blocks error: `#[rustc_comptime]` attribute cannot be used on provided trait methods --> $DIR/trait_comptime.rs:8:5 @@ -12,7 +12,7 @@ error: `#[rustc_comptime]` attribute cannot be used on provided trait methods LL | #[rustc_comptime] | ^^^^^^^^^^^^^^^^^ | - = help: `#[rustc_comptime]` can be applied to functions and inherent methods + = help: `#[rustc_comptime]` can be applied to functions, inherent impl blocks, and inherent methods error: `#[rustc_comptime]` attribute cannot be used on trait methods in impl blocks --> $DIR/trait_comptime.rs:21:5 @@ -20,7 +20,7 @@ error: `#[rustc_comptime]` attribute cannot be used on trait methods in impl blo LL | #[rustc_comptime] | ^^^^^^^^^^^^^^^^^ | - = help: `#[rustc_comptime]` can be applied to functions and inherent methods + = help: `#[rustc_comptime]` can be applied to functions, inherent impl blocks, and inherent methods error: aborting due to 3 previous errors