- the self type includes some local type; and,
- type parameters in the self type must be constrained by a local type.
A type parameter is called *constrained* if it appears in some type-parameter of a local type.
Here are some examples that are accepted. In all of these examples, I
assume that `Foo` is a trait defined in another crate. If `Foo` were
defined in the local crate, then all the examples would be legal.
- `impl Foo for LocalType`
- `impl<T> Foo<T> for LocalType` -- T does not appear in Self, so it is OK
- `impl<T> Foo<T> for LocalType<T>` -- T here is constrained by LocalType
- `impl<T> Foo<T> for (LocalType<T>, T)` -- T here is constrained by LocalType
Here are some illegal examples (again, these examples assume that
`Foo` is not local to the current crate):
- `impl Foo for int` -- the Self type is not local
- `impl<T> Foo for T` -- T appears in Self unconstrained by a local type
- `impl<T> Foo for (LocalType, T)` -- T appears in Self unconstrained by a local type
This is a [breaking-change]. For the time being, you can opt out of
the new rules by placing `#[old_orphan_check]` on the trait (and
enabling the feature gate where the trait is defined). Longer term,
you should restructure your traits to avoid the problem. Usually this
means changing the order of parameters so that the "central" type
parameter is in the `Self` position.
As an example of that refactoring, consider the `BorrowFrom` trait:
```rust
pub trait BorrowFrom<Sized? Owned> for Sized? {
fn borrow_from(owned: &Owned) -> &Self;
}
```
As defined, this trait is commonly implemented for custom pointer
types, such as `Arc`. Those impls follow the pattern:
```rust
impl<T> BorrowFrom<Arc<T>> for T {...}
```
Unfortunately, this impl is illegal because the self type `T` is not
local to the current crate. Therefore, we are going to change the order of the parameters,
so that `BorrowFrom` becomes `Borrow`:
```rust
pub trait Borrow<Sized? Borrowed> for Sized? {
fn borrow_from(owned: &Self) -> &Borrowed;
}
```
Now the `Arc` impl is written:
```rust
impl<T> Borrow<T> for Arc<T> { ... }
```
This impl is legal because the self type (`Arc<T>`) is local.
The earlier collections stabilization did not cover the modules
themselves. This commit marks as stable those modules whose types have
been stabilized.
This commit marks as stable those parts of `core::ops` that are in their
final planned form: `Drop`, all of the mathematical operators (`Add`,
`Sub`, etc), `Deref`/`DerefMut`. It leaves the `Index*`, `Slice*` and
`Fn*` traits unstable, as they are still undergoing active changes.
This commit wraps up the adjustments to the iterator for recent language
changes.
* Moves `rposition` from `ExactSizeIterator` to `IteratorExt` using a
`where` clause, thereby removing the `ExactSizeIterator:
DoubleEndedIterator` constraint.
* Merges `MutableDoubleEndedIterator` into `IteratorExt`, renaming
`reverse_` to `reverse_in_place`.
* Merges `IteratorOrdExt`, `IteratorCloneExt` and `CloneIteratorExt`
into `IteratorExt` using `where` clauses.
Marks as `#[stable]`:
* the `iter` module itself
* `FromIterator`, `Extend`
* `Iterator`, `IteratorExt`
* `map`
* `filter`
* `filter_map`
* `skip_while`
* `take_while`
* `scan`
* `flat_map`
* `inspect`
* `collect`
* `fold`
* `all`
* `any`
* `find`
* `rposition`
* `max`, `min`
* Various adapter types related to the above methods
Because of the trait merging, this is a:
[breaking-change]
The first few commits in the PR are just general refactoring. I was intending them for some other code I didn't get around to writing yet, but might as well land them now.
cc @japaric
Fixes#19541
Instead of copy-pasting the whole macro_rules! item from the original .rs file,
we serialize a separate name, attributes list, and body, the latter as
pretty-printed TTs. The compilation of macro_rules! macros is decoupled
somewhat from the expansion of macros in item position.
This filters out comments, and facilitates selective imports.
Many of libstd's macros are now re-exported from libcore and libcollections.
Their libstd definitions have moved to a macros_stage0 module and can disappear
after the next snapshot.
Where the two crates had already diverged, I took the libstd versions as
they're generally newer and better-tested. See e.g. d3c831b, which was a fix to
libstd's assert_eq!() that didn't make it into libcore's.
Fixes#16806.