Reserved syntax

Summary

Details

RFC 3593 reserved syntax in the 2024 Edition for guarded string literals that do not have a prefix to make room for possible future language changes. The 2021 Edition reserved syntax for guarded strings with a prefix, such as ident##"foo"##. The 2024 Edition extends that to also reserve strings without the ident prefix.

There are two reserved syntaxes:

This reservation is done across an edition boundary because of interactions with tokenization and macros. For example, consider this macro:

macro_rules! demo {
    ( $a:tt ) => { println!("one token") };
    ( $a:tt $b:tt $c:tt ) => { println!("three tokens") };
}

demo!("foo");
demo!(r#"foo"#);
demo!(#"foo"#);
demo!(###)

Prior to the 2024 Edition, this produces:

one token
one token
three tokens
three tokens

Starting in the 2024 Edition, the #"foo"# line and the ### line now generates a compile error because those forms are now reserved.

Migration

The rust_2024_guarded_string_incompatible_syntax lint will identify any tokens that match the reserved syntax, and will suggest a modification to insert spaces where necessary to ensure the tokens continue to be parsed separately.

The lint is part of the rust-2024-compatibility lint group which is included in the automatic edition migration. In order to migrate your code to be Rust 2024 Edition compatible, run:

cargo fix --edition

Alternatively, you can manually enable the lint to find macro calls where you may need to update the tokens:

// Add this to the root of your crate to do a manual migration.
#![warn(rust_2024_guarded_string_incompatible_syntax)]