rust-lang / rust-lang/rust-clippy
New lint: types which cannot be constructed in `const`
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 13.5k
- Forks
- 2.2k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 32
Description
Possible name: missing_const_constructor
What it does
Flags types which cannot be constructed using any constant expression. That is, the type meets all of these criteria:
- Is public in a library crate.
- Cannot be constructed as a literal outside the crate (struct or union with private fields or
#[non_exhaustive]). - Does not have an associated nonmethod function
pub const fn <any name>(...) -> Self {or constantpub const <ANY NAME>: Self. (When const trait impls are stabilized,const impl Defaultshould be checked for too.) - Has only fields whose types are themselves constructible in
constor generic. (This rule might be hard to implement precisely, but is only to reduce false positives.)
Categories
- Kind: Restriction
I think something this might be a good lint to warn by default, similar to new_without_default, but it would require much better rules for avoiding false positives before that would be reasonable. As described, I think it's like exhaustive_structs — something one will opt into and then often allow anyway.
This is also a close relative of missing_const_for_fn (which I just learned about while writing this up) but this will trigger when the type has no public const constructor even if it doesn't have a public non-const constructor that could be const.
Advantages
Making sure types have const constructors increases composability: if some crate wants to have a constant instance of some struct it defines, then all fields of it must also be constructible in const. Thus, a single forgotten consideration of const in a library can have a wide impact. If you aren't a const enthusiast it is easy to forget to add const to fns, let alone to add alternatives when the function obviously can't be const.
Drawbacks
- It will warn about some types which should not be constructible in
consteven if the definition seems to permit it, such as newtyped integer handles to runtime-allocated resources. - It might encourage authors to use
const fnwithout knowing the reasons not to (constraint on future compatible versions of the same function). missing_const_for_fnprobably covers a lot of the same ground. However, that lint won't catch cases where the existing constructors can't be constified but a const constructor could be written, so I think this is still worthwhile. (For example,Vec::new()exists and is const, even thoughVec::from([])has the same function and cannot be const since it may allocate.)
Example
To copy an example in my own code,
#[derive(Clone, Debug)]
pub struct IntAllocator<T: num_traits::int::PrimInt + Debug> {
last_allocated: Option<T>,
free_list: Vec<T>,
}
impl<T: PrimInt + Debug> IntAllocator<T> {
pub fn new() -> Self {
Self {
last_allocated: None,
free_list: Vec::new(),
}
}
// ... non-constructor functions follow...
}
would trigger the lint on the struct IntAllocator. Perhaps the logic from missing_const_for_fn could produce a suggestion to modify the existing new; if no such function was found, there would still be a lint but no suggestion.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing the existing missing_const_for_fn lint and compare its analysis and suggestion behavior with the proposed missing_const_constructor rules. Define how the listed visibility, construction, field-type, and false-positive cases should be handled, then add coverage for the IntAllocator example and the stated exclusions. Done means the lint reliably identifies public types without a usable const construction path.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100