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

WIP format literal arg inlining #10740

Closed
wants to merge 1 commit into from
Closed

Conversation

nyurik
Copy link
Contributor

@nyurik nyurik commented May 4, 2023

A rough draft of #10739 implementation. The goal is to allow any kind of literal string arguments to be inlined automatically.

format!("hello {}", "world")
// is replaced with
format!("hello world")
changelog: [`uninlined_format_args`]: support for inlining string literals

@rustbot
Copy link
Collaborator

rustbot commented May 4, 2023

r? @llogiq

(rustbot has picked a reviewer for you, use r? to override)

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label May 4, 2023
Copy link
Contributor

@llogiq llogiq left a comment

Choose a reason for hiding this comment

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

Looks good to me. I have but one request for clarification and I'd like to see a test with macros.

} else if !matches!(arg.kind, FormatArgumentKind::Captured(_))
&& let Some(FormatPlaceholder{span: Some(placeholder_span), ..}) = placeholder
&& let rustc_ast::ExprKind::Lit(lit) = &arg.expr.kind
&& lit.kind == LitKind::Str // FIXME: lit.kind must match the format string kind
Copy link
Contributor

Choose a reason for hiding this comment

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

This isn't clear to me. What other kinds would there be?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

there are also raw strings

Copy link
Contributor Author

Choose a reason for hiding this comment

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

And possibly byte strings too? Not certain

@@ -262,3 +262,17 @@ fn tester2() {
local_i32,
};
}

fn literals() {
Copy link
Contributor

Choose a reason for hiding this comment

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

I worry about cases where the format string and literal value come from different macro expansions. We should have a test where that is the case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Alexendoo
Copy link
Member

I'd say this should be under a new lint name, although it's similar what it's doing is different enough to the existing uninlined_format_args

The existing implementation can also be used, it handles the various raw/non-raw permutations of the literal and format string as well as some other literals. You'd have to change the part where it checks the macro names before it's called + do a lint rename for both print_literal and write_literal to the new one

@nyurik
Copy link
Contributor Author

nyurik commented May 4, 2023

@Alexendoo after some more thinking, it seems separating it into a new lint would create more problems than solve:

  • multiple lints operating on the same expression tend to cause issues, esp in the --fix mode
  • a format expression with numeric indexes would be ignored by both lints unless used together: format!("{0} {1}", var, "str") will be ignored by both the uninlined_format_args and the string inlining lint, but when used together it would suggest the format!("{var} str")
  • the original lint name uninlined_format_args fits perfectly for the string inlining as well, so wouldn't cause any confusion

So in short, we would not really gain anything besides problems from multiple lints... Not worth it IMO :)

@Alexendoo
Copy link
Member

I don't see what problem that would cause here, overlapping suggestions would cause rustfix ui tests to fail (cargo fix can handle them though) but the suggestions here wouldn't have overlapping spans

The main thing is so that you can set the lint levels independently, e.g. print_literal and write_literal are style but uninlined_format_args is pedantic. It wouldn't be unusual to want to disable one independently if they were in the same group

It would also make the lint documentation more confusing to have to explain the two different kinds of inlining in one lint, and how allow-mixed-uninlined-format-args would only apply to one of those kinds

format!("{0} {1}", var, "str") doesn't seem likely enough to occur to make up for that

@nyurik
Copy link
Contributor Author

nyurik commented May 5, 2023

@Alexendoo you do raise important config point. I think we can actually achieve both goals if we track the type of inlining needed -- e.g. if both are enabled, and both are needed (the "literal", var case above), we can show just one suggestion (under either of the names, or even add a note saying that both were involved). If only one is enabled, it won't even consider the other in the inlining.

@Alexendoo
Copy link
Member

To me that sounds too complicated/novel considering the problem is relatively minor

@llogiq
Copy link
Contributor

llogiq commented May 7, 2023

Agreed, let's not complicate the solution. As long as both lints don't step on each other's toes by issuing incompatible suggestions, having two lints that don't care about each other is fine.

@bors
Copy link
Contributor

bors commented Jun 12, 2023

☔ The latest upstream changes (presumably #10358) made this pull request unmergeable. Please resolve the merge conflicts.

A rough draft of rust-lang#10739 implementation. The goal is to allow any kind of literal string arguments to be inlined automatically.

```rust
format!("hello {}", "world")
// is replaced with
format!("hello world")
```
@bors
Copy link
Contributor

bors commented Feb 19, 2024

☔ The latest upstream changes (presumably #12306) made this pull request unmergeable. Please resolve the merge conflicts.

@xFrednet
Copy link
Member

Hey @nyurik, this is a ping from triage. Do you still plan to continue this PR? If you need help, you're always welcome to ask questions here or on Zulip :)

@xFrednet
Copy link
Member

Hey this is triage, I'm closing this due to inactivity. If you want to continue this implementation, you're welcome to create a new PR. Thank you for the time, you already put into this!

Interested parties are welcome to pick this implementation up as well :)

@rustbot label +S-inactive-closed -S-waiting-on-author -S-waiting-on-review

@xFrednet xFrednet closed this Jun 20, 2024
@rustbot rustbot added S-inactive-closed Status: Closed due to inactivity and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties labels Jun 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-inactive-closed Status: Closed due to inactivity
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants