# Add an allow-by default lint for statics that could be constants

**URL:** https://internals.rust-lang.org/t/add-an-allow-by-default-lint-for-statics-that-could-be-constants/20930
**Category:** language design
**Created:** [May 27, 2024, 9:07pm UTC](https://internals.rust-lang.org/t/add-an-allow-by-default-lint-for-statics-that-could-be-constants/20930 "2024-05-27T21:07:39Z")
**Posts on this page:** 12
**Page:** 1

<div class="post-metadata">

### Author: ![binarycat](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/binarycat/32/12210_2.png) [@binarycat](https://internals.rust-lang.org/u/binarycat)
#### Post date: [May 27, 2024, 9:07pm UTC](https://internals.rust-lang.org/t/add-an-allow-by-default-lint-for-statics-that-could-be-constants/20930/1 "2024-05-27T21:07:39Z")

</div>

this would be similar to the dead\_code lint and the unused mut lint, but for private static items that could be const items.

as i understand it, there are a few downsides to statics, such as not being able to perform constant folding or constant deduplication.

the advantages of statics is you can take their address, they can reference other constants, and they can be mutable.

however, if you never use these features of a static, you are only getting the downside, with no upside. larger codebases may wish to avoid this.

this would only apply to items not exported from the crate, as public items may need to be statics so that other crates can use them as such, similarly to how public items will never be considered dead code.

something like `warn(static_could_be_const)` would be useful.

---

<div class="post-metadata">

### Author: ![tczajka](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/tczajka/32/8923_2.png) [@tczajka](https://internals.rust-lang.org/u/tczajka)
#### Post date: [May 27, 2024, 9:47pm UTC](https://internals.rust-lang.org/t/add-an-allow-by-default-lint-for-statics-that-could-be-constants/20930/2 "2024-05-27T21:47:50Z")

</div>

Another advantage of `static` is that it is only computed once, not on every use.

---

<div class="post-metadata">

### Author: ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)
#### Post date: [May 27, 2024, 10:19pm UTC](https://internals.rust-lang.org/t/add-an-allow-by-default-lint-for-statics-that-could-be-constants/20930/3 "2024-05-27T22:19:12Z")

</div>

Big statics are often intentional to avoid duplication, even if they'd work entirely fine as constants, for example.

I don't think this is a good rustc lint. As allow-by-default, the people who would most benefit from it wouldn't know about it to turn it on in the first place. And checking exactly whether it's a good idea to have it a static feels like the kind of unreliable or incredibly slow (because it'd look at all the code in the whole crate) check that we wouldn't really want, especially if the only recourse is to `allow` it.

Do you have some examples from the wild of things that you think are worth linting? Maybe there's something more specific where it would ok to enable it at warn-by-default, which would make it way more acceptable.

