Skip to content

Diagnostics should recognize string/char escape sequences from C and suggest appropriate Rust equivalents #148884

@Kmeakin

Description

@Kmeakin

Code

// https://godbolt.org/z/8jz7v9hPf

// Specified by both C and Rust
pub const SINGLE_QUOTE: char = '\'';
pub const DOUBLE_QUOTE: char = '\"';
pub const BACKSLASH: char = '\\';
pub const NEWLINE: char = '\n';
pub const CARRIAGE_RETURN: char = '\r';
pub const HORIZONTAL_TAB: char = '\t';
pub const NULL: char = '\0';

// Specified by C, but not Rust
pub const QUESTION_MARK: char = '\?';
pub const AUDIBLE_BELL: char = '\a';
pub const BACKSPACE: char = '\b';
pub const FORM_FEED: char = '\f';
pub const VERTICAL_TAB: char = '\v';
pub const OCTAL: char = '\1';

// Not specified by C, but recognized by GCC as an extension.
// Used for ANSI escape sequences in terminal emulators.
pub const ESCAPE: char = '\e';

Current output

Compiling playground v0.0.1 (/playground)
error: unknown character escape: `?`
  --> src/lib.rs:10:35
   |
11 | pub const QUESTION_MARK: char = '\?';
   |                                   ^ unknown character escape
   |
   = help: for more information, visit <https://doc.rust-lang.org/reference/tokens.html#literals>
help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal
   |
11 - pub const QUESTION_MARK: char = '\?';
11 + pub const QUESTION_MARK: char = r"\?";
   |

error: unknown character escape: `a`
  --> src/lib.rs:12:34
   |
12 | pub const AUDIBLE_BELL: char = '\a';
   |                                  ^ unknown character escape
   |
   = help: for more information, visit <https://doc.rust-lang.org/reference/tokens.html#literals>
help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal
   |
12 - pub const AUDIBLE_BELL: char = '\a';
12 + pub const AUDIBLE_BELL: char = r"\a";
   |

error: unknown character escape: `b`
  --> src/lib.rs:13:31
   |
13 | pub const BACKSPACE: char = '\b';
   |                               ^ unknown character escape
   |
   = help: for more information, visit <https://doc.rust-lang.org/reference/tokens.html#literals>
help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal
   |
13 - pub const BACKSPACE: char = '\b';
13 + pub const BACKSPACE: char = r"\b";
   |

error: unknown character escape: `f`
  --> src/lib.rs:14:31
   |
14 | pub const FORM_FEED: char = '\f';
   |                               ^ unknown character escape
   |
   = help: for more information, visit <https://doc.rust-lang.org/reference/tokens.html#literals>
help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal
   |
14 - pub const FORM_FEED: char = '\f';
14 + pub const FORM_FEED: char = r"\f";
   |

error: unknown character escape: `v`
  --> src/lib.rs:15:34
   |
15 | pub const VERTICAL_TAB: char = '\v';
   |                                  ^ unknown character escape
   |
   = help: for more information, visit <https://doc.rust-lang.org/reference/tokens.html#literals>
help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal
   |
15 - pub const VERTICAL_TAB: char = '\v';
15 + pub const VERTICAL_TAB: char = r"\v";
   |

error: unknown character escape: `1`
  --> src/lib.rs:16:27
   |
16 | pub const OCTAL: char = '\1';
   |                           ^ unknown character escape
   |
   = help: for more information, visit <https://doc.rust-lang.org/reference/tokens.html#literals>
help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal
   |
16 - pub const OCTAL: char = '\1';
16 + pub const OCTAL: char = r"\1";
   |

error: unknown character escape: `e`
  --> src/lib.rs:19:28
   |
19 | pub const ESCAPE: char = '\e';
   |                            ^ unknown character escape
   |
   = help: for more information, visit <https://doc.rust-lang.org/reference/tokens.html#literals>
help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal
   |
19 - pub const ESCAPE: char = '\e';
19 + pub const ESCAPE: char = r"\e";
   |

error: could not compile `playground` (lib) due to 7 previous errors

Desired output

Compiling playground v0.0.1 (/playground)
error: unknown character escape: `?`
  --> src/lib.rs:10:35
   |
10 | pub const QUESTION_MARK: char = '\?';
   |                                   ^ unknown character escape
   |
   = help: for more information, visit <https://doc.rust-lang.org/reference/tokens.html#literals>
help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal
   |
10 - pub const QUESTION_MARK: char = '\?';
10 + pub const QUESTION_MARK: char = r"\?";
   |
help: if you mean to write a literal question mark, don't escape the character
   |
10 - pub const QUESTION_MARK: char = '\?';
10 + pub const QUESTION_MARK: char = '?';

error: unknown character escape: `a`
  --> src/lib.rs:12:34
   |
12 | pub const AUDIBLE_BELL: char = '\a';
   |                                  ^ unknown character escape
   |
   = help: for more information, visit <https://doc.rust-lang.org/reference/tokens.html#literals>
help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal
   |
