Skip to content

Commit 7a9a58b

Browse files
committed
Change behaviour of escaped literals: \t, \r and \n
1 parent 013a68c commit 7a9a58b

File tree

1 file changed

+31
-30
lines changed

1 file changed

+31
-30
lines changed

text/3830-dedented-string-literals.md

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -808,9 +808,35 @@ Note: **Literal newlines** (*not* escaped newlines: `\n`) are represented with `
808808

809809
### Treatment of literal escapes: `\t`, `\r` and `\n`
810810

811-
- Whitespace escape characters such as `\t`, `\r` and `\n` are treated as literal code when present in the content of the dedented string, therefore the normal dedentation rules apply to them.
812-
- This does not apply to `\n` after the opening quote, nor the `\n` before the line containing the closing quote. In this case escaping the newline is not allowed, it has to be a literal newline. (As described previously.)
813-
- The line containing the closing quote `"` can therefore contain `\t` escapes, as they are considered to be literal tabs.
811+
`\t` is allowed in the line which contains the closing quote. Writing it is equivalent to inserting a literal tab.
812+
813+
The escaped characters `\t`, `\r` and `\n` are treated as regular characters for the purposes of dedentation.
814+
815+
So the following:
816+
817+
```rs
818+
println!(
819+
d"
820+
\ta
821+
\tb
822+
\tc
823+
\t"
824+
);
825+
```
826+
827+
Prints, with each indentation being **1 tab**:
828+
829+
```
830+
a
831+
b
832+
c
833+
```
834+
835+
The indentation is not removed, because common indentation in this example is 0.
836+
837+
Escaped characters at the beginning of the string are interpreted as any other character, and **not** whitespace.
838+
839+
After the dedentation is calculated, the escapes then expand into their literal counterparts.
814840

815841
### Edge Cases
816842

@@ -835,18 +861,6 @@ assert_eq!(
835861
"hello\n\nworld"
836862
);
837863

838-
// We make use of whitespace escape characters
839-
//
840-
// This might make code more confusing, so one of the future-possibilities
841-
// is to have a warn-by-default lint to disallow these characters in dedented strings.
842-
assert_eq!(
843-
d"
844-
\thello\n\t\n\tworld
845-
\t",
846-
847-
"hello\nworld"
848-
);
849-
850864
// line consisting of only spaces is allowed
851865

852866
// However, nothing is removed because the:
@@ -1668,19 +1682,6 @@ There could be a lint which detects strings which could be written clearer as de
16681682

16691683
## `rustc` warn-by-default lint to disallow whitespace escape characters
16701684

1671-
In the following example:
1672-
1673-
```rs
1674-
assert_eq!(
1675-
d"
1676-
\thello\n\t\n\tworld
1677-
\t",
1678-
//^^ common leading whitespace (will be removed)
1679-
1680-
"hello\nworld"
1681-
);
1682-
```
1683-
1684-
Using escaped whitespace characters is the same as if the characters were written literally. (in the *content* of the string. This excludes the requirement of a **literal** newline after the double quote and before the line of the closing quote).
1685+
As explained in the [reference level explanation](#reference-level-explanation), using whitespace escapes `\t`, `\n` and `\r` are allowed.
16851686

1686-
This is confusing, and might not work in the way people expect it to work. A warn-by-default lint could be added to disallow `\n`, `\t` and `\r` in dedented strings. (Or for instance, only allow `\t` anytime after the stripped indentation)
1687+
Their behaviour might be surprising, so it is worth to consider a warn-by-default lint for them.

0 commit comments

Comments
 (0)