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
7 changed files with 114 additions and 25 deletions
|
@ -105,6 +105,11 @@ expand_meta_var_dif_seq_matchers = {$msg}
|
||||||
expand_meta_var_expr_unrecognized_var =
|
expand_meta_var_expr_unrecognized_var =
|
||||||
variable `{$key}` is not recognized in meta-variable expression
|
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 =
|
expand_module_circular =
|
||||||
circular modules: {$modules}
|
circular modules: {$modules}
|
||||||
|
|
||||||
|
|
|
@ -416,6 +416,23 @@ pub struct DuplicateMatcherBinding {
|
||||||
pub prev: Span,
|
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)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(expand_invalid_fragment_specifier)]
|
#[diag(expand_invalid_fragment_specifier)]
|
||||||
#[help]
|
#[help]
|
||||||
|
|
|
@ -115,6 +115,7 @@ use rustc_errors::MultiSpan;
|
||||||
use rustc_lint_defs::BuiltinLintDiag;
|
use rustc_lint_defs::BuiltinLintDiag;
|
||||||
use rustc_session::lint::builtin::{META_VARIABLE_MISUSE, MISSING_FRAGMENT_SPECIFIER};
|
use rustc_session::lint::builtin::{META_VARIABLE_MISUSE, MISSING_FRAGMENT_SPECIFIER};
|
||||||
use rustc_session::parse::ParseSess;
|
use rustc_session::parse::ParseSess;
|
||||||
|
use rustc_span::edition::Edition;
|
||||||
use rustc_span::symbol::kw;
|
use rustc_span::symbol::kw;
|
||||||
use rustc_span::{symbol::MacroRulesNormalizedIdent, ErrorGuaranteed, Span};
|
use rustc_span::{symbol::MacroRulesNormalizedIdent, ErrorGuaranteed, Span};
|
||||||
|
|
||||||
|
@ -122,6 +123,8 @@ use smallvec::SmallVec;
|
||||||
|
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
|
use super::quoted::VALID_FRAGMENT_NAMES_MSG_2021;
|
||||||
|
|
||||||
/// Stack represented as linked list.
|
/// Stack represented as linked list.
|
||||||
///
|
///
|
||||||
/// Those are used for environments because they grow incrementally and are not mutable.
|
/// 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
|
// 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
|
// `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.
|
// as a hard error and then once as a buffered lint.
|
||||||
psess.buffer_lint(
|
if span.edition() >= Edition::Edition2024 {
|
||||||
MISSING_FRAGMENT_SPECIFIER,
|
psess.dcx().emit_err(errors::MissingFragmentSpecifier {
|
||||||
span,
|
span,
|
||||||
node_id,
|
add_span: span.shrink_to_hi(),
|
||||||
BuiltinLintDiag::MissingFragmentSpecifier,
|
valid: VALID_FRAGMENT_NAMES_MSG_2021,
|
||||||
);
|
});
|
||||||
|
} else {
|
||||||
|
psess.buffer_lint(
|
||||||
|
MISSING_FRAGMENT_SPECIFIER,
|
||||||
|
span,
|
||||||
|
node_id,
|
||||||
|
BuiltinLintDiag::MissingFragmentSpecifier,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if !macros.is_empty() {
|
if !macros.is_empty() {
|
||||||
psess.dcx().span_bug(span, "unexpected MetaVarDecl in nested lhs");
|
psess.dcx().span_bug(span, "unexpected MetaVarDecl in nested lhs");
|
||||||
|
|
|
@ -16,7 +16,7 @@ use rustc_span::Span;
|
||||||
const VALID_FRAGMENT_NAMES_MSG: &str = "valid fragment specifiers are \
|
const VALID_FRAGMENT_NAMES_MSG: &str = "valid fragment specifiers are \
|
||||||
`ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, \
|
`ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, \
|
||||||
`literal`, `path`, `meta`, `tt`, `item` and `vis`";
|
`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`, \
|
`ident`, `block`, `stmt`, `expr`, `expr_2021`, `pat`, \
|
||||||
`ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, \
|
`ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, \
|
||||||
`item` and `vis`";
|
`item` and `vis`";
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
error: missing fragment specifier
|
error: missing fragment specifier
|
||||||
--> $DIR/macro-missing-fragment.rs:4:20
|
--> $DIR/macro-missing-fragment.rs:9:20
|
||||||
|
|
|
|
||||||
LL | ( $( any_token $field_rust_type )* ) => {};
|
LL | ( $( any_token $field_rust_type )* ) => {};
|
||||||
| ^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
warning: missing fragment specifier
|
warning: missing fragment specifier
|
||||||
--> $DIR/macro-missing-fragment.rs:4:20
|
--> $DIR/macro-missing-fragment.rs:9:20
|
||||||
|
|
|
|
||||||
LL | ( $( any_token $field_rust_type )* ) => {};
|
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!
|
= 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: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>
|
||||||
note: the lint level is defined here
|
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)]
|
LL | #![warn(missing_fragment_specifier)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
warning: missing fragment specifier
|
warning: missing fragment specifier
|
||||||
--> $DIR/macro-missing-fragment.rs:12:7
|
--> $DIR/macro-missing-fragment.rs:19:7
|
||||||
|
|
|
|
||||||
LL | ( $name ) => {};
|
LL | ( $name ) => {};
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
@ -28,7 +28,7 @@ LL | ( $name ) => {};
|
||||||
= note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>
|
= note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>
|
||||||
|
|
||||||
warning: missing fragment specifier
|
warning: missing fragment specifier
|
||||||
--> $DIR/macro-missing-fragment.rs:18:7
|
--> $DIR/macro-missing-fragment.rs:26:7
|
||||||
|
|
|
|
||||||
LL | ( $name ) => {};
|
LL | ( $name ) => {};
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
@ -40,7 +40,7 @@ error: aborting due to 1 previous error; 3 warnings emitted
|
||||||
|
|
||||||
Future incompatibility report: Future breakage diagnostic:
|
Future incompatibility report: Future breakage diagnostic:
|
||||||
warning: missing fragment specifier
|
warning: missing fragment specifier
|
||||||
--> $DIR/macro-missing-fragment.rs:4:20
|
--> $DIR/macro-missing-fragment.rs:9:20
|
||||||
|
|
|
|
||||||
LL | ( $( any_token $field_rust_type )* ) => {};
|
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!
|
= 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: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>
|
||||||
note: the lint level is defined here
|
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)]
|
LL | #![warn(missing_fragment_specifier)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Future breakage diagnostic:
|
Future breakage diagnostic:
|
||||||
warning: missing fragment specifier
|
warning: missing fragment specifier
|
||||||
--> $DIR/macro-missing-fragment.rs:12:7
|
--> $DIR/macro-missing-fragment.rs:19:7
|
||||||
|
|
|
|
||||||
LL | ( $name ) => {};
|
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!
|
= 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: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>
|
||||||
note: the lint level is defined here
|
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)]
|
LL | #![warn(missing_fragment_specifier)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Future breakage diagnostic:
|
Future breakage diagnostic:
|
||||||
warning: missing fragment specifier
|
warning: missing fragment specifier
|
||||||
--> $DIR/macro-missing-fragment.rs:18:7
|
--> $DIR/macro-missing-fragment.rs:26:7
|
||||||
|
|
|
|
||||||
LL | ( $name ) => {};
|
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!
|
= 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: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>
|
||||||
note: the lint level is defined here
|
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)]
|
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)]
|
#![warn(missing_fragment_specifier)]
|
||||||
|
|
||||||
macro_rules! used_arm {
|
macro_rules! used_arm {
|
||||||
( $( any_token $field_rust_type )* ) => {};
|
( $( any_token $field_rust_type )* ) => {};
|
||||||
//~^ ERROR missing fragment
|
//[e2015]~^ ERROR missing fragment
|
||||||
//~| WARN missing fragment
|
//[e2015]~| WARN missing fragment
|
||||||
//~| WARN this was previously accepted
|
//[e2015]~| WARN this was previously accepted
|
||||||
|
//[e2024]~^^^^ ERROR missing fragment
|
||||||
|
//[e2024]~| ERROR missing fragment
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! used_macro_unused_arm {
|
macro_rules! used_macro_unused_arm {
|
||||||
() => {};
|
() => {};
|
||||||
( $name ) => {};
|
( $name ) => {};
|
||||||
//~^ WARN missing fragment
|
//[e2015]~^ WARN missing fragment
|
||||||
//~| WARN this was previously accepted
|
//[e2015]~| WARN this was previously accepted
|
||||||
|
//[e2024]~^^^ ERROR missing fragment
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! unused_macro {
|
macro_rules! unused_macro {
|
||||||
( $name ) => {};
|
( $name ) => {};
|
||||||
//~^ WARN missing fragment
|
//[e2015]~^ WARN missing fragment
|
||||||
//~| WARN this was previously accepted
|
//[e2015]~| WARN this was previously accepted
|
||||||
|
//[e2024]~^^^ ERROR missing fragment
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
Loading…
Add table
Reference in a new issue