Skip to content

Do not suggest borrow that is already there in fully-qualified call #132469

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

Merged
merged 2 commits into from
Jul 7, 2025

Conversation

estebank
Copy link
Contributor

@estebank estebank commented Nov 1, 2024

When encountering &str::from("value") do not suggest &&str::from("value").

Fix #132041.

@rustbot
Copy link
Collaborator

rustbot commented Nov 1, 2024

r? @Nadrieril

rustbot has assigned @Nadrieril.
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 S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Nov 1, 2024
Comment on lines 1212 to 1213
if let hir::Node::Expr(expr) = self.tcx.parent_hir_node(*hir_id)
&& let hir::ExprKind::Call(base, _) = expr.kind
&& let hir::ExprKind::Path(hir::QPath::TypeRelative(ty, _)) = base.kind
&& ty.span == span
Copy link
Member

Choose a reason for hiding this comment

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

I'm not following the logic: where in this condition are you checking that the expression is already borrowed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can add the check for the existing borrow one level up, but I also wanted to avoid suggesting &str::from("") when we have str::from("") as that won't help either.

Copy link
Member

@Nadrieril Nadrieril Nov 9, 2024

Choose a reason for hiding this comment

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

I see, so the comment below could be saying something like "don't suggest borrowing when this wouldn't fix the problem (because the type is specified by a path instead of inferred)"?

Copy link
Member

Choose a reason for hiding this comment

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

Ah I understand my confusion: I had understood "Do not suggest borrowing when we already do so" as "Do not suggest borrowing when the expression is already borrowed"

Copy link
Member

@Nadrieril Nadrieril Mar 13, 2025

Choose a reason for hiding this comment

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

Coming back to this: I still don't understand what this branch is catching. Can you rephrase the comment to be more explicit about what the branch means plz?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi! Sorry, I had to spend time building context back for myself as well. The whole story:

When trying to find if any trait provides an method or associated function, the resolver needs to keep all trait impls and their obligations in consideration. When evaluating something like Ty::func(), we will inject obligations coming from Ty with the HirId and Span corresponding to that PathSegment, like Sized or any of its where-bound clauses. Because <str as From<&str>::from doesn't exist, we hit that unmet obligation. So far this is the normal behavior.

In suggest_add_reference_to_arg, we try to identify expressions where the obligation isn't met for the found type, but is for the borrow of the found type. So if you have foo(bar) we suggest foo(&mut bar) if appropriate. But that logic kind of assumed that the source of the obligation was an expression, and not a path segment of a type relative path (like Foo::bar, as opposed to type absolute paths like <Foo as Trait>::bar or <Foo>::bar. Because of how rare this case was in our test suite, it seemed like the only situation where the logic I initially added would only ever trigger in a situation like &Foo::bar(), so it didn't seem necessary to make additional checks for the borrow actually being there (which is what was quite confusing of the code as written). The reason this "fixed" the issue was because by having the early return we ensured we didn't suggest the spurious &.

Looking at the changes and situation with fresh eyes, I noticed a couple of cases where we could hit that new logic in item signatures as well, so I added more checks (namely, the expected one that was missing) and added structured suggestions, as we now had all of the spans we needed for that.

@apiraino
Copy link
Contributor

given this comment,

@rustbot author

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 24, 2025
@rustbot
Copy link
Collaborator

rustbot commented Apr 24, 2025

Reminder, once the PR becomes ready for a review, use @rustbot ready.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I noticed there's another case that this PR doesn't account for, which provides an incorrect suggestion:

error[E0277]: the trait bound `S: Trait` is not satisfied
  --> $DIR/dont-suggest-borrowing-existing-borrow.rs:17:13
   |
LL |     let _ = S::foo();
   |             ^ the trait `Trait` is not implemented for `S`
   |
help: consider borrowing here
   |
LL |     let _ = &S::foo();
   |             +
LL |     let _ = &mut S::foo();
   |             ++++

Copy link
Member

@Nadrieril Nadrieril left a comment

Choose a reason for hiding this comment

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

LGTM, r=me unless you want to also fix that other case

@estebank
Copy link
Contributor Author

estebank commented Jul 7, 2025

@bors r=Nadrieril

@Nadrieril I opened a ticket for that other case. I'll address it later or (even better) someone might snipe it as it is a tricky but not complex case.

@bors
Copy link
Collaborator

bors commented Jul 7, 2025

📌 Commit 7603adc has been approved by Nadrieril

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jul 7, 2025
bors added a commit that referenced this pull request Jul 7, 2025
Rollup of 9 pull requests

Successful merges:

 - #132469 (Do not suggest borrow that is already there in fully-qualified call)
 - #143340 (awhile -> a while where appropriate)
 - #143438 (Fix the link in `rustdoc.md`)
 - #143539 (Regression tests for repr ICEs)
 - #143566 (Fix `x86_64-unknown-netbsd` platform support page)
 - #143572 (Remove unused allow attrs)
 - #143583 (`loop_match`: fix 'no terminator on block')
 - #143584 (make `Machine::load_mir` infallible)
 - #143591 (Fix missing words in future tracking issue)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 00a4418 into rust-lang:master Jul 7, 2025
10 checks passed
@rustbot rustbot added this to the 1.90.0 milestone Jul 7, 2025
rust-timer added a commit that referenced this pull request Jul 7, 2025
Rollup merge of #132469 - estebank:issue-132041, r=Nadrieril

Do not suggest borrow that is already there in fully-qualified call

When encountering `&str::from("value")` do not suggest `&&str::from("value")`.

Fix #132041.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Unhelpful borrowing suggested when wrongly constructing an unsized type
5 participants