Skip to content

Extend implicit_clone to handle to_string calls #14177

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

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

Conversation

smoelius
Copy link
Contributor

@smoelius smoelius commented Feb 9, 2025

Put another way, merge string_to_string into implicit_clone, as suggested here: #14173 (comment)

Note: I wrote this comment:

/// Note that `to_string` is not flagged by `implicit_clone`. So other lints that call
/// `is_clone_like` and that do flag `to_string` must handle it separately. See, e.g.,
/// `is_to_owned_like` in `unnecessary_to_owned.rs`.

Here is the context for why I wrote it: #7978 (comment)

Regardless, it's probably time for the comment to go away. Extending implicit_clone to handle to_string calls yields many hits within Clippy's codebase.

changelog: extend implicit_clone to handle to_string calls

@rustbot
Copy link
Collaborator

rustbot commented Feb 9, 2025

r? @y21

rustbot has assigned @y21.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Feb 9, 2025
@smoelius smoelius force-pushed the implicit-clone-to-string branch 2 times, most recently from 72eccf1 to a1615be Compare February 9, 2025 01:01
@smoelius
Copy link
Contributor Author

smoelius commented Feb 9, 2025

@y21 Sorry for the force pushes. I think it should be good now.

@smoelius smoelius force-pushed the implicit-clone-to-string branch from a1615be to cb609f7 Compare February 23, 2025 01:15
Copy link
Member

@y21 y21 left a comment

Choose a reason for hiding this comment

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

Makes sense to me. I opened a thread on Zulip to give people a chance and some time to comment on this since this involves a deprecation

@samueltardieu
Copy link
Contributor

nit: tests/ui/string_to_string.{rs,fixed,stderr} should probably be removed, this no longer corresponds to a lint, and is covered by the new tests/ui/implicit_clone.rs tests.

@smoelius smoelius force-pushed the implicit-clone-to-string branch from 656f7a5 to daa7c5f Compare March 8, 2025 17:30
@smoelius
Copy link
Contributor Author

smoelius commented Mar 8, 2025

Hmm. sting_to_string.stderr is hard-coded in .github/driver.sh:

# Run a lint and make sure it produces the expected output. It's also expected to exit with code 1
# FIXME: How to match the clippy invocation in compile-test.rs?
./target/debug/clippy-driver -Dwarnings -Aunused -Zui-testing --emit metadata --crate-type bin tests/ui/string_to_string.rs 2>string_to_string.stderr && exit 1
sed -e "/= help: for/d" string_to_string.stderr > normalized.stderr
diff -u normalized.stderr tests/ui/string_to_string.stderr

@smoelius
Copy link
Contributor Author

From what I can tell, driver.sh requires a stderr file with a certain structure. I picked the first one I could find that worked. That happened to be char_lit_as_u8.stderr.

@y21
Copy link
Member

y21 commented Mar 12, 2025

From what I can tell, driver.sh requires a stderr file with a certain structure. I picked the first one I could find that worked. That happened to be char_lit_as_u8.stderr.

Yeah, I think that should be fine. Looking at git blame for that line, looks like the lint name on that line has changed a couple of times before.

Copy link
Member

@y21 y21 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, and the thread on Zulip got a bunch of positive reactions so we should be fine here with deprecating/merging the lint.

However, going to tag @flip1995 here for the change in .github/driver.sh. It looks correct to me, but just making sure because he's said he wants to be notified of any changes that affect CI.

@smoelius
Copy link
Contributor Author

@y21 I really appreciate your efforts.

Unfortunately, I think this PR is presently unmergeable as a result of #14396.

The only path forward I can see to to migrate that PR's improvements to implicit_clone.

Do you agree?

@y21
Copy link
Member

y21 commented Mar 19, 2025

