Skip to content

Commit 4e851a5

Browse files
committed
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 <#40107>
1 parent 3d68afc commit 4e851a5

File tree

7 files changed

+108
-19
lines changed

7 files changed

+108
-19
lines changed

compiler/rustc_expand/messages.ftl

+5
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,11 @@ expand_meta_var_dif_seq_matchers = {$msg}
105105
expand_meta_var_expr_unrecognized_var =
106106
variable `{$key}` is not recognized in meta-variable expression
107107
108+
expand_missing_fragment_specifier = missing fragment specifier
109+
.note = fragment specifiers must be specified in the 2024 edition
110+
.suggestion_add_fragspec = try adding a specifier here
111+
.valid = {$valid}
112+
108113
expand_module_circular =
109114
circular modules: {$modules}
110115

compiler/rustc_expand/src/errors.rs

+17
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,23 @@ pub struct DuplicateMatcherBinding {
416416
pub prev: Span,
417417
}
418418

419+
#[derive(Diagnostic)]
420+
#[diag(expand_missing_fragment_specifier)]
421+
#[note]
422+
#[help(expand_valid)]
423+
pub struct MissingFragmentSpecifier {
424+
#[primary_span]
425+
pub span: Span,
426+
#[suggestion(
427+
expand_suggestion_add_fragspec,
428+
style = "verbose",
429+
code = ":spec",
430+
applicability = "maybe-incorrect"
431+
)]
432+
pub add_span: Span,
433+
pub valid: &'static str,
434+
}
435+
419436
#[derive(Diagnostic)]
420437
#[diag(expand_invalid_fragment_specifier)]
421438
#[help]

compiler/rustc_expand/src/mbe/macro_check.rs

+17-6
Original file line numberDiff line numberDiff line change
@@ -115,13 +115,16 @@ use rustc_errors::MultiSpan;
115115
use rustc_lint_defs::BuiltinLintDiag;
116116
use rustc_session::lint::builtin::{META_VARIABLE_MISUSE, MISSING_FRAGMENT_SPECIFIER};
117117
use rustc_session::parse::ParseSess;
118+
use rustc_span::edition::Edition;
118119
use rustc_span::symbol::kw;
119120
use rustc_span::{symbol::MacroRulesNormalizedIdent, ErrorGuaranteed, Span};
120121

121122
use smallvec::SmallVec;
122123

123124
use std::iter;
124125

