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

Support constant string concatenation #3318

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

DeviousStoat
Copy link

Implements support for string concatenation in module constants' expressions.

const foo = "foo"
const foobar = foo <> "bar"
const foofoobarbaz = foo <> foobar <> "baz"

closes #3208

Copy link
Member

@lpil lpil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lovely work! I've left some notes inline. Thank you


Constant::StringConcatenation { .. } => docvec![const_inline(value, env), "/binary"],

_ => panic!("Constant string concatenation argument can only be a string or const var at code generation time"),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove these panics, code generation is not the place to do type checking, and other variants could be suitable in future. Calling const_inline on whatever the Constant::* is is good.

compiler-core/src/erlang/tests/strings.rs Show resolved Hide resolved
r#"
const foo = "foo"
const foobar = foo <> "bar"
const foofoobarbaz = foo <> foobar <> "baz"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Split this into multiple tests please, we only test one example per test.

Could we also have a test for a much larger number of concatenations in one constant too please.

compiler-core/src/format/tests.rs Show resolved Hide resolved
compiler-core/src/type_/tests/errors.rs Outdated Show resolved Hide resolved
compiler-core/src/javascript/tests/strings.rs Outdated Show resolved Hide resolved
@DeviousStoat DeviousStoat force-pushed the const-string-concatenation branch 2 times, most recently from 53dce10 to f978801 Compare June 23, 2024 21:38
@DeviousStoat
Copy link
Author

I think I addressed your comments.
Btw, don't know if it matters too much as I haven't worked on too many big rust projects but I think this codebase is really well made, it's a joy to work on it and easy to pickup, akin to the gleam language itself

Copy link
Member

@lpil lpil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh that you, you are very kind! 💜

This is looking great! Thank you. 2 small thing in the notes


-spec main() -> binary().
main() ->
<<"a"/utf8,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should render like this:

main() ->
    <<"a"/utf8,
      "b"/utf8,
      "c"/utf8,
      ...

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ooh right, it's not just format problem, we don't need to /binary the concatenation, we can build a bit array of /utf8 strings. This is a lot nicer now, I am starting to understand what you meant with "string concatenation doesn't require compile time code execution"

fn const_string_concat_naked_right() {
assert_module_error!(
"
const foo = \"foo\" <>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the foobar from this file please 🙏

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops sorry missed this one

// instead of
// <<"a"/utf8,
// "b"/utf8>>
.set_nesting(INDENT + 2)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be wrong if the indent level is supposed to be anything other than 1!

For example:

const x = [
  <<
    ...,
    ...,
  >>
]

I don't mind so much about the exact format used, but the indentation should increase as there's more nesting

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh right, I pushed a change with a test case for a long concatenation in a list.
Let me know what you think, it doesn't exactly has the format that you specified before but the indentation should be good now.

I think to render like that:

main() ->
    <<"a"/utf8,
      "b"/utf8,
      "c"/utf8,
      ...

would require changes in the nesting logic or a special case I am not sure, I could look into it if you want

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow string concatenation when defining const values
2 participants