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

Recommend fix count() -> len() on slices #87614

Merged
merged 1 commit into from
Dec 7, 2021

Conversation

notriddle
Copy link
Contributor

Fixes #87302

@rust-highfive
Copy link
Collaborator

r? @jackh726

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jul 30, 2021
@rust-log-analyzer

This comment has been minimized.

@jackh726
Copy link
Member

My first thought is (without reading too much of the code): what other methods do we have suggestions like this for? Also, even though this is technically compiler code, it seems more like a @rust-lang/libs decision; it reminds me somewhat of the rustdoc aliases: at what point is it "okay" and when is it "too much"

@notriddle
Copy link
Contributor Author

My first thought is (without reading too much of the code): what other methods do we have suggestions like this for?

The same file I modified also has a suggestion for as_str(self: &str), which is another method that doesn't exist but developers are likely to try to call (and has exactly one, obvious, correction to apply).

@cuviper
Copy link
Member

cuviper commented Jul 30, 2021

Could this use #[rustc_on_unimplemented(... from_method = "count" ...)] on Iterator?

@notriddle
Copy link
Contributor Author

notriddle commented Jul 30, 2021

Here's what I tried, to achieve the effect using that system. It didn't work.

diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index a1a336a0574..bdee0e202c6 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -25,6 +25,13 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {}
 /// [impl]: crate::iter#implementing-iterator
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_on_unimplemented(
+    on(
+        all(
+            any(_Self = "[]", _Self = "std::vec::Vec", _Self = "std::string::String", _Self = "str"),
+            from_method = "count",
+        ),
+        label = "consider using `.len()`"
+    ),
     on(
         _Self = "std::ops::RangeTo<Idx>",
         label = "if you meant to iterate until a value, add a starting value",

Here's the message that it gives:

error[E0599]: the method `count` exists for array `[{integer}; 4]`, but its trait bounds were not satisfied
  --> $DIR/count2len.rs:5:11
   |
LL |     slice.count();
   |           ^^^^^ method cannot be called on `[{integer}; 4]` due to unsatisfied trait bounds
   |
   = note: the following trait bounds were not satisfied:
           `[{integer}; 4]: Iterator`
           which is required by `&mut [{integer}; 4]: Iterator`
           `[{integer}]: Iterator`
           which is required by `&mut [{integer}]: Iterator`

I notice that my changes have no effect on it, but also, that the {Self} isn't an iterator language isn't being used anywhere in here, either. Maybe because there are multiple applicable trait implementations?

@cuviper
Copy link
Member

cuviper commented Aug 3, 2021

My hunch is that the &mut I implementation is in the way. Maybe you need _Self = "&[]"?

@notriddle
Copy link
Contributor Author

notriddle commented Aug 3, 2021

No. _Self = "&[]" doesn't do anything different. Neither does _Self = "&mut []".

@camelid camelid added A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 20, 2021
@jackh726
Copy link
Member

I'm going to defer to libs (or libs-api?) here.

r? @cuviper feel free to reassign

@rust-highfive rust-highfive assigned cuviper and unassigned jackh726 Aug 20, 2021
@inquisitivecrystal inquisitivecrystal added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Aug 24, 2021
@bors
Copy link
Contributor

bors commented Sep 1, 2021

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

@camelid
Copy link
Member

camelid commented Sep 8, 2021

@notriddle Please rebase instead of merging in upstream changes because of the "No-Merge Policy". Thanks!

@JohnCSimon JohnCSimon added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 27, 2021
@JohnCSimon JohnCSimon added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Oct 19, 2021
@jackh726 jackh726 added T-libs Relevant to the library team, which will review and decide on the PR/issue. and removed T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Oct 21, 2021
@JohnCSimon JohnCSimon added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Nov 8, 2021
@Mark-Simulacrum
Copy link
Member

This feels like a fairly reasonable change to me (obviously, we can iterate further on the message in the future). I'm not entirely convinced at whether this is a particularly common case, but the extra work is not huge, and so it seems like an OK change to make in my opinion.

My cursory look at the compiler code suggests we don't consider on_unimplemented for this kind of error, so we might want to implement that in the future -- but it seems unnecessary to block this improvement on that larger goal.

I also agree with others on the "is this too much" angle, but ultimately, this is something relatively easy to back out and we're not yet seeing a huge influx of such targeted messages that I'm worried. :)


That said, I think the proposed error message in this PR is pretty suboptimal -- we're hiding the trait the user might've been intending to reference, not even mentioning its name:

error[E0599]: no method named `count` found for array `[{integer}; 4]` in the current scope
  --> $DIR/count2len.rs:5:11
   |
LL |     slice.count();
   |          -^^^^^--
   |          ||
   |          |method cannot be called on `[{integer}; 4]` due to unsatisfied trait bounds
   |          help: consider using `len` instead

I think it would be good to rework this to something like:

error[E0599]: no method named `count` found for array `[{integer}; 4]` in the current scope
  --> $DIR/count2len.rs:5:11
   |
LL |     slice.count();
   |          --------
   |          |
   |          help: consider using `len` instead
   |
   note: `count` is defined on `std::iter::Iterator`, which `[{integer}; 4]` does not implement

Or potentially to hide the "unsatisfied due to trait bounds" error altogether, though not sure on that front.

cc @rust-lang/wg-diagnostics -- wondering if you have opinions on this particular case or if we should instead invest in expanding rustc_on_unimplemented to cover cases like this and avoid ad-hoc code in the compiler.

@notriddle
Copy link
Contributor Author

I agree. Rebased and pushed a new error message, that's closer to what you wrote.

error[E0599]: no method named `count` found for array `[{integer}; 4]` in the current scope
  --> $DIR/count2len.rs:5:11
   |
LL |     slice.count();
   |           ^^^^^
   |           |
   |           method cannot be called on `[{integer}; 4]` due to unsatisfied trait bounds
   |           help: consider using `len` instead
   |
   = note: `count` is defined on `Iterator`, which `[{integer}; 4]` does not implement

Copy link
Member

@Mark-Simulacrum Mark-Simulacrum left a comment

Choose a reason for hiding this comment

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

r=me with nit fixed

compiler/rustc_typeck/src/check/method/suggest.rs Outdated Show resolved Hide resolved
@Mark-Simulacrum Mark-Simulacrum 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 Dec 7, 2021
@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Dec 7, 2021
@notriddle
Copy link
Contributor Author

@rustbot label: -S-waiting-on-author +S-waiting-on-review

@Mark-Simulacrum
Copy link
Member

@bors r+ rollup

@bors
Copy link
Contributor

bors commented Dec 7, 2021

📌 Commit 6a17ee6 has been approved by Mark-Simulacrum

@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-review Status: Awaiting review from the assignee but also interested parties. labels Dec 7, 2021
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Dec 7, 2021
…rk-Simulacrum

Recommend fix `count()` -> `len()` on slices

Fixes rust-lang#87302
bors added a commit to rust-lang-ci/rust that referenced this pull request Dec 7, 2021
…askrgr

Rollup of 10 pull requests

Successful merges:

 - rust-lang#87614 (Recommend fix `count()` -> `len()` on slices)
 - rust-lang#91065 (Add test for evaluate_obligation: Ok(EvaluatedToOkModuloRegions) ICE)
 - rust-lang#91312 (Fix AnonConst ICE)
 - rust-lang#91341 (Add `array::IntoIter::{empty, from_raw_parts}`)
 - rust-lang#91493 (Remove a dead code path.)
 - rust-lang#91503 (Tweak "call this function" suggestion to have smaller span)
 - rust-lang#91547 (Suggest try_reserve in try_reserve_exact)
 - rust-lang#91562 (Pretty print async block without redundant space)
 - rust-lang#91620 (Update books)
 - rust-lang#91622 (:arrow_up: rust-analyzer)

Failed merges:

 - rust-lang#91571 (Remove unneeded access to pretty printer's `s` field in favor of deref)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit f84a734 into rust-lang:master Dec 7, 2021
@rustbot rustbot added this to the 1.59.0 milestone Dec 7, 2021
@notriddle notriddle deleted the notriddle-count2len branch December 7, 2021 14:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Suggest len instead of count on arrays, slices, or vectors