Yeah, detecting .map(String::to_string) (and I suppose .map(<_>::to_owned) as part of implicit_clone makes sense to me.

However, I don't think special-casing .map(|v| v.to_string()) to suggest .cloned() as is done in that PR is necessary (if I understood that correctly from the PR) -- this lint would already detect it and if it would just suggest .map(|v| v.clone()) as it naturally does without any special handling, the map_clone lint dedicated to looking for that pattern will suggest .cloned() in a subsequent clippy run.

@smoelius smoelius force-pushed the implicit-clone-to-string branch from f8ad6f6 to 0b85f4d Compare March 20, 2025 18:22
@smoelius
Copy link
Contributor Author

The only path forward I can see to to migrate that PR's improvements to implicit_clone.

Scratch that. I am undoing the following commits. I explain why below.

#14396 matches on both method calls and calls to type-relative paths. But the code that calls implicit_clone matches on just method calls.

I think it would be desirable to have implicit_clone work for calls to type-relative paths. But I think that would require a larger change to both implicit_clone and the code that calls it.

So string_to_string will continue to live on, but only for the functionality added in #14396.

I find the present situation unfortunate, but I guess it's what we've got.

@smoelius
Copy link
Contributor Author

@y21 Could I impose on you to please try to merge this?

@y21
Copy link
Member

y21 commented Mar 25, 2025

One issue with this split as it is now is that we get two warnings with different suggestions on the same code, Some(String::new()).as_ref().map(|s| s.to_string());.

I still don't think that we really need the .to_string()-in-map specific suggestion that was added in the other PR, and if we just drop the ExprKind::MethodCall code in string_to_string (type-relative path would stay), that would resolve this issue. The map_clone/useless_asref lints can also emit more specialized warnings

@smoelius smoelius force-pushed the implicit-clone-to-string branch 2 times, most recently from b3e48ef to 46f720c Compare March 28, 2025 16:55
@smoelius
Copy link
Contributor Author

The map_clone/useless_asref lints can also emit more specialized warnings

Sorry, you mentioned map_clone in #14177 (comment) and I didn't catch it. I humbly think that extending map_clone is a brilliant idea.

So this PR is back to deprecating string_to_string.

A quick note: to avoid overlapping warnings between implict_clone and map_clone, I copied is_called_from_map_like and is_parent_map_like to implicit_clone, and call them here:

&& is_called_from_map_like(cx, expr).is_none()

Sorry to give you more code to review.

@smoelius smoelius force-pushed the implicit-clone-to-string branch from 46f720c to 12dff35 Compare March 28, 2025 22:27
@smoelius
Copy link
Contributor Author

The force push was to make one comment slightly less verbose.

@rustbot

This comment has been minimized.

@smoelius smoelius force-pushed the implicit-clone-to-string branch from 12dff35 to d80c373 Compare April 13, 2025 17:43
@rustbot

This comment has been minimized.

@smoelius smoelius force-pushed the implicit-clone-to-string branch from d80c373 to 9a85c45 Compare April 20, 2025 00:46
@rustbot

This comment has been minimized.

@smoelius smoelius force-pushed the implicit-clone-to-string branch from 9a85c45 to d36e477 Compare May 7, 2025 09:13
@rustbot

This comment has been minimized.

@smoelius smoelius force-pushed the implicit-clone-to-string branch from d36e477 to c6cc428 Compare May 14, 2025 22:38
@rustbot

This comment has been minimized.

@smoelius smoelius force-pushed the implicit-clone-to-string branch from c6cc428 to 8ab047e Compare May 16, 2025 22:17
@rustbot

This comment has been minimized.

@smoelius smoelius force-pushed the implicit-clone-to-string branch from 8ab047e to b09d9d6 Compare May 19, 2025 23:32
@smoelius
Copy link
Contributor Author

Hey, @y21. Is anything holding this PR back?

@y21
Copy link
Member

y21 commented May 20, 2025

Sorry, you mentioned map_clone in #14177 (comment) and I didn't catch it. I humbly think that extending map_clone is a brilliant idea.

Is this actually needed? I'm still not entirely convinced that even moving the logic that was added in that PR elsewhere is worth it. My suggestion was to just deprecate the string_to_string lint as this PR did from the start and leave the extra logic that the other PR added behind, entirely, not moving it to/extending other lints.

My reasoning is that map_clone and string_to_string in combination already handle this today (at least from some quick testing, please correct me if I'm wrong), without us needing this extra handling.

Let's take this newly added test case from tests/ui/map_clone.rs as an example: let _ = variable2.map(|x| x.to_string());

If we just deprecate the lint entirely and move only the to_string -> clone detection to implicit_clone, then implicit_clone would change that to let _ = variable2.map(|x| x.clone());. If you then run clippy on it again, clippy will further refactor that to let _ = variable2.cloned(); (naturally by map_clone - again this is without any changes to it).

So even without this extra logic, we end up with the same ideal code, it just takes two clippy runs instead of one to get there, but IMHO this is a natural interaction between two lints (progressively refactoring it further). I think rustfix also handles this pretty well and applies multiple consecutive --fixes if new lints arise in suggested code

So, rephrasing, just to be clear, my suggestion would be:

  • Deprecate string_to_string, removing all code from that lint, even what was added in that PR
  • Lint .to_string() on String as part of implicit_clone

Which is essentially what the PR was doing from the start, I believe. WDYT? It would also simplify the PR a bit. If you do think that the extra logic from the PR to go to the ideal suggestion directly instead of having it naturally handled by the two lints is really worth keeping, I'm also ok accepting the changes you've proposed (I merely wanted to elaborate on what exactly I meant). It's also possible that my suggestion doesn't work because I've missed a subtle detail

@smoelius
Copy link
Contributor Author

smoelius commented May 21, 2025

My suggestion was to just deprecate the string_to_string lint as this PR did from the start and leave the extra logic that the other PR added behind, entirely, not moving it to/extending other lints.

To be sure I understand, what you're suggesting would amount to reverting #14396. Is that right?

If so, I'm not sure my opinion matters. Should we involve the author and reviewers of #14396?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy