Skip to content

unnecessary_string_new #8650

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

Closed
yoav-lavi opened this issue Apr 6, 2022 · 4 comments · Fixed by #8660
Closed

unnecessary_string_new #8650

yoav-lavi opened this issue Apr 6, 2022 · 4 comments · Fixed by #8660
Labels
A-lint Area: New lints E-medium Call for participation: Medium difficulty level problem and requires some initial experience. L-style Lint: Belongs in the style lint group

Comments

@yoav-lavi
Copy link
Contributor

yoav-lavi commented Apr 6, 2022

What it does

Detects cases of &String::new() being passed to something expecting &str.

This is a followup on @flip1995's suggestion:

A separate lint about using an owned empty string where also a "" would be possible might be better to put time in than trying to cover all cases in this lint.

When checking godbolt.org it seems that &String::new() does an extra allocation although in benchmarks they seemed to perform similarly (which leads me to believe it may be optimized away in some cases, or that the allocation is almost insignificant in this case).

See examples of this happening here (might include cases of &String)

I also opened a question on /r/rust to make sure there aren't cases that this would be valid.

Lint Name

unnecessary_string_new

Category

style

Advantage

Shorter, possibly more performant

Drawbacks

None that I'm aware of

Example

"12345".split(&String::new());

Could be written as:

"12345".split("");
@yoav-lavi yoav-lavi added the A-lint Area: New lints label Apr 6, 2022
@flip1995 flip1995 added good-first-issue These issues are a good way to get started with Clippy L-style Lint: Belongs in the style lint group E-medium Call for participation: Medium difficulty level problem and requires some initial experience. and removed good-first-issue These issues are a good way to get started with Clippy labels Apr 6, 2022
@flip1995
Copy link
Member

flip1995 commented Apr 6, 2022

Thanks for opening this issue!

Looking at the godbolt, even with -Copt-level=3 the compiler still creates the allocation. I guess a zero-size allocation is really cheap, so doing this in only a few cases probably doesn't show that much of an performance impact.

This lint might be similar to the ptr_arg lint, but with the additional step of figuring out what the actual required type is. Maybe this can be done with expr_ty_adjusted, but if not this might be a bit more difficult with figuring out the actual type by looking at the function definition.

But the ptr_arg lint should be a good starting point for figuring out if you're dealing with a type like &String, &Vec, ...

@yoav-lavi
Copy link
Contributor Author

/u/lebensterben also suggested the following on the Reddit post (which could be a separate lint):

Yep. Also &Vec::new() should also be considered anti-pattern when it's expecting &[]

@yoav-lavi
Copy link
Contributor Author

yoav-lavi commented Apr 6, 2022

@flip1995 apparently the reason this performs the same is that there isn't an actual allocation,
also shown in the docs:

Given that the String is empty, this will not allocate any initial buffer.

I'm assuming this is still valid for stylistic reasons, also needs to be checked if 100% of the additional output from String::new() is optimized away

@yoav-lavi
Copy link
Contributor Author

/u/1vader added that &String::from("abc") where you can pass "abc" would also be a good idea to avoid

bors added a commit that referenced this issue Apr 11, 2022
`unnecessary_owned_empty_string`

[`unnecessary_owned_empty_string`]

Fixes #8650

- \[x] Followed [lint naming conventions][lint_naming]
- \[x] Added passing UI tests (including committed `.stderr` file)
- \[x] `cargo test` passes locally
- \[x] Executed `cargo dev update_lints`
- \[x] Added lint documentation
- \[x] Run `cargo dev fmt`

[lint_naming]: https://rust-lang.github.io/rfcs/0344-conventions-galore.html#lints

changelog: Adds `unnecessary_owned_empty_string`, a lint that detects passing owned empty strings to a function expecting `&str`
@bors bors closed this as completed in 5c19ae9 Apr 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lint Area: New lints E-medium Call for participation: Medium difficulty level problem and requires some initial experience. L-style Lint: Belongs in the style lint group
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants