summaryrefslogtreecommitdiffstats
path: root/src/test/ui/type-alias-enum-variants
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /src/test/ui/type-alias-enum-variants
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--src/test/ui/type-alias-enum-variants/enum-variant-generic-args-pass.rs59
-rw-r--r--src/test/ui/type-alias-enum-variants/enum-variant-generic-args.rs105
-rw-r--r--src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr512
-rw-r--r--src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.rs23
-rw-r--r--src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr28
-rw-r--r--src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.rs41
-rw-r--r--src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr41
-rw-r--r--src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.rs14
-rw-r--r--src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr9
-rw-r--r--src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs19
-rw-r--r--src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr45
-rw-r--r--src/test/ui/type-alias-enum-variants/issue-57866.rs24
-rw-r--r--src/test/ui/type-alias-enum-variants/issue-61801-path-pattern-can-infer.rs28
-rw-r--r--src/test/ui/type-alias-enum-variants/issue-63151-dead-code-lint-fields-in-patterns.rs26
-rw-r--r--src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.rs14
-rw-r--r--src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.stderr11
-rw-r--r--src/test/ui/type-alias-enum-variants/resolve-to-enum-variant-in-type-namespace-and-error.rs11
-rw-r--r--src/test/ui/type-alias-enum-variants/resolve-to-enum-variant-in-type-namespace-and-error.stderr8
-rw-r--r--src/test/ui/type-alias-enum-variants/self-in-enum-definition.rs8
-rw-r--r--src/test/ui/type-alias-enum-variants/self-in-enum-definition.stderr33
-rw-r--r--src/test/ui/type-alias-enum-variants/type-alias-enum-variants-pass.rs69
21 files changed, 1128 insertions, 0 deletions
diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args-pass.rs b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args-pass.rs
new file mode 100644
index 000000000..0aa644db0
--- /dev/null
+++ b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args-pass.rs
@@ -0,0 +1,59 @@
+// run-pass
+
+// Check that resolving, in the value namespace, to an `enum` variant
+// through a type alias is well behaved in the presence of generics.
+// We check for situations with:
+// 1. a generic type `Alias<T>`, we can type-apply `Alias` when referring to a variant.
+// 2. a monotype `AliasFixed` of generic `Enum<T>`, we can refer to variants
+// and the type-application of `T` in `AliasFixed` is kept.
+
+#![allow(irrefutable_let_patterns)]
+
+enum Enum<T> { TSVariant(#[allow(unused_tuple_struct_fields)] T), SVariant { _v: T }, UVariant }
+type Alias<T> = Enum<T>;
+type AliasFixed = Enum<()>;
+
+macro_rules! is_variant {
+ (TSVariant, $expr:expr) => (is_variant!(@check TSVariant, (_), $expr));
+ (SVariant, $expr:expr) => (is_variant!(@check SVariant, { _v: _ }, $expr));
+ (UVariant, $expr:expr) => (is_variant!(@check UVariant, {}, $expr));
+ (@check $variant:ident, $matcher:tt, $expr:expr) => (
+ assert!(if let Enum::$variant::<()> $matcher = $expr { true } else { false },
+ "expr does not have correct type");
+ );
+}
+
+fn main() {
+ // Tuple struct variant
+
+ is_variant!(TSVariant, Enum::TSVariant(()));
+ is_variant!(TSVariant, Enum::TSVariant::<()>(()));
+ is_variant!(TSVariant, Enum::<()>::TSVariant(()));
+
+ is_variant!(TSVariant, Alias::TSVariant(()));
+ is_variant!(TSVariant, Alias::<()>::TSVariant(()));
+
+ is_variant!(TSVariant, AliasFixed::TSVariant(()));
+
+ // Struct variant
+
+ is_variant!(SVariant, Enum::SVariant { _v: () });
+ is_variant!(SVariant, Enum::SVariant::<()> { _v: () });
+ is_variant!(SVariant, Enum::<()>::SVariant { _v: () });
+
+ is_variant!(SVariant, Alias::SVariant { _v: () });
+ is_variant!(SVariant, Alias::<()>::SVariant { _v: () });
+
+ is_variant!(SVariant, AliasFixed::SVariant { _v: () });
+
+ // Unit variant
+
+ is_variant!(UVariant, Enum::UVariant);
+ is_variant!(UVariant, Enum::UVariant::<()>);
+ is_variant!(UVariant, Enum::<()>::UVariant);
+
+ is_variant!(UVariant, Alias::UVariant);
+ is_variant!(UVariant, Alias::<()>::UVariant);
+
+ is_variant!(UVariant, AliasFixed::UVariant);
+}
diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.rs b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.rs
new file mode 100644
index 000000000..0031a4665
--- /dev/null
+++ b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.rs
@@ -0,0 +1,105 @@
+// Checks that applied type arguments of enums, and aliases to them, are respected.
+// For example, `Self` is never a type constructor. Therefore, no types can be applied to it.
+//
+// We also check that the variant to an type-aliased enum cannot be type applied whether
+// that alias is generic or monomorphic.
+
+enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant }
+type Alias<T> = Enum<T>;
+type AliasFixed = Enum<()>;
+
+impl<T> Enum<T> {
+ fn ts_variant() {
+ Self::TSVariant(());
+ //~^ ERROR mismatched types [E0308]
+ Self::TSVariant::<()>(());
+ //~^ ERROR type arguments are not allowed on this type [E0109]
+ Self::<()>::TSVariant(());
+ //~^ ERROR type arguments are not allowed on self type [E0109]
+ //~| ERROR mismatched types [E0308]
+ Self::<()>::TSVariant::<()>(());
+ //~^ ERROR type arguments are not allowed on self type [E0109]
+ //~| ERROR type arguments are not allowed on this type [E0109]
+ }
+
+ fn s_variant() {
+ Self::SVariant { v: () };
+ //~^ ERROR mismatched types [E0308]
+ Self::SVariant::<()> { v: () };
+ //~^ ERROR type arguments are not allowed on this type [E0109]
+ //~| ERROR mismatched types [E0308]
+ Self::<()>::SVariant { v: () };
+ //~^ ERROR type arguments are not allowed on self type [E0109]
+ //~| ERROR mismatched types [E0308]
+ Self::<()>::SVariant::<()> { v: () };
+ //~^ ERROR type arguments are not allowed on self type [E0109]
+ //~| ERROR type arguments are not allowed on this type [E0109]
+ //~| ERROR mismatched types [E0308]
+ }
+
+ fn u_variant() {
+ Self::UVariant::<()>;
+ //~^ ERROR type arguments are not allowed on this type [E0109]
+ Self::<()>::UVariant;
+ //~^ ERROR type arguments are not allowed on self type [E0109]
+ Self::<()>::UVariant::<()>;
+ //~^ ERROR type arguments are not allowed on self type [E0109]
+ //~| ERROR type arguments are not allowed on this type [E0109]
+ }
+}
+
+fn main() {
+ // Tuple struct variant
+
+ Enum::<()>::TSVariant::<()>(());
+ //~^ ERROR type arguments are not allowed on tuple variant `TSVariant` [E0109]
+
+ Alias::TSVariant::<()>(());
+ //~^ ERROR type arguments are not allowed on this type [E0109]
+ Alias::<()>::TSVariant::<()>(());
+ //~^ ERROR type arguments are not allowed on this type [E0109]
+
+ AliasFixed::TSVariant::<()>(());
+ //~^ ERROR type arguments are not allowed on this type [E0109]
+ AliasFixed::<()>::TSVariant(());
+ //~^ ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
+ AliasFixed::<()>::TSVariant::<()>(());
+ //~^ ERROR type arguments are not allowed on this type [E0109]
+ //~| ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
+
+ // Struct variant
+
+ Enum::<()>::SVariant::<()> { v: () };
+ //~^ ERROR type arguments are not allowed on variant `SVariant` [E0109]
+
+ Alias::SVariant::<()> { v: () };
+ //~^ ERROR type arguments are not allowed on this type [E0109]
+ Alias::<()>::SVariant::<()> { v: () };
+ //~^ ERROR type arguments are not allowed on this type [E0109]
+
+ AliasFixed::SVariant::<()> { v: () };
+ //~^ ERROR type arguments are not allowed on this type [E0109]
+ AliasFixed::<()>::SVariant { v: () };
+ //~^ ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
+ AliasFixed::<()>::SVariant::<()> { v: () };
+ //~^ ERROR type arguments are not allowed on this type [E0109]
+ //~| ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
+
+ // Unit variant
+
+ Enum::<()>::UVariant::<()>;
+ //~^ ERROR type arguments are not allowed on unit variant `UVariant` [E0109]
+
+ Alias::UVariant::<()>;
+ //~^ ERROR type arguments are not allowed on this type [E0109]
+ Alias::<()>::UVariant::<()>;
+ //~^ ERROR type arguments are not allowed on this type [E0109]
+
+ AliasFixed::UVariant::<()>;
+ //~^ ERROR type arguments are not allowed on this type [E0109]
+ AliasFixed::<()>::UVariant;
+ //~^ ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
+ AliasFixed::<()>::UVariant::<()>;
+ //~^ ERROR type arguments are not allowed on this type [E0109]
+ //~| ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
+}
diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr
new file mode 100644
index 000000000..a922d7a5e
--- /dev/null
+++ b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr
@@ -0,0 +1,512 @@
+error[E0308]: mismatched types
+ --> $DIR/enum-variant-generic-args.rs:13:25
+ |
+LL | impl<T> Enum<T> {
+ | - this type parameter
+LL | fn ts_variant() {
+LL | Self::TSVariant(());
+ | --------------- ^^ expected type parameter `T`, found `()`
+ | |
+ | arguments to this enum variant are incorrect
+ |
+ = note: expected type parameter `T`
+ found unit type `()`
+note: tuple variant defined here
+ --> $DIR/enum-variant-generic-args.rs:7:16
+ |
+LL | enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant }
+ | ^^^^^^^^^
+
+error[E0109]: type arguments are not allowed on this type
+ --> $DIR/enum-variant-generic-args.rs:15:27
+ |
+LL | Self::TSVariant::<()>(());
+ | --------- ^^ type argument not allowed
+ | |
+ | not allowed on this type
+
+error[E0109]: type arguments are not allowed on self type
+ --> $DIR/enum-variant-generic-args.rs:17:16
+ |
+LL | Self::<()>::TSVariant(());
+ | ---- ^^ type argument not allowed
+ | |
+ | not allowed on self type
+ |
+note: `Self` is of type `Enum<T>`
+ --> $DIR/enum-variant-generic-args.rs:7:6
+ |
+LL | enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant }
+ | ^^^^ `Self` corresponds to this type
+...
+LL | impl<T> Enum<T> {
+ | --------------- `Self` is on type `Enum` in this `impl`
+help: the `Self` type doesn't accept type parameters, use the concrete type's name `Enum` instead if you want to specify its type parameters
+ |
+LL | Enum::<()>::TSVariant(());
+ | ~~~~
+
+error[E0308]: mismatched types
+ --> $DIR/enum-variant-generic-args.rs:17:31
+ |
+LL | impl<T> Enum<T> {
+ | - this type parameter
+...
+LL | Self::<()>::TSVariant(());
+ | --------------------- ^^ expected type parameter `T`, found `()`
+ | |
+ | arguments to this enum variant are incorrect
+ |
+ = note: expected type parameter `T`
+ found unit type `()`
+note: tuple variant defined here
+ --> $DIR/enum-variant-generic-args.rs:7:16
+ |
+LL | enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant }
+ | ^^^^^^^^^
+
+error[E0109]: type arguments are not allowed on self type
+ --> $DIR/enum-variant-generic-args.rs:20:16
+ |
+LL | Self::<()>::TSVariant::<()>(());
+ | ---- ^^ type argument not allowed
+ | |
+ | not allowed on self type
+ |
+note: `Self` is of type `Enum<T>`
+ --> $DIR/enum-variant-generic-args.rs:7:6
+ |
+LL | enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant }
+ | ^^^^ `Self` corresponds to this type
+...
+LL | impl<T> Enum<T> {
+ | --------------- `Self` is on type `Enum` in this `impl`
+help: the `Self` type doesn't accept type parameters, use the concrete type's name `Enum` instead if you want to specify its type parameters
+ |
+LL | Enum::<()>::TSVariant::<()>(());
+ | ~~~~
+
+error[E0109]: type arguments are not allowed on this type
+ --> $DIR/enum-variant-generic-args.rs:20:33
+ |
+LL | Self::<()>::TSVariant::<()>(());
+ | --------- ^^ type argument not allowed
+ | |
+ | not allowed on this type
+
+error[E0308]: mismatched types
+ --> $DIR/enum-variant-generic-args.rs:26:29
+ |
+LL | impl<T> Enum<T> {
+ | - this type parameter
+...
+LL | Self::SVariant { v: () };
+ | ^^ expected type parameter `T`, found `()`
+ |
+ = note: expected type parameter `T`
+ found unit type `()`
+
+error[E0109]: type arguments are not allowed on this type
+ --> $DIR/enum-variant-generic-args.rs:28:26
+ |
+LL | Self::SVariant::<()> { v: () };
+ | -------- ^^ type argument not allowed
+ | |
+ | not allowed on this type
+ |
+ = note: enum variants can't have type parameters
+help: you might have meant to specity type parameters on enum `Enum`
+ |
+LL - Self::SVariant::<()> { v: () };
+LL + Enum::<()>::SVariant { v: () };
+ |
+
+error[E0308]: mismatched types
+ --> $DIR/enum-variant-generic-args.rs:28:35
+ |
+LL | impl<T> Enum<T> {
+ | - this type parameter
+...
+LL | Self::SVariant::<()> { v: () };
+ | ^^ expected type parameter `T`, found `()`
+ |
+ = note: expected type parameter `T`
+ found unit type `()`
+
+error[E0109]: type arguments are not allowed on self type
+ --> $DIR/enum-variant-generic-args.rs:31:16
+ |
+LL | Self::<()>::SVariant { v: () };
+ | ---- ^^ type argument not allowed
+ | |
+ | not allowed on self type
+ |
+note: `Self` is of type `Enum<T>`
+ --> $DIR/enum-variant-generic-args.rs:7:6
+ |
+LL | enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant }
+ | ^^^^ `Self` corresponds to this type
+...
+LL | impl<T> Enum<T> {
+ | --------------- `Self` is on type `Enum` in this `impl`
+help: the `Self` type doesn't accept type parameters, use the concrete type's name `Enum` instead if you want to specify its type parameters
+ |
+LL | Enum::<()>::SVariant { v: () };
+ | ~~~~
+
+error[E0308]: mismatched types
+ --> $DIR/enum-variant-generic-args.rs:31:35
+ |
+LL | impl<T> Enum<T> {
+ | - this type parameter
+...
+LL | Self::<()>::SVariant { v: () };
+ | ^^ expected type parameter `T`, found `()`
+ |
+ = note: expected type parameter `T`
+ found unit type `()`
+
+error[E0109]: type arguments are not allowed on self type
+ --> $DIR/enum-variant-generic-args.rs:34:16
+ |
+LL | Self::<()>::SVariant::<()> { v: () };
+ | ---- ^^ type argument not allowed
+ | |
+ | not allowed on self type
+ |
+note: `Self` is of type `Enum<T>`
+ --> $DIR/enum-variant-generic-args.rs:7:6
+ |
+LL | enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant }
+ | ^^^^ `Self` corresponds to this type
+...
+LL | impl<T> Enum<T> {
+ | --------------- `Self` is on type `Enum` in this `impl`
+help: the `Self` type doesn't accept type parameters, use the concrete type's name `Enum` instead if you want to specify its type parameters
+ |
+LL | Enum::<()>::SVariant::<()> { v: () };
+ | ~~~~
+
+error[E0109]: type arguments are not allowed on this type
+ --> $DIR/enum-variant-generic-args.rs:34:32
+ |
+LL | Self::<()>::SVariant::<()> { v: () };
+ | -------- ^^ type argument not allowed
+ | |
+ | not allowed on this type
+ |
+ = note: enum variants can't have type parameters
+help: you might have meant to specity type parameters on enum `Enum`
+ |
+LL - Self::<()>::SVariant::<()> { v: () };
+LL + Enum::<()>::SVariant { v: () };
+ |
+
+error[E0308]: mismatched types
+ --> $DIR/enum-variant-generic-args.rs:34:41
+ |
+LL | impl<T> Enum<T> {
+ | - this type parameter
+...
+LL | Self::<()>::SVariant::<()> { v: () };
+ | ^^ expected type parameter `T`, found `()`
+ |
+ = note: expected type parameter `T`
+ found unit type `()`
+
+error[E0109]: type arguments are not allowed on this type
+ --> $DIR/enum-variant-generic-args.rs:41:26
+ |
+LL | Self::UVariant::<()>;
+ | -------- ^^ type argument not allowed
+ | |
+ | not allowed on this type
+
+error[E0109]: type arguments are not allowed on self type
+ --> $DIR/enum-variant-generic-args.rs:43:16
+ |
+LL | Self::<()>::UVariant;
+ | ---- ^^ type argument not allowed
+ | |
+ | not allowed on self type
+ |
+note: `Self` is of type `Enum<T>`
+ --> $DIR/enum-variant-generic-args.rs:7:6
+ |
+LL | enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant }
+ | ^^^^ `Self` corresponds to this type
+...
+LL | impl<T> Enum<T> {
+ | --------------- `Self` is on type `Enum` in this `impl`
+help: the `Self` type doesn't accept type parameters, use the concrete type's name `Enum` instead if you want to specify its type parameters
+ |
+LL | Enum::<()>::UVariant;
+ | ~~~~
+
+error[E0109]: type arguments are not allowed on self type
+ --> $DIR/enum-variant-generic-args.rs:45:16
+ |
+LL | Self::<()>::UVariant::<()>;
+ | ---- ^^ type argument not allowed
+ | |
+ | not allowed on self type
+ |
+note: `Self` is of type `Enum<T>`
+ --> $DIR/enum-variant-generic-args.rs:7:6
+ |
+LL | enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant }
+ | ^^^^ `Self` corresponds to this type
+...
+LL | impl<T> Enum<T> {
+ | --------------- `Self` is on type `Enum` in this `impl`
+help: the `Self` type doesn't accept type parameters, use the concrete type's name `Enum` instead if you want to specify its type parameters
+ |
+LL | Enum::<()>::UVariant::<()>;
+ | ~~~~
+
+error[E0109]: type arguments are not allowed on this type
+ --> $DIR/enum-variant-generic-args.rs:45:32
+ |
+LL | Self::<()>::UVariant::<()>;
+ | -------- ^^ type argument not allowed
+ | |
+ | not allowed on this type
+
+error[E0109]: type arguments are not allowed on tuple variant `TSVariant`
+ --> $DIR/enum-variant-generic-args.rs:54:29
+ |
+LL | Enum::<()>::TSVariant::<()>(());
+ | --------- ^^ type argument not allowed
+ | |
+ | not allowed on tuple variant `TSVariant`
+
+error[E0109]: type arguments are not allowed on this type
+ --> $DIR/enum-variant-generic-args.rs:57:24
+ |
+LL | Alias::TSVariant::<()>(());
+ | --------- ^^ type argument not allowed
+ | |
+ | not allowed on this type
+
+error[E0109]: type arguments are not allowed on this type
+ --> $DIR/enum-variant-generic-args.rs:59:30
+ |
+LL | Alias::<()>::TSVariant::<()>(());
+ | --------- ^^ type argument not allowed
+ | |
+ | not allowed on this type
+
+error[E0109]: type arguments are not allowed on this type
+ --> $DIR/enum-variant-generic-args.rs:62:29
+ |
+LL | AliasFixed::TSVariant::<()>(());
+ | --------- ^^ type argument not allowed
+ | |
+ | not allowed on this type
+
+error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
+ --> $DIR/enum-variant-generic-args.rs:64:5
+ |
+LL | AliasFixed::<()>::TSVariant(());
+ | ^^^^^^^^^^------ help: remove these generics
+ | |
+ | expected 0 generic arguments
+ |
+note: type alias defined here, with 0 generic parameters
+ --> $DIR/enum-variant-generic-args.rs:9:6
+ |
+LL | type AliasFixed = Enum<()>;
+ | ^^^^^^^^^^
+
+error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
+ --> $DIR/enum-variant-generic-args.rs:66:5
+ |
+LL | AliasFixed::<()>::TSVariant::<()>(());
+ | ^^^^^^^^^^------ help: remove these generics
+ | |
+ | expected 0 generic arguments
+ |
+note: type alias defined here, with 0 generic parameters
+ --> $DIR/enum-variant-generic-args.rs:9:6
+ |
+LL | type AliasFixed = Enum<()>;
+ | ^^^^^^^^^^
+
+error[E0109]: type arguments are not allowed on this type
+ --> $DIR/enum-variant-generic-args.rs:66:35
+ |
+LL | AliasFixed::<()>::TSVariant::<()>(());
+ | --------- ^^ type argument not allowed
+ | |
+ | not allowed on this type
+
+error[E0109]: type arguments are not allowed on variant `SVariant`
+ --> $DIR/enum-variant-generic-args.rs:72:28
+ |
+LL | Enum::<()>::SVariant::<()> { v: () };
+ | -------- ^^ type argument not allowed
+ | |
+ | not allowed on variant `SVariant`
+ |
+ = note: enum variants can't have type parameters
+
+error[E0109]: type arguments are not allowed on this type
+ --> $DIR/enum-variant-generic-args.rs:75:23
+ |
+LL | Alias::SVariant::<()> { v: () };
+ | -------- ^^ type argument not allowed
+ | |
+ | not allowed on this type
+ |
+ = note: enum variants can't have type parameters
+help: you might have meant to specity type parameters on enum `Enum`
+ |
+LL - Alias::SVariant::<()> { v: () };
+LL + Alias::<()>::SVariant { v: () };
+ |
+
+error[E0109]: type arguments are not allowed on this type
+ --> $DIR/enum-variant-generic-args.rs:77:29
+ |
+LL | Alias::<()>::SVariant::<()> { v: () };
+ | -------- ^^ type argument not allowed
+ | |
+ | not allowed on this type
+ |
+ = note: enum variants can't have type parameters
+help: you might have meant to specity type parameters on enum `Enum`
+ |
+LL - Alias::<()>::SVariant::<()> { v: () };
+LL + Alias::<()>::SVariant { v: () };
+ |
+
+error[E0109]: type arguments are not allowed on this type
+ --> $DIR/enum-variant-generic-args.rs:80:28
+ |
+LL | AliasFixed::SVariant::<()> { v: () };
+ | -------- ^^ type argument not allowed
+ | |
+ | not allowed on this type
+ |
+ = note: enum variants can't have type parameters
+help: you might have meant to specity type parameters on enum `Enum`
+ |
+LL - AliasFixed::SVariant::<()> { v: () };
+LL + AliasFixed::<()>::SVariant { v: () };
+ |
+
+error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
+ --> $DIR/enum-variant-generic-args.rs:82:5
+ |
+LL | AliasFixed::<()>::SVariant { v: () };
+ | ^^^^^^^^^^------ help: remove these generics
+ | |
+ | expected 0 generic arguments
+ |
+note: type alias defined here, with 0 generic parameters
+ --> $DIR/enum-variant-generic-args.rs:9:6
+ |
+LL | type AliasFixed = Enum<()>;
+ | ^^^^^^^^^^
+
+error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
+ --> $DIR/enum-variant-generic-args.rs:84:5
+ |
+LL | AliasFixed::<()>::SVariant::<()> { v: () };
+ | ^^^^^^^^^^------ help: remove these generics
+ | |
+ | expected 0 generic arguments
+ |
+note: type alias defined here, with 0 generic parameters
+ --> $DIR/enum-variant-generic-args.rs:9:6
+ |
+LL | type AliasFixed = Enum<()>;
+ | ^^^^^^^^^^
+
+error[E0109]: type arguments are not allowed on this type
+ --> $DIR/enum-variant-generic-args.rs:84:34
+ |
+LL | AliasFixed::<()>::SVariant::<()> { v: () };
+ | -------- ^^ type argument not allowed
+ | |
+ | not allowed on this type
+ |
+ = note: enum variants can't have type parameters
+help: you might have meant to specity type parameters on enum `Enum`
+ |
+LL - AliasFixed::<()>::SVariant::<()> { v: () };
+LL + AliasFixed::<()>::SVariant { v: () };
+ |
+
+error[E0109]: type arguments are not allowed on unit variant `UVariant`
+ --> $DIR/enum-variant-generic-args.rs:90:28
+ |
+LL | Enum::<()>::UVariant::<()>;
+ | -------- ^^ type argument not allowed
+ | |
+ | not allowed on unit variant `UVariant`
+
+error[E0109]: type arguments are not allowed on this type
+ --> $DIR/enum-variant-generic-args.rs:93:23
+ |
+LL | Alias::UVariant::<()>;
+ | -------- ^^ type argument not allowed
+ | |
+ | not allowed on this type
+
+error[E0109]: type arguments are not allowed on this type
+ --> $DIR/enum-variant-generic-args.rs:95:29
+ |
+LL | Alias::<()>::UVariant::<()>;
+ | -------- ^^ type argument not allowed
+ | |
+ | not allowed on this type
+
+error[E0109]: type arguments are not allowed on this type
+ --> $DIR/enum-variant-generic-args.rs:98:28
+ |
+LL | AliasFixed::UVariant::<()>;
+ | -------- ^^ type argument not allowed
+ | |
+ | not allowed on this type
+
+error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
+ --> $DIR/enum-variant-generic-args.rs:100:5
+ |
+LL | AliasFixed::<()>::UVariant;
+ | ^^^^^^^^^^------ help: remove these generics
+ | |
+ | expected 0 generic arguments
+ |
+note: type alias defined here, with 0 generic parameters
+ --> $DIR/enum-variant-generic-args.rs:9:6
+ |
+LL | type AliasFixed = Enum<()>;
+ | ^^^^^^^^^^
+
+error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
+ --> $DIR/enum-variant-generic-args.rs:102:5
+ |
+LL | AliasFixed::<()>::UVariant::<()>;
+ | ^^^^^^^^^^------ help: remove these generics
+ | |
+ | expected 0 generic arguments
+ |
+note: type alias defined here, with 0 generic parameters
+ --> $DIR/enum-variant-generic-args.rs:9:6
+ |
+LL | type AliasFixed = Enum<()>;
+ | ^^^^^^^^^^
+
+error[E0109]: type arguments are not allowed on this type
+ --> $DIR/enum-variant-generic-args.rs:102:34
+ |
+LL | AliasFixed::<()>::UVariant::<()>;
+ | -------- ^^ type argument not allowed
+ | |
+ | not allowed on this type
+
+error: aborting due to 39 previous errors
+
+Some errors have detailed explanations: E0107, E0109, E0308.
+For more information about an error, try `rustc --explain E0107`.
diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.rs b/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.rs
new file mode 100644
index 000000000..3a8712f2a
--- /dev/null
+++ b/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.rs
@@ -0,0 +1,23 @@
+// Check that an `enum` variant is resolved, in the value namespace,
+// with higher priority than other inherent items when there is a conflict.
+
+enum E {
+ V(u8)
+}
+
+impl E {
+ fn V() {}
+}
+
+enum E2 {
+ V,
+}
+
+impl E2 {
+ const V: u8 = 0;
+}
+
+fn main() {
+ <E>::V(); //~ ERROR this enum variant takes 1 argument but 0 arguments were supplied
+ let _: u8 = <E2>::V; //~ ERROR mismatched types
+}
diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr b/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr
new file mode 100644
index 000000000..006253f84
--- /dev/null
+++ b/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr
@@ -0,0 +1,28 @@
+error[E0061]: this enum variant takes 1 argument but 0 arguments were supplied
+ --> $DIR/enum-variant-priority-higher-than-other-inherent.rs:21:5
+ |
+LL | <E>::V();
+ | ^^^^^^-- an argument of type `u8` is missing
+ |
+note: tuple variant defined here
+ --> $DIR/enum-variant-priority-higher-than-other-inherent.rs:5:5
+ |
+LL | V(u8)
+ | ^
+help: provide the argument
+ |
+LL | <E>::V(/* u8 */);
+ | ~~~~~~~~~~~~~~~~
+
+error[E0308]: mismatched types
+ --> $DIR/enum-variant-priority-higher-than-other-inherent.rs:22:17
+ |
+LL | let _: u8 = <E2>::V;
+ | -- ^^^^^^^ expected `u8`, found enum `E2`
+ | |
+ | expected due to this
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0061, E0308.
+For more information about an error, try `rustc --explain E0061`.
diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.rs b/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.rs
new file mode 100644
index 000000000..acbf15dcb
--- /dev/null
+++ b/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.rs
@@ -0,0 +1,41 @@
+// Check that a projection `Self::V` in a trait implementation,
+// with an associated type named `V`, for an `enum` with a variant named `V`,
+// results in triggering the deny-by-default lint `ambiguous_associated_items`.
+// The lint suggests that qualified syntax should be used instead.
+// That is, the user would write `<Self as Tr>::V`.
+//
+// The rationale for this is that while `enum` variants do currently
+// not exist in the type namespace but solely in the value namespace,
+// RFC #2593 "Enum variant types", would add enum variants to the type namespace.
+// However, currently `enum` variants are resolved with high priority as
+// they are resolved as inherent associated items.
+// Should #2953 therefore be implemented, `Self::V` would suddenly switch
+// from referring to the associated type `V` instead of the variant `V`.
+// The lint exists to keep us forward compatible with #2593.
+//
+// As a closing note, provided that #2933 was implemented and
+// if `enum` variants were given lower priority than associated types,
+// it would be impossible to refer to the `enum` variant `V` whereas
+// the associated type could be referred to with qualified syntax as seen above.
+
+enum E {
+ V
+}
+
+trait Tr {
+ type V;
+ fn f() -> Self::V;
+}
+
+impl Tr for E {
+ type V = u8;
+ fn f() -> Self::V { 0 }
+ //~^ ERROR ambiguous associated item
+ //~| ERROR ambiguous associated item
+ //~| WARN this was previously accepted
+ //~| WARN this was previously accepted
+ //~| HELP use fully-qualified syntax
+ //~| HELP use fully-qualified syntax
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr b/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr
new file mode 100644
index 000000000..aaa3159e0
--- /dev/null
+++ b/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr
@@ -0,0 +1,41 @@
+error: ambiguous associated item
+ --> $DIR/enum-variant-priority-lint-ambiguous_associated_items.rs:32:15
+ |
+LL | fn f() -> Self::V { 0 }
+ | ^^^^^^^ help: use fully-qualified syntax: `<E as Tr>::V`
+ |
+ = note: `#[deny(ambiguous_associated_items)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #57644 <https://github.com/rust-lang/rust/issues/57644>
+note: `V` could refer to the variant defined here
+ --> $DIR/enum-variant-priority-lint-ambiguous_associated_items.rs:22:5
+ |
+LL | V
+ | ^
+note: `V` could also refer to the associated type defined here
+ --> $DIR/enum-variant-priority-lint-ambiguous_associated_items.rs:26:5
+ |
+LL | type V;
+ | ^^^^^^
+
+error: ambiguous associated item
+ --> $DIR/enum-variant-priority-lint-ambiguous_associated_items.rs:32:15
+ |
+LL | fn f() -> Self::V { 0 }
+ | ^^^^^^^ help: use fully-qualified syntax: `<E as Tr>::V`
+ |
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #57644 <https://github.com/rust-lang/rust/issues/57644>
+note: `V` could refer to the variant defined here
+ --> $DIR/enum-variant-priority-lint-ambiguous_associated_items.rs:22:5
+ |
+LL | V
+ | ^
+note: `V` could also refer to the associated type defined here
+ --> $DIR/enum-variant-priority-lint-ambiguous_associated_items.rs:26:5
+ |
+LL | type V;
+ | ^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.rs b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.rs
new file mode 100644
index 000000000..ab40bf580
--- /dev/null
+++ b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.rs
@@ -0,0 +1,14 @@
+pub enum Enum {
+ A(usize),
+}
+
+impl Enum {
+ fn foo(&self) -> () {
+ match self {
+ Self::A => (),
+ //~^ ERROR expected unit struct, unit variant or constant, found tuple variant
+ }
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr
new file mode 100644
index 000000000..15d15f2f4
--- /dev/null
+++ b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr
@@ -0,0 +1,9 @@
+error[E0533]: expected unit struct, unit variant or constant, found tuple variant `Self::A`
+ --> $DIR/incorrect-variant-form-through-Self-issue-58006.rs:8:13
+ |
+LL | Self::A => (),
+ | ^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0533`.
diff --git a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs
new file mode 100644
index 000000000..e4abb96b4
--- /dev/null
+++ b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs
@@ -0,0 +1,19 @@
+// Check that creating/matching on an enum variant through an alias with
+// the wrong braced/unit form is caught as an error.
+
+enum Enum { Braced {}, Unit, Tuple() }
+type Alias = Enum;
+
+fn main() {
+ Alias::Braced;
+ //~^ ERROR expected unit struct, unit variant or constant, found struct variant `Alias::Braced` [E0533]
+ let Alias::Braced = panic!();
+ //~^ ERROR expected unit struct, unit variant or constant, found struct variant `Alias::Braced` [E0533]
+ let Alias::Braced(..) = panic!();
+ //~^ ERROR expected tuple struct or tuple variant, found struct variant `Alias::Braced` [E0164]
+
+ Alias::Unit();
+ //~^ ERROR expected function, found enum variant `Alias::Unit`
+ let Alias::Unit() = panic!();
+ //~^ ERROR expected tuple struct or tuple variant, found unit variant `Alias::Unit` [E0164]
+}
diff --git a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr
new file mode 100644
index 000000000..8f3180a86
--- /dev/null
+++ b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr
@@ -0,0 +1,45 @@
+error[E0533]: expected unit struct, unit variant or constant, found struct variant `Alias::Braced`
+ --> $DIR/incorrect-variant-form-through-alias-caught.rs:8:5
+ |
+LL | Alias::Braced;
+ | ^^^^^^^^^^^^^
+
+error[E0533]: expected unit struct, unit variant or constant, found struct variant `Alias::Braced`
+ --> $DIR/incorrect-variant-form-through-alias-caught.rs:10:9
+ |
+LL | let Alias::Braced = panic!();
+ | ^^^^^^^^^^^^^
+
+error[E0164]: expected tuple struct or tuple variant, found struct variant `Alias::Braced`
+ --> $DIR/incorrect-variant-form-through-alias-caught.rs:12:9
+ |
+LL | let Alias::Braced(..) = panic!();
+ | ^^^^^^^^^^^^^^^^^ not a tuple variant or struct
+
+error[E0618]: expected function, found enum variant `Alias::Unit`
+ --> $DIR/incorrect-variant-form-through-alias-caught.rs:15:5
+ |
+LL | enum Enum { Braced {}, Unit, Tuple() }
+ | ---- enum variant `Alias::Unit` defined here
+...
+LL | Alias::Unit();
+ | ^^^^^^^^^^^--
+ | |
+ | call expression requires function
+ |
+help: `Alias::Unit` is a unit enum variant, and does not take parentheses to be constructed
+ |
+LL - Alias::Unit();
+LL + Alias::Unit;
+ |
+
+error[E0164]: expected tuple struct or tuple variant, found unit variant `Alias::Unit`
+ --> $DIR/incorrect-variant-form-through-alias-caught.rs:17:9
+ |
+LL | let Alias::Unit() = panic!();
+ | ^^^^^^^^^^^^^ not a tuple variant or struct
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0164, E0533, E0618.
+For more information about an error, try `rustc --explain E0164`.
diff --git a/src/test/ui/type-alias-enum-variants/issue-57866.rs b/src/test/ui/type-alias-enum-variants/issue-57866.rs
new file mode 100644
index 000000000..5e105b20a
--- /dev/null
+++ b/src/test/ui/type-alias-enum-variants/issue-57866.rs
@@ -0,0 +1,24 @@
+// check-pass
+
+enum Outer<T> {
+ A(T)
+}
+
+enum Inner {
+ A(i32)
+}
+
+type OuterAlias = Outer<Inner>;
+
+fn ice(x: OuterAlias) {
+ // Fine
+ match x {
+ OuterAlias::A(Inner::A(_)) => (),
+ }
+ // Not fine
+ match x {
+ OuterAlias::A(Inner::A(y)) => (),
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-enum-variants/issue-61801-path-pattern-can-infer.rs b/src/test/ui/type-alias-enum-variants/issue-61801-path-pattern-can-infer.rs
new file mode 100644
index 000000000..9c9eaab8d
--- /dev/null
+++ b/src/test/ui/type-alias-enum-variants/issue-61801-path-pattern-can-infer.rs
@@ -0,0 +1,28 @@
+// In this regression test we check that a path pattern referring to a unit variant
+// through a type alias is successful in inferring the generic argument.
+
+// check-pass
+
+enum Opt<T> {
+ N,
+ S(T),
+}
+
+type OptAlias<T> = Opt<T>;
+
+fn f1(x: OptAlias<u8>) {
+ match x {
+ OptAlias::N // We previously failed to infer `T` to `u8`.
+ => (),
+ _ => (),
+ }
+
+ match x {
+ <
+ OptAlias<_> // And we failed to infer this type also.
+ >::N => (),
+ _ => (),
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-enum-variants/issue-63151-dead-code-lint-fields-in-patterns.rs b/src/test/ui/type-alias-enum-variants/issue-63151-dead-code-lint-fields-in-patterns.rs
new file mode 100644
index 000000000..66fb8dd0d
--- /dev/null
+++ b/src/test/ui/type-alias-enum-variants/issue-63151-dead-code-lint-fields-in-patterns.rs
@@ -0,0 +1,26 @@
+// check-pass
+
+// Regression test for the issue #63151:
+// Spurious unused field warning when matching variants under a `Self` scope
+//
+// This test checks that the `dead_code` lint properly inspects fields
+// in struct patterns that use a type relative path.
+
+#![deny(dead_code)]
+
+enum Enum {
+ Variant { field: usize }
+}
+
+impl Enum {
+ fn read_field(self) -> usize {
+ match self {
+ Self::Variant { field } => field
+ }
+ }
+}
+
+fn main() {
+ let e = Enum::Variant { field: 42 };
+ println!("{}", e.read_field());
+}
diff --git a/src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.rs b/src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.rs
new file mode 100644
index 000000000..872ece0c0
--- /dev/null
+++ b/src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.rs
@@ -0,0 +1,14 @@
+// Check that a generic type for an `enum` admits type application
+// on both the type constructor and the generic type's variant.
+//
+// Also check that a type alias to said generic type admits type application
+// on the type constructor but *NOT* the variant.
+
+type Alias<T> = Option<T>;
+
+fn main() {
+ let _ = Option::<u8>::None; // OK
+ let _ = Option::None::<u8>; // OK (Lint in future!)
+ let _ = Alias::<u8>::None; // OK
+ let _ = Alias::None::<u8>; //~ ERROR type arguments are not allowed on this type
+}
diff --git a/src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.stderr b/src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.stderr
new file mode 100644
index 000000000..51b1c8a10
--- /dev/null
+++ b/src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.stderr
@@ -0,0 +1,11 @@
+error[E0109]: type arguments are not allowed on this type
+ --> $DIR/no-type-application-on-aliased-enum-variant.rs:13:27
+ |
+LL | let _ = Alias::None::<u8>;
+ | ---- ^^ type argument not allowed
+ | |
+ | not allowed on this type
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0109`.
diff --git a/src/test/ui/type-alias-enum-variants/resolve-to-enum-variant-in-type-namespace-and-error.rs b/src/test/ui/type-alias-enum-variants/resolve-to-enum-variant-in-type-namespace-and-error.rs
new file mode 100644
index 000000000..11f4b05d0
--- /dev/null
+++ b/src/test/ui/type-alias-enum-variants/resolve-to-enum-variant-in-type-namespace-and-error.rs
@@ -0,0 +1,11 @@
+// Check that the compiler will resolve `<E>::V` to the variant `V` in the type namespace
+// but will reject this because `enum` variants do not exist in the type namespace.
+
+enum E {
+ V
+}
+
+fn check() -> <E>::V {}
+//~^ ERROR expected type, found variant `V`
+
+fn main() {}
diff --git a/src/test/ui/type-alias-enum-variants/resolve-to-enum-variant-in-type-namespace-and-error.stderr b/src/test/ui/type-alias-enum-variants/resolve-to-enum-variant-in-type-namespace-and-error.stderr
new file mode 100644
index 000000000..f190bfb69
--- /dev/null
+++ b/src/test/ui/type-alias-enum-variants/resolve-to-enum-variant-in-type-namespace-and-error.stderr
@@ -0,0 +1,8 @@
+error: expected type, found variant `V`
+ --> $DIR/resolve-to-enum-variant-in-type-namespace-and-error.rs:8:15
+ |
+LL | fn check() -> <E>::V {}
+ | ^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type-alias-enum-variants/self-in-enum-definition.rs b/src/test/ui/type-alias-enum-variants/self-in-enum-definition.rs
new file mode 100644
index 000000000..8dadd77fc
--- /dev/null
+++ b/src/test/ui/type-alias-enum-variants/self-in-enum-definition.rs
@@ -0,0 +1,8 @@
+#[repr(u8)]
+enum Alpha {
+ V1 = 41,
+ V2 = Self::V1 as u8 + 1, // OK; See #50072.
+ V3 = Self::V1 {} as u8 + 2, //~ ERROR cycle detected when simplifying constant
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-enum-variants/self-in-enum-definition.stderr b/src/test/ui/type-alias-enum-variants/self-in-enum-definition.stderr
new file mode 100644
index 000000000..4775e6882
--- /dev/null
+++ b/src/test/ui/type-alias-enum-variants/self-in-enum-definition.stderr
@@ -0,0 +1,33 @@
+error[E0391]: cycle detected when simplifying constant for the type system `Alpha::V3::{constant#0}`
+ --> $DIR/self-in-enum-definition.rs:5:10
+ |
+LL | V3 = Self::V1 {} as u8 + 2,
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+note: ...which requires simplifying constant for the type system `Alpha::V3::{constant#0}`...
+ --> $DIR/self-in-enum-definition.rs:5:10
+ |
+LL | V3 = Self::V1 {} as u8 + 2,
+ | ^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires const-evaluating + checking `Alpha::V3::{constant#0}`...
+ --> $DIR/self-in-enum-definition.rs:5:10
+ |
+LL | V3 = Self::V1 {} as u8 + 2,
+ | ^^^^^^^^^^^^^^^^^^^^^
+ = note: ...which requires computing layout of `Alpha`...
+ = note: ...which again requires simplifying constant for the type system `Alpha::V3::{constant#0}`, completing the cycle
+note: cycle used when collecting item types in top-level module
+ --> $DIR/self-in-enum-definition.rs:1:1
+ |
+LL | / #[repr(u8)]
+LL | | enum Alpha {
+LL | | V1 = 41,
+LL | | V2 = Self::V1 as u8 + 1, // OK; See #50072.
+... |
+LL | |
+LL | | fn main() {}
+ | |____________^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0391`.
diff --git a/src/test/ui/type-alias-enum-variants/type-alias-enum-variants-pass.rs b/src/test/ui/type-alias-enum-variants/type-alias-enum-variants-pass.rs
new file mode 100644
index 000000000..39677733d
--- /dev/null
+++ b/src/test/ui/type-alias-enum-variants/type-alias-enum-variants-pass.rs
@@ -0,0 +1,69 @@
+// run-pass
+
+// Check that it is possible to resolve, in the value namespace,
+// to an `enum` variant through a type alias. This includes `Self`.
+// Type qualified syntax `<Type>::Variant` also works when syntactically valid.
+
+#[derive(Debug, PartialEq, Eq)]
+enum Foo {
+ Bar(i32),
+ Baz { i: i32 },
+ Qux,
+}
+
+type FooAlias = Foo;
+type OptionAlias = Option<i32>;
+
+macro_rules! check_pat {
+ ($x:expr, $p:pat) => {
+ assert!(if let $p = $x { true } else { false });
+ };
+}
+
+impl Foo {
+ fn bar() -> Self {
+ let x = Self::Bar(3);
+ assert_eq!(x, <Self>::Bar(3));
+ check_pat!(x, Self::Bar(3));
+ x
+ }
+
+ fn baz() -> Self {
+ let x = Self::Baz { i: 42 };
+ check_pat!(x, Self::Baz { i: 42 });
+ x
+ }
+
+ fn qux() -> Self {
+ let x = Self::Qux;
+ assert_eq!(x, <Self>::Qux);
+ check_pat!(x, Self::Qux);
+ check_pat!(x, <Self>::Qux);
+ x
+ }
+}
+
+fn main() {
+ let bar = Foo::Bar(1);
+ assert_eq!(bar, FooAlias::Bar(1));
+ assert_eq!(bar, <FooAlias>::Bar(1));
+ check_pat!(bar, FooAlias::Bar(1));
+
+ let baz = FooAlias::Baz { i: 2 };
+ assert_eq!(baz, Foo::Baz { i: 2 });
+ check_pat!(baz, FooAlias::Baz { i: 2 });
+
+ let qux = Foo::Qux;
+ assert_eq!(qux, FooAlias::Qux);
+ assert_eq!(qux, <FooAlias>::Qux);
+ check_pat!(qux, FooAlias::Qux);
+ check_pat!(qux, <FooAlias>::Qux);
+
+ assert_eq!(Foo::bar(), Foo::Bar(3));
+ assert_eq!(Foo::baz(), Foo::Baz { i: 42 });
+ assert_eq!(Foo::qux(), Foo::Qux);
+
+ let some = Option::Some(4);
+ assert_eq!(some, OptionAlias::Some(4));
+ check_pat!(some, OptionAlias::Some(4));
+}