| //! Auto-trait impls whose self type is a free (lazy) type alias are checked against the |
| //! type the alias *expands* to, not the alias itself. An alias resolving to an otherwise |
| //! valid nominal type is accepted, just as if the underlying type had been written |
| //! directly; an alias resolving to a problematic type is still rejected. |
| //! |
| //! Regression test for <https://github.com/rust-lang/rust/issues/157756>. |
| |
| #![feature(checked_type_aliases, auto_traits, negative_impls)] |
| #![allow(incomplete_features)] |
| |
| struct Local; |
| |
| auto trait Marker {} |
| |
| // Aliases expanding to a local nominal type are accepted for both a cross-crate auto trait |
| // (`Sync`) and a local one (`Marker`), exactly as if `Local` had been named directly. |
| type ToLocal = Local; |
| unsafe impl Sync for ToLocal {} |
| impl Marker for ToLocal {} |
| |
| // Nested aliases are expanded transitively, so an alias chain ending in a local nominal type |
| // is accepted as well. |
| struct Inner; |
| type Mid = Inner; |
| type Nested = Mid; |
| impl Marker for Nested {} |
| |
| // A generic alias instantiated with a local nominal type is accepted. |
| struct Generic; |
| type Id<T> = T; |
| impl Marker for Id<Generic> {} |
| |
| // Negative auto-trait impls go through the same orphan check, so an alias to a local nominal |
| // type is accepted for them too. |
| struct Negated; |
| type ToNeg = Negated; |
| impl !Marker for ToNeg {} |
| |
| // An alias expanding to a reference is still rejected for the cross-crate auto trait. Using |
| // `&'static NotSync` (with `NotSync: !Sync`) avoids overlapping std's `Send for &T` impl, so |
| // the only error is the auto-trait nominal-type restriction. |
| struct NotSync; |
| impl !Sync for NotSync {} |
| type ToRef = &'static NotSync; |
| unsafe impl Send for ToRef {} |
| //~^ ERROR cross-crate traits with a default impl, like `Send`, can only be implemented for a struct/enum type, not `&'static NotSync` |
| |
| // An alias expanding to a trait object is still rejected for the local auto trait. |
| type ToDyn = dyn Send; |
| impl Marker for ToDyn {} |
| //~^ ERROR traits with a default impl, like `Marker`, cannot be implemented for trait object `(dyn Send + 'static)` |
| |
| fn main() {} |