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:
parent
a526d7ce45
commit
8c402f125c
@ -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}
|
||||
|
||||
|
@ -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]
|
||||
|
@ -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");
|
||||
|
@ -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`";
|
||||
|
@ -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)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
47
tests/ui/macros/macro-missing-fragment.e2024.stderr
Normal file
47
tests/ui/macros/macro-missing-fragment.e2024.stderr
Normal 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
|
||||
|
@ -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() {
|
||||
|
Loading…
Reference in New Issue
Block a user