# Idea: rustc & cargo should warn on unspecified edition

**URL:** <https://internals.rust-lang.org/t/idea-rustc-cargo-should-warn-on-unspecified-edition/20309>\
**Category:** tools and infrastructure\
**Created:** [February 11, 2024, 10:24pm UTC](https://internals.rust-lang.org/t/idea-rustc-cargo-should-warn-on-unspecified-edition/20309 "2024-02-11T22:24:56Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![kpreid](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kpreid/32/8484_2.png) [@kpreid](https://internals.rust-lang.org/u/kpreid)\
**Post date:** [February 11, 2024, 10:24pm UTC](https://internals.rust-lang.org/t/idea-rustc-cargo-should-warn-on-unspecified-edition/20309/1 "2024-02-11T22:24:56Z")

</div>

A moderately common source of beginner confusion is that they encounter unexpected behavior due to not specifying a language edition, and getting the default 2015 edition. This can be either due to calling `rustc` instead of `cargo` and not specifying any options, or writing a `Cargo.toml` from scratch (that is, not using `cargo new`) without remembering to include the `edition` field.

Users in this position encounter various surprising behaviors, such as needing `extern crate` to use dependencies, and not being able to write `async` code. As new language editions are released, the number of such surprises will increase.

Therefore, I propose that **tools should warn if the edition is unspecified**. More precisely, there should be a warning in any of the cases where 2015 is chosen by default:

- `rustc` shall warn if no `--edition` is passed.
- `cargo` shall warn if the manifest of a package does not contain a `package.edition` in its `Cargo.toml`.

The warning would of course be hidden for downloaded dependencies, like other warnings already are. It would tell the reader that `"2015"` should be used if the code is old code not being modified, and the current edition should be used for new code.

* * *

There's some mildly interesting complications in implementing this — for example, Cargo currently translates explicit `edition = "2015"` into not passing `--edition` to rustc at all, and there are a very large number of UI tests (tests that assert the output of the compiler, including warnings) in the rust-lang/rust repository that have unspecified edition. All that I know of are solvable, but it made the problem bigger than "I'll just make a PR or two" as I thought when I came up with this idea.

So, I'd like to know: Does this sound like the right direction to go in? Are there situations where the warning would not be straightforwardly fixable?

---

<div class="post-metadata">

**Author:** ![CAD97](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cad97/32/3460_2.png) [@CAD97](https://internals.rust-lang.org/u/CAD97)\
**Post date:** [February 12, 2024, 2:34am UTC](https://internals.rust-lang.org/t/idea-rustc-cargo-should-warn-on-unspecified-edition/20309/2 "2024-02-12T02:34:48Z")

</div>

I'm all for it. I presumably know what I'm doing and have still confused myself with an accidentally missing edition specification as well. I'd even suggest doing so for virtual workspace manifests without a resolver key (usually inferred from package edition) as well.

While it's a bigger change, the change should still be reasonably straightforward:

- Make cargo always pass `--edition`.
- Emit the warning. Bless the changed UI test outputs containing the warning to automatically update them.
- Slowly update UI tests over time to specify edition.

---

<div class="post-metadata">

**Author:** ![bjorn3](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/bjorn3/32/2736_2.png) [@bjorn3](https://internals.rust-lang.org/u/bjorn3)\
**Post date:** [February 12, 2024, 7:24am UTC](https://internals.rust-lang.org/t/idea-rustc-cargo-should-warn-on-unspecified-edition/20309/3 "2024-02-12T07:24:20Z")

</div>

> [@CAD97](#):
>
> I'd even suggest doing so for virtual workspace manifests without a resolver key (usually inferred from package edition) as well.

Cargo already warns if you have a 2021 edition crate in a workspace without explicit resolver version.

---

<div class="post-metadata">

**Author:** ![matklad](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/matklad/32/12266_2.png) [@matklad](https://internals.rust-lang.org/u/matklad)\
**Post date:** [February 12, 2024, 8:04am UTC](https://internals.rust-lang.org/t/idea-rustc-cargo-should-warn-on-unspecified-edition/20309/4 "2024-02-12T08:04:40Z")

</div>

I’d say:

- `rustc` should use the latest edition by default.
- `cargo` should flat out error if the edition is unspecified (with a carve out for dependencies)

2015 default is going to look increasingly ridiculous as the time goes by, so it seems like it’s the question of when.

And now seems like a decent time: 2015 was a while ago, _and_ a lot of code from those days doesn’t build any more anyway (there were a couple of breaking macro changes, and mem::unitialized).

---

<div class="post-metadata">

**Author:** ![josh](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/josh/32/5934_2.png) [@josh](https://internals.rust-lang.org/u/josh)\
**Post date:** [February 12, 2024, 9:01am UTC](https://internals.rust-lang.org/t/idea-rustc-cargo-should-warn-on-unspecified-edition/20309/5 "2024-02-12T09:01:06Z")

</div>

> [@matklad](#):
>
> `rustc` should use the latest edition by default.

This would break backwards compatibility, repeatedly. Emitting a loud warning seems fine, but using the latest edition by default would break existing Rust 2015 code in mysterious ways.

Worse, using the latest edition would induce _new_ code to rely on that, which will then cause _that_ code to get broken every 3 years, eliminating some of the benefit of the edition system.

If we were going to change the default and break such builds, I'd say we should change rustc to error out without an edition specified, rather than using the latest edition. But before we consider doing that we'd need to warn for a nice long time.

> [@matklad](#):
>
> `cargo` should flat out error if the edition is unspecified (with a carve out for dependencies)

For a first pass, I think it makes sense to emit a warning, and let the usual warning-suppression for dependencies handle it. That'll get any actively maintained crate switching over, which will then just leave all the existing crates.

---

<div class="post-metadata">

**Author:** ![epage](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/epage/32/3171_2.png) [@epage](https://internals.rust-lang.org/u/epage)\
**Post date:** [February 12, 2024, 2:51pm UTC](https://internals.rust-lang.org/t/idea-rustc-cargo-should-warn-on-unspecified-edition/20309/6 "2024-02-12T14:51:05Z")

</div>

I'm fine with a warning on an unset Edition in `Cargo.toml`.

Since [cargo-script](https://github.com/rust-lang/rfcs/pull/3502) is a new thing and needs very low overhead for its target audience, it defaults the edition to "current" with a warning that it is unset. I feel this gets us a nice middle ground of people assuming they will get the currently documented behavior while ensuring long-lived scripts don't break (since they'll be annoyed into silencing the warning).

---

<div class="post-metadata">

**Author:** ![ekuber](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ekuber/32/1646_2.png) [@ekuber](https://internals.rust-lang.org/u/ekuber)\
**Post date:** [February 13, 2024, 12:47am UTC](https://internals.rust-lang.org/t/idea-rustc-cargo-should-warn-on-unspecified-edition/20309/7 "2024-02-13T00:47:36Z")

</div>

For what it's worth, feel free to file tickets for errors that are caused by using later edition features in earlier editions. There's precedent for errors telling you that you're using the wrong edition and to pass in `--edition=2021` when needed, but I'm sure there are tons of cases we don't handle today.

---

<div class="post-metadata">

**Author:** ![Noratrieb](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/noratrieb/32/12440_2.png) [@Noratrieb](https://internals.rust-lang.org/u/Noratrieb)\
**Post date:** [February 14, 2024, 6:07am UTC](https://internals.rust-lang.org/t/idea-rustc-cargo-should-warn-on-unspecified-edition/20309/8 "2024-02-14T06:07:14Z")

</div>

I think doing this in cargo is a great idea. I'm less sure about doing it for rustc. My workflow of working on the compiler is certainly not standard, but I (and everyone else who frequently invoked rustc for testing things probably) would find such a warning really annoying and would probably try to hack in some environment variable to turn it off (that I would also want to enable in UI tests). I guess adding such an environment variable would be fine, but also comes with downsides. No one should be using rustc directly anyways, but I'm not sure how we can effectively tell people about that.

---

<div class="post-metadata">

**Author:** ![toc](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/toc/32/6692_2.png) [@toc](https://internals.rust-lang.org/u/toc)\
**Post date:** [February 14, 2024, 6:28am UTC](https://internals.rust-lang.org/t/idea-rustc-cargo-should-warn-on-unspecified-edition/20309/9 "2024-02-14T06:28:41Z")

</div>

> [@Noratrieb](#):
>
> hack in some environment variable

Why wouldn't you just pass in `--edition 2015`?

---

<div class="post-metadata">

**Author:** ![josh](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/josh/32/5934_2.png) [@josh](https://internals.rust-lang.org/u/josh)\
**Post date:** [February 14, 2024, 8:47am UTC](https://internals.rust-lang.org/t/idea-rustc-cargo-should-warn-on-unspecified-edition/20309/10 "2024-02-14T08:47:20Z")

</div>

> [@Noratrieb](#):
>
> No one should be using rustc directly anyways

Many people do, and it's valid to use rustc without cargo. (It's annoying when those uses break other rust conventions, or make it deliberately difficult to integrate crates and cargo as well, but it's still a valid use case.)

---

<div class="post-metadata">

**Author:** ![ryanavella](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ryanavella/32/13254_2.png) [@ryanavella](https://internals.rust-lang.org/u/ryanavella)\
**Post date:** [February 14, 2024, 6:56pm UTC](https://internals.rust-lang.org/t/idea-rustc-cargo-should-warn-on-unspecified-edition/20309/11 "2024-02-14T18:56:50Z")

</div>

> [@josh](#):
>
> > [@matklad](#):
> >
> > `rustc` should use the latest edition by default.
> 
> This would break backwards compatibility, repeatedly.

Do we promise a stable cli for `rustc` across versions? I searched the rustc dev guide and the rustc book but didn't see anything definitive.

> [@josh](#):
>
> Emitting a loud warning seems fine, but using the latest edition by default would break existing Rust 2015 code in mysterious ways.

To clarify, you mean Rust 2015 code using a build system other than `cargo`?

> **Thoughts not necessarily directed at you, but which I want to write down before I forget**
>
> Build systems which wrap around `rustc` (e.g. cargo, buck) should already be passing `--edition` for every invocation. This might be an unnamed rule in the software world, but I generally expect wrapper tools to provide the "maximal set" of flags to the tools they wrap, even those flags that could technically be omitted.
> 
> As for users who are directly using the `rustc` cli, I suspect they skew towards experts in build-systems and compilers who are well-accustomed to working in very unstable corners of the Rust ecosystem. Breaking changes are their bread and butter.

---

<div class="post-metadata">

**Author:** ![mjw](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mjw/32/6108_2.png) [@mjw](https://internals.rust-lang.org/u/mjw)\
**Post date:** [February 14, 2024, 7:14pm UTC](https://internals.rust-lang.org/t/idea-rustc-cargo-should-warn-on-unspecified-edition/20309/12 "2024-02-14T19:14:32Z")

</div>

For what it's worth, the discussion of the default for `rustc --edition` in the original "Evolving Rust through Epochs" RFC is [here](https://github.com/rust-lang/rfcs/pull/2052#pullrequestreview-47747206) and [here](https://github.com/rust-lang/rfcs/pull/2052#issuecomment-312747178).

---

<div class="post-metadata">

**Author:** ![josh](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/josh/32/5934_2.png) [@josh](https://internals.rust-lang.org/u/josh)\
**Post date:** [February 14, 2024, 7:31pm UTC](https://internals.rust-lang.org/t/idea-rustc-cargo-should-warn-on-unspecified-edition/20309/13 "2024-02-14T19:31:47Z")

</div>

> [@ryanavella](#):
>
> Build systems which wrap around `rustc` (e.g. cargo, buck) should already be passing `--edition` for every invocation. This might be an unnamed rule in the software world, but I generally expect wrapper tools to provide the "maximal set" of flags to the tools they wrap, even those flags that could technically be omitted.

I wouldn't go as far as "maximal set", but I agree that build systems that invoke `rustc` for the user should always be passing `--edition`. (Of course, if the user is writing the `rustc` invocation _themselves_ without help from the build tool, then they're the one responsible for adding `--edition`.)

---

<div class="post-metadata">

**Author:** ![steffahn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/steffahn/32/13288_2.png) [@steffahn](https://internals.rust-lang.org/u/steffahn)\
**Post date:** [February 14, 2024, 10:13pm UTC](https://internals.rust-lang.org/t/idea-rustc-cargo-should-warn-on-unspecified-edition/20309/14 "2024-02-14T22:13:49Z")

</div>

I think it's a reasonable idea to furthermore include a suggestion to **use cargo** in the warning that invocation of `rustc` without `--edition` would generate. I think a significant portion of the users that use `rustc` manually and forget the `--edition` argument are users that _mainly_ made the mistake of not using cargo; this is in line with the "no one should be using rustc directly anyways" kind of sentiment above, the weaker version of which is "no one should be using rustc directly unless they know _exactly why_ they 'need' to use it manually"\[1\]

Also, in addition to usage of explicit `--edition 2015` for silencing the warning, it _might_ also be reasonable to silence the warning when flags are detected that are characteristic for `rustc` invocation by automatic tooling, such as `cargo`; the warning is meant to address manual users of the `rustc` command, after all. This way, it would even be an option that cargo keeps current behavior of not passing `--edition 2015`. (I'm not sure what the best contenders are. For example, `cargo` probably always uses JSON output mode, so that's one potential candidate. Maybe there is no good candidate, or this is deemed too inconsistent, I'm only meaning this as an idea that _might_ be sensible, anyways.)

* * *

1. and the set of users that don't know why they use `rustc` manually and the set of users that don't know how to use rustc manually (i.e. to pass `--edition`) should have good overlap

---

<div class="post-metadata">

**Author:** ![matklad](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/matklad/32/12266_2.png) [@matklad](https://internals.rust-lang.org/u/matklad)\
**Post date:** [February 15, 2024, 8:42am UTC](https://internals.rust-lang.org/t/idea-rustc-cargo-should-warn-on-unspecified-edition/20309/15 "2024-02-15T08:42:27Z")

</div>

> [@steffahn](#):
>
> I think a significant portion of the users that use `rustc` manually and forget the `--edition` argument are users that _mainly_ made the mistake of not using cargo;

My gut feeling is that the overwhelming majority of cargo-less rustc invocations are just people trying isolated snippets of code, as a local playground of sorts.

---

<div class="post-metadata">

**Author:** ![bjorn3](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/bjorn3/32/2736_2.png) [@bjorn3](https://internals.rust-lang.org/u/bjorn3)\
**Post date:** [February 15, 2024, 12:08pm UTC](https://internals.rust-lang.org/t/idea-rustc-cargo-should-warn-on-unspecified-edition/20309/16 "2024-02-15T12:08:45Z")

</div>

> [@matklad](#):
>
> My gut feeling is that the overwhelming majority of cargo-less rustc invocations are just people trying isolated snippets of code, as a local playground of sorts.

This use case will be fixed by cargo scripts, right? And if it doesn't, for this use case you almost certainly don't want to use the 2015 edition and explicitly specifying the edition would suppress the warning.

---

<div class="post-metadata">

**Author:** ![zackw](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/zackw/32/2071_2.png) [@zackw](https://internals.rust-lang.org/u/zackw)\
**Post date:** [February 15, 2024, 1:30pm UTC](https://internals.rust-lang.org/t/idea-rustc-cargo-should-warn-on-unspecified-edition/20309/17 "2024-02-15T13:30:24Z")

</div>

> [@bjorn3](#):
>
> This use case will be fixed by cargo scripts, right?

No, because at least two-thirds of the time, if I'm messing with an isolated snippet, I'm about to file a bug report on something, and I want to know whether the problem changes or disappears if I take cargo out of the loop.

I might want cargo to tell me the options I need to give rustc to make some already-built dependency crate available to the test program, but that's it.

> [@bjorn3](#):
>
> for this use case you almost certainly don't want to use the 2015 edition

Indeed. In the context of test snippets, I wouldn't mind it being an _error_ not to specify an edition.

* * *

Come to think of it, why can't I specify the edition in the _code_? Like

```rust
#![rust_edition(2021)]

```

at the top of the crate root.

---

<div class="post-metadata">

**Author:** ![notriddle](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/notriddle/32/14082_2.png) [@notriddle](https://internals.rust-lang.org/u/notriddle)\
**Post date:** [February 15, 2024, 6:58pm UTC](https://internals.rust-lang.org/t/idea-rustc-cargo-should-warn-on-unspecified-edition/20309/18 "2024-02-15T18:58:18Z")

</div>

4 posts were merged into an existing topic: [Specifying the edition in the source file](https://internals.rust-lang.org/t/specifying-the-edition-in-the-source-file/20337)

---

<div class="post-metadata">

**Author:** ![epage](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/epage/32/3171_2.png) [@epage](https://internals.rust-lang.org/u/epage)\
**Post date:** [February 28, 2024, 9:42pm UTC](https://internals.rust-lang.org/t/idea-rustc-cargo-should-warn-on-unspecified-edition/20309/19 "2024-02-28T21:42:48Z")

</div>

FYI I have posted [cargo#13499](https://github.com/rust-lang/cargo/pull/13499) to ensure cargo always passes `--edition` so rustc would be able to produce a warning without negatively affecting cargo users, if the compiler team so chooses.

Still working on the cargo warning. Its a lot of test updates...

---

<div class="post-metadata">

**Author:** ![epage](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/epage/32/3171_2.png) [@epage](https://internals.rust-lang.org/u/epage)\
**Post date:** [February 29, 2024, 9:07pm UTC](https://internals.rust-lang.org/t/idea-rustc-cargo-should-warn-on-unspecified-edition/20309/20 "2024-02-29T21:07:40Z")

</div>

I posted [cargo#13505](https://github.com/rust-lang/cargo/pull/13505) for providing the cargo warning

[Next page](https://internals.rust-lang.org/t/idea-rustc-cargo-should-warn-on-unspecified-edition/20309.md?page=2)
