From fdfb964a821a2f61353146629977eecafc0aa947 Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 18 Jan 2018 15:28:10 +0000 Subject: [PATCH 1/4] Document the behaviour of infinite iterators on potentially-computable methods MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It’s not entirely clear from the current documentation what behaviour calling a method such as `min` on an infinite iterator like `RangeFrom` is. One might expect this to terminate, but in fact, for infinite iterators, `min` is always nonterminating (at least in the standard library). This adds a quick note about this behaviour for clarification. --- src/libcore/iter/iterator.rs | 4 ++++ src/libcore/iter/mod.rs | 14 ++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 35cd7441c66bc..209a22d534a2e 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -24,6 +24,10 @@ fn _assert_is_object_safe(_: &Iterator) {} /// This is the main iterator trait. For more about the concept of iterators /// generally, please see the [module-level documentation]. In particular, you /// may want to know how to [implement `Iterator`][impl]. +/// +/// Note: Methods on infinite iterators that generally require traversing every +/// element to produce a result may not terminate, even on traits for which a +/// result is determinable in finite time. /// /// [module-level documentation]: index.html /// [impl]: index.html#implementing-iterator diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index 06c29b47bf921..3a5a72d1b87c1 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -297,8 +297,22 @@ //! ``` //! //! This will print the numbers `0` through `4`, each on their own line. +//! +//! Bear in mind that methods on infinite iterators, even those for which a +//! result can be computed in finite time, may not terminate. Specifically, +//! methods such as [`min`], which in the general case require traversing +//! every element in the iterator, are likely never to terminate for any +//! infinite iterators. +//! +//! ``` +//! let positives = 1..; +//! let least = positives.min().unwrap(); // Oh no! An infinite loop! +//! // `positives.min` causes an infinite loop, so we won't reach this point! +//! println!("The least positive number is {}.", least); +//! ``` //! //! [`take`]: trait.Iterator.html#method.take +//! [`min`]: trait.Iterator.html#method.min #![stable(feature = "rust1", since = "1.0.0")] From 91668fbf230b388330da9591ba310c7e35ef9611 Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 18 Jan 2018 17:49:32 +0000 Subject: [PATCH 2/4] Make example no_run --- src/libcore/iter/iterator.rs | 2 +- src/libcore/iter/mod.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 209a22d534a2e..da9af214207b6 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -24,7 +24,7 @@ fn _assert_is_object_safe(_: &Iterator) {} /// This is the main iterator trait. For more about the concept of iterators /// generally, please see the [module-level documentation]. In particular, you /// may want to know how to [implement `Iterator`][impl]. -/// +/// /// Note: Methods on infinite iterators that generally require traversing every /// element to produce a result may not terminate, even on traits for which a /// result is determinable in finite time. diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index 3a5a72d1b87c1..ae10ac385ab50 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -297,14 +297,14 @@ //! ``` //! //! This will print the numbers `0` through `4`, each on their own line. -//! +//! //! Bear in mind that methods on infinite iterators, even those for which a //! result can be computed in finite time, may not terminate. Specifically, //! methods such as [`min`], which in the general case require traversing //! every element in the iterator, are likely never to terminate for any //! infinite iterators. -//! -//! ``` +//! +//! ```no_run //! let positives = 1..; //! let least = positives.min().unwrap(); // Oh no! An infinite loop! //! // `positives.min` causes an infinite loop, so we won't reach this point! From 0be51730ee51c009cdd7cd5f77fcd1f2b898f5b7 Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 19 Jan 2018 21:16:34 +0000 Subject: [PATCH 3/4] Adjust language as per suggestions --- src/libcore/iter/iterator.rs | 8 ++++---- src/libcore/iter/mod.rs | 12 +++++++----- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index da9af214207b6..23fded0669a6f 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -25,10 +25,6 @@ fn _assert_is_object_safe(_: &Iterator) {} /// generally, please see the [module-level documentation]. In particular, you /// may want to know how to [implement `Iterator`][impl]. /// -/// Note: Methods on infinite iterators that generally require traversing every -/// element to produce a result may not terminate, even on traits for which a -/// result is determinable in finite time. -/// /// [module-level documentation]: index.html /// [impl]: index.html#implementing-iterator #[stable(feature = "rust1", since = "1.0.0")] @@ -1430,6 +1426,10 @@ pub trait Iterator { /// Folding is useful whenever you have a collection of something, and want /// to produce a single value from it. /// + /// Note: `fold()`, and similar methods that traverse the entire iterator, + /// may not terminate for infinite iterators, even on traits for which a + /// result is determinable in finite time. + /// /// # Examples /// /// Basic usage: diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index ae10ac385ab50..d1fdedd1b235f 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -299,15 +299,17 @@ //! This will print the numbers `0` through `4`, each on their own line. //! //! Bear in mind that methods on infinite iterators, even those for which a -//! result can be computed in finite time, may not terminate. Specifically, -//! methods such as [`min`], which in the general case require traversing -//! every element in the iterator, are likely never to terminate for any -//! infinite iterators. +//! result can be determined mathematically in finite time, may not terminate. +//! Specifically, methods such as [`min`], which in the general case require +//! traversing every element in the iterator, are likely not to return +//! successfully for any infinite iterators. //! //! ```no_run //! let positives = 1..; //! let least = positives.min().unwrap(); // Oh no! An infinite loop! -//! // `positives.min` causes an infinite loop, so we won't reach this point! +//! // `positives.min` will either overflow and panic (in debug mode), +//! // or cause an infinite loop (in release mode), so we won't reach +//! // this point! //! println!("The least positive number is {}.", least); //! ``` //! From f129374d11d51ca23d85bc678fbc1ed4e7082ab1 Mon Sep 17 00:00:00 2001 From: varkor Date: Sun, 21 Jan 2018 19:45:27 +0000 Subject: [PATCH 4/4] Use repeat instead of RangeFrom --- src/libcore/iter/mod.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index d1fdedd1b235f..4490f15f446fe 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -305,12 +305,10 @@ //! successfully for any infinite iterators. //! //! ```no_run -//! let positives = 1..; -//! let least = positives.min().unwrap(); // Oh no! An infinite loop! -//! // `positives.min` will either overflow and panic (in debug mode), -//! // or cause an infinite loop (in release mode), so we won't reach -//! // this point! -//! println!("The least positive number is {}.", least); +//! let ones = std::iter::repeat(1); +//! let least = ones.min().unwrap(); // Oh no! An infinite loop! +//! // `ones.min()` causes an infinite loop, so we won't reach this point! +//! println!("The smallest number one is {}.", least); //! ``` //! //! [`take`]: trait.Iterator.html#method.take