-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Adding the has_item function to the iterator trait. #127604
Conversation
…in a &str iterator
…here Self::Item implement Self::Item == arg
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @Amanieu (or someone else) some time within the next two weeks. Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (
|
rust-analyzer is developed in its own repository. If possible, consider making this change to rust-lang/rust-analyzer instead. cc @rust-lang/rust-analyzer |
This comment has been minimized.
This comment has been minimized.
"##, | ||
}, | ||
Lint { | ||
label: "contains", | ||
description: r##"# `contains` | ||
|
||
The tracking issue for this feature is: [#94047] | ||
|
||
[#94047]: https://github.com/rust-lang/rust/issues/94047 | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file is autogenerated so no need for adding this (its also adding it one slot too late)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yonikremer see this comment too, you can revert this file
library/core/Cargo.toml
Outdated
# Adds a function to check if an element is contained in an iterator | ||
contains = [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Library features don't need to be listed here, this is just for Cargo features that get exposed during build-std
|
||
/// Advances the iterator and returns an array containing the next `N` values. | ||
/// Advances the iterator and returns an array has_iteming the next `N` values. | ||
/// | ||
/// If there are not enough elements to fill the array then `Err` is returned | ||
/// containing an iterator over the remaining elements. | ||
/// has_iteming an iterator over the remaining elements. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like maybe you did find+replace on contain
? Change looks accidental (more of these below, please double check the diff)
/// The returned iterator is a prefix of length `n` if the original iterator | ||
/// contains at least `n` elements, otherwise it contains all of the | ||
/// has_items at least `n` elements, otherwise it has_items all of the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same
|
||
/// Converts an iterator of pairs into a pair of containers. | ||
/// Converts an iterator of pairs into a pair of has_itemers. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lol, this one is kind of funny
/// Example: | ||
/// ``` | ||
/// #![feature(iter_has_item)] | ||
/// assert!(![1i32, 2i32, 3i32].iter().has_item(&4i32)); | ||
/// assert!([Some(2i32), Option::<i32>::None].iter().has_item(&None)); | ||
/// assert!([Some(2i32), Option::<i32>::None].iter().has_item(&Some(2i32))); | ||
/// assert!(!Vec::<i32>::new().iter().has_item(&1i32)); | ||
/// assert!([1i32, 2i32, 2i32, 3i32].iter().has_item(&2i32)); | ||
/// #[derive(PartialEq)] | ||
/// struct Item { | ||
/// value: i32, | ||
/// } | ||
/// assert!([Item { value: 1i32 }, Item { value: 2i32 }].iter().has_item(&Item { value: 2i32 })); | ||
/// assert!(["a", "b", "c"].iter().has_item(&"b".to_owned())); | ||
/// assert!(!["a", "b", "c"].iter().has_item(&"d".to_owned())); | ||
/// assert!(["a", "b", "c"].iter().has_item(&"b")); | ||
/// assert!(!["a", "b", "c"].iter().has_item(&"d")); | ||
/// assert!(["a".to_owned(), "b".to_owned(), "c".to_owned()].iter().has_item(&"b")); | ||
/// assert!(!["a".to_owned(), "b".to_owned(), "c".to_owned()].iter().has_item(&"d")); | ||
/// assert!((1..1000).has_item(500i32)); | ||
/// ``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned at the ACP, make the doc example something small and easy to understand. More complete testing only needs to live in unit/integration tests.
/// Checks if the Iterator has a value. | ||
/// 'has_items' is short-circuiting; in other words, it will stop processing | ||
/// as soon as the function finds the item in the Iterator. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// Checks if the Iterator has a value. | |
/// 'has_items' is short-circuiting; in other words, it will stop processing | |
/// as soon as the function finds the item in the Iterator. | |
/// Returns `true` if the iterator contains a value. | |
/// | |
/// 'has_items' is short-circuiting; in other words, it will stop processing | |
/// as soon as the function finds the item in the `Iterator`. |
Made the summary line more consistent with slice::contains
/HashSet::contains
. Also remember that a line break is needed between the summary and the content (otherwise the whole thing gets treated as a summary line).
#[unstable(feature = "iter_has_item", reason = "new API", issue = "127494")] | ||
fn has_item<Q: ?Sized>(&mut self, item: Q) -> bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From #127494, this can be renamed back to contains
…to use the function contains of the Iterator trait
This comment has been minimized.
This comment has been minimized.
@tgross35 I have updated the pull request. Now it breaks external libraries like ide-assist. |
There is a pull request for Super trait shadowing here. It just needs someone to review it. |
@@ -1327,7 +1327,7 @@ pub trait Iterator { | |||
/// `take(n)` yields elements until `n` elements are yielded or the end of | |||
/// the iterator is reached (whichever happens first). | |||
/// The returned iterator is a prefix of length `n` if the original iterator | |||
/// contains at least `n` elements, otherwise it contains all of the | |||
/// contains at least `n` elements, otherwise it containss all of the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// contains at least `n` elements, otherwise it containss all of the | |
/// contains at least `n` elements, otherwise it contains all of the |
Co-authored-by: Juniper Tyree <[email protected]>
This comment has been minimized.
This comment has been minimized.
"##, | ||
}, | ||
Lint { | ||
label: "contains", | ||
description: r##"# `contains` | ||
|
||
The tracking issue for this feature is: [#94047] | ||
|
||
[#94047]: https://github.com/rust-lang/rust/issues/94047 | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yonikremer see this comment too, you can revert this file
/// Performance: | ||
/// This method checks the whole iterator, which takes O(n) time. | ||
/// If the iterator is sorted, or a hash map please use the appropriate method instead. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// Performance: | |
/// This method checks the whole iterator, which takes O(n) time. | |
/// If the iterator is sorted, or a hash map please use the appropriate method instead. | |
/// This method checks the whole iterator, which is O(n). If the iterator is a sorted | |
/// slice, [`binary_search`](slice::binary_search) may be faster. If this is an iterator | |
/// on collections that have a `.contains()` or `.contains_key()` method (such as | |
/// [`HashMap`] or [`BTreeSet`]), using those methods directly will be faster. |
We can be more specific about what the appropriate methods are here. No section heading needed, I think rustdoc would have just merged Performance:
into the next paragraph anyway.
You can check the rendering with ./x doc library/core --open
#[test] | ||
fn test_happy_path_item_not_in_iterator() { | ||
assert!(![1i32, 2i32, 3i32].iter().contains(&4i32)); | ||
} | ||
|
||
#[test] | ||
fn test_edge_case_handling_none_values() { | ||
assert!([Some(2i32), Option::<i32>::None].iter().contains(&None)); | ||
assert!([Some(2i32), Option::<i32>::None].iter().contains(&Some(2i32))); | ||
} | ||
|
||
#[test] | ||
fn test_edge_case_handling_empty_iterator() { | ||
assert!(!Vec::<i32>::new().iter().contains(&1i32)); | ||
} | ||
|
||
#[test] | ||
fn test_edge_case_handling_iterator_with_duplicates() { | ||
assert!([1i32, 2i32, 2i32, 3i32].iter().contains(&2i32)); | ||
} | ||
|
||
#[test] | ||
/// Tests that short-circuiting works correctly when using `contains` | ||
/// When you run the function, it should move the iterator forward after the first appearance of the item | ||
fn test_short_circuiting() { | ||
let vector: Vec<i32> = vec![1i32, 2i32, 3i32, 1i32, 1i32]; | ||
let mut iterator = vector.into_iter(); | ||
assert!(iterator.contains(1i32)); | ||
assert_eq!(iterator.next(), Some(2)); | ||
assert!(!iterator.contains(4i32)); | ||
assert_eq!(iterator.next(), None); | ||
} | ||
|
||
#[test] | ||
fn test_edge_case_handling_iterator_with_custom_struct() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: since these tests only check .contains()
, they should have test_contains
in the name
/// assert!([1, 2, 3].iter().contains(&1)); | ||
/// assert!(![1, 2, 3].iter().contains(&4)); | ||
/// // You can check if a String is in a string slice iterator. | ||
/// assert!(["a", "b", "c"].iter().contains(&"b".to_owned())); | ||
/// // You can also check if a String iterator contains a string slice. | ||
/// assert!(["a".to_owned(), "b".to_owned(), "c".to_owned()].iter().contains(&"b")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe make it an example that you couldn't just use slice::contains(...)
on, like [1, 2, 3].iter().map(|x| x * 3).contains(6)
fn main() { | ||
let vec = Vec::new(); | ||
Vec::contains(&vec, &0); | ||
//~^ ERROR no function or associated item named `contains` found for struct `Vec<_, _>` in the current scope | ||
//~^ ERROR `Vec<_, _>` is not an iterator [E0599] | ||
//~| HELP the function `contains` is implemented on `[_]` | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bit of an unfortunate suggestion change for an unstable method. This was added in #100302, cc @compiler-errors since this will no longer test what it was intended to.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pls file a bug, we probably can filter by stability or sth idk
also please make sure this commit history gets squashed before approval -- 27 commits is a bit excessive, especially when a lot of the commits are removing/renaming and don't add much valuable information to the commit history lol |
That PR is a draft so it is not ready yet. That feature will fix the conflicts with You can try it locally to see the interactions. After you build you can do |
There are merge commits (commits with multiple parents) in your changes. We have a no merge policy so these commits will need to be removed for this pull request to be merged. You can start a rebase with the following commands:
The following commits are merge commits: |
The job Click to see the possible cause of the failure (guessed by this bot)
|
☔ The latest upstream changes (presumably #128313) made this pull request unmergeable. Please resolve the merge conflicts. |
@yonikremer this still has a merge confict that needs to be removed and pr rebased over in order for this to proceed. If you need help doing this let us know |
@yonikremer |
Refrences
the tracking issue and the feature proposal.
Here is my implementation, including the doc string and tests