126+
use super::quoted::VALID_FRAGMENT_NAMES_MSG_2021;
127+
125128
/// Stack represented as linked list.
126129
///
127130
/// Those are used for environments because they grow incrementally and are not mutable.
@@ -269,12 +272,20 @@ fn check_binders(
269272
// FIXME: Report this as a hard error eventually and remove equivalent errors from
270273
// `parse_tt_inner` and `nameize`. Until then the error may be reported twice, once
271274
// as a hard error and then once as a buffered lint.
272-
psess.buffer_lint(
273-
MISSING_FRAGMENT_SPECIFIER,
274-
span,
275-
node_id,
276-
BuiltinLintDiag::MissingFragmentSpecifier,
277-
);
275+
if psess.edition >= Edition::Edition2024 {
276+
psess.dcx().emit_err(errors::MissingFragmentSpecifier {
277+
span,
278+
add_span: span.shrink_to_hi(),
279+
valid: VALID_FRAGMENT_NAMES_MSG_2021,
280+
});
281+
} else {
282+
psess.buffer_lint(
283+
MISSING_FRAGMENT_SPECIFIER,
284+
span,
285+
node_id,
286+
BuiltinLintDiag::MissingFragmentSpecifier,
287+
);
288+
}
278289
}
279290
if !macros.is_empty() {
280291
psess.dcx().span_bug(span, "unexpected MetaVarDecl in nested lhs");

compiler/rustc_expand/src/mbe/quoted.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use rustc_span::Span;
1616
const VALID_FRAGMENT_NAMES_MSG: &str = "valid fragment specifiers are \
1717
`ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, \
1818
`literal`, `path`, `meta`, `tt`, `item` and `vis`";
19-
const VALID_FRAGMENT_NAMES_MSG_2021: &str = "valid fragment specifiers are \
19+
pub const VALID_FRAGMENT_NAMES_MSG_2021: &str = "valid fragment specifiers are \
2020
`ident`, `block`, `stmt`, `expr`, `expr_2021`, `pat`, \
2121
`ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, \
2222
`item` and `vis`";

tests/ui/macros/macro-missing-fragment.stderr renamed to tests/ui/macros/macro-missing-fragment.e2015.stderr

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
error: missing fragment specifier
2-
--> $DIR/macro-missing-fragment.rs:4:20
2+
--> $DIR/macro-missing-fragment.rs:9:20
33
|
44
LL | ( $( any_token $field_rust_type )* ) => {};
55
| ^^^^^^^^^^^^^^^^
66

77
warning: missing fragment specifier
8-
--> $DIR/macro-missing-fragment.rs:4:20
8+
--> $DIR/macro-missing-fragment.rs:9:20
99
|
1010
LL | ( $( any_token $field_rust_type )* ) => {};
1111
| ^^^^^^^^^^^^^^^^
1212
|
1313
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
1414
= note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>
1515
note: the lint level is defined here
16-
--> $DIR/macro-missing-fragment.rs:1:9
16+
--> $DIR/macro-missing-fragment.rs:6:9
1717
|
1818
LL | #![warn(missing_fragment_specifier)]
1919
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
2020

2121
warning: missing fragment specifier
22-
--> $DIR/macro-missing-fragment.rs:12:7
22+
--> $DIR/macro-missing-fragment.rs:19:7
2323
|
2424
LL | ( $name ) => {};
2525
| ^^^^^
@@ -28,7 +28,7 @@ LL | ( $name ) => {};
2828
= note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>
2929

3030
warning: missing fragment specifier
31-
--> $DIR/macro-missing-fragment.rs:18:7
31+
--> $DIR/macro-missing-fragment.rs:26:7
3232
|
3333
LL | ( $name ) => {};
3434
| ^^^^^
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
error: missing fragment specifier
2+
--> $DIR/macro-missing-fragment.rs:9:20
3+
|
4+
LL | ( $( any_token $field_rust_type )* ) => {};
5+
| ^^^^^^^^^^^^^^^^
6+
|
7+
= note: fragment specifiers must be specified in the 2024 edition
8+
= help: valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `expr_2021`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis`
9+
help: try adding a specifier here
10+
|
11+
LL | ( $( any_token $field_rust_type:spec )* ) => {};
12+
| +++++
13+
14+
error: missing fragment specifier
15+
--> $DIR/macro-missing-fragment.rs:19:7
16+
|
17+
LL | ( $name ) => {};
18+
| ^^^^^
19+
|
20+
= note: fragment specifiers must be specified in the 2024 edition
21+
= help: valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `expr_2021`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis`
22+
help: try adding a specifier here
23+
|
24+
LL | ( $name:spec ) => {};
25+
| +++++
26+
27+
error: missing fragment specifier
28+
--> $DIR/macro-missing-fragment.rs:26:7
29+
|
30+
LL | ( $name ) => {};
31+
| ^^^^^
32+
|
33+
= note: fragment specifiers must be specified in the 2024 edition
34+
= help: valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `expr_2021`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis`
35+
help: try adding a specifier here
36+
|
37+
LL | ( $name:spec ) => {};
38+
| +++++
39+
40+
error: missing fragment specifier
41+
--> $DIR/macro-missing-fragment.rs:9:20
42+
|
43+
LL | ( $( any_token $field_rust_type )* ) => {};
44+
| ^^^^^^^^^^^^^^^^
45+
46+
error: aborting due to 4 previous errors
47+

tests/ui/macros/macro-missing-fragment.rs

+16-7
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,32 @@
1+
//@ revisions: e2015 e2024
2+
//@[e2015] edition:2015
3+
//@[e2024] edition:2024
4+
//@[e2024] compile-flags: -Zunstable-options
5+
16
#![warn(missing_fragment_specifier)]
27

38
macro_rules! used_arm {
49
( $( any_token $field_rust_type )* ) => {};
5-
//~^ ERROR missing fragment
6-
//~| WARN missing fragment
7-
//~| WARN this was previously accepted
10+
//[e2015]~^ ERROR missing fragment
11+
//[e2015]~| WARN missing fragment
12+
//[e2015]~| WARN this was previously accepted
13+
//[e2024]~^^^^ ERROR missing fragment
14+
//[e2024]~| ERROR missing fragment
815
}
916

1017
macro_rules! used_macro_unused_arm {
1118
() => {};
1219
( $name ) => {};
13-
//~^ WARN missing fragment
14-
//~| WARN this was previously accepted
20+
//[e2015]~^ WARN missing fragment
21+
//[e2015]~| WARN this was previously accepted
22+
//[e2024]~^^^ ERROR missing fragment
1523
}
1624

1725
macro_rules! unused_macro {
1826
( $name ) => {};
19-
//~^ WARN missing fragment
20-
//~| WARN this was previously accepted
27+
//[e2015]~^ WARN missing fragment
28+
//[e2015]~| WARN this was previously accepted
29+
//[e2024]~^^^ ERROR missing fragment
2130
}
2231

2332
fn main() {

0 commit comments

Comments
 (0)