diff --git a/src/test/ui/generics/issue-61631-default-type-param-can-reference-self-in-trait.rs b/src/test/ui/generics/issue-61631-default-type-param-can-reference-self-in-trait.rs new file mode 100644 index 0000000000000..cc93794e8fcdc --- /dev/null +++ b/src/test/ui/generics/issue-61631-default-type-param-can-reference-self-in-trait.rs @@ -0,0 +1,20 @@ +#![crate_type="lib"] + +// rust-lang/rust#61631: The use of `Self` in the defaults of generic +// types in a *trait* definition are allowed. +// +// It *must* be accepted; we have used this pattern extensively since +// Rust 1.0 (see e.g. `trait Add`). +trait Tnobound

{} + +impl Tnobound for () { } + +// This variant is accepted at the definition site; but it will be +// rejected at every possible usage site (such as the one immediately +// below). Maybe one day we will attempt to catch it at the definition +// site, but today this is accepted due to compiler implementation +// limitations. +trait Tsized {} + +impl Tsized for () {} +//~^ ERROR the size for values of type `[()]` cannot be known at compilation time [E0277] diff --git a/src/test/ui/generics/issue-61631-default-type-param-can-reference-self-in-trait.stderr b/src/test/ui/generics/issue-61631-default-type-param-can-reference-self-in-trait.stderr new file mode 100644 index 0000000000000..ea0664c48d4d8 --- /dev/null +++ b/src/test/ui/generics/issue-61631-default-type-param-can-reference-self-in-trait.stderr @@ -0,0 +1,12 @@ +error[E0277]: the size for values of type `[()]` cannot be known at compilation time + --> $DIR/issue-61631-default-type-param-can-reference-self-in-trait.rs:19:6 + | +LL | impl Tsized for () {} + | ^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `std::marker::Sized` is not implemented for `[()]` + = note: to learn more, visit + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/generics/issue-61631-default-type-param-cannot-reference-self.rs b/src/test/ui/generics/issue-61631-default-type-param-cannot-reference-self.rs new file mode 100644 index 0000000000000..b560cc2ce7060 --- /dev/null +++ b/src/test/ui/generics/issue-61631-default-type-param-cannot-reference-self.rs @@ -0,0 +1,45 @@ +#![crate_type="lib"] + +// rust-lang/rust#61631: Uses of `Self` in the defaults of generic +// types for ADT's are not allowed. We justify this because the `Self` +// type could be considered the "final" type parameter, that is only +// well-defined after all of the other type parameters on the ADT have +// been instantiated. +// +// These were previously were ICE'ing at the usage point anyway (see +// `demo_usages` below), so there should not be any backwards +// compatibility concern. + +struct Snobound<'a, P = Self> { x: Option<&'a P> } +//~^ ERROR type parameters cannot use `Self` in their defaults [E0735] + +enum Enobound<'a, P = Self> { A, B(Option<&'a P>) } +//~^ ERROR type parameters cannot use `Self` in their defaults [E0735] + +union Unobound<'a, P = Self> { x: i32, y: Option<&'a P> } +//~^ ERROR type parameters cannot use `Self` in their defaults [E0735] + +// Disallowing `Self` in defaults sidesteps need to check the bounds +// on the defaults in cases like these. + +struct Ssized<'a, P: Sized = [Self]> { x: Option<&'a P> } +//~^ ERROR type parameters cannot use `Self` in their defaults [E0735] + +enum Esized<'a, P: Sized = [Self]> { A, B(Option<&'a P>) } +//~^ ERROR type parameters cannot use `Self` in their defaults [E0735] + +union Usized<'a, P: Sized = [Self]> { x: i32, y: Option<&'a P> } +//~^ ERROR type parameters cannot use `Self` in their defaults [E0735] + +fn demo_usages() { + // An ICE means you only get the error from the first line of the + // demo; comment each out to observe the other ICEs when trying + // this out on older versions of Rust. + + let _ice: Snobound; + let _ice: Enobound; + let _ice: Unobound; + let _ice: Ssized; + let _ice: Esized; + let _ice: Usized; +} diff --git a/src/test/ui/generics/issue-61631-default-type-param-cannot-reference-self.stderr b/src/test/ui/generics/issue-61631-default-type-param-cannot-reference-self.stderr new file mode 100644 index 0000000000000..689ffbd0febc2 --- /dev/null +++ b/src/test/ui/generics/issue-61631-default-type-param-cannot-reference-self.stderr @@ -0,0 +1,39 @@ +error[E0735]: type parameters cannot use `Self` in their defaults + --> $DIR/issue-61631-default-type-param-cannot-reference-self.rs:13:25 + | +LL | struct Snobound<'a, P = Self> { x: Option<&'a P> } + | ^^^^ `Self` in type parameter default + +error[E0735]: type parameters cannot use `Self` in their defaults + --> $DIR/issue-61631-default-type-param-cannot-reference-self.rs:16:23 + | +LL | enum Enobound<'a, P = Self> { A, B(Option<&'a P>) } + | ^^^^ `Self` in type parameter default + +error[E0735]: type parameters cannot use `Self` in their defaults + --> $DIR/issue-61631-default-type-param-cannot-reference-self.rs:19:24 + | +LL | union Unobound<'a, P = Self> { x: i32, y: Option<&'a P> } + | ^^^^ `Self` in type parameter default + +error[E0735]: type parameters cannot use `Self` in their defaults + --> $DIR/issue-61631-default-type-param-cannot-reference-self.rs:25:31 + | +LL | struct Ssized<'a, P: Sized = [Self]> { x: Option<&'a P> } + | ^^^^ `Self` in type parameter default + +error[E0735]: type parameters cannot use `Self` in their defaults + --> $DIR/issue-61631-default-type-param-cannot-reference-self.rs:28:29 + | +LL | enum Esized<'a, P: Sized = [Self]> { A, B(Option<&'a P>) } + | ^^^^ `Self` in type parameter default + +error[E0735]: type parameters cannot use `Self` in their defaults + --> $DIR/issue-61631-default-type-param-cannot-reference-self.rs:31:30 + | +LL | union Usized<'a, P: Sized = [Self]> { x: i32, y: Option<&'a P> } + | ^^^^ `Self` in type parameter default + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0735`.