12 - pub const AUDIBLE_BELL: char = '\a';
12 + pub const AUDIBLE_BELL: char = r"\a";
   |
help: if you meant to write an audible bell (perhaps transcribing code from another language), consider a hex or unicode escape
   |
12 - pub const AUDIBLE_BELL: char = '\a';
12 + pub const AUDIBLE_BELL: char = '\x07';
12 + pub const AUDIBLE_BELL: char = '\u{07}';

error: unknown character escape: `b`
  --> src/lib.rs:13:31
   |
13 | pub const BACKSPACE: char = '\b';
   |                               ^ unknown character escape
   |
   = help: for more information, visit <https://doc.rust-lang.org/reference/tokens.html#literals>
help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal
   |
13 - pub const BACKSPACE: char = '\b';
13 + pub const BACKSPACE: char = r"\b";
   |
help: if you meant to write a backspace (perhaps transcribing code from another language), consider a hex or unicode escape
   |
13 - pub const BACKSPACE: char = '\b';
13 + pub const BACKSPACE: char = '\x08';
13 + pub const BACKSPACE: char = '\u{08}';

error: unknown character escape: `f`
  --> src/lib.rs:14:31
   |
14 | pub const FORM_FEED: char = '\f';
   |                               ^ unknown character escape
   |
   = help: for more information, visit <https://doc.rust-lang.org/reference/tokens.html#literals>
help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal
   |
14 - pub const FORM_FEED: char = '\f';
14 + pub const FORM_FEED: char = r"\f";
   |
help: if you meant to write a form feed (perhaps transcribing code from another language), consider a hex or unicode escape
   |
14 - pub const FORM_FEED: char = '\f';
14 + pub const FORM_FEED: char = '\x0C';
14 + pub const FORM_FEED: char = '\u{0C}';

error: unknown character escape: `v`
  --> src/lib.rs:15:34
   |
15 | pub const VERTICAL_TAB: char = '\v';
   |                                  ^ unknown character escape
   |
   = help: for more information, visit <https://doc.rust-lang.org/reference/tokens.html#literals>
help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal
   |
15 - pub const VERTICAL_TAB: char = '\v';
15 + pub const VERTICAL_TAB: char = r"\v";
   |
help: if you meant to write a vertical tab (perhaps transcribing code from another language), consider a hex or unicode escape
   |
15 - pub const VERTICAL_TAB: char = '\v';
15 + pub const VERTICAL_TAB: char = '\x0B';
15 + pub const VERTICAL_TAB: char = '\u{0B}';

error: unknown character escape: `1`
  --> src/lib.rs:16:27
   |
16 | pub const OCTAL: char = '\1';
   |                           ^ unknown character escape
   |
   = help: for more information, visit <https://doc.rust-lang.org/reference/tokens.html#literals>
help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal
   |
16 - pub const OCTAL: char = '\1';
16 + pub const OCTAL: char = r"\1";
   |
help: if you meant to write an ASCII control code character (perhaps transcribing code from another language), consider a hex or unicode escape
   |
16 - pub const OCTAL: char = '\1';
16 - pub const OCTAL: char = '\x01';
16 + pub const OCTAL: char = '\u{01}';

error: unknown character escape: `e`
  --> src/lib.rs:19:28
   |
20 | pub const ESCAPE: char = '\e';
   |                            ^ unknown character escape
   |
   = help: for more information, visit <https://doc.rust-lang.org/reference/tokens.html#literals>
help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal
   |
20 - pub const ESCAPE: char = '\e';
20 + pub const ESCAPE: char = r"\e";
   |
help: if you meant to write an ANSI escape sequence (perhaps transcribing code from another language), consider a hex or unicode escape
   |
20 - pub const ESCAPE: char = '\e';
20 + pub const ESCAPE: char = '\x1B';
20 + pub const ESCAPE: char = '\u{1B}';

error: could not compile `playground` (lib) due to 7 previous errors

Rationale and extra context

C specifies the following "escape sequences" in string and character literals:

  • \': single quote
  • \": double quote
  • \?: question mark
  • \a: audible bell
  • \b: backspace
  • \f: form feed
  • \n: newline
  • \r: carriage return
  • \t: horizontal tab
  • \v: vertical tab
  • \nnn: arbitrary octal value
  • \xn...: arbitrary hexadecimal value
  • \unnnn: unicode value
  • \Unnnnnnnn: unicode value

\a, \b, \f and \v have been copied by most other languages since C (eg javascript, python)

Of these, Rust only accepts \', \", \n, \r, \t and \0. Users porting code from other languages to Rust may be confused when Rust gives them a syntax error. It would be helpful to offer a diagnostic suggesting the Rust equivalent using Rust's \x... or \u{...} syntax

Other cases

Rust Version

rustc 1.93.0-nightly (6647be936 2025-11-09)
binary: rustc
commit-hash: 6647be93640686a2a443a49f15c3390b68c8b5dd
commit-date: 2025-11-09
host: x86_64-unknown-linux-gnu
release: 1.93.0-nightly
LLVM version: 21.1.3
Compiler returned: 0

Anything else?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions