Make missing_fragment_specifier an error in edition 2024

`missing_fragment_specifier` has been a future compatibility warning
since 2017. Uplifting it to an unconditional hard error was attempted in
2020, but eventually reverted due to fallout.

Make it an error only in edition >= 2024, leaving the lint for older
editions. This change will make it easier to support more macro syntax
that relies on usage of `$`.

Fixes <https://github.com/rust-lang/rust/issues/40107>
This commit is contained in:
Trevor Gross 2024-07-20 07:18:09 -05:00
parent a526d7ce45
commit 8c402f125c
7 changed files with 114 additions and 25 deletions

View File

@ -105,6 +105,11 @@ expand_meta_var_dif_seq_matchers = {$msg}
expand_meta_var_expr_unrecognized_var =
variable `{$key}` is not recognized in meta-variable expression
expand_missing_fragment_specifier = missing fragment specifier
.note = fragment specifiers must be specified in the 2024 edition
.suggestion_add_fragspec = try adding a specifier here
.valid = {$valid}
expand_module_circular =
circular modules: {$modules}

View File

@ -416,6 +416,23 @@ pub struct DuplicateMatcherBinding {
pub prev: Span,
}
#[derive(Diagnostic)]
#[diag(expand_missing_fragment_specifier)]
#[note]
#[help(expand_valid)]
pub struct MissingFragmentSpecifier {
#[primary_span]
pub span: Span,
#[suggestion(
expand_suggestion_add_fragspec,
style = "verbose",
code = ":spec",
applicability = "maybe-incorrect"
)]
pub add_span: Span,
pub valid: &'static str,
}
#[derive(Diagnostic)]
#[diag(expand_invalid_fragment_specifier)]
#[help]

View File

@ -115,6 +115,7 @@
use rustc_lint_defs::BuiltinLintDiag;
use rustc_session::lint::builtin::{META_VARIABLE_MISUSE, MISSING_FRAGMENT_SPECIFIER};
use rustc_session::parse::ParseSess;
use rustc_span::edition::Edition;
use rustc_span::symbol::kw;
use rustc_span::{symbol::MacroRulesNormalizedIdent, ErrorGuaranteed, Span};
@ -122,6 +123,8 @@
use std::iter;
use super::quoted::VALID_FRAGMENT_NAMES_MSG_2021;
/// Stack represented as linked list.
///
/// Those are used for environments because they grow incrementally and are not mutable.
@ -269,12 +272,20 @@ fn check_binders(
// FIXME: Report this as a hard error eventually and remove equivalent errors from
// `parse_tt_inner` and `nameize`. Until then the error may be reported twice, once
// as a hard error and then once as a buffered lint.
psess.buffer_lint(
MISSING_FRAGMENT_SPECIFIER,
span,
node_id,
BuiltinLintDiag::MissingFragmentSpecifier,
);
if span.edition() >= Edition::Edition2024 {
psess.dcx().emit_err(errors::MissingFragmentSpecifier {
span,
add_span: span.shrink_to_hi(),
valid: VALID_FRAGMENT_NAMES_MSG_2021,
});
} else {
psess.buffer_lint(
MISSING_FRAGMENT_SPECIFIER,
span,
node_id,
BuiltinLintDiag::MissingFragmentSpecifier,
);
}
}
if !macros.is_empty() {
psess.dcx().span_bug(span, "unexpected MetaVarDecl in nested lhs");

View File

@ -16,7 +16,7 @@
const VALID_FRAGMENT_NAMES_MSG: &str = "valid fragment specifiers are \
`ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, \
`literal`, `path`, `meta`, `tt`, `item` and `vis`";
const VALID_FRAGMENT_NAMES_MSG_2021: &str = "valid fragment specifiers are \
pub const VALID_FRAGMENT_NAMES_MSG_2021: &str = "valid fragment specifiers are \
`ident`, `block`, `stmt`, `expr`, `expr_2021`, `pat`, \
`ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, \
`item` and `vis`";

View File

@ -1,11 +1,11 @@
error: missing fragment specifier
--> $DIR/macro-missing-fragment.rs:4:20
--> $DIR/macro-missing-fragment.rs:9:20
|
LL | ( $( any_token $field_rust_type )* ) => {};
| ^^^^^^^^^^^^^^^^
warning: missing fragment specifier
--> $DIR/macro-missing-fragment.rs:4:20
--> $DIR/macro-missing-fragment.rs:9:20
|
LL | ( $( any_token $field_rust_type )* ) => {};
| ^^^^^^^^^^^^^^^^
@ -13,13 +13,13 @@ LL | ( $( any_token $field_rust_type )* ) => {};
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>
note: the lint level is defined here
--> $DIR/macro-missing-fragment.rs:1:9
--> $DIR/macro-missing-fragment.rs:6:9
|
LL | #![warn(missing_fragment_specifier)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: missing fragment specifier
--> $DIR/macro-missing-fragment.rs:12:7
--> $DIR/macro-missing-fragment.rs:19:7
|
LL | ( $name ) => {};
| ^^^^^
@ -28,7 +28,7 @@ LL | ( $name ) => {};
= note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>
warning: missing fragment specifier
--> $DIR/macro-missing-fragment.rs:18:7
--> $DIR/macro-missing-fragment.rs:26:7
|
LL | ( $name ) => {};
| ^^^^^
@ -40,7 +40,7 @@ error: aborting due to 1 previous error; 3 warnings emitted
Future incompatibility report: Future breakage diagnostic:
warning: missing fragment specifier
--> $DIR/macro-missing-fragment.rs:4:20
--> $DIR/macro-missing-fragment.rs:9:20
|
LL | ( $( any_token $field_rust_type )* ) => {};
| ^^^^^^^^^^^^^^^^
@ -48,14 +48,14 @@ LL | ( $( any_token $field_rust_type )* ) => {};
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>
note: the lint level is defined here
--> $DIR/macro-missing-fragment.rs:1:9
--> $DIR/macro-missing-fragment.rs:6:9
|
LL | #![warn(missing_fragment_specifier)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
warning: missing fragment specifier
--> $DIR/macro-missing-fragment.rs:12:7
--> $DIR/macro-missing-fragment.rs:19:7
|
LL | ( $name ) => {};
| ^^^^^
@ -63,14 +63,14 @@ LL | ( $name ) => {};
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>
note: the lint level is defined here
--> $DIR/macro-missing-fragment.rs:1:9
--> $DIR/macro-missing-fragment.rs:6:9
|
LL | #![warn(missing_fragment_specifier)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
warning: missing fragment specifier
--> $DIR/macro-missing-fragment.rs:18:7
--> $DIR/macro-missing-fragment.rs:26:7
|
LL | ( $name ) => {};
| ^^^^^
@ -78,7 +78,7 @@ LL | ( $name ) => {};
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>
note: the lint level is defined here
--> $DIR/macro-missing-fragment.rs:1:9
--> $DIR/macro-missing-fragment.rs:6:9
|
LL | #![warn(missing_fragment_specifier)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -0,0 +1,47 @@
error: missing fragment specifier
--> $DIR/macro-missing-fragment.rs:9:20
|
LL | ( $( any_token $field_rust_type )* ) => {};
| ^^^^^^^^^^^^^^^^
|
= note: fragment specifiers must be specified in the 2024 edition
= help: valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `expr_2021`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis`
help: try adding a specifier here
|
LL | ( $( any_token $field_rust_type:spec )* ) => {};
| +++++
error: missing fragment specifier
--> $DIR/macro-missing-fragment.rs:19:7
|
LL | ( $name ) => {};
| ^^^^^
|
= note: fragment specifiers must be specified in the 2024 edition
= help: valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `expr_2021`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis`
help: try adding a specifier here
|
LL | ( $name:spec ) => {};
| +++++
error: missing fragment specifier
--> $DIR/macro-missing-fragment.rs:26:7
|
LL | ( $name ) => {};
| ^^^^^
|
= note: fragment specifiers must be specified in the 2024 edition
= help: valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `expr_2021`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis`
help: try adding a specifier here
|
LL | ( $name:spec ) => {};
| +++++
error: missing fragment specifier
--> $DIR/macro-missing-fragment.rs:9:20
|
LL | ( $( any_token $field_rust_type )* ) => {};
| ^^^^^^^^^^^^^^^^
error: aborting due to 4 previous errors

View File

@ -1,23 +1,32 @@
//@ revisions: e2015 e2024
//@[e2015] edition:2015
//@[e2024] edition:2024
//@[e2024] compile-flags: -Zunstable-options
#![warn(missing_fragment_specifier)]
macro_rules! used_arm {
( $( any_token $field_rust_type )* ) => {};
//~^ ERROR missing fragment
//~| WARN missing fragment
//~| WARN this was previously accepted
//[e2015]~^ ERROR missing fragment
//[e2015]~| WARN missing fragment
//[e2015]~| WARN this was previously accepted
//[e2024]~^^^^ ERROR missing fragment
//[e2024]~| ERROR missing fragment
}
macro_rules! used_macro_unused_arm {
() => {};
( $name ) => {};
//~^ WARN missing fragment
//~| WARN this was previously accepted
//[e2015]~^ WARN missing fragment
//[e2015]~| WARN this was previously accepted
//[e2024]~^^^ ERROR missing fragment
}
macro_rules! unused_macro {
( $name ) => {};
//~^ WARN missing fragment
//~| WARN this was previously accepted
//[e2015]~^ WARN missing fragment
//[e2015]~| WARN this was previously accepted
//[e2024]~^^^ ERROR missing fragment
}
fn main() {