blob: 978143ef7cf5696ae429b03dee3f708af3a17b70 [file]
//! 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() {}