Repository navigation
Description
This is the summary issue for the CONST_EVALUATABLE_UNCHECKED future-compatibility warning. The goal of this page is to describe why this change was made and how you can fix code that is affected by it. It also provides a place to ask questions
or register a complaint if you feel the change should not be made. For more information on the policy around future-compatibility warnings, see our breaking change policy guidelines.
What is the warning for?
In version 1.43 we accidentally allowed some uses of generic parameters in repeat expressions. This has a few problems which are outlined in the following document for now.
When will this warning become a hard error?
Most probably after const well-formedness bounds get stabilized, which is currently not yet implemented. There might be a subset of cases here which we can allow without needing any changes, but these require further careful consideration.
How to fix this?
As we only allowed generic constants where the actual type did not matter, it should always be possible to replace the generic parameters with dummy types. For example [0; std::mem::size_of::<*mut T>()] can be changed to [0; std::mem::size_of::<*mut ()>()].
Please report your case here so we may take it into consideration when deciding on how to proceed.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsIdea
Activity
m-ou-se commentedon Sep 12, 2020
Merging #74532 just now ran into this problem. I worked around it by using
()as dummy type:Here, not only
*mut Twas a problem, butSelf(which isAtomicPtr<T>) was a problem as well.danielhenrymantilla commentedon Feb 16, 2021
Following from https://users.rust-lang.org/t/cant-understand-warning-when-using-const-evaluatable-checked/55630/6?u=yandros, the following snippet causes three warnings associated with the lint of this tracking issue, and a hard error:
where
fooin both cases features, for some generic constantN:some non-generic type with an evaluatable constraint / that depends on a(n assumed) fallible computation of
N(N - 0in the examples; note that I am not talking aboutN - 0being infallible, but rather, of a computation that does not fail for a concrete value ofN(10 in the example));an unrelated (to the above type) type parameter
T.In the case of
WithConst, I am using a helper type to introduceN(and the evaluatable bound!) clearly before the generic typeTis ever introduced, to ensure the evaluatable bound cannot possibly depend onT.As you can see, a caller that:
forwards the generic type parameter,
but using a concrete constant parameter (one that does verify the evaluatable bound),
now triggers either this warning, or some related error when the constant is braced (which is sadly required when using a non-literal constant; even when the function features an evaluatable bound on said non-literal constant).
Playground
Finally, the last two calls in this example are interesting: by moving the logic of the function within the generic-and-evaluatable-bounded
implblock forWithConst, we can later introduce that<T>type parameter without issues, and we can then call that helper function from outside with a fixed constant and it doesn't trigger a warning whatsoever.This leads to two questions:
is this warning behavior really intended to affect these things?
And what about the workaround: is that intended too?
lcnr commentedon Feb 26, 2021
From what I can tell this is not expected,
is_const_evaluatableseems to be incorrect here iffeature(const_evaluatable_checked)is active.Afaict all of the examples you've given should work without warnings or errors.
is8ac commentedon Sep 17, 2021
In
1.57.0-nightly (e4828d5b7 2021-09-16)bazproduceswarning: cannot use constants which depend on generic parameters in types.bardoes not.tspiteri commentedon Feb 23, 2022
While checking whether the fixed crate can be ported from typenum to nightly with
generic_const_exprs, I hit this warning. I am not sure whether it's a false positive or whether the behavior I want is meant to be disallowed, but I think it should be allowed when enablinggeneric_const_exprs.I've reduced the code though I left some stuff to show why it would be useful.
lcnr commentedon Feb 23, 2022
@tspiteri this is a bug which only happens with
feature(generic_const_exprs), opened #94293 to track thatpeter-lyons-kehl commentedon May 15, 2022
I admit not understanding this (and reasoning behind it) fully. But I have use case for an associative type with a bound that depends on its owner (trait)'s const generic parameter. Any alternatives/workarounds, please?
Short example failing no Nightly (thanks to ilyvion#9946 for narrowing it down): https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=c133c09b2fa155bb3f4b9ee45e6c011e.
My use case: https://github.com/ranging-rs/slicing-rs/blob/main/src/slices/mod.rs#L30=. I know it's a semantic/voluntary-like constraint only, but I believe it deserves its place. (Feel free to follow up at ranging-rs/slicing-rs#1.)
11 remaining items
Manishearth commentedon Oct 11, 2024
ICU4X hits this here:
https://github.com/unicode-org/icu4x/blob/fcef14a31dbe5e2d0ee5f2a489872df373c2d0de/utils/zerotrie/src/options.rs#L135-L138
We use
Self::FLAGSin a bunch of match statements, so it must be a constant.This const is not dependent on the generic parameter.
KizzyCode commentedon Feb 17, 2025
I think what bugs me here is that it's obvious for my brain that this value is "fully constant".
FIFO_SIZEshould always be0xFF, as it does not depend on the generic parameter – if I don't miss anything, there is no way this code could ever compile or specialize to something else then0xFFin current Rust.And if that assumption is true, IMO this should be treated as a special case that is "fully constant", and should not fail. Of course, this is from my developer-UX "consumer" perspective – I don't know how hard it is to make the compiler prove that case, or if it would block future language development 😅
(Sorry for the late reply; I somehow accidentally unsubscribed here.)
Ddystopia commentedon Feb 28, 2025
I guess there is some regression, as it warned this piece of code (warning and code are redacted):
It clearly does not use any generics.
BoxyUwU commentedon Mar 6, 2025
@Ddystopia inline consts desugar to an item that uses all in scope generic parameters, you should remove the
constblock there as it does not accomplish anything, if you need braces around an array length simply writing{ ... }should work fine. no need forconst { ... }MorganBennetDev commentedon Apr 28, 2025
Ran into this warning and wanted to share my confusion with it. My confusion stems from the fact that this warning seems to be triggered inconsistently. Example of this
The other thing that I found confusing was that the warning shows up on the declaration of
DOESNT_CHANGEand not the usage (which is what caused the warning to appear).I am using
cargo 1.88.0-nightly (d811228b1 2025-04-15)andrustc 1.88.0-nightly (077cedc2a 2025-04-19).BoxyUwU commentedon Apr 29, 2025
@MorganBennetDev that seems like a bug to me. I don't expect us to make that an error when we fix the special casing of repeat expr counts. I split that out into #140447
edwloef commentedon Nov 3, 2025
Sycrosity commentedon Dec 3, 2025
I'm a bit confused on whether the triggering of this warning is expected behaviour or not.
Code, Errors and Questions
```rust struct Identifier(heapless::String);
impl Identifier {
const NAMESPACE: &'static str = "default";
}
impl Decode for Identifier {
async fn decode(...) -> Result {
}
warning: cannot use constants which depend on generic parameters in types
--> src/identifier.rs:43:39
|
43 | ...f = [0u8; Self::NAMESPACE.len() + 1];
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #76200 #76200
This even works if
const NAMESPACE_LEN: usize = Identifier::<N>::NAMESPACE.len().In both situations,
NAMESPACE.len()does not depend onN, but the const's are impl's of a generic type.If this is true:
then neither of these implementations should work, but from a DX POV they should both work.
If I missing something here please do correct me.
Using
cargo 1.91.1 (ea2d97820 2025-10-10)lcnr commentedon Dec 3, 2025
@Sycrosity can you provide a complete example where it does not lint?
Sycrosity commentedon Dec 3, 2025
@lcnr I think I accidentally used
Identifier::<1>::NAMESPACE_LEN()rather thanSelf::NAMESPACE_LEN()which I believe is the intended behaviour (though as others have mentioned, feels expected). I've provided the two implementations below just in case.Code where the lint is triggered
Code which doesn't lint