Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Concatenating bytestrings fails; rustc suggests non-existent bconcat!() #52710

Closed
jsgf opened this issue Jul 25, 2018 · 6 comments
Closed

Concatenating bytestrings fails; rustc suggests non-existent bconcat!() #52710

jsgf opened this issue Jul 25, 2018 · 6 comments
Labels
C-feature-request Category: A feature request, i.e: not implemented / a PR. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@jsgf
Copy link
Contributor

jsgf commented Jul 25, 2018

concat!() doesn't work on bytestrings (why?). When trying it, it fails with:

1 | const FOO: &[u8] = concat!("foo", "bar");
  |                    ^^^^^^^^^^^^^^^^^^^^^
  |                    |
  |                    expected slice, found str
  |                    help: consider adding a leading `b`: `bconcat!("foo", "bar")`
  |
  = note: expected type `&'static [u8]`
             found type `&'static str`

bconcat!() sounds interesting, but it isn't documented, and the compiler doesn't accept it:

error: cannot find macro `bconcat!` in this scope
 --> src/main.rs:1:20
  |
1 | const FOO: &[u8] = bconcat!("foo", "bar");
  |                    ^^^^^^^ help: you could try the macro: `concat`

I think the real fix here is that bconcat!() should exist.

@jonas-schievink
Copy link
Contributor

Heh, this is because the compiler assumes you used a normal string literal like "abc" and just slaps a b in front of it to create the suggestion. A bconcat! macro never existed.

@jsgf
Copy link
Contributor Author

jsgf commented Jul 25, 2018

Heh indeed. I originally tried concat!(b"foo", b"bar"), but:

error: cannot concatenate a byte string literal
 --> src/main.rs:1:28
  |
1 | const FOO: &[u8] = concat!(b"foo", b"bar");
  |                            ^^^^^^

error: cannot concatenate a byte string literal
 --> src/main.rs:1:36
  |
1 | const FOO: &[u8] = concat!(b"foo", b"bar");
  |                                    ^^^^^^

error: aborting due to 2 previous errors

I can't think of a reason why concat shouldn't support this though. Is there something I'm missing?

@kennytm kennytm added T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. C-feature-accepted Category: A feature request that has been accepted pending implementation. C-feature-request Category: A feature request, i.e: not implemented / a PR. A-diagnostics Area: Messages for errors, warnings, and lints C-bug Category: This is a bug. and removed C-feature-accepted Category: A feature request that has been accepted pending implementation. labels Jul 25, 2018
@kennytm
Copy link
Member

kennytm commented Jul 25, 2018

cc @estebank #51978 about the bconcat diagnostic issue.

@estebank
Copy link
Contributor

I'll take a look and fix the incorrect suggestion.

The concat!() restriction is here:

https://github.com/rust-lang/rust/blob/master/src/libsyntax_ext/concat.rs

It seems to me that the only real restriction that it should have is not mixing byte str literals and str literals when concatenating, and even then it should be possible to convert from one to the other.

Changing the linked code to keep two accumulators, one for str and another as a Vec<u8> for byte str, and returning base::MacEager::expr(cx.expr_lit(sp, ast::LitKind::ByteStr(rustc_data_structures::sync::Lrc::new(byte_acc)))) would be enough to add the desired functionality.

@rust-lang/lang is there any reason to not change concat!() to accept concatenating multiple byte strs?

@estebank
Copy link
Contributor

The diagnostic bug is fixed in nightly by #51978.

@estebank
Copy link
Contributor

Closing. There's now an RFC for the feature and the bug has been fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-feature-request Category: A feature request, i.e: not implemented / a PR. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants