diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 4f637a23e69..dd298ce84fa 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -453,9 +453,6 @@ declare_features! ( // Allows `#[doc(alias = "...")]`. (active, doc_alias, "1.27.0", Some(50146), None), - // Allows defining `existential type`s. - (active, existential_type, "1.28.0", Some(63063), None), - // Allows inconsistent bounds in where clauses. (active, trivial_bounds, "1.28.0", Some(48214), None), @@ -560,6 +557,9 @@ declare_features! ( // Allows `[x; N]` where `x` is a constant (RFC 2203). (active, const_in_array_repeat_expressions, "1.37.0", Some(49147), None), + // Allows `impl Trait` to be used inside type aliases (RFC 2515). + (active, type_alias_impl_trait, "1.38.0", Some(63063), None), + // ------------------------------------------------------------------------- // feature-group-end: actual feature gates // ------------------------------------------------------------------------- @@ -625,6 +625,9 @@ declare_features! ( (removed, dropck_parametricity, "1.38.0", Some(28498), None, None), (removed, await_macro, "1.38.0", Some(50547), None, Some("subsumed by `.await` syntax")), + // Allows defining `existential type`s. + (removed, existential_type, "1.38.0", Some(63063), None, + Some("removed in favor of `#![feature(type_alias_impl_trait)]`")), // ------------------------------------------------------------------------- // feature-group-end: removed features @@ -2017,7 +2020,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { ast::ItemKind::Existential(..) => { gate_feature_post!( &self, - existential_type, + type_alias_impl_trait, i.span, "existential types are unstable" ); @@ -2246,7 +2249,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { ast::ImplItemKind::Existential(..) => { gate_feature_post!( &self, - existential_type, + type_alias_impl_trait, ii.span, "existential types are unstable" ); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 7096d6799e2..ec95a2090d6 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -6805,40 +6805,29 @@ impl<'a> Parser<'a> { Ok(self.mk_item(lo.to(prev_span), invalid, ItemKind::ForeignMod(m), visibility, attrs)) } - /// Parses `type Foo = Bar;` - /// or - /// `existential type Foo: Bar;` - /// or - /// `return `None`` + /// Parses `type Foo = Bar;` or returns `None` /// without modifying the parser state. fn eat_type(&mut self) -> Option> { // This parses the grammar: // Ident ["<"...">"] ["where" ...] ("=" | ":") Ty ";" - if self.check_keyword(kw::Type) || - self.check_keyword(kw::Existential) && - self.is_keyword_ahead(1, &[kw::Type]) { - let existential = self.eat_keyword(kw::Existential); - assert!(self.eat_keyword(kw::Type)); - Some(self.parse_existential_or_alias(existential)) + if self.eat_keyword(kw::Type) { + Some(self.parse_type_alias()) } else { None } } /// Parses a type alias or existential type. - fn parse_existential_or_alias( - &mut self, - existential: bool, - ) -> PResult<'a, (Ident, AliasKind, ast::Generics)> { + fn parse_type_alias(&mut self) -> PResult<'a, (Ident, AliasKind, ast::Generics)> { let ident = self.parse_ident()?; let mut tps = self.parse_generics()?; tps.where_clause = self.parse_where_clause()?; - let alias = if existential { - self.expect(&token::Colon)?; + self.expect(&token::Eq)?; + let alias = if self.check_keyword(kw::Impl) { + self.bump(); let bounds = self.parse_generic_bounds(Some(self.prev_span))?; AliasKind::Existential(bounds) } else { - self.expect(&token::Eq)?; let ty = self.parse_ty()?; AliasKind::Weak(ty) }; diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 308f7d5d4e3..331a758aca8 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -677,6 +677,7 @@ symbols! { tuple_indexing, Ty, ty, + type_alias_impl_trait, TyCtxt, TyKind, type_alias_enum_variants, diff --git a/src/test/ui/feature-gates/feature-gate-existential-type.rs b/src/test/ui/feature-gates/feature-gate-existential-type.rs deleted file mode 100644 index 6dfd2d10870..00000000000 --- a/src/test/ui/feature-gates/feature-gate-existential-type.rs +++ /dev/null @@ -1,17 +0,0 @@ -// Check that existential types must be ungated to use the `existential` keyword - -existential type Foo: std::fmt::Debug; //~ ERROR existential types are unstable - -trait Bar { - type Baa: std::fmt::Debug; - fn define() -> Self::Baa; -} - -impl Bar for () { - existential type Baa: std::fmt::Debug; //~ ERROR existential types are unstable - fn define() -> Self::Baa { 0 } -} - -fn define() -> Foo { 0 } - -fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-existential-type.stderr b/src/test/ui/feature-gates/feature-gate-existential-type.stderr deleted file mode 100644 index 30e25e55aff..00000000000 --- a/src/test/ui/feature-gates/feature-gate-existential-type.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0658]: existential types are unstable - --> $DIR/feature-gate-existential-type.rs:3:1 - | -LL | existential type Foo: std::fmt::Debug; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/63063 - = help: add `#![feature(existential_type)]` to the crate attributes to enable - -error[E0658]: existential types are unstable - --> $DIR/feature-gate-existential-type.rs:11:5 - | -LL | existential type Baa: std::fmt::Debug; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/63063 - = help: add `#![feature(existential_type)]` to the crate attributes to enable - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.rs b/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.rs new file mode 100644 index 00000000000..e169cbcc34c --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.rs @@ -0,0 +1,15 @@ +type Foo = impl std::fmt::Debug; //~ ERROR existential types are unstable + +trait Bar { + type Baa: std::fmt::Debug; + fn define() -> Self::Baa; +} + +impl Bar for () { + type Baa = impl std::fmt::Debug; //~ ERROR existential types are unstable + fn define() -> Self::Baa { 0 } +} + +fn define() -> Foo { 0 } + +fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr b/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr new file mode 100644 index 00000000000..83b16af8586 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr @@ -0,0 +1,21 @@ +error[E0658]: existential types are unstable + --> $DIR/feature-gate-type_alias_impl_trait.rs:1:1 + | +LL | type Foo = impl std::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/63063 + = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable + +error[E0658]: existential types are unstable + --> $DIR/feature-gate-type_alias_impl_trait.rs:9:5 + | +LL | type Baa = impl std::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/63063 + = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`.