From ef24de24a82fe681581cc130f342363c47c0969a Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 7 Jun 2024 07:48:48 +0200 Subject: Merging upstream version 1.75.0+dfsg1. Signed-off-by: Daniel Baumann --- library/core/src/ops/coroutine.rs | 139 ++++++++++++++++++++++++++++++++ library/core/src/ops/deref.rs | 163 +++++++++++++++++++++++++++++--------- library/core/src/ops/function.rs | 24 +++--- library/core/src/ops/generator.rs | 135 ------------------------------- library/core/src/ops/index.rs | 2 +- library/core/src/ops/mod.rs | 10 +-- library/core/src/ops/range.rs | 8 ++ library/core/src/ops/try_trait.rs | 45 +++-------- 8 files changed, 298 insertions(+), 228 deletions(-) create mode 100644 library/core/src/ops/coroutine.rs delete mode 100644 library/core/src/ops/generator.rs (limited to 'library/core/src/ops') 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 { + /// 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 { + /// 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` 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; +} + +#[unstable(feature = "coroutine_trait", issue = "43122")] +impl, R> Coroutine for Pin<&mut G> { + type Yield = G::Yield; + type Return = G::Return; + + fn resume(mut self: Pin<&mut Self>, arg: R) -> CoroutineState { + G::resume((*self).as_mut(), arg) + } +} + +#[unstable(feature = "coroutine_trait", issue = "43122")] +impl + Unpin, R> Coroutine for &mut G { + type Yield = G::Yield; + type Return = G::Return; + + fn resume(mut self: Pin<&mut Self>, arg: R) -> CoroutineState { + 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`, and `v` is a value of type `T`, then: /// -/// If `T` implements `Deref`, 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`][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 Box` 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`][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 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`, and `x` is a value of type `T`, +/// If `T` implements `DerefMut`, 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 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 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: FnMut { #[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: FnMut { // 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: FnOnce { #[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: FnOnce { // 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 { - /// 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 { - /// 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` 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; -} - -#[unstable(feature = "generator_trait", issue = "43122")] -impl, R> Generator for Pin<&mut G> { - type Yield = G::Yield; - type Return = G::Return; - - fn resume(mut self: Pin<&mut Self>, arg: R) -> GeneratorState { - G::resume((*self).as_mut(), arg) - } -} - -#[unstable(feature = "generator_trait", issue = "43122")] -impl + Unpin, R> Generator for &mut G { - type Yield = G::Yield; - type Return = G::Return; - - fn resume(mut self: Pin<&mut Self>, arg: R) -> GeneratorState { - 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 " ), 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 " ), 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> Range { /// 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(&self, item: &U) -> bool where @@ -141,6 +142,7 @@ impl> Range { /// 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> RangeFrom { /// assert!(!(0.0..).contains(&f32::NAN)); /// assert!(!(f32::NAN..).contains(&0.5)); /// ``` + #[inline] #[stable(feature = "range_contains", since = "1.35.0")] pub fn contains(&self, item: &U) -> bool where @@ -294,6 +297,7 @@ impl> RangeTo { /// assert!(!(..1.0).contains(&f32::NAN)); /// assert!(!(..f32::NAN).contains(&0.5)); /// ``` + #[inline] #[stable(feature = "range_contains", since = "1.35.0")] pub fn contains(&self, item: &U) -> bool where @@ -500,6 +504,7 @@ impl> RangeInclusive { /// // 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(&self, item: &U) -> bool where @@ -613,6 +618,7 @@ impl> RangeToInclusive { /// assert!(!(..=1.0).contains(&f32::NAN)); /// assert!(!(..=f32::NAN).contains(&0.5)); /// ``` + #[inline] #[stable(feature = "range_contains", since = "1.35.0")] pub fn contains(&self, item: &U) -> bool where @@ -758,6 +764,7 @@ impl 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 { /// Start index bound. /// @@ -807,6 +814,7 @@ pub trait RangeBounds { /// 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(&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", - _Self = "std::result::Result", - ), - any( - R = "core::option::Option", - R = "std::option::Option", - ) + _Self = "core::result::Result", + R = "core::option::Option", ), 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", - _Self = "std::result::Result", - ) + _Self = "core::result::Result", ), // 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", - _Self = "std::option::Option", - ), - any( - R = "core::result::Result", - R = "std::result::Result", - ) + _Self = "core::option::Option", + R = "core::result::Result", ), 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", - _Self = "std::option::Option", - ) + _Self = "core::option::Option", ), // `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", - _Self = "std::ops::ControlFlow", - ), - any( - R = "core::ops::ControlFlow", - R = "std::ops::ControlFlow", - ) + _Self = "core::ops::control_flow::ControlFlow", + R = "core::ops::control_flow::ControlFlow", ), message = "the `?` operator in {ItemContext} that returns `ControlFlow` \ can only be used on other `ControlFlow`s (with the same Break type)", @@ -309,10 +285,7 @@ pub trait Try: FromResidual { on( all( from_desugaring = "QuestionMark", - any( - _Self = "core::ops::ControlFlow", - _Self = "std::ops::ControlFlow", - ) + _Self = "core::ops::control_flow::ControlFlow", // `R` is not a `ControlFlow`, as that case was matched previously ), message = "the `?` operator can only be used on `ControlFlow`s \ -- cgit v1.2.3