Skip to content

Commit 02afa73

Browse files
jplatteestebank
authored andcommitted
Update byte_concat text to propose a separate concat_bytes! macro
1 parent ba2d9d7 commit 02afa73

File tree

1 file changed

+50
-54
lines changed

1 file changed

+50
-54
lines changed

text/0000-byte-concat.md

Lines changed: 50 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -6,87 +6,83 @@
66
# Summary
77
[summary]: #summary
88

9-
Allow the use of `concat!()` to join byte sequences onto an `u8` array,
10-
beyond the current support for `str` literals.
9+
Add a macro `concat_bytes!()` to join byte sequences onto an `u8` array,
10+
the same way `concat!()` currently supports for `str` literals.
1111

1212
# Motivation
1313
[motivation]: #motivation
1414

1515
`concat!()` is convenient and useful to create compile time `str` literals
16-
from `str`, `bool`, numeric and `char` literals in the code. This RFC would
17-
expand this capability to produce `[u8]` instead of `str` when any of its
18-
arguments is a byte `str` or a byte `char`.
16+
from `str`, `bool`, numeric and `char` literals in the code. This RFC adds an
17+
equivalent capability for `[u8]` instead of `str`.
1918

2019
# Guide-level explanation
2120
[guide-level-explanation]: #guide-level-explanation
2221

23-
Whenever any of the arguments to `concat!()` is a byte literal, its output
24-
will be a byte literal, and the other arguments will be evaluated on their
25-
byte contents.
26-
27-
- `str`s and `char`s are evaluated in the same way as `String::as_bytes`,
28-
- `bool`s are not accepted, use a numeric literal instead,
29-
- numeric literals passed to `concat!()` must fit in `u8`, any number
30-
larger than `std::u8::MAX` causes a compile time error, like the
31-
following:
32-
```
33-
error: cannot concatenate a non-`u8` literal in a byte string literal
34-
--> $FILE:XX:YY
35-
|
36-
XX | concat!(256, b"val");
37-
| ^^^ this value is larger than `255`
38-
```
39-
- numeric array literals that can be coerced to `[u8]` are accepted, if the
40-
literals are outside of `u8` range, it will cause a compile time error:
41-
```
42-
error: cannot concatenate a non-`u8` literal in a byte string literal
43-
--> $FILE:XX:YY
44-
|
45-
XX | concat!([300, 1, 2, 256], b"val");
46-
| ^^^ ^^^ this value is larger than `255`
47-
| |
48-
| this value is larger than `255`
49-
```
50-
51-
For example, `concat!(42, b"va", b'l', [1, 2])` evaluates to
22+
The `concat_bytes!()` macro concatenates literals into a static byte slice.
23+
The following literal types are supported:
24+
25+
- byte string literals (`b"..."`)
26+
- byte literals (`b'b'`)
27+
- numeric literals – must fit in `u8`, any number larger than `u8::MAX` causes
28+
a compile time error like the following:
29+
30+
```
31+
error: cannot concatenate a non-`u8` literal in a byte string literal
32+
--> $FILE:XX:YY
33+
|
34+
XX | concat_bytes!(256, b"val");
35+
| ^^^ this value is larger than `255`
36+
```
37+
- numeric array literals – if any literal is outside of `u8` range, it will
38+
cause a compile time error:
39+
40+
```
41+
error: cannot concatenate a non-`u8` literal in a byte string literal
42+
--> $FILE:XX:YY
43+
|
44+
XX | concat_bytes!([300, 1, 2, 256], b"val");
45+
| ^^^ ^^^ this value is larger than `255`
46+
| |
47+
| this value is larger than `255`
48+
```
49+
50+
For example, `concat_bytes!(42, b"va", b'l', [1, 2])` evaluates to
5251
`[42, 118, 97, 108, 1, 2]`.
5352

5453
# Reference-level explanation
5554
[reference-level-explanation]: #reference-level-explanation
5655

57-
[PR #52838](https://github.com/rust-lang/rust/pull/52838) lays the
58-
foundation for the implementation of the full RFC.
59-
60-
This new feature could be surprising when editting existing code, if
61-
`concat!("foo", `b`, `a`, `r`, 3)` were changed to
62-
`concat!("foo", `b`, b`a`, `r`, 3)`, as the macro call would change from
63-
being evaluated as a `str` literal "foobar3" to `[u8]`
64-
`[102, 111, 111, 98, 97, 114, 3]`.
56+
<!-- TODO -->
6557

6658
# Drawbacks
6759
[drawbacks]: #drawbacks
6860

69-
As mentioned in the previous section, this causes `concat!()`'s output to be
70-
dependant on its input.
61+
None known.
7162

7263
# Rationale and alternatives
7364
[rationale-and-alternatives]: #rationale-and-alternatives
7465

75-
A new macro `bconcat!()` could be introduced instead. People in the wild
76-
have already intended to use `concat!()` for byte literals. A new macro
77-
could be explained to users through diagnostics, but using the existing
78-
macro adds support for something that a user could expect to work.
66+
`concat!` could instead be changed to sometimes produce byte literals instead of
67+
string literals, like a previous revision of this RFC proposed. This would make
68+
it hard to ensure the right output type is produced – users would have to use
69+
hacks like adding a dummy `b""` argument to force a byte literal output.
7970

8071
# Prior art
8172
[prior-art]: #prior-art
8273

83-
[PR #52838](https://github.com/rust-lang/rust/pull/52838) lays the
84-
foundation for the implementation of the full RFC, trying to enable a real
85-
use seen in the wild.
74+
<!-- TODO -->
8675

8776
# Unresolved questions
8877
[unresolved-questions]: #unresolved-questions
8978

90-
- What parts of the design do you expect to resolve through the RFC process before this gets merged?
91-
- What parts of the design do you expect to resolve through the implementation of this feature before stabilization?
92-
- What related issues do you consider out of scope for this RFC that could be addressed in the future independently of the solution that comes out of this RFC?
79+
- Should additional literal types be supported? Byte string literals are
80+
basically the same thing as byte slice references, so it might make sense to
81+
support those as well (support `&[0, 1, 2]` in addition to `[0, 1, 2]`).
82+
- What to do with string and character literals? They could either be supported
83+
with their underlying UTF-8 representation being concatenated, or rejected.
84+
- If supported, it would probably make sense to also support boolean literals
85+
so `concat_bytes!()` supports all inputs `concat!()` does.
86+
- If rejected, it would probably makes sense to also reject boolean literals
87+
to avoid any possible confusion about their representation (`b"true"` and
88+
`b"false"` vs. `1` and `0`).

0 commit comments

Comments
 (0)