about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-07-01 03:11:19 +0000
committerbors <bors@rust-lang.org>2019-07-01 03:11:19 +0000
commit5748825cc8c74cccef0059cdd4043e6e9b4aa188 (patch)
tree0b989373bea2f277c413b84b9ab236141a83885d
parent0af8e872ea5ac77effa59f8d3f8794f12cb8865c (diff)
parent57e6869a6be56cd75e382deb313fb5f4d1bb1fda (diff)
downloadrust-5748825cc8c74cccef0059cdd4043e6e9b4aa188.tar.gz
rust-5748825cc8c74cccef0059cdd4043e6e9b4aa188.zip
Auto merge of #61682 - Centril:stabilize-type_alias_enum_variants, r=petrochenkov
Stabilize `type_alias_enum_variants` in Rust 1.37.0

Stabilize `#![feature(type_alias_enum_variants)]` which allows type-relative resolution with highest priority to `enum` variants in both expression and pattern contexts. For example, you may now write:

```rust
enum Option<T> {
    None,
    Some(T),
}

type OptAlias<T> = Option<T>;

fn work_on_alias(x: Option<u8>) -> u8 {
    match x {
        OptAlias::Some(y) => y + 1,
        OptAlias::None => 0,
    }
}
```

Closes https://github.com/rust-lang/rfcs/issues/2218
Closes https://github.com/rust-lang/rust/issues/52118

