summaryrefslogtreecommitdiffstats
path: root/library/core/src/ops
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-07 05:48:48 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-07 05:48:48 +0000
commitef24de24a82fe681581cc130f342363c47c0969a (patch)
tree0d494f7e1a38b95c92426f58fe6eaa877303a86c /library/core/src/ops
parentReleasing progress-linux version 1.74.1+dfsg1-1~progress7.99u1. (diff)
downloadrustc-ef24de24a82fe681581cc130f342363c47c0969a.tar.xz
rustc-ef24de24a82fe681581cc130f342363c47c0969a.zip
Merging upstream version 1.75.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'library/core/src/ops')
-rw-r--r--library/core/src/ops/coroutine.rs139
-rw-r--r--library/core/src/ops/deref.rs163
-rw-r--r--library/core/src/ops/function.rs24
-rw-r--r--library/core/src/ops/generator.rs135
-rw-r--r--library/core/src/ops/index.rs2
-rw-r--r--library/core/src/ops/mod.rs10
-rw-r--r--library/core/src/ops/range.rs8
-rw-r--r--library/core/src/ops/try_trait.rs45
8 files changed, 298 insertions, 228 deletions
diff --git a/library/core/src/ops/coroutine.rs b/library/core/src/ops/coroutine.rs
new file mode 100644
index 000000000..cd5ca988f
--- /dev/null
+++ b/library/core/src/ops/coroutine.rs
@@ -0,0 +1,139 @@
+use crate::marker::Unpin;
+use crate::pin::Pin;
+
+/// The result of a coroutine resumption.
+///
+/// This enum is returned from the `Coroutine::resume` method and indicates the
+/// possible return values of a coroutine. Currently this corresponds to either
+/// a suspension point (`Yielded`) or a termination point (`Complete`).
+#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
+#[cfg_attr(bootstrap, lang = "generator_state")]
+#[cfg_attr(not(bootstrap), lang = "coroutine_state")]
+#[unstable(feature = "coroutine_trait", issue = "43122")]
+pub enum CoroutineState<Y, R> {
+ /// The coroutine suspended with a value.
+ ///
+ /// This state indicates that a coroutine has been suspended, and typically
+ /// corresponds to a `yield` statement. The value provided in this variant
+ /// corresponds to the expression passed to `yield` and allows coroutines to
+ /// provide a value each time they yield.
+ Yielded(Y),
+
+ /// The coroutine completed with a return value.
+ ///
+ /// This state indicates that a coroutine has finished execution with the
+ /// provided value. Once a coroutine has returned `Complete` it is
+ /// considered a programmer error to call `resume` again.
+ Complete(R),
+}
+
+/// The trait implemented by builtin coroutine types.
+///
+/// Coroutines are currently an
+/// experimental language feature in Rust. Added in [RFC 2033] coroutines are
+/// currently intended to primarily provide a building block for async/await
+/// syntax but will likely extend to also providing an ergonomic definition for
+/// iterators and other primitives.
+///
+/// The syntax and semantics for coroutines is unstable and will require a
+/// further RFC for stabilization. At this time, though, the syntax is
+/// closure-like:
+///
+/// ```rust
+/// #![cfg_attr(bootstrap, feature(generators))]
+/// #![cfg_attr(not(bootstrap), feature(coroutines))]
+/// #![feature(coroutine_trait)]
+///
+/// use std::ops::{Coroutine, CoroutineState};
+/// use std::pin::Pin;
+///
+/// fn main() {
+/// let mut coroutine = || {
+/// yield 1;
+/// "foo"
+/// };
+///
+/// match Pin::new(&mut coroutine).resume(()) {
+/// CoroutineState::Yielded(1) => {}
+/// _ => panic!("unexpected return from resume"),
+/// }
+/// match Pin::new(&mut coroutine).resume(()) {
+/// CoroutineState::Complete("foo") => {}
+/// _ => panic!("unexpected return from resume"),
+/// }
+/// }
+/// ```
+///
+/// More documentation of coroutines can be found in the [unstable book].
+///
+/// [RFC 2033]: https://github.com/rust-lang/rfcs/pull/2033
+/// [unstable book]: ../../unstable-book/language-features/coroutines.html
+#[cfg_attr(bootstrap, lang = "generator")]
+#[cfg_attr(not(bootstrap), lang = "coroutine")]
+#[unstable(feature = "coroutine_trait", issue = "43122")]
+#[fundamental]
+pub trait Coroutine<R = ()> {
+ /// The type of value this coroutine yields.
+ ///
+ /// This associated type corresponds to the `yield` expression and the
+ /// values which are allowed to be returned each time a coroutine yields.
+ /// For example an iterator-as-a-coroutine would likely have this type as
+ /// `T`, the type being iterated over.
+ type Yield;
+
+ /// The type of value this coroutine returns.
+ ///
+ /// This corresponds to the type returned from a coroutine either with a
+ /// `return` statement or implicitly as the last expression of a coroutine
+ /// literal. For example futures would use this as `Result<T, E>` as it
+ /// represents a completed future.
+ type Return;
+
+ /// Resumes the execution of this coroutine.
+ ///
+ /// This function will resume execution of the coroutine or start execution
+ /// if it hasn't already. This call will return back into the coroutine's
+ /// last suspension point, resuming execution from the latest `yield`. The
+ /// coroutine will continue executing until it either yields or returns, at
+ /// which point this function will return.
+ ///
+ /// # Return value
+ ///
+ /// The `CoroutineState` enum returned from this function indicates what
+ /// state the coroutine is in upon returning. If the `Yielded` variant is
+ /// returned then the coroutine has reached a suspension point and a value
+ /// has been yielded out. Coroutines in this state are available for
+ /// resumption at a later point.
+ ///
+ /// If `Complete` is returned then the coroutine has completely finished
+ /// with the value provided. It is invalid for the coroutine to be resumed
+ /// again.
+ ///
+ /// # Panics
+ ///
+ /// This function may panic if it is called after the `Complete` variant has
+ /// been returned previously. While coroutine literals in the language are
+ /// guaranteed to panic on resuming after `Complete`, this is not guaranteed
+ /// for all implementations of the `Coroutine` trait.
+ fn resume(self: Pin<&mut Self>, arg: R) -> CoroutineState<Self::Yield, Self::Return>;
+}
+
+#[unstable(feature = "coroutine_trait", issue = "43122")]
+impl<G: ?Sized + Coroutine<R>, R> Coroutine<R> for Pin<&mut G> {
+ type Yield = G::Yield;
+ type Return = G::Return;
+
+ fn resume(mut self: Pin<&mut Self>, arg: R) -> CoroutineState<Self::Yield, Self::Return> {
+ G::resume((*self).as_mut(), arg)
+ }
+}
+
+#[unstable(feature = "coroutine_trait", issue = "43122")]
+impl<G: ?Sized + Coroutine<R> + Unpin, R> Coroutine<R> for &mut G {
+ type Yield = G::Yield;
+ type Return = G::Return;
+
+ fn resume(mut self: Pin<&mut Self>, arg: R) -> CoroutineState<Self::Yield, Self::Return> {
+ G::resume(Pin::new(&mut *self), arg)
+ }
+}
diff --git a/library/core/src/ops/deref.rs b/library/core/src/ops/deref.rs
index 911761c6e..99adbb915 100644
--- a/library/core/src/ops/deref.rs
+++ b/library/core/src/ops/deref.rs
@@ -3,40 +3,107 @@
/// In addition to being used for explicit dereferencing operations with the
/// (unary) `*` operator in immutable contexts, `Deref` is also used implicitly
/// by the compiler in many circumstances. This mechanism is called
-/// ['`Deref` coercion'][more]. In mutable contexts, [`DerefMut`] is used.
+/// ["`Deref` coercion"][coercion]. In mutable contexts, [`DerefMut`] is used and
+/// mutable deref coercion similarly occurs.
///
-/// Implementing `Deref` for smart pointers makes accessing the data behind them
-/// convenient, which is why they implement `Deref`. On the other hand, the
-/// rules regarding `Deref` and [`DerefMut`] were designed specifically to
-/// accommodate smart pointers. Because of this, **`Deref` should only be
-/// implemented for smart pointers** to avoid confusion.
+/// **Warning:** Deref coercion is a powerful language feature which has
+/// far-reaching implications for every type that implements `Deref`. The
+/// compiler will silently insert calls to `Deref::deref`. For this reason, one
+/// should be careful about implementing `Deref` and only do so when deref
+/// coercion is desirable. See [below][implementing] for advice on when this is
+/// typically desirable or undesirable.
///
-/// For similar reasons, **this trait should never fail**. Failure during
-/// dereferencing can be extremely confusing when `Deref` is invoked implicitly.
+/// Types that implement `Deref` or `DerefMut` are often called "smart
+/// pointers" and the mechanism of deref coercion has been specifically designed
+/// to facilitate the pointer-like behaviour that name suggests. Often, the
+/// purpose of a "smart pointer" type is to change the ownership semantics
+/// of a contained value (for example, [`Rc`][rc] or [`Cow`][cow]) or the
+/// storage semantics of a contained value (for example, [`Box`][box]).
///
-/// Violating these requirements is a logic error. The behavior resulting from a logic error is not
-/// specified, but users of the trait must ensure that such logic errors do *not* result in
-/// undefined behavior. This means that `unsafe` code **must not** rely on the correctness of this
-/// method.
+/// # Deref coercion
///
-/// # More on `Deref` coercion
+/// If `T` implements `Deref<Target = U>`, and `v` is a value of type `T`, then:
///
-/// If `T` implements `Deref<Target = U>`, and `x` is a value of type `T`, then:
-///
-/// * In immutable contexts, `*x` (where `T` is neither a reference nor a raw pointer)
-/// is equivalent to `*Deref::deref(&x)`.
+/// * In immutable contexts, `*v` (where `T` is neither a reference nor a raw
+/// pointer) is equivalent to `*Deref::deref(&v)`.
/// * Values of type `&T` are coerced to values of type `&U`
-/// * `T` implicitly implements all the (immutable) methods of the type `U`.
+/// * `T` implicitly implements all the methods of the type `U` which take the
+/// `&self` receiver.
///
/// For more details, visit [the chapter in *The Rust Programming Language*][book]
/// as well as the reference sections on [the dereference operator][ref-deref-op],
-/// [method resolution] and [type coercions].
+/// [method resolution], and [type coercions].
+///
+/// # When to implement `Deref` or `DerefMut`
+///
+/// The same advice applies to both deref traits. In general, deref traits
+/// **should** be implemented if:
+///
+/// 1. a value of the type transparently behaves like a value of the target
+/// type;
+/// 1. the implementation of the deref function is cheap; and
+/// 1. users of the type will not be surprised by any deref coercion behaviour.
+///
+/// In general, deref traits **should not** be implemented if:
+///
+/// 1. the deref implementations could fail unexpectedly; or
+/// 1. the type has methods that are likely to collide with methods on the
+/// target type; or
+/// 1. committing to deref coercion as part of the public API is not desirable.
+///
+/// Note that there's a large difference between implementing deref traits
+/// generically over many target types, and doing so only for specific target
+/// types.
+///
+/// Generic implementations, such as for [`Box<T>`][box] (which is generic over
+/// every type and dereferences to `T`) should be careful to provide few or no
+/// methods, since the target type is unknown and therefore every method could
+/// collide with one on the target type, causing confusion for users.
+/// `impl<T> Box<T>` has no methods (though several associated functions),
+/// partly for this reason.
+///
+/// Specific implementations, such as for [`String`][string] (whose `Deref`
+/// implementation has `Target = str`) can have many methods, since avoiding
+/// collision is much easier. `String` and `str` both have many methods, and
+/// `String` additionally behaves as if it has every method of `str` because of
+/// deref coercion. The implementing type may also be generic while the
+/// implementation is still specific in this sense; for example, [`Vec<T>`][vec]
+/// dereferences to `[T]`, so methods of `T` are not applicable.
+///
+/// Consider also that deref coericion means that deref traits are a much larger
+/// part of a type's public API than any other trait as it is implicitly called
+/// by the compiler. Therefore, it is advisable to consider whether this is
+/// something you are comfortable supporting as a public API.
+///
+/// The [`AsRef`] and [`Borrow`][core::borrow::Borrow] traits have very similar
+/// signatures to `Deref`. It may be desirable to implement either or both of
+/// these, whether in addition to or rather than deref traits. See their
+/// documentation for details.
+///
+/// # Fallibility
+///
+/// **This trait's method should never unexpectedly fail**. Deref coercion means
+/// the compiler will often insert calls to `Deref::deref` implicitly. Failure
+/// during dereferencing can be extremely confusing when `Deref` is invoked
+/// implicitly. In the majority of uses it should be infallible, though it may
+/// be acceptable to panic if the type is misused through programmer error, for
+/// example.
+///
+/// However, infallibility is not enforced and therefore not guaranteed.
+/// As such, `unsafe` code should not rely on infallibility in general for
+/// soundness.
///
/// [book]: ../../book/ch15-02-deref.html
-/// [more]: #more-on-deref-coercion
+/// [coercion]: #deref-coercion
+/// [implementing]: #when-to-implement-deref-or-derefmut
/// [ref-deref-op]: ../../reference/expressions/operator-expr.html#the-dereference-operator
/// [method resolution]: ../../reference/expressions/method-call-expr.html
/// [type coercions]: ../../reference/type-coercions.html
+/// [box]: ../../alloc/boxed/struct.Box.html
+/// [string]: ../../alloc/string/struct.String.html
+/// [vec]: ../../alloc/vec/struct.Vec.html
+/// [rc]: ../../alloc/rc/struct.Rc.html
+/// [cow]: ../../alloc/borrow/enum.Cow.html
///
/// # Examples
///
@@ -107,30 +174,29 @@ impl<T: ?Sized> Deref for &mut T {
/// In addition to being used for explicit dereferencing operations with the
/// (unary) `*` operator in mutable contexts, `DerefMut` is also used implicitly
/// by the compiler in many circumstances. This mechanism is called
-/// ['`Deref` coercion'][more]. In immutable contexts, [`Deref`] is used.
-///
-/// Implementing `DerefMut` for smart pointers makes mutating the data behind
-/// them convenient, which is why they implement `DerefMut`. On the other hand,
-/// the rules regarding [`Deref`] and `DerefMut` were designed specifically to
-/// accommodate smart pointers. Because of this, **`DerefMut` should only be
-/// implemented for smart pointers** to avoid confusion.
+/// ["mutable deref coercion"][coercion]. In immutable contexts, [`Deref`] is used.
///
-/// For similar reasons, **this trait should never fail**. Failure during
-/// dereferencing can be extremely confusing when `DerefMut` is invoked
-/// implicitly.
+/// **Warning:** Deref coercion is a powerful language feature which has
+/// far-reaching implications for every type that implements `DerefMut`. The
+/// compiler will silently insert calls to `DerefMut::deref_mut`. For this
+/// reason, one should be careful about implementing `DerefMut` and only do so
+/// when mutable deref coercion is desirable. See [the `Deref` docs][implementing]
+/// for advice on when this is typically desirable or undesirable.
///
-/// Violating these requirements is a logic error. The behavior resulting from a logic error is not
-/// specified, but users of the trait must ensure that such logic errors do *not* result in
-/// undefined behavior. This means that `unsafe` code **must not** rely on the correctness of this
-/// method.
+/// Types that implement `DerefMut` or `Deref` are often called "smart
+/// pointers" and the mechanism of deref coercion has been specifically designed
+/// to facilitate the pointer-like behaviour that name suggests. Often, the
+/// purpose of a "smart pointer" type is to change the ownership semantics
+/// of a contained value (for example, [`Rc`][rc] or [`Cow`][cow]) or the
+/// storage semantics of a contained value (for example, [`Box`][box]).
///
-/// # More on `Deref` coercion
+/// # Mutable deref coercion
///
-/// If `T` implements `DerefMut<Target = U>`, and `x` is a value of type `T`,
+/// If `T` implements `DerefMut<Target = U>`, and `v` is a value of type `T`,
/// then:
///
-/// * In mutable contexts, `*x` (where `T` is neither a reference nor a raw pointer)
-/// is equivalent to `*DerefMut::deref_mut(&mut x)`.
+/// * In mutable contexts, `*v` (where `T` is neither a reference nor a raw pointer)
+/// is equivalent to `*DerefMut::deref_mut(&mut v)`.
/// * Values of type `&mut T` are coerced to values of type `&mut U`
/// * `T` implicitly implements all the (mutable) methods of the type `U`.
///
@@ -138,11 +204,29 @@ impl<T: ?Sized> Deref for &mut T {
/// as well as the reference sections on [the dereference operator][ref-deref-op],
/// [method resolution] and [type coercions].
///
+/// # Fallibility
+///
+/// **This trait's method should never unexpectedly fail**. Deref coercion means
+/// the compiler will often insert calls to `DerefMut::deref_mut` implicitly.
+/// Failure during dereferencing can be extremely confusing when `DerefMut` is
+/// invoked implicitly. In the majority of uses it should be infallible, though
+/// it may be acceptable to panic if the type is misused through programmer
+/// error, for example.
+///
+/// However, infallibility is not enforced and therefore not guaranteed.
+/// As such, `unsafe` code should not rely on infallibility in general for
+/// soundness.
+///
/// [book]: ../../book/ch15-02-deref.html
-/// [more]: #more-on-deref-coercion
+/// [coercion]: #mutable-deref-coercion
+/// [implementing]: Deref#when-to-implement-deref-or-derefmut
/// [ref-deref-op]: ../../reference/expressions/operator-expr.html#the-dereference-operator
/// [method resolution]: ../../reference/expressions/method-call-expr.html
/// [type coercions]: ../../reference/type-coercions.html
+/// [box]: ../../alloc/boxed/struct.Box.html
+/// [string]: ../../alloc/string/struct.String.html
+/// [rc]: ../../alloc/rc/struct.Rc.html
+/// [cow]: ../../alloc/borrow/enum.Cow.html
///
/// # Examples
///
@@ -180,6 +264,7 @@ impl<T: ?Sized> Deref for &mut T {
pub trait DerefMut: Deref {
/// Mutably dereferences the value.
#[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_diagnostic_item = "deref_mut_method"]
fn deref_mut(&mut self) -> &mut Self::Target;
}
diff --git a/library/core/src/ops/function.rs b/library/core/src/ops/function.rs
index 20f0bba4c..51e304dd7 100644
--- a/library/core/src/ops/function.rs
+++ b/library/core/src/ops/function.rs
@@ -56,7 +56,7 @@ use crate::marker::Tuple;
#[lang = "fn"]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_paren_sugar]
-#[rustc_on_unimplemented(
+#[cfg_attr(not(bootstrap), rustc_on_unimplemented(
on(
Args = "()",
note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`"
@@ -67,9 +67,9 @@ use crate::marker::Tuple;
// SAFETY: tidy is not smart enough to tell that the below unsafe block is a string
label = "call the function in a closure: `|| unsafe {{ /* code */ }}`"
),
- message = "expected a `{Fn}<{Args}>` closure, found `{Self}`",
- label = "expected an `Fn<{Args}>` closure, found `{Self}`"
-)]
+ message = "expected a `{Trait}` closure, found `{Self}`",
+ label = "expected an `{Trait}` closure, found `{Self}`"
+))]
#[fundamental] // so that regex can rely that `&str: !FnMut`
#[must_use = "closures are lazy and do nothing unless called"]
// FIXME(effects) #[const_trait]
@@ -143,7 +143,7 @@ pub trait Fn<Args: Tuple>: FnMut<Args> {
#[lang = "fn_mut"]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_paren_sugar]
-#[rustc_on_unimplemented(
+#[cfg_attr(not(bootstrap), rustc_on_unimplemented(
on(
Args = "()",
note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`"
@@ -154,9 +154,9 @@ pub trait Fn<Args: Tuple>: FnMut<Args> {
// SAFETY: tidy is not smart enough to tell that the below unsafe block is a string
label = "call the function in a closure: `|| unsafe {{ /* code */ }}`"
),
- message = "expected a `{FnMut}<{Args}>` closure, found `{Self}`",
- label = "expected an `FnMut<{Args}>` closure, found `{Self}`"
-)]
+ message = "expected a `{Trait}` closure, found `{Self}`",
+ label = "expected an `{Trait}` closure, found `{Self}`"
+))]
#[fundamental] // so that regex can rely that `&str: !FnMut`
#[must_use = "closures are lazy and do nothing unless called"]
// FIXME(effects) #[const_trait]
@@ -222,7 +222,7 @@ pub trait FnMut<Args: Tuple>: FnOnce<Args> {
#[lang = "fn_once"]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_paren_sugar]
-#[rustc_on_unimplemented(
+#[cfg_attr(not(bootstrap), rustc_on_unimplemented(
on(
Args = "()",
note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`"
@@ -233,9 +233,9 @@ pub trait FnMut<Args: Tuple>: FnOnce<Args> {
// SAFETY: tidy is not smart enough to tell that the below unsafe block is a string
label = "call the function in a closure: `|| unsafe {{ /* code */ }}`"
),
- message = "expected a `{FnOnce}<{Args}>` closure, found `{Self}`",
- label = "expected an `FnOnce<{Args}>` closure, found `{Self}`"
-)]
+ message = "expected a `{Trait}` closure, found `{Self}`",
+ label = "expected an `{Trait}` closure, found `{Self}`"
+))]
#[fundamental] // so that regex can rely that `&str: !FnMut`
#[must_use = "closures are lazy and do nothing unless called"]
// FIXME(effects) #[const_trait]
diff --git a/library/core/src/ops/generator.rs b/library/core/src/ops/generator.rs
deleted file mode 100644
index fee4beb1e..000000000
--- a/library/core/src/ops/generator.rs
+++ /dev/null
@@ -1,135 +0,0 @@
-use crate::marker::Unpin;
-use crate::pin::Pin;
-
-/// The result of a generator resumption.
-///
-/// This enum is returned from the `Generator::resume` method and indicates the
-/// possible return values of a generator. Currently this corresponds to either
-/// a suspension point (`Yielded`) or a termination point (`Complete`).
-#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
-#[lang = "generator_state"]
-#[unstable(feature = "generator_trait", issue = "43122")]
-pub enum GeneratorState<Y, R> {
- /// The generator suspended with a value.
- ///
- /// This state indicates that a generator has been suspended, and typically
- /// corresponds to a `yield` statement. The value provided in this variant
- /// corresponds to the expression passed to `yield` and allows generators to
- /// provide a value each time they yield.
- Yielded(Y),
-
- /// The generator completed with a return value.
- ///
- /// This state indicates that a generator has finished execution with the
- /// provided value. Once a generator has returned `Complete` it is
- /// considered a programmer error to call `resume` again.
- Complete(R),
-}
-
-/// The trait implemented by builtin generator types.
-///
-/// Generators, also commonly referred to as coroutines, are currently an
-/// experimental language feature in Rust. Added in [RFC 2033] generators are
-/// currently intended to primarily provide a building block for async/await
-/// syntax but will likely extend to also providing an ergonomic definition for
-/// iterators and other primitives.
-///
-/// The syntax and semantics for generators is unstable and will require a
-/// further RFC for stabilization. At this time, though, the syntax is
-/// closure-like:
-///
-/// ```rust
-/// #![feature(generators, generator_trait)]
-///
-/// use std::ops::{Generator, GeneratorState};
-/// use std::pin::Pin;
-///
-/// fn main() {
-/// let mut generator = || {
-/// yield 1;
-/// "foo"
-/// };
-///
-/// match Pin::new(&mut generator).resume(()) {
-/// GeneratorState::Yielded(1) => {}
-/// _ => panic!("unexpected return from resume"),
-/// }
-/// match Pin::new(&mut generator).resume(()) {
-/// GeneratorState::Complete("foo") => {}
-/// _ => panic!("unexpected return from resume"),
-/// }
-/// }
-/// ```
-///
-/// More documentation of generators can be found in the [unstable book].
-///
-/// [RFC 2033]: https://github.com/rust-lang/rfcs/pull/2033
-/// [unstable book]: ../../unstable-book/language-features/generators.html
-#[lang = "generator"]
-#[unstable(feature = "generator_trait", issue = "43122")]
-#[fundamental]
-pub trait Generator<R = ()> {
- /// The type of value this generator yields.
- ///
- /// This associated type corresponds to the `yield` expression and the
- /// values which are allowed to be returned each time a generator yields.
- /// For example an iterator-as-a-generator would likely have this type as
- /// `T`, the type being iterated over.
- type Yield;
-
- /// The type of value this generator returns.
- ///
- /// This corresponds to the type returned from a generator either with a
- /// `return` statement or implicitly as the last expression of a generator
- /// literal. For example futures would use this as `Result<T, E>` as it
- /// represents a completed future.
- type Return;
-
- /// Resumes the execution of this generator.
- ///
- /// This function will resume execution of the generator or start execution
- /// if it hasn't already. This call will return back into the generator's
- /// last suspension point, resuming execution from the latest `yield`. The
- /// generator will continue executing until it either yields or returns, at
- /// which point this function will return.
- ///
- /// # Return value
- ///
- /// The `GeneratorState` enum returned from this function indicates what
- /// state the generator is in upon returning. If the `Yielded` variant is
- /// returned then the generator has reached a suspension point and a value
- /// has been yielded out. Generators in this state are available for
- /// resumption at a later point.
- ///
- /// If `Complete` is returned then the generator has completely finished
- /// with the value provided. It is invalid for the generator to be resumed
- /// again.
- ///
- /// # Panics
- ///
- /// This function may panic if it is called after the `Complete` variant has
- /// been returned previously. While generator literals in the language are
- /// guaranteed to panic on resuming after `Complete`, this is not guaranteed
- /// for all implementations of the `Generator` trait.
- fn resume(self: Pin<&mut Self>, arg: R) -> GeneratorState<Self::Yield, Self::Return>;
-}
-
-#[unstable(feature = "generator_trait", issue = "43122")]
-impl<G: ?Sized + Generator<R>, R> Generator<R> for Pin<&mut G> {
- type Yield = G::Yield;
- type Return = G::Return;
-
- fn resume(mut self: Pin<&mut Self>, arg: R) -> GeneratorState<Self::Yield, Self::Return> {
- G::resume((*self).as_mut(), arg)
- }
-}
-
-#[unstable(feature = "generator_trait", issue = "43122")]
-impl<G: ?Sized + Generator<R> + Unpin, R> Generator<R> for &mut G {
- type Yield = G::Yield;
- type Return = G::Return;
-
- fn resume(mut self: Pin<&mut Self>, arg: R) -> GeneratorState<Self::Yield, Self::Return> {
- G::resume(Pin::new(&mut *self), arg)
- }
-}
diff --git a/library/core/src/ops/index.rs b/library/core/src/ops/index.rs
index f4649be54..6ceee4637 100644
--- a/library/core/src/ops/index.rs
+++ b/library/core/src/ops/index.rs
@@ -153,7 +153,7 @@ see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#ind
see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
),
on(
- any(_Self = "alloc::string::String", _Self = "std::string::String"),
+ _Self = "alloc::string::String",
note = "you can use `.chars().nth()` or `.bytes().nth()`
see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
),
diff --git a/library/core/src/ops/mod.rs b/library/core/src/ops/mod.rs
index 97d9b750d..35654d0b8 100644
--- a/library/core/src/ops/mod.rs
+++ b/library/core/src/ops/mod.rs
@@ -8,8 +8,8 @@
//! trait, but since the assignment operator (`=`) has no backing trait, there
//! is no way of overloading its semantics. Additionally, this module does not
//! provide any mechanism to create new operators. If traitless overloading or
-//! custom operators are required, you should look toward macros or compiler
-//! plugins to extend Rust's syntax.
+//! custom operators are required, you should look toward macros to extend
+//! Rust's syntax.
//!
//! Implementations of operator traits should be unsurprising in their
//! respective contexts, keeping in mind their usual meanings and
@@ -141,10 +141,10 @@
mod arith;
mod bit;
mod control_flow;
+mod coroutine;
mod deref;
mod drop;
mod function;
-mod generator;
mod index;
mod index_range;
mod range;
@@ -198,8 +198,8 @@ pub use self::try_trait::Residual;
pub(crate) use self::try_trait::{ChangeOutputType, NeverShortCircuit};
-#[unstable(feature = "generator_trait", issue = "43122")]
-pub use self::generator::{Generator, GeneratorState};
+#[unstable(feature = "coroutine_trait", issue = "43122")]
+pub use self::coroutine::{Coroutine, CoroutineState};
#[unstable(feature = "coerce_unsized", issue = "18598")]
pub use self::unsize::CoerceUnsized;
diff --git a/library/core/src/ops/range.rs b/library/core/src/ops/range.rs
index cc596293c..b419a738f 100644
--- a/library/core/src/ops/range.rs
+++ b/library/core/src/ops/range.rs
@@ -115,6 +115,7 @@ impl<Idx: PartialOrd<Idx>> Range<Idx> {
/// assert!(!(0.0..f32::NAN).contains(&0.5));
/// assert!(!(f32::NAN..1.0).contains(&0.5));
/// ```
+ #[inline]
#[stable(feature = "range_contains", since = "1.35.0")]
pub fn contains<U>(&self, item: &U) -> bool
where
@@ -141,6 +142,7 @@ impl<Idx: PartialOrd<Idx>> Range<Idx> {
/// assert!( (3.0..f32::NAN).is_empty());
/// assert!( (f32::NAN..5.0).is_empty());
/// ```
+ #[inline]
#[stable(feature = "range_is_empty", since = "1.47.0")]
pub fn is_empty(&self) -> bool {
!(self.start < self.end)
@@ -213,6 +215,7 @@ impl<Idx: PartialOrd<Idx>> RangeFrom<Idx> {
/// assert!(!(0.0..).contains(&f32::NAN));
/// assert!(!(f32::NAN..).contains(&0.5));
/// ```
+ #[inline]
#[stable(feature = "range_contains", since = "1.35.0")]
pub fn contains<U>(&self, item: &U) -> bool
where
@@ -294,6 +297,7 @@ impl<Idx: PartialOrd<Idx>> RangeTo<Idx> {
/// assert!(!(..1.0).contains(&f32::NAN));
/// assert!(!(..f32::NAN).contains(&0.5));
/// ```
+ #[inline]
#[stable(feature = "range_contains", since = "1.35.0")]
pub fn contains<U>(&self, item: &U) -> bool
where
@@ -500,6 +504,7 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
/// // Precise field values are unspecified here
/// assert!(!r.contains(&3) && !r.contains(&5));
/// ```
+ #[inline]
#[stable(feature = "range_contains", since = "1.35.0")]
pub fn contains<U>(&self, item: &U) -> bool
where
@@ -613,6 +618,7 @@ impl<Idx: PartialOrd<Idx>> RangeToInclusive<Idx> {
/// assert!(!(..=1.0).contains(&f32::NAN));
/// assert!(!(..=f32::NAN).contains(&0.5));
/// ```
+ #[inline]
#[stable(feature = "range_contains", since = "1.35.0")]
pub fn contains<U>(&self, item: &U) -> bool
where
@@ -758,6 +764,7 @@ impl<T: Clone> Bound<&T> {
/// `RangeBounds` is implemented by Rust's built-in range types, produced
/// by range syntax like `..`, `a..`, `..b`, `..=c`, `d..e`, or `f..=g`.
#[stable(feature = "collections_range", since = "1.28.0")]
+#[rustc_diagnostic_item = "RangeBounds"]
pub trait RangeBounds<T: ?Sized> {
/// Start index bound.
///
@@ -807,6 +814,7 @@ pub trait RangeBounds<T: ?Sized> {
/// assert!(!(0.0..1.0).contains(&f32::NAN));
/// assert!(!(0.0..f32::NAN).contains(&0.5));
/// assert!(!(f32::NAN..1.0).contains(&0.5));
+ #[inline]
#[stable(feature = "range_contains", since = "1.35.0")]
fn contains<U>(&self, item: &U) -> bool
where
diff --git a/library/core/src/ops/try_trait.rs b/library/core/src/ops/try_trait.rs
index 17625dacc..3f8c8efd4 100644
--- a/library/core/src/ops/try_trait.rs
+++ b/library/core/src/ops/try_trait.rs
@@ -226,14 +226,8 @@ pub trait Try: FromResidual {
on(
all(
from_desugaring = "QuestionMark",
- any(
- _Self = "core::result::Result<T, E>",
- _Self = "std::result::Result<T, E>",
- ),
- any(
- R = "core::option::Option<core::convert::Infallible>",
- R = "std::option::Option<std::convert::Infallible>",
- )
+ _Self = "core::result::Result<T, E>",
+ R = "core::option::Option<core::convert::Infallible>",
),
message = "the `?` operator can only be used on `Result`s, not `Option`s, \
in {ItemContext} that returns `Result`",
@@ -243,10 +237,7 @@ pub trait Try: FromResidual {
on(
all(
from_desugaring = "QuestionMark",
- any(
- _Self = "core::result::Result<T, E>",
- _Self = "std::result::Result<T, E>",
- )
+ _Self = "core::result::Result<T, E>",
),
// There's a special error message in the trait selection code for
// `From` in `?`, so this is not shown for result-in-result errors,
@@ -259,14 +250,8 @@ pub trait Try: FromResidual {
on(
all(
from_desugaring = "QuestionMark",
- any(
- _Self = "core::option::Option<T>",
- _Self = "std::option::Option<T>",
- ),
- any(
- R = "core::result::Result<T, E>",
- R = "std::result::Result<T, E>",
- )
+ _Self = "core::option::Option<T>",
+ R = "core::result::Result<T, E>",
),
message = "the `?` operator can only be used on `Option`s, not `Result`s, \
in {ItemContext} that returns `Option`",
@@ -276,10 +261,7 @@ pub trait Try: FromResidual {
on(
all(
from_desugaring = "QuestionMark",
- any(
- _Self = "core::option::Option<T>",
- _Self = "std::option::Option<T>",
- )
+ _Self = "core::option::Option<T>",
),
// `Option`-in-`Option` always works, as there's only one possible
// residual, so this can also be phrased strongly.
@@ -291,14 +273,8 @@ pub trait Try: FromResidual {
on(
all(
from_desugaring = "QuestionMark",
- any(
- _Self = "core::ops::ControlFlow<B, C>",
- _Self = "std::ops::ControlFlow<B, C>",
- ),
- any(
- R = "core::ops::ControlFlow<B, C>",
- R = "std::ops::ControlFlow<B, C>",
- )
+ _Self = "core::ops::control_flow::ControlFlow<B, C>",
+ R = "core::ops::control_flow::ControlFlow<B, C>",
),
message = "the `?` operator in {ItemContext} that returns `ControlFlow<B, _>` \
can only be used on other `ControlFlow<B, _>`s (with the same Break type)",
@@ -309,10 +285,7 @@ pub trait Try: FromResidual {
on(
all(
from_desugaring = "QuestionMark",
- any(
- _Self = "core::ops::ControlFlow<B, C>",
- _Self = "std::ops::ControlFlow<B, C>",
- )
+ _Self = "core::ops::control_flow::ControlFlow<B, C>",
// `R` is not a `ControlFlow`, as that case was matched previously
),
message = "the `?` operator can only be used on `ControlFlow`s \