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; - -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; - -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 `::Variant` [E0533] - let Alias::Variant = panic!(); - //~^ ERROR expected unit struct/variant or constant, found struct variant `::Variant` [E0533] - let Alias::Variant(..) = panic!(); - //~^ ERROR expected tuple struct/variant, found struct variant `::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 `::Variant` - --> $DIR/type-alias-enum-variants-panic.rs:11:5 - | -LL | Alias::Variant; - | ^^^^^^^^^^^^^^ - -error[E0533]: expected unit struct/variant or constant, found struct variant `::Variant` - --> $DIR/type-alias-enum-variants-panic.rs:13:9 - | -LL | let Alias::Variant = panic!(); - | ^^^^^^^^^^^^^^ - -error[E0164]: expected tuple struct/variant, found struct variant `::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() { - ::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 | ::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() -> ::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 = Option; - -fn main() { - let _ = Option::::None; // OK - let _ = Option::None::; // OK (Lint in future!) - let _ = Alias::::None; // OK - let _ = Alias::None::; // 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 similarity index 59% rename from src/test/ui/pattern/enum-variant-generic-args.rs rename to 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`, we can type-apply `Alias` when referring to a variant. +// 2. a monotype `AliasFixed` of generic `Enum`, we can refer to variants +// and the type-application of `T` in `AliasFixed` is kept. #![allow(irrefutable_let_patterns)] -#[allow(dead_code)] -enum Enum { TSVariant(T), SVariant { v: T } } +enum Enum { TSVariant(T), SVariant { v: T }, UVariant } type Alias = Enum; 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 similarity index 65% rename from src/test/ui/enum-variant-generic-args.rs rename to 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 { TSVariant(T), SVariant { v: T } } +enum Enum { TSVariant(T), SVariant { v: T }, UVariant } type Alias = Enum; type AliasFixed = Enum<()>; @@ -32,6 +36,16 @@ impl Enum { //~^^ 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 similarity index 58% rename from src/test/ui/enum-variant-generic-args.stderr rename to 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() { + ::V(); //~ ERROR this function takes 1 parameter but 0 parameters were supplied + let _: u8 = ::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 | ::V(); + | ^^^^^^^^ expected 1 parameter + +error[E0308]: mismatched types + --> $DIR/enum-variant-priority-higher-than-other-inherent.rs:22:17 + | +LL | let _: u8 = ::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 `::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 similarity index 74% rename from src/test/ui/type-alias-enum-variants-priority.stderr rename to 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: `::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 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 similarity index 86% rename from src/test/ui/issues/issue-58006.rs rename to 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 similarity index 73% rename from src/test/ui/issues/issue-58006.stderr rename to 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 `::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 `::Braced` [E0533] + let Alias::Braced = panic!(); + //~^ ERROR expected unit struct/variant or constant, found struct variant `::Braced` [E0533] + let Alias::Braced(..) = panic!(); + //~^ ERROR expected tuple struct/variant, found struct variant `::Braced` [E0164] + + Alias::Unit(); + //~^ ERROR expected function, found enum variant `::Unit` + let Alias::Unit() = panic!(); + //~^ ERROR expected tuple struct/variant, found unit variant `::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 `::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 `::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 `::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 `::Unit` + --> $DIR/incorrect-variant-form-through-alias-caught.rs:17:5 + | +LL | enum Enum { Braced {}, Unit, Tuple() } + | ---- `::Unit` defined here +... +LL | Alias::Unit(); + | ^^^^^^^^^^^-- + | | + | call expression requires function +help: `::Unit` is a unit variant, you need to write it without the parenthesis + | +LL | ::Unit; + | ^^^^^^^^^^^^^ + +error[E0164]: expected tuple struct/variant, found unit variant `::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 similarity index 88% rename from src/test/ui/issues/issue-57866.rs rename to 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 { 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 { 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 = Option; + +fn main() { + let _ = Option::::None; // OK + let _ = Option::None::; // OK (Lint in future!) + let _ = Alias::::None; // OK + let _ = Alias::None::; //~ 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 similarity index 69% rename from src/test/ui/type-alias-enum-variants.stderr rename to 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::; // Error +LL | let _ = Alias::None::; | ^^ 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 `::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() -> ::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 similarity index 66% rename from src/test/ui/type-alias-enum-variants-priority-3.stderr rename to 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() -> ::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 `::Variant` also works when syntactically valid. + +#[derive(Debug, PartialEq, Eq)] +enum Foo { + Bar(i32), + Baz { i: i32 }, + Qux, +} + +type FooAlias = Foo; +type OptionAlias = Option; + +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, ::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, ::Qux); + check_pat!(x, Self::Qux); + check_pat!(x, ::Qux); + x + } +} + +fn main() { + let bar = Foo::Bar(1); + assert_eq!(bar, FooAlias::Bar(1)); + assert_eq!(bar, ::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, ::Qux); + check_pat!(qux, FooAlias::Qux); + check_pat!(qux, ::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)); +}