(Alternatively, maybe it'd be better as a R-A hint or clippy "did you know you could do this a different way?" idea...)

---

<div class="post-metadata">

### Author: ![binarycat](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/binarycat/32/12210_2.png) [@binarycat](https://internals.rust-lang.org/u/binarycat)
#### Post date: [May 27, 2024, 10:48pm UTC](https://internals.rust-lang.org/t/add-an-allow-by-default-lint-for-statics-that-could-be-constants/20930/4 "2024-05-27T22:48:52Z")

</div>

i don't think it would have to be any slower than dead code checking, although i did not know rustc duplicates large constants like that, that's a usecase i wasn't aware of, and one that's less quantifyable.

---

<div class="post-metadata">

### Author: ![kornel](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kornel/32/2711_2.png) [@kornel](https://internals.rust-lang.org/u/kornel)
#### Post date: [May 28, 2024, 1:24pm UTC](https://internals.rust-lang.org/t/add-an-allow-by-default-lint-for-statics-that-could-be-constants/20930/5 "2024-05-28T13:24:01Z")

</div>

There's no point deduplicating small types like integers, so the lint could complain about values that are same size or smaller than a pointer to the static.

---

<div class="post-metadata">

### Author: ![binarycat](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/binarycat/32/12210_2.png) [@binarycat](https://internals.rust-lang.org/u/binarycat)
#### Post date: [May 30, 2024, 4:01pm UTC](https://internals.rust-lang.org/t/add-an-allow-by-default-lint-for-statics-that-could-be-constants/20930/6 "2024-05-30T16:01:00Z")

</div>

note that pointer size is platform dependent. i don't think there's any lints that give a different output depending on target platform?

---

<div class="post-metadata">

### Author: ![kornel](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kornel/32/2711_2.png) [@kornel](https://internals.rust-lang.org/u/kornel)
#### Post date: [May 30, 2024, 10:47pm UTC](https://internals.rust-lang.org/t/add-an-allow-by-default-lint-for-statics-that-could-be-constants/20930/7 "2024-05-30T22:47:03Z")

</div>

That's an implementation detail. It could be `$bikeshed`-bits for all platforms.

---

<div class="post-metadata">

### Author: ![binarycat](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/binarycat/32/12210_2.png) [@binarycat](https://internals.rust-lang.org/u/binarycat)
#### Post date: [May 31, 2024, 1:07am UTC](https://internals.rust-lang.org/t/add-an-allow-by-default-lint-for-statics-that-could-be-constants/20930/8 "2024-05-31T01:07:44Z")

</div>

1. this is the rust internals forum. where is one to discuss implementation details if not here?
2. it changes things significantly. taking the address of an `i32` would waste space on a 64 bit target, but save space on 16 bit targets.

---

<div class="post-metadata">

### Author: ![kornel](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kornel/32/2711_2.png) [@kornel](https://internals.rust-lang.org/u/kornel)
#### Post date: [May 31, 2024, 1:55am UTC](https://internals.rust-lang.org/t/add-an-allow-by-default-lint-for-statics-that-could-be-constants/20930/9 "2024-05-31T01:55:42Z")

</div>

There are no significant 16-bit Rust targets, and writing for such platforms is a completely different style of programming. Many Rust APIs and lints don't make sense there. The lint could be disabled there entirely. There's no rule saying lints can't be platform specific.

There's a cost of extra CPU instructions that load the value. There's cost of missed optimizations from it being a run-time indirect value, and not a compile time constant.

---

<div class="post-metadata">

### Author: ![binarycat](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/binarycat/32/12210_2.png) [@binarycat](https://internals.rust-lang.org/u/binarycat)
#### Post date: [May 31, 2024, 2:25am UTC](https://internals.rust-lang.org/t/add-an-allow-by-default-lint-for-statics-that-could-be-constants/20930/10 "2024-05-31T02:25:03Z")

</div>

the main usecase i can think of for &u32 on an embedded target is some sort of tree/graph with each node labeled with a set of bitfields that are likely to be duplicated. using an arena allocator for the graph would handle any possible difficulties with freeing memory, and for a graph with a lot of nodes, those downsides may be worth it in order to save memory.

there's exactly one tier 3 16 bit target: msp430-none-elf

---

<div class="post-metadata">

### Author: ![farnz](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/farnz/32/6587_2.png) [@farnz](https://internals.rust-lang.org/u/farnz)
#### Post date: [May 31, 2024, 11:04am UTC](https://internals.rust-lang.org/t/add-an-allow-by-default-lint-for-statics-that-could-be-constants/20930/11 "2024-05-31T11:04:38Z")

</div>

Note, though, that there's also a speed tradeoff - last time I measured on x86-64, by-value was better for anything up to one cache line (64 bytes) in size, and better for two cache lines if cache line aligned.

As a result, I'd suggest that the lint remains useful even if it suggests changes that would make your binary larger on some platforms; it could lint on statics less than or equal to 64 bytes, and be a useful hint.

---

<div class="post-metadata">

### Author: ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)
#### Post date: [August 29, 2024, 11:04am UTC](https://internals.rust-lang.org/t/add-an-allow-by-default-lint-for-statics-that-could-be-constants/20930/12 "2024-08-29T11:04:41Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
