rust/tests
bors cd6ec97f0d Auto merge of #116773 - dtolnay:validatestable, r=compiler-errors
Validate `feature` and `since` values inside `#[stable(…)]`

Previously the string passed to `#[unstable(feature = "...")]` would be validated as an identifier, but not `#[stable(feature = "...")]`. In the standard library there were `stable` attributes containing the empty string, and kebab-case string, neither of which should be allowed.

Pre-existing validation of `unstable`:

```rust
// src/lib.rs

#![allow(internal_features)]
#![feature(staged_api)]
#![unstable(feature = "kebab-case", issue = "none")]

#[unstable(feature = "kebab-case", issue = "none")]
pub struct Struct;
```

```console
error[E0546]: 'feature' is not an identifier
 --> src/lib.rs:5:1
  |
5 | #![unstable(feature = "kebab-case", issue = "none")]
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```

For an `unstable` attribute, the need for an identifier is obvious because the downstream code needs to write a `#![feature(...)]` attribute containing that identifier. `#![feature(kebab-case)]` is not valid syntax and `#![feature(kebab_case)]` would not work if that is not the name of the feature.

Having a valid identifier even in `stable` is less essential but still useful because it allows for informative diagnostic about the stabilization of a feature. Compare:

```rust
// src/lib.rs

#![allow(internal_features)]
#![feature(staged_api)]
#![stable(feature = "kebab-case", since = "1.0.0")]

#[stable(feature = "kebab-case", since = "1.0.0")]
pub struct Struct;
```

```rust
// src/main.rs

#![feature(kebab_case)]

use repro::Struct;

fn main() {}
```

```console
error[E0635]: unknown feature `kebab_case`
 --> src/main.rs:3:12
  |
3 | #![feature(kebab_case)]
  |            ^^^^^^^^^^
```

vs the situation if we correctly use `feature = "snake_case"` and `#![feature(snake_case)]`, as enforced by this PR:

```console
warning: the feature `snake_case` has been stable since 1.0.0 and no longer requires an attribute to enable
 --> src/main.rs:3:12
  |
3 | #![feature(snake_case)]
  |            ^^^^^^^^^^
  |
  = note: `#[warn(stable_features)]` on by default
```
2023-10-24 15:06:20 +00:00
..
test_utils Move/rename lazy::Sync{OnceCell,Lazy} to sync::{Once,Lazy}Lock 2022-06-16 19:54:42 +04:00
ui Auto merge of #116773 - dtolnay:validatestable, r=compiler-errors 2023-10-24 15:06:20 +00:00
ui-cargo Merge commit '98363cbf6a' into clippyup 2023-09-12 18:44:06 +02:00
ui-internal Merge commit '2b030eb03d' into clippyup 2023-10-21 14:16:11 +02:00
ui-toml Merge commit '2b030eb03d' into clippyup 2023-10-21 14:16:11 +02:00
workspace_test Merge commit '37f4c1725d' into clippyup 2023-07-02 14:59:02 +02:00
check-fmt.rs Merge commit 'f51aade56f' into clippyup 2022-08-31 09:24:45 -04:00
clippy.toml Merge commit '3ae8faff4d' into clippyup 2021-06-03 08:41:37 +02:00
compile-test.rs Merge commit '2b030eb03d' into clippyup 2023-10-21 14:16:11 +02:00
dogfood.rs Merge commit '371120bdbf' into clippyup 2023-05-05 17:45:49 +02:00
headers.rs Merge commit '080b587854' into clippyup 2023-08-24 21:32:12 +02:00
integration.rs Merge commit '5436dba826' into clippyup 2023-07-31 23:53:53 +02:00
lint_message_convention.rs Merge commit 'd9c24d1b1e' into clippyup 2023-07-17 10:22:32 +02:00
missing-test-files.rs Merge commit '37f4c1725d' into clippyup 2023-07-02 14:59:02 +02:00
versioncheck.rs Merge commit '4bdfb0741d' into clippyup 2022-12-17 14:12:54 +01:00
workspace.rs Merge commit '37f4c1725d' into clippyup 2023-07-02 14:59:02 +02:00