r? @petrochenkov
-rw-r--r--src/doc/unstable-book/src/language-features/type-alias-enum-variants.md36
-rw-r--r--src/librustc_resolve/lib.rs2
-rw-r--r--src/librustc_typeck/astconv.rs2
-rw-r--r--src/librustc_typeck/check/method/mod.rs3
-rw-r--r--src/librustc_typeck/lib.rs17
-rw-r--r--src/libsyntax/feature_gate.rs5
-rw-r--r--src/test/run-pass/type-alias-enum-variants-2.rs30
-rw-r--r--src/test/run-pass/type-alias-enum-variants.rs30
-rw-r--r--src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.rs19
-rw-r--r--src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.stderr34
-rw-r--r--src/test/ui/type-alias-enum-variants-panic.rs17
-rw-r--r--src/test/ui/type-alias-enum-variants-panic.stderr21
-rw-r--r--src/test/ui/type-alias-enum-variants-priority-2.rs13
-rw-r--r--src/test/ui/type-alias-enum-variants-priority-2.stderr12
-rw-r--r--src/test/ui/type-alias-enum-variants-priority-3.rs10
-rw-r--r--src/test/ui/type-alias-enum-variants-priority.rs19
-rw-r--r--src/test/ui/type-alias-enum-variants.rs11
-rw-r--r--src/test/ui/type-alias-enum-variants/enum-variant-generic-args-pass.rs (renamed from src/test/ui/pattern/enum-variant-generic-args.rs)22
-rw-r--r--src/test/ui/type-alias-enum-variants/enum-variant-generic-args.rs (renamed from src/test/ui/enum-variant-generic-args.rs)36
-rw-r--r--src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr (renamed from src/test/ui/enum-variant-generic-args.stderr)124
-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.stderr22
-rw-r--r--src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.rs37
-rw-r--r--src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr (renamed from src/test/ui/type-alias-enum-variants-priority.stderr)6
-rw-r--r--src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.rs (renamed from src/test/ui/issues/issue-58006.rs)1
-rw-r--r--src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr (renamed from src/test/ui/issues/issue-58006.stderr)2
-rw-r--r--src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs21
-rw-r--r--src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr43
-rw-r--r--src/test/ui/type-alias-enum-variants/issue-57866.rs (renamed from src/test/ui/issues/issue-57866.rs)2
-rw-r--r--src/test/ui/type-alias-enum-variants/issue-61801-path-pattern-can-infer.rs2
-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.stderr (renamed from src/test/ui/type-alias-enum-variants.stderr)4
-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.stderr (renamed from src/test/ui/type-alias-enum-variants-priority-3.stderr)2
-rw-r--r--src/test/ui/type-alias-enum-variants/type-alias-enum-variants-pass.rs69
35 files changed, 399 insertions, 323 deletions
diff --git a/src/doc/unstable-book/src/language-features/type-alias-enum-variants.md b/src/doc/unstable-book/src/language-features/type-alias-enum-variants.md
deleted file mode 100644
index bcdeafc4b11..00000000000
--- a/src/doc/unstable-book/src/language-features/type-alias-enum-variants.md
+++ /dev/null
@@ -1,36 +0,0 @@
-# `type_alias_enum_variants`
-
-The tracking issue for this feature is: [#49683]
-
-[#49683]: https://github.com/rust-lang/rust/issues/49683
-
-------------------------
-
-The `type_alias_enum_variants` feature enables the use of variants on type
-aliases that refer to enums, as both a constructor and a pattern. That is,
-it allows for the syntax `EnumAlias::Variant`, which behaves exactly the same
-as `Enum::Variant` (assuming that `EnumAlias` is an alias for some enum type
-`Enum`).
-
-Note that since `Self` exists as a type alias, this feature also enables the
-use of the syntax `Self::Variant` within an impl block for an enum type.
-
-```rust
-#![feature(type_alias_enum_variants)]
-
-enum Foo {
-    Bar(i32),
-    Baz { i: i32 },
-}
-
-type Alias = Foo;
-
-fn main() {
-    let t = Alias::Bar(0);
-    let t = Alias::Baz { i: 0 };
-    match t {
-        Alias::Bar(_i) => {}
-        Alias::Baz { i: _i } => {}
-    }
-}
-```
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 81adfac0a29..f4c23a023b1 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -6,7 +6,7 @@
 #![feature(label_break_value)]
 #![feature(nll)]
 #![feature(rustc_diagnostic_macros)]
-#![feature(type_alias_enum_variants)]
+#![cfg_attr(bootstrap, feature(type_alias_enum_variants))]
 
 #![recursion_limit="256"]
 
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 0375ad4a08f..9b8f6a556bf 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -34,7 +34,6 @@ use std::collections::BTreeSet;
 use std::iter;
 use std::slice;
 
-use super::{check_type_alias_enum_variants_enabled};
 use rustc_data_structures::fx::FxHashSet;
 
 #[derive(Debug)]
@@ -1595,7 +1594,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 });
                 if let Some(variant_def) = variant_def {
                     if permit_variants {
-                        check_type_alias_enum_variants_enabled(tcx, span);
                         tcx.check_stability(variant_def.def_id, Some(hir_ref_id), span);
                         return Ok((qself_ty, DefKind::Variant, variant_def.def_id));
                     } else {
diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs
index b492197870b..b8b65279fe7 100644
--- a/src/librustc_typeck/check/method/mod.rs
+++ b/src/librustc_typeck/check/method/mod.rs
@@ -26,7 +26,6 @@ use rustc::infer::{self, InferOk};
 use syntax::ast;
 use syntax_pos::Span;
 
-use crate::{check_type_alias_enum_variants_enabled};
 use self::probe::{IsSuggestion, ProbeScope};
 
 pub fn provide(providers: &mut ty::query::Providers<'_>) {
@@ -417,8 +416,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     tcx.hygienic_eq(method_name, vd.ident, adt_def.did)
                 });
                 if let Some(variant_def) = variant_def {
-                    check_type_alias_enum_variants_enabled(tcx, span);
-
                     // Braced variants generate unusable names in value namespace (reserved for
                     // possible future use), so variants resolved as associated items may refer to
                     // them as well. It's ok to use the variant's id as a ctor id since an
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 182594e7684..85ae55b2dd9 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -105,7 +105,7 @@ use rustc::lint;
 use rustc::middle;
 use rustc::session;
 use rustc::util::common::ErrorReported;
-use rustc::session::config::{EntryFnType, nightly_options};
+use rustc::session::config::EntryFnType;
 use rustc::traits::{ObligationCause, ObligationCauseCode, TraitEngine, TraitEngineExt};
 use rustc::ty::subst::SubstsRef;
 use rustc::ty::{self, Ty, TyCtxt};
@@ -124,21 +124,6 @@ pub struct TypeAndSubsts<'tcx> {
     ty: Ty<'tcx>,
 }
 
-fn check_type_alias_enum_variants_enabled<'tcx>(tcx: TyCtxt<'tcx>, span: Span) {
-    if !tcx.features().type_alias_enum_variants {
-        let mut err = tcx.sess.struct_span_err(
-            span,
-            "enum variants on type aliases are experimental"
-        );
-        if nightly_options::is_nightly_build() {
-            help!(&mut err,
-                "add `#![feature(type_alias_enum_variants)]` to the \
-                crate attributes to enable");
-        }
-        err.emit();
-    }
-}
-
 fn require_c_abi_if_c_variadic(tcx: TyCtxt<'_>, decl: &hir::FnDecl, abi: Abi, span: Span) {
     if decl.c_variadic && !(abi == Abi::C || abi == Abi::Cdecl) {
         let mut err = struct_span_err!(tcx.sess, span, E0045,
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index a6e8441a915..f97e9d43854 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -530,9 +530,6 @@ declare_features! (
     // Allows using `reason` in lint attributes and the `#[expect(lint)]` lint check.
     (active, lint_reasons, "1.31.0", Some(54503), None),
 
-    // Allows paths to enum variants on type aliases.
-    (active, type_alias_enum_variants, "1.31.0", Some(49683), None),
-
     // Allows exhaustive integer pattern matching on `usize` and `isize`.
     (active, precise_pointer_size_matching, "1.32.0", Some(56354), None),
 
@@ -853,6 +850,8 @@ declare_features! (
     (accepted, extern_crate_self, "1.34.0", Some(56409), None),
     // Allows arbitrary delimited token streams in non-macro attributes.
     (accepted, unrestricted_attribute_tokens, "1.34.0", Some(55208), None),
+    // Allows paths to enum variants on type aliases including `Self`.
+    (accepted, type_alias_enum_variants, "1.37.0", Some(49683), None),
     // Allows using `#[repr(align(X))]` on enums with equivalent semantics
     // to wrapping an enum in a wrapper struct with `#[repr(align(X))]`.
     (accepted, repr_align_enum, "1.37.0", Some(57996), None),
diff --git a/src/test/run-pass/type-alias-enum-variants-2.rs b/src/test/run-pass/type-alias-enum-variants-2.rs
deleted file mode 100644
index 0cf413babcb..00000000000
--- a/src/test/run-pass/type-alias-enum-variants-2.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-#![feature(type_alias_enum_variants)]
-
-#[derive(Debug, PartialEq, Eq)]
-enum Foo {
-    Bar(i32),
-    Baz { i: i32 },
-}
-
-type FooAlias = Foo;
-type OptionAlias = Option<i32>;
-
-impl Foo {
-    fn foo() -> Self {
-        Self::Bar(3)
-    }
-}
-
-fn main() {
-    let t = FooAlias::Bar(1);
-    assert_eq!(t, Foo::Bar(1));
-    let t = FooAlias::Baz { i: 2 };
-    assert_eq!(t, Foo::Baz { i: 2 });
-    match t {
-        FooAlias::Bar(_i) => {}
-        FooAlias::Baz { i } => { assert_eq!(i, 2); }
-    }
-    assert_eq!(Foo::foo(), Foo::Bar(3));
-
-    assert_eq!(OptionAlias::Some(4), Option::Some(4));
-}
diff --git a/src/test/run-pass/type-alias-enum-variants.rs b/src/test/run-pass/type-alias-enum-variants.rs
deleted file mode 100644
index 0cf413babcb..00000000000
--- a/src/test/run-pass/type-alias-enum-variants.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-#![feature(type_alias_enum_variants)]
-
-#[derive(Debug, PartialEq, Eq)]
-enum Foo {
-    Bar(i32),
-    Baz { i: i32 },
-}
-
-type FooAlias = Foo;
-type OptionAlias = Option<i32>;
-
-impl Foo {
-    fn foo() -> Self {
-        Self::Bar(3)
-    }
-}
-
-fn main() {
-    let t = FooAlias::Bar(1);
-    assert_eq!(t, Foo::Bar(1));
-    let t = FooAlias::Baz { i: 2 };
-    assert_eq!(t, Foo::Baz { i: 2 });
-    match t {
-        FooAlias::Bar(_i) => {}
-        FooAlias::Baz { i } => { assert_eq!(i, 2); }
-    }
-    assert_eq!(Foo::foo(), Foo::Bar(3));
-
-    assert_eq!(OptionAlias::Some(4), Option::Some(4));
-}
diff --git a/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.rs b/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.rs
deleted file mode 100644
index c7d3304a128..00000000000
--- a/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-enum Foo {
-    Bar(i32),
-    Baz { i: i32 },
-}
-
-type Alias = Foo;
-
-fn main() {
-    let t = Alias::Bar(0);
-    //~^ ERROR enum variants on type aliases are experimental
-    let t = Alias::Baz { i: 0 };
-    //~^ ERROR enum variants on type aliases are experimental
-    match t {
-        Alias::Bar(_i) => {}
-        //~^ ERROR enum variants on type aliases are experimental
-        Alias::Baz { i: _i } => {}
-        //~^ ERROR enum variants on type aliases are experimental
-    }
-}
diff --git a/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.stderr b/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.stderr
deleted file mode 100644
index 43535af7c69..00000000000
--- a/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.stderr
+++ /dev/null
@@ -1,34 +0,0 @@
-error: enum variants on type aliases are experimental
-  --> $DIR/feature-gate-type_alias_enum_variants.rs:9:13
-   |
-LL |     let t = Alias::Bar(0);
-   |             ^^^^^^^^^^
-   |
-   = help: add `#![feature(type_alias_enum_variants)]` to the crate attributes to enable
-
-error: enum variants on type aliases are experimental
-  --> $DIR/feature-gate-type_alias_enum_variants.rs:11:13
-   |
-LL |     let t = Alias::Baz { i: 0 };
-   |             ^^^^^^^^^^
-   |
-   = help: add `#![feature(type_alias_enum_variants)]` to the crate attributes to enable
-
-error: enum variants on type aliases are experimental
-  --> $DIR/feature-gate-type_alias_enum_variants.rs:14:9
-   |
-LL |         Alias::Bar(_i) => {}
-   |         ^^^^^^^^^^^^^^
-   |
-   = help: add `#![feature(type_alias_enum_variants)]` to the crate attributes to enable
-
-error: enum variants on type aliases are experimental
-  --> $DIR/feature-gate-type_alias_enum_variants.rs:16:9
-   |
-LL |         Alias::Baz { i: _i } => {}
-   |         ^^^^^^^^^^
-   |
-   = help: add `#![feature(type_alias_enum_variants)]` to the crate attributes to enable
-
-error: aborting due to 4 previous errors
-
diff --git a/src/test/ui/type-alias-enum-variants-panic.rs b/src/test/ui/type-alias-enum-variants-panic.rs
deleted file mode 100644
index f97592f5d3b..00000000000
--- a/src/test/ui/type-alias-enum-variants-panic.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-// ignore-tidy-linelength
-
-#![feature(type_alias_enum_variants)]
-
-#![allow(unreachable_code)]
-
-enum Enum { Variant {} }
-type Alias = Enum;
-
-fn main() {
-    Alias::Variant;
-    //~^ ERROR expected unit struct/variant or constant, found struct variant `<Alias>::Variant` [E0533]
-    let Alias::Variant = panic!();
-    //~^ ERROR expected unit struct/variant or constant, found struct variant `<Alias>::Variant` [E0533]
-    let Alias::Variant(..) = panic!();
-    //~^ ERROR expected tuple struct/variant, found struct variant `<Alias>::Variant` [E0164]
-}
diff --git a/src/test/ui/type-alias-enum-variants-panic.stderr b/src/test/ui/type-alias-enum-variants-panic.stderr
deleted file mode 100644
index 24cf85f5278..00000000000
--- a/src/test/ui/type-alias-enum-variants-panic.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-error[E0533]: expected unit struct/variant or constant, found struct variant `<Alias>::Variant`
-  --> $DIR/type-alias-enum-variants-panic.rs:11:5
-   |
-LL |     Alias::Variant;
-   |     ^^^^^^^^^^^^^^
-
-error[E0533]: expected unit struct/variant or constant, found struct variant `<Alias>::Variant`
-  --> $DIR/type-alias-enum-variants-panic.rs:13:9
-   |
-LL |     let Alias::Variant = panic!();
-   |         ^^^^^^^^^^^^^^
-
-error[E0164]: expected tuple struct/variant, found struct variant `<Alias>::Variant`
-  --> $DIR/type-alias-enum-variants-panic.rs:15:9
-   |
-LL |     let Alias::Variant(..) = panic!();
-   |         ^^^^^^^^^^^^^^^^^^ not a tuple variant or struct
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0164`.
diff --git a/src/test/ui/type-alias-enum-variants-priority-2.rs b/src/test/ui/type-alias-enum-variants-priority-2.rs
deleted file mode 100644
index 295f8acf62f..00000000000
--- a/src/test/ui/type-alias-enum-variants-priority-2.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-#![feature(type_alias_enum_variants)]
-
-enum E {
-    V(u8)
-}
-
-impl E {
-    fn V() {}
-}
-
-fn main() {
-    <E>::V(); //~ ERROR this function takes 1 parameter but 0 parameters were supplied
-}
diff --git a/src/test/ui/type-alias-enum-variants-priority-2.stderr b/src/test/ui/type-alias-enum-variants-priority-2.stderr
deleted file mode 100644
index 10a4b44084a..00000000000
--- a/src/test/ui/type-alias-enum-variants-priority-2.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0061]: this function takes 1 parameter but 0 parameters were supplied
-  --> $DIR/type-alias-enum-variants-priority-2.rs:12:5
-   |
-LL |     V(u8)
-   |     ----- defined here
-...
-LL |     <E>::V();
-   |     ^^^^^^^^ expected 1 parameter
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0061`.
diff --git a/src/test/ui/type-alias-enum-variants-priority-3.rs b/src/test/ui/type-alias-enum-variants-priority-3.rs
deleted file mode 100644
index 33f96553b57..00000000000
--- a/src/test/ui/type-alias-enum-variants-priority-3.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-#![feature(type_alias_enum_variants)]
-
-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-priority.rs b/src/test/ui/type-alias-enum-variants-priority.rs
deleted file mode 100644
index 82cd21b09d3..00000000000
--- a/src/test/ui/type-alias-enum-variants-priority.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-#![feature(type_alias_enum_variants)]
-
-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
-    //~| WARN this was previously accepted
-}
-
-fn main() {}
diff --git a/src/test/ui/type-alias-enum-variants.rs b/src/test/ui/type-alias-enum-variants.rs
deleted file mode 100644
index c5974e55692..00000000000
--- a/src/test/ui/type-alias-enum-variants.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-#![feature(type_alias_enum_variants)]
-
-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 for this type
-}
diff --git a/src/test/ui/pattern/enum-variant-generic-args.rs b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args-pass.rs
index 85599530ea6..0c212096f92 100644
--- a/src/test/ui/pattern/enum-variant-generic-args.rs
+++ b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args-pass.rs
@@ -1,17 +1,22 @@
 // run-pass
 
-#![feature(type_alias_enum_variants)]
+// 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)]
 
-#[allow(dead_code)]
-enum Enum<T> { TSVariant(T), SVariant { v: T } }
+enum Enum<T> { TSVariant(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");
@@ -40,4 +45,15 @@ fn main() {
     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/enum-variant-generic-args.rs b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.rs
index dd1f5f334df..f182c3ba8c7 100644
--- a/src/test/ui/enum-variant-generic-args.rs
+++ b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.rs
@@ -1,6 +1,10 @@
-#![feature(type_alias_enum_variants)]
+// 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 } }
+enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant }
 type Alias<T> = Enum<T>;
 type AliasFixed = Enum<()>;
 
@@ -32,6 +36,16 @@ impl<T> Enum<T> {
         //~^^ ERROR type arguments are not allowed for this type [E0109]
         //~^^^ ERROR mismatched types [E0308]
     }
+
+    fn u_variant() {
+        Self::UVariant::<()>;
+        //~^ ERROR type arguments are not allowed for this type [E0109]
+        Self::<()>::UVariant;
+        //~^ ERROR type arguments are not allowed for this type [E0109]
+        Self::<()>::UVariant::<()>;
+        //~^ ERROR type arguments are not allowed for this type [E0109]
+        //~^^ ERROR type arguments are not allowed for this type [E0109]
+    }
 }
 
 fn main() {
@@ -70,4 +84,22 @@ fn main() {
     AliasFixed::<()>::SVariant::<()> { v: () };
     //~^ ERROR type arguments are not allowed for this type [E0109]
     //~^^ ERROR wrong number of type arguments: expected 0, found 1 [E0107]
+
+    // Unit variant
+
+    Enum::<()>::UVariant::<()>;
+    //~^ ERROR type arguments are not allowed for this type [E0109]
+
+    Alias::UVariant::<()>;
+    //~^ ERROR type arguments are not allowed for this type [E0109]
+    Alias::<()>::UVariant::<()>;
+    //~^ ERROR type arguments are not allowed for this type [E0109]
+
+    AliasFixed::UVariant::<()>;
+    //~^ ERROR type arguments are not allowed for this type [E0109]
+    AliasFixed::<()>::UVariant;
+    //~^ ERROR wrong number of type arguments: expected 0, found 1 [E0107]
+    AliasFixed::<()>::UVariant::<()>;
+    //~^ ERROR type arguments are not allowed for this type [E0109]
+    //~^^ ERROR wrong number of type arguments: expected 0, found 1 [E0107]
 }
diff --git a/src/test/ui/enum-variant-generic-args.stderr b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr
index 97b111a5c85..ee73622cb7b 100644
--- a/src/test/ui/enum-variant-generic-args.stderr
+++ b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/enum-variant-generic-args.rs:9:25
+  --> $DIR/enum-variant-generic-args.rs:13:25
    |
 LL |         Self::TSVariant(());
    |                         ^^ expected type parameter, found ()
@@ -8,19 +8,19 @@ LL |         Self::TSVariant(());
               found type `()`
 
 error[E0109]: type arguments are not allowed for this type
-  --> $DIR/enum-variant-generic-args.rs:11:27
+  --> $DIR/enum-variant-generic-args.rs:15:27
    |
 LL |         Self::TSVariant::<()>(());
    |                           ^^ type argument not allowed
 
 error[E0109]: type arguments are not allowed for this type
-  --> $DIR/enum-variant-generic-args.rs:13:16
+  --> $DIR/enum-variant-generic-args.rs:17:16
    |
 LL |         Self::<()>::TSVariant(());
    |                ^^ type argument not allowed
 
 error[E0308]: mismatched types
-  --> $DIR/enum-variant-generic-args.rs:13:31
+  --> $DIR/enum-variant-generic-args.rs:17:31
    |
 LL |         Self::<()>::TSVariant(());
    |                               ^^ expected type parameter, found ()
@@ -29,19 +29,19 @@ LL |         Self::<()>::TSVariant(());
               found type `()`
 
 error[E0109]: type arguments are not allowed for this type
-  --> $DIR/enum-variant-generic-args.rs:16:16
+  --> $DIR/enum-variant-generic-args.rs:20:16
    |
 LL |         Self::<()>::TSVariant::<()>(());
    |                ^^ type argument not allowed
 
 error[E0109]: type arguments are not allowed for this type
-  --> $DIR/enum-variant-generic-args.rs:16:33
+  --> $DIR/enum-variant-generic-args.rs:20:33
    |
 LL |         Self::<()>::TSVariant::<()>(());
    |                                 ^^ type argument not allowed
 
 error[E0308]: mismatched types
-  --> $DIR/enum-variant-generic-args.rs:22:29
+  --> $DIR/enum-variant-generic-args.rs:26:29
    |
 LL |         Self::SVariant { v: () };
    |                             ^^ expected type parameter, found ()
@@ -50,13 +50,13 @@ LL |         Self::SVariant { v: () };
               found type `()`
 
 error[E0109]: type arguments are not allowed for this type
-  --> $DIR/enum-variant-generic-args.rs:24:26
+  --> $DIR/enum-variant-generic-args.rs:28:26
    |
 LL |         Self::SVariant::<()> { v: () };
    |                          ^^ type argument not allowed
 
 error[E0308]: mismatched types
-  --> $DIR/enum-variant-generic-args.rs:24:35
+  --> $DIR/enum-variant-generic-args.rs:28:35
    |
 LL |         Self::SVariant::<()> { v: () };
    |                                   ^^ expected type parameter, found ()
@@ -65,13 +65,13 @@ LL |         Self::SVariant::<()> { v: () };
               found type `()`
 
 error[E0109]: type arguments are not allowed for this type
-  --> $DIR/enum-variant-generic-args.rs:27:16
+  --> $DIR/enum-variant-generic-args.rs:31:16
    |
 LL |         Self::<()>::SVariant { v: () };
    |                ^^ type argument not allowed
 
 error[E0308]: mismatched types
-  --> $DIR/enum-variant-generic-args.rs:27:35
+  --> $DIR/enum-variant-generic-args.rs:31:35
    |
 LL |         Self::<()>::SVariant { v: () };
    |                                   ^^ expected type parameter, found ()
@@ -80,19 +80,19 @@ LL |         Self::<()>::SVariant { v: () };
               found type `()`
 
 error[E0109]: type arguments are not allowed for this type
-  --> $DIR/enum-variant-generic-args.rs:30:16
+  --> $DIR/enum-variant-generic-args.rs:34:16
    |
 LL |         Self::<()>::SVariant::<()> { v: () };
    |                ^^ type argument not allowed
 
 error[E0109]: type arguments are not allowed for this type
-  --> $DIR/enum-variant-generic-args.rs:30:32
+  --> $DIR/enum-variant-generic-args.rs:34:32
    |
 LL |         Self::<()>::SVariant::<()> { v: () };
    |                                ^^ type argument not allowed
 
 error[E0308]: mismatched types
-  --> $DIR/enum-variant-generic-args.rs:30:41
+  --> $DIR/enum-variant-generic-args.rs:34:41
    |
 LL |         Self::<()>::SVariant::<()> { v: () };
    |                                         ^^ expected type parameter, found ()
@@ -101,90 +101,156 @@ LL |         Self::<()>::SVariant::<()> { v: () };
               found type `()`
 
 error[E0109]: type arguments are not allowed for this type
-  --> $DIR/enum-variant-generic-args.rs:40:29
+  --> $DIR/enum-variant-generic-args.rs:41:26
+   |
+LL |         Self::UVariant::<()>;
+   |                          ^^ type argument not allowed
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/enum-variant-generic-args.rs:43:16
+   |
+LL |         Self::<()>::UVariant;
+   |                ^^ type argument not allowed
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/enum-variant-generic-args.rs:45:16
+   |
+LL |         Self::<()>::UVariant::<()>;
+   |                ^^ type argument not allowed
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/enum-variant-generic-args.rs:45:32
+   |
+LL |         Self::<()>::UVariant::<()>;
+   |                                ^^ type argument not allowed
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/enum-variant-generic-args.rs:54:29
    |
 LL |     Enum::<()>::TSVariant::<()>(());
    |                             ^^ type argument not allowed
 
 error[E0109]: type arguments are not allowed for this type
-  --> $DIR/enum-variant-generic-args.rs:43:24
+  --> $DIR/enum-variant-generic-args.rs:57:24
    |
 LL |     Alias::TSVariant::<()>(());
    |                        ^^ type argument not allowed
 
 error[E0109]: type arguments are not allowed for this type
-  --> $DIR/enum-variant-generic-args.rs:45:30
+  --> $DIR/enum-variant-generic-args.rs:59:30
    |
 LL |     Alias::<()>::TSVariant::<()>(());
    |                              ^^ type argument not allowed
 
 error[E0109]: type arguments are not allowed for this type
-  --> $DIR/enum-variant-generic-args.rs:48:29
+  --> $DIR/enum-variant-generic-args.rs:62:29
    |
 LL |     AliasFixed::TSVariant::<()>(());
    |                             ^^ type argument not allowed
 
 error[E0107]: wrong number of type arguments: expected 0, found 1
-  --> $DIR/enum-variant-generic-args.rs:50:18
+  --> $DIR/enum-variant-generic-args.rs:64:18
    |
 LL |     AliasFixed::<()>::TSVariant(());
    |                  ^^ unexpected type argument
 
 error[E0107]: wrong number of type arguments: expected 0, found 1
-  --> $DIR/enum-variant-generic-args.rs:52:18
+  --> $DIR/enum-variant-generic-args.rs:66:18
    |
 LL |     AliasFixed::<()>::TSVariant::<()>(());
    |                  ^^ unexpected type argument
 
 error[E0109]: type arguments are not allowed for this type
-  --> $DIR/enum-variant-generic-args.rs:52:35
+  --> $DIR/enum-variant-generic-args.rs:66:35
    |
 LL |     AliasFixed::<()>::TSVariant::<()>(());
    |                                   ^^ type argument not allowed
 
 error[E0109]: type arguments are not allowed for this type
-  --> $DIR/enum-variant-generic-args.rs:58:28
+  --> $DIR/enum-variant-generic-args.rs:72:28
    |
 LL |     Enum::<()>::SVariant::<()> { v: () };
    |                            ^^ type argument not allowed
 
 error[E0109]: type arguments are not allowed for this type
-  --> $DIR/enum-variant-generic-args.rs:61:23
+  --> $DIR/enum-variant-generic-args.rs:75:23
    |
 LL |     Alias::SVariant::<()> { v: () };
    |                       ^^ type argument not allowed
 
 error[E0109]: type arguments are not allowed for this type
-  --> $DIR/enum-variant-generic-args.rs:63:29
+  --> $DIR/enum-variant-generic-args.rs:77:29
    |
 LL |     Alias::<()>::SVariant::<()> { v: () };
    |                             ^^ type argument not allowed
 
 error[E0109]: type arguments are not allowed for this type
-  --> $DIR/enum-variant-generic-args.rs:66:28
+  --> $DIR/enum-variant-generic-args.rs:80:28
    |
 LL |     AliasFixed::SVariant::<()> { v: () };
    |                            ^^ type argument not allowed
 
 error[E0107]: wrong number of type arguments: expected 0, found 1
-  --> $DIR/enum-variant-generic-args.rs:68:18
+  --> $DIR/enum-variant-generic-args.rs:82:18
    |
 LL |     AliasFixed::<()>::SVariant { v: () };
    |                  ^^ unexpected type argument
 
 error[E0107]: wrong number of type arguments: expected 0, found 1
-  --> $DIR/enum-variant-generic-args.rs:70:18
+  --> $DIR/enum-variant-generic-args.rs:84:18
    |
 LL |     AliasFixed::<()>::SVariant::<()> { v: () };
    |                  ^^ unexpected type argument
 
 error[E0109]: type arguments are not allowed for this type
-  --> $DIR/enum-variant-generic-args.rs:70:34
+  --> $DIR/enum-variant-generic-args.rs:84:34
    |
 LL |     AliasFixed::<()>::SVariant::<()> { v: () };
    |                                  ^^ type argument not allowed
 
-error: aborting due to 28 previous errors
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/enum-variant-generic-args.rs:90:28
+   |
+LL |     Enum::<()>::UVariant::<()>;
+   |                            ^^ type argument not allowed
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/enum-variant-generic-args.rs:93:23
+   |
+LL |     Alias::UVariant::<()>;
+   |                       ^^ type argument not allowed
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/enum-variant-generic-args.rs:95:29
+   |
+LL |     Alias::<()>::UVariant::<()>;
+   |                             ^^ type argument not allowed
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/enum-variant-generic-args.rs:98:28
+   |
+LL |     AliasFixed::UVariant::<()>;
+   |                            ^^ type argument not allowed
+
+error[E0107]: wrong number of type arguments: expected 0, found 1
+  --> $DIR/enum-variant-generic-args.rs:100:18
+   |
+LL |     AliasFixed::<()>::UVariant;
+   |                  ^^ unexpected type argument
+
+error[E0107]: wrong number of type arguments: expected 0, found 1
+  --> $DIR/enum-variant-generic-args.rs:102:18
+   |
+LL |     AliasFixed::<()>::UVariant::<()>;
+   |                  ^^ unexpected type argument
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/enum-variant-generic-args.rs:102:34
+   |
+LL |     AliasFixed::<()>::UVariant::<()>;
+   |                                  ^^ type argument not allowed
+
+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 00000000000..fa3e1a35fc2
--- /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 function takes 1 parameter but 0 parameters 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 00000000000..0394ddab46c
--- /dev/null
+++ b/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr
@@ -0,0 +1,22 @@
+error[E0061]: this function takes 1 parameter but 0 parameters were supplied
+  --> $DIR/enum-variant-priority-higher-than-other-inherent.rs:21:5
+   |
+LL |     V(u8)
+   |     ----- defined here
+...
+LL |     <E>::V();
+   |     ^^^^^^^^ expected 1 parameter
+
+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`
+   |
+   = note: expected type `u8`
+              found type `E2`
+
+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 00000000000..7f69590400b
--- /dev/null
+++ b/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.rs
@@ -0,0 +1,37 @@
+// 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
+    //~| WARN this was previously accepted
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-enum-variants-priority.stderr b/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr
index b8271807b83..f0dd689934f 100644
--- a/src/test/ui/type-alias-enum-variants-priority.stderr
+++ b/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr
@@ -1,5 +1,5 @@
 error: ambiguous associated item
-  --> $DIR/type-alias-enum-variants-priority.rs:14:15
+  --> $DIR/enum-variant-priority-lint-ambiguous_associated_items.rs:32:15
    |
 LL |     fn f() -> Self::V { 0 }
    |               ^^^^^^^ help: use fully-qualified syntax: `<E as Trait>::V`
@@ -8,12 +8,12 @@ LL |     fn f() -> Self::V { 0 }
    = 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 variant defined here
-  --> $DIR/type-alias-enum-variants-priority.rs:4:5
+  --> $DIR/enum-variant-priority-lint-ambiguous_associated_items.rs:22:5
    |
 LL |     V
    |     ^
 note: `V` could also refer to associated type defined here
-  --> $DIR/type-alias-enum-variants-priority.rs:8:5
+  --> $DIR/enum-variant-priority-lint-ambiguous_associated_items.rs:26:5
    |
 LL |     type V;
    |     ^^^^^^^
diff --git a/src/test/ui/issues/issue-58006.rs b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.rs
index 1fb5fefa759..c1e56fc4caa 100644
--- a/src/test/ui/issues/issue-58006.rs
+++ b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.rs
@@ -1,4 +1,3 @@
-#![feature(type_alias_enum_variants)]
 pub enum Enum {
     A(usize),
 }
diff --git a/src/test/ui/issues/issue-58006.stderr b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr
index c34e133c6c4..128a85e1563 100644
--- a/src/test/ui/issues/issue-58006.stderr
+++ b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr
@@ -1,5 +1,5 @@
 error[E0533]: expected unit struct/variant or constant, found tuple variant `<Self>::A`
-  --> $DIR/issue-58006.rs:9:13
+  --> $DIR/incorrect-variant-form-through-Self-issue-58006.rs:8:13
    |
 LL |             Self::A => (),
    |             ^^^^^^^
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 00000000000..ce45d59198a
--- /dev/null
+++ b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs
@@ -0,0 +1,21 @@
+// ignore-tidy-linelength
+
+// 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/variant or constant, found struct variant `<Alias>::Braced` [E0533]
+    let Alias::Braced = panic!();
+    //~^ ERROR expected unit struct/variant or constant, found struct variant `<Alias>::Braced` [E0533]
+    let Alias::Braced(..) = panic!();
+    //~^ ERROR expected tuple struct/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/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 00000000000..c1ea816b7fa
--- /dev/null
+++ b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr
@@ -0,0 +1,43 @@
+error[E0533]: expected unit struct/variant or constant, found struct variant `<Alias>::Braced`
+  --> $DIR/incorrect-variant-form-through-alias-caught.rs:10:5
+   |
+LL |     Alias::Braced;
+   |     ^^^^^^^^^^^^^
+
+error[E0533]: expected unit struct/variant or constant, found struct variant `<Alias>::Braced`
+  --> $DIR/incorrect-variant-form-through-alias-caught.rs:12:9
+   |
+LL |     let Alias::Braced = panic!();
+   |         ^^^^^^^^^^^^^
+
+error[E0164]: expected tuple struct/variant, found struct variant `<Alias>::Braced`
+  --> $DIR/incorrect-variant-form-through-alias-caught.rs:14: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:17:5
+   |
+LL | enum Enum { Braced {}, Unit, Tuple() }
+   |                        ---- `<Alias>::Unit` defined here
+...
+LL |     Alias::Unit();
+   |     ^^^^^^^^^^^--
+   |     |
+   |     call expression requires function
+help: `<Alias>::Unit` is a unit variant, you need to write it without the parenthesis
+   |
+LL |     <Alias>::Unit;
+   |     ^^^^^^^^^^^^^
+
+error[E0164]: expected tuple struct/variant, found unit variant `<Alias>::Unit`
+  --> $DIR/incorrect-variant-form-through-alias-caught.rs:19: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, E0618.
+For more information about an error, try `rustc --explain E0164`.
diff --git a/src/test/ui/issues/issue-57866.rs b/src/test/ui/type-alias-enum-variants/issue-57866.rs
index 77c50e53868..fa351ed51dd 100644
--- a/src/test/ui/issues/issue-57866.rs
+++ b/src/test/ui/type-alias-enum-variants/issue-57866.rs
@@ -1,7 +1,5 @@
 // compile-pass
 
-#![feature(type_alias_enum_variants)]
-
 enum Outer<T> {
     A(T)
 }
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
index 21be61acb0c..dfc618b1649 100644
--- 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
@@ -3,8 +3,6 @@
 
 // compile-pass
 
-#![feature(type_alias_enum_variants)]
-
 enum Opt<T> {
     N,
     S(T),
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 00000000000..c1153fa4dc7
--- /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 for this type
+}
diff --git a/src/test/ui/type-alias-enum-variants.stderr b/src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.stderr
index 55f250fa7ee..a1064d69251 100644
--- a/src/test/ui/type-alias-enum-variants.stderr
+++ b/src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.stderr
@@ -1,7 +1,7 @@
 error[E0109]: type arguments are not allowed for this type
-  --> $DIR/type-alias-enum-variants.rs:9:27
+  --> $DIR/no-type-application-on-aliased-enum-variant.rs:13:27
    |
-LL |     let _ = Alias::None::<u8>; // Error
+LL |     let _ = Alias::None::<u8>;
    |                           ^^ type argument not allowed
 
 error: aborting due to previous error
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 00000000000..11f4b05d0bf
--- /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-priority-3.stderr b/src/test/ui/type-alias-enum-variants/resolve-to-enum-variant-in-type-namespace-and-error.stderr
index b3451542a25..f190bfb6983 100644
--- a/src/test/ui/type-alias-enum-variants-priority-3.stderr
+++ b/src/test/ui/type-alias-enum-variants/resolve-to-enum-variant-in-type-namespace-and-error.stderr
@@ -1,5 +1,5 @@
 error: expected type, found variant `V`
-  --> $DIR/type-alias-enum-variants-priority-3.rs:7:15
+  --> $DIR/resolve-to-enum-variant-in-type-namespace-and-error.rs:8:15
    |
 LL | fn check() -> <E>::V {}
    |               ^^^^^^
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 00000000000..39677733d52
--- /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));
+}