Cfg-gating `impl const Trait` generates feature-gate error

The following code does not compile, because it requires that the const_trait_impl feature be enabled, even though it is cfg'd out:

#![cfg_attr(
    feature = "nightly",
    feature(const_trait_impl, const_default)
]

struct A(u8);

#[cfg(feature = "nightly")]
impl const Default for A {
    fn default() -> Self {
        Self(0)
    }
}

... which results in the following error:

error[E0658]: const trait impls are experimental
  --> src/lib.rs:49:6
   |
49 | impl const Default for A {
   |      ^^^^^
   |
   = note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
   = note: this compiler was built on 2026-04-29; consider upgrading it if it is out of date

... and even when I test with #[cfg(target_arch = "aarch64")] (and I'm not building for ARM64), the same error is generated. So far as I understand, the code shouldn't even be enumerated by the compiler. Am I doing something wrong, or is this a bug?

Thanks.

This error is emitted during parsing. #[cfg] is only evaluated after parsing. You will either have to put your impl in a dedicated file which is only included on nightly or you have to put it in a macro like so:

macro_rules! identity {
    ($($a:tt)*) => { $($a)* }
}

#[cfg(feature = "nightly")]
identity! {
    impl const Default for A {
        fn default() -> Self {
            Self(0)
        }
    }
}

I see. Would that not constitute a bug, then? It seems like extremely unintuitive behaviour. Is there an existing issue where it's been discussed by the Rust developers, that you know of?

It's a bit annoying because this is already inside a macro. Moving it to another file is ... difficult to figure out how to do?

You can't feature-gate ungrammatical code in general, you have to be able to parse the file to even know that there are attributes, never mind how to interpret them. Attributes aren't like C preprocessor directives. const in that position violates the Rust grammar in versions that don't support const traits.

I see. Thank you for the explanation!

As I actually try to implement this in a way that isn't a nightmare to maintain, I'm having some trouble. It seems like I have to duplicate every single impl body in order to use impl const in a macro, somehow keeping the actual implementations consistent across the nightly and non-nightly files where the implementation macros actually reside.

I noticed that the standard library uses the #[rustc_const_unstable(feature = "const_convert", issue = "143773")] attribute, which I guess (?) just implements const traits opportunistically? Is there something like that for mere mortals?

No, there isn't, but I think you can use one of crates.io: Rust Package Registry or crates.io: Rust Package Registry (can't endorse, just found them by quickly searching in crates.io before suggesting you implemented their functionality yourself).