The fact that let mut is longer than let is intentional. The language designers wanted to encourage people to use let as the "default", not overuse let mut unnecessarily.
It is certainly possible to add this feature. The question is, will the benefit of the code being more concise, only, be worth the cost of the compiler, and human readers, learning another single-purpose piece of syntax? That is the argument you must make, not merely that is it possible and would be shorter.
This page documents some of those ideas, along with the concerns that argue against them.
If something appears on this page, that doesn’t mean Rust would never consider making any similar change. It does mean that any hypothetical successful proposal to do so would need to address at a minimum all of these known concerns, whether by proposing a new and previously unseen approach that avoids all the concerns, or by making an extraordinary case for why their proposal outweighs those concerns.
Hopeful proposers of any of these ideas should document their extensive research into the many past discussions on these topics and ensure they have something new to offer.
[…]
Fundamental changes to Rust syntax
This includes proposals such as changing the generic syntax to not use </>, changing block constructs to not require braces, changing function calls to not require parentheses, and many other similar proposals. These also include proposals to add “alternative” syntaxes, in addition to those that replace the existing syntax. Many of these proposals come from people who also write other languages. Arguments range from the ergonomic (“I don’t want to type this”) to the aesthetic (“I don’t like how this looks”).
Changes that would break existing Rust code are non-starters. Even in an edition, changes this fundamental remain extremely unlikely. The established Rust community with knowledge of existing Rust syntax has a great deal of value, and to be considered, a syntax change proposal would have to be not just better, but so wildly better as to overcome the massive downside of switching.
In addition, such changes often go against one or more other aspects of Rust’s design philosophy. For instance, we don’t want to make changes that make code easier to write but harder to read, or changes that make code more error-prone to modify and maintain.
That said, we are open to proposals that involve new syntax, especially for new features, or to improve an existing fundamental feature. The bar for new syntax (e.g. new operators) is high, but not insurmountable. But the bar for changes to existing syntax is even higher.
The core problem is that you're also, perhaps unknowingly, asking for
a giant argument about when it's better to use which form
a giant argument about whether everyone should have to move to the new form
a giant argument about how rustfmt should decide which to use
a bunch of confusion when people see older resources that weren't updated
a ton of churn on everyone with existing code to move to the new thing
It's just not worth it.
The rust philosophy for this is that it's fine to ask people to just accept the structured suggestion. I, for example, continually make the mistake of struct Foo { x: u32; y: u32 } -- a semicolon instead of a comma -- but the answer isn't "Rust should accept that"; it's "oops, I accepted the structured suggestion and it's fine now".
I imagine many people that want to detect or prevent shadowing rely on lints (e.g., clippy::shadow_unrelated), and I'd guess it wouldn't be that difficult to expand existing lints to detect such code or add new lints that would detect it.
Such lints already fire in the absence of let when dealing with function/closure parameters:
#[expect(clippy::shadow_unrelated, reason = "example")]
fn foo() -> u32 {
let x = 3u32;
x + Some(0u32)
.map(|mut x| {
x += 1;
x
})
.unwrap_or_default()
}
Huh? Unlike other languages, shadowing in rust is common practise. You transfer ownership of some variable to a fiction and assign the result back to the same name. Switching between mut and non-mut bindings is also common.
I would be very surprised if people commonly lint against shadowing rather than take advantage of it.
The fact the lint exists (and IIRC there’s also the more extreme “no shadowing at all” lint) suggests there are enough people that want to ban it from their codebase for whatever reason.
Of course you can, but please don't. You can do whatever with your own fork, but bluntly speaking, actually submitting a PR is just wasting everyone's time.
There is an assumed condition in my response seeing how I was replying to a post that objected to this proposal on grounds that it would "be harder to detect shadowing in your code" (emphasis added).
For those of us that want to detect or prevent shadowing, most likely use lints to detect it. Existing lints that do that could easily be extended to detect additional forms of shadowing caused from this proposal; thus it wouldn't be "harder" from a programmatic view.
I edited my post to make this conditional explicit.