Skip to content

Commit ca71c8f

Browse files
Rollup merge of #133487 - pitaj:reserve-guarded-strings, r=fee1-dead
fix confusing diagnostic for reserved `##` Closes #131615
2 parents 23bab15 + 44f4f67 commit ca71c8f

14 files changed

+141
-107
lines changed

compiler/rustc_lint/messages.ftl

+3
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,9 @@ lint_renamed_lint = lint `{$name}` has been renamed to `{$replace}`
733733
734734
lint_requested_level = requested on the command line with `{$level} {$lint_name}`
735735
736+
lint_reserved_multihash = reserved token in Rust 2024
737+
.suggestion = insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024
738+
736739
lint_reserved_prefix = prefix `{$prefix}` is unknown
737740
.label = unknown prefix
738741
.suggestion = insert whitespace here to avoid this being parsed as a prefix in Rust 2021

compiler/rustc_lint/src/context/diagnostics.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,12 @@ pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: &
176176
lints::RawPrefix { label: label_span, suggestion: label_span.shrink_to_hi() }
177177
.decorate_lint(diag);
178178
}
179-
BuiltinLintDiag::ReservedString(suggestion) => {
180-
lints::ReservedString { suggestion }.decorate_lint(diag);
179+
BuiltinLintDiag::ReservedString { is_string, suggestion } => {
180+
if is_string {
181+
lints::ReservedString { suggestion }.decorate_lint(diag);
182+
} else {
183+
lints::ReservedMultihash { suggestion }.decorate_lint(diag);
184+
}
181185
}
182186
BuiltinLintDiag::UnusedBuiltinAttribute { attr_name, macro_name, invoc_span } => {
183187
lints::UnusedBuiltinAttribute { invoc_span, attr_name, macro_name }.decorate_lint(diag);

compiler/rustc_lint/src/lints.rs

+7
Original file line numberDiff line numberDiff line change
@@ -3059,3 +3059,10 @@ pub(crate) struct ReservedString {
30593059
#[suggestion(code = " ", applicability = "machine-applicable")]
30603060
pub suggestion: Span,
30613061
}
3062+
3063+
#[derive(LintDiagnostic)]
3064+
#[diag(lint_reserved_multihash)]
3065+
pub(crate) struct ReservedMultihash {
3066+
#[suggestion(code = " ", applicability = "machine-applicable")]
3067+
pub suggestion: Span,
3068+
}

compiler/rustc_lint_defs/src/lib.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -663,8 +663,11 @@ pub enum BuiltinLintDiag {
663663
ReservedPrefix(Span, String),
664664
/// `'r#` in edition < 2021.
665665
RawPrefix(Span),
666-
/// `##` or `#"` is edition < 2024.
667-
ReservedString(Span),
666+
/// `##` or `#"` in edition < 2024.
667+
ReservedString {
668+
is_string: bool,
669+
suggestion: Span,
670+
},
668671
TrailingMacro(bool, Ident),
669672
BreakWithLabelAndLoop(Span),
670673
UnicodeTextFlow(Span, String),

compiler/rustc_parse/messages.ftl

+4
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,10 @@ parse_require_colon_after_labeled_expression = labeled expression must be follow
716716
.label = the label
717717
.suggestion = add `:` after the label
718718
719+
parse_reserved_multihash = reserved multi-hash token is forbidden
720+
.note = sequences of two or more # are reserved for future use since Rust 2024
721+
.suggestion_whitespace = consider inserting whitespace here
722+
719723
parse_reserved_string = invalid string literal
720724
.note = unprefixed guarded string literals are reserved for future use since Rust 2024
721725
.suggestion_whitespace = consider inserting whitespace here

compiler/rustc_parse/src/errors.rs

+9
Original file line numberDiff line numberDiff line change
@@ -2151,6 +2151,15 @@ pub(crate) enum UnknownPrefixSugg {
21512151
},
21522152
}
21532153

2154+
#[derive(Diagnostic)]
2155+
#[diag(parse_reserved_multihash)]
2156+
#[note]
2157+
pub(crate) struct ReservedMultihash {
2158+
#[primary_span]
2159+
pub span: Span,
2160+
#[subdiagnostic]
2161+
pub sugg: Option<GuardedStringSugg>,
2162+
}
21542163
#[derive(Diagnostic)]
21552164
#[diag(parse_reserved_string)]
21562165
#[note]

compiler/rustc_parse/src/lexer/mod.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -816,7 +816,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
816816

817817
let mut cursor = Cursor::new(str_before);
818818

819-
let (span, unterminated) = match cursor.guarded_double_quoted_string() {
819+
let (is_string, span, unterminated) = match cursor.guarded_double_quoted_string() {
820820
Some(rustc_lexer::GuardedStr { n_hashes, terminated, token_len }) => {
821821
let end = start + BytePos(token_len);
822822
let span = self.mk_sp(start, end);
@@ -829,13 +829,13 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
829829

830830
let unterminated = if terminated { None } else { Some(str_start) };
831831

832-
(span, unterminated)
832+
(true, span, unterminated)
833833
}
834-
_ => {
834+
None => {
835835
// We should only get here in the `##+` case.
836836
debug_assert_eq!(self.str_from_to(start, start + BytePos(2)), "##");
837837

838-
(span, None)
838+
(false, span, None)
839839
}
840840
};
841841
if edition2024 {
@@ -857,7 +857,11 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
857857
};
858858

859859
// In Edition 2024 and later, emit a hard error.
860-
let err = self.dcx().emit_err(errors::ReservedString { span, sugg });
860+
let err = if is_string {
861+
self.dcx().emit_err(errors::ReservedString { span, sugg })
862+
} else {
863+
self.dcx().emit_err(errors::ReservedMultihash { span, sugg })
864+
};
861865

862866
token::Literal(token::Lit {
863867
kind: token::Err(err),
@@ -870,7 +874,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
870874
RUST_2024_GUARDED_STRING_INCOMPATIBLE_SYNTAX,
871875
span,
872876
ast::CRATE_NODE_ID,
873-
BuiltinLintDiag::ReservedString(space_span),
877+
BuiltinLintDiag::ReservedString { is_string, suggestion: space_span },
874878
);
875879

876880
// For backwards compatibility, roll back to after just the first `#`

tests/ui/rust-2024/reserved-guarded-strings-lexing.rs

+12-12
Original file line numberDiff line numberDiff line change
@@ -26,24 +26,24 @@ macro_rules! demo7 {
2626

2727
fn main() {
2828
demo3!(## "foo");
29-
//~^ WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax]
29+
//~^ WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax]
3030
//~| WARNING hard error in Rust 2024
3131
demo4!(### "foo");
32-
//~^ WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax]
32+
//~^ WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax]
3333
//~| WARNING hard error in Rust 2024
34-
//~| WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax]
34+
//~| WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax]
3535
//~| WARNING hard error in Rust 2024
3636
demo4!(## "foo"#);
37-
//~^ WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax]
37+
//~^ WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax]
3838
//~| WARNING hard error in Rust 2024
3939
demo7!(### "foo"###);
40-
//~^ WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax]
40+
//~^ WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax]
4141
//~| WARNING hard error in Rust 2024
42-
//~| WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax]
42+
//~| WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax]
4343
//~| WARNING hard error in Rust 2024
44-
//~| WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax]
44+
//~| WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax]
4545
//~| WARNING hard error in Rust 2024
46-
//~| WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax]
46+
//~| WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax]
4747
//~| WARNING hard error in Rust 2024
4848

4949
demo5!(###"foo"#);
@@ -56,14 +56,14 @@ fn main() {
5656
demo5!(#"foo"###);
5757
//~^ WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax]
5858
//~| WARNING hard error in Rust 2024
59-
//~| WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax]
59+
//~| WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax]
6060
//~| WARNING hard error in Rust 2024
61-
//~| WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax]
61+
//~| WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax]
6262
//~| WARNING hard error in Rust 2024
6363
demo4!("foo"###);
64-
//~^ WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax]
64+
//~^ WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax]
6565
//~| WARNING hard error in Rust 2024
66-
//~| WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax]
66+
//~| WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax]
6767
//~| WARNING hard error in Rust 2024
6868

6969
// Non-ascii identifiers

tests/ui/rust-2024/reserved-guarded-strings-lexing.stderr

+24-24
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ error: identifiers cannot contain emoji: `🙃`
2828
LL | demo3!(🙃#"");
2929
| ^^
3030

31-
warning: will be parsed as a guarded string in Rust 2024
31+
warning: reserved token in Rust 2024
3232
--> $DIR/reserved-guarded-strings-lexing.rs:28:12
3333
|
3434
LL | demo3!(## "foo");
@@ -41,98 +41,98 @@ note: the lint level is defined here
4141
|
4242
LL | #![warn(rust_2024_guarded_string_incompatible_syntax)]
4343
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
44-
help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024
44+
help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024
4545
|
4646
LL | demo3!(# # "foo");
4747
| +
4848

49-
warning: will be parsed as a guarded string in Rust 2024
49+
warning: reserved token in Rust 2024
5050
--> $DIR/reserved-guarded-strings-lexing.rs:31:12
5151
|
5252
LL | demo4!(### "foo");
5353
| ^^
5454
|
5555
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
5656
= note: for more information, see issue #123735 <https://github.com/rust-lang/rust/issues/123735>
57-
help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024
57+
help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024
5858
|
5959
LL | demo4!(# ## "foo");
6060
| +
6161

62-
warning: will be parsed as a guarded string in Rust 2024
62+
warning: reserved token in Rust 2024
6363
--> $DIR/reserved-guarded-strings-lexing.rs:31:13
6464
|
6565
LL | demo4!(### "foo");
6666
| ^^
6767
|
6868
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
6969
= note: for more information, see issue #123735 <https://github.com/rust-lang/rust/issues/123735>
70-
help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024
70+
help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024
7171
|
7272
LL | demo4!(## # "foo");
7373
| +
7474

75-
warning: will be parsed as a guarded string in Rust 2024
75+
warning: reserved token in Rust 2024
7676
--> $DIR/reserved-guarded-strings-lexing.rs:36:12
7777
|
7878
LL | demo4!(## "foo"#);
7979
| ^^
8080
|
8181
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
8282
= note: for more information, see issue #123735 <https://github.com/rust-lang/rust/issues/123735>
83-
help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024
83+
help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024
8484
|
8585
LL | demo4!(# # "foo"#);
8686
| +
8787

88-
warning: will be parsed as a guarded string in Rust 2024
88+
warning: reserved token in Rust 2024
8989
--> $DIR/reserved-guarded-strings-lexing.rs:39:12
9090
|
9191
LL | demo7!(### "foo"###);
9292
| ^^
9393
|
9494
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
9595
= note: for more information, see issue #123735 <https://github.com/rust-lang/rust/issues/123735>
96-
help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024
96+
help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024
9797
|
9898
LL | demo7!(# ## "foo"###);
9999
| +
100100

101-
warning: will be parsed as a guarded string in Rust 2024
101+
warning: reserved token in Rust 2024
102102
--> $DIR/reserved-guarded-strings-lexing.rs:39:13
103103
|
104104
LL | demo7!(### "foo"###);
105105
| ^^
106106
|
107107
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
108108
= note: for more information, see issue #123735 <https://github.com/rust-lang/rust/issues/123735>
109-
help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024
109+
help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024
110110
|
111111
LL | demo7!(## # "foo"###);
112112
| +
113113

114-
warning: will be parsed as a guarded string in Rust 2024
114+
warning: reserved token in Rust 2024
115115
--> $DIR/reserved-guarded-strings-lexing.rs:39:21
116116
|
117117
LL | demo7!(### "foo"###);
118118
| ^^
119119
|
120120
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
121121
= note: for more information, see issue #123735 <https://github.com/rust-lang/rust/issues/123735>
122-
help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024
122+
help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024
123123
|
124124
LL | demo7!(### "foo"# ##);
125125
| +
126126

127-
warning: will be parsed as a guarded string in Rust 2024
127+
warning: reserved token in Rust 2024
128128
--> $DIR/reserved-guarded-strings-lexing.rs:39:22
129129
|
130130
LL | demo7!(### "foo"###);
131131
| ^^
132132
|
133133
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
134134
= note: for more information, see issue #123735 <https://github.com/rust-lang/rust/issues/123735>
135-
help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024
135+
help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024
136136
|
137137
LL | demo7!(### "foo"## #);
138138
| +
@@ -189,54 +189,54 @@ help: insert whitespace here to avoid this being parsed as a guarded string in R
189189
LL | demo5!(# "foo"###);
190190
| +
191191

192-
warning: will be parsed as a guarded string in Rust 2024
192+
warning: reserved token in Rust 2024
193193
--> $DIR/reserved-guarded-strings-lexing.rs:56:18
194194
|
195195
LL | demo5!(#"foo"###);
196196
| ^^
197197
|
198198
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
199199
= note: for more information, see issue #123735 <https://github.com/rust-lang/rust/issues/123735>
200-
help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024
200+
help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024
201201
|
202202
LL | demo5!(#"foo"# ##);
203203
| +
204204

205-
warning: will be parsed as a guarded string in Rust 2024
205+
warning: reserved token in Rust 2024
206206
--> $DIR/reserved-guarded-strings-lexing.rs:56:19
207207
|
208208
LL | demo5!(#"foo"###);
209209
| ^^
210210
|
211211
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
212212
= note: for more information, see issue #123735 <https://github.com/rust-lang/rust/issues/123735>
213-
help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024
213+
help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024
214214
|
215215
LL | demo5!(#"foo"## #);
216216
| +
217217

218-
warning: will be parsed as a guarded string in Rust 2024
218+
warning: reserved token in Rust 2024
219219
--> $DIR/reserved-guarded-strings-lexing.rs:63:17
220220
|
221221
LL | demo4!("foo"###);
222222
| ^^
223223
|
224224
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
225225
= note: for more information, see issue #123735 <https://github.com/rust-lang/rust/issues/123735>
226-
help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024
226+
help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024
227227
|
228228
LL | demo4!("foo"# ##);
229229
| +
230230

231-
warning: will be parsed as a guarded string in Rust 2024
231+
warning: reserved token in Rust 2024
232232
--> $DIR/reserved-guarded-strings-lexing.rs:63:18
233233
|
234234
LL | demo4!("foo"###);
235235
| ^^
236236
|
237237
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
238238
= note: for more information, see issue #123735 <https://github.com/rust-lang/rust/issues/123735>
239-
help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024
239+
help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024
240240
|
241241
LL | demo4!("foo"## #);
242242
| +

0 commit comments

Comments
 (0)