about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-08-03 02:21:23 +0000
committerbors <bors@rust-lang.org>2019-08-03 02:21:23 +0000
commitd7270712cb446aad0817040bbca73a8d024f67b0 (patch)
tree22cf18615b2177381934d771fc3710e6fd04c257 /src/libsyntax
parentd9bd4b289f07956819c59704d88d9eed61af3a6d (diff)
parentfbd7e0cf0e31ab612343311a61fe4f58a76a1698 (diff)
downloadrust-d7270712cb446aad0817040bbca73a8d024f67b0.tar.gz
rust-d7270712cb446aad0817040bbca73a8d024f67b0.zip
Auto merge of #63180 - varkor:trait-alias-impl-trait, r=Centril
Change opaque type syntax from `existential type` to type alias `impl Trait`

This implements a new feature gate `type_alias_impl_trait` (this is slightly different from the originally proposed feature name, but matches what has been used in discussion since), deprecating the old `existential_types` feature.

The syntax for opaque types has been changed. In addition, the "existential" terminology has been replaced with "opaque", as per previous discussion and the RFC.

This makes partial progress towards implementing https://github.com/rust-lang/rust/issues/63063.

r? @Centril
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs14
-rw-r--r--src/libsyntax/feature_gate.rs21
-rw-r--r--src/libsyntax/mut_visit.rs4
-rw-r--r--src/libsyntax/parse/parser.rs43
-rw-r--r--src/libsyntax/print/pprust.rs14
-rw-r--r--src/libsyntax/visit.rs4
6 files changed, 46 insertions, 54 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 87113b4b98e..60db7a16a77 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -1488,6 +1488,7 @@ pub enum TraitItemKind {
     Macro(Mac),
 }
 
+/// Represents anything within an `impl` block.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct ImplItem {
     pub id: NodeId,
@@ -1502,12 +1503,13 @@ pub struct ImplItem {
     pub tokens: Option<TokenStream>,
 }
 
+/// Represents various kinds of content within an `impl`.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub enum ImplItemKind {
     Const(P<Ty>, P<Expr>),
     Method(MethodSig, P<Block>),
     Type(P<Ty>),
-    Existential(GenericBounds),
+    OpaqueTy(GenericBounds),
     Macro(Mac),
 }
 
@@ -1710,7 +1712,7 @@ pub enum TyKind {
     ///
     /// The `NodeId` exists to prevent lowering from having to
     /// generate `NodeId`s on the fly, which would complicate
-    /// the generation of `existential type` items significantly.
+    /// the generation of opaque `type Foo = impl Trait` items significantly.
     ImplTrait(NodeId, GenericBounds),
     /// No-op; kept solely so that we can pretty-print faithfully.
     Paren(P<Ty>),
@@ -2334,10 +2336,10 @@ pub enum ItemKind {
     ///
     /// E.g., `type Foo = Bar<u8>;`.
     Ty(P<Ty>, Generics),
-    /// An existential type declaration (`existential type`).
+    /// An opaque `impl Trait` type alias.
     ///
-    /// E.g., `existential type Foo: Bar + Boo;`.
-    Existential(GenericBounds, Generics),
+    /// E.g., `type Foo = impl Bar + Boo;`.
+    OpaqueTy(GenericBounds, Generics),
     /// An enum definition (`enum` or `pub enum`).
     ///
     /// E.g., `enum Foo<A, B> { C<A>, D<B> }`.
@@ -2391,7 +2393,7 @@ impl ItemKind {
             ItemKind::ForeignMod(..) => "foreign module",
             ItemKind::GlobalAsm(..) => "global asm",
             ItemKind::Ty(..) => "type alias",
-            ItemKind::Existential(..) => "existential type",
+            ItemKind::OpaqueTy(..) => "opaque type",
             ItemKind::Enum(..) => "enum",
             ItemKind::Struct(..) => "struct",
             ItemKind::Union(..) => "union",
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 4f637a23e69..33d10b269e1 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
@@ -2014,12 +2017,12 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
                 gate_feature_post!(&self, decl_macro, i.span, msg);
             }
 
-            ast::ItemKind::Existential(..) => {
+            ast::ItemKind::OpaqueTy(..) => {
                 gate_feature_post!(
                     &self,
-                    existential_type,
+                    type_alias_impl_trait,
                     i.span,
-                    "existential types are unstable"
+                    "`impl Trait` in type aliases is unstable"
                 );
             }
 
@@ -2243,12 +2246,12 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
 
         match ii.node {
             ast::ImplItemKind::Method(..) => {}
-            ast::ImplItemKind::Existential(..) => {
+            ast::ImplItemKind::OpaqueTy(..) => {
                 gate_feature_post!(
                     &self,
-                    existential_type,
+                    type_alias_impl_trait,
                     ii.span,
-                    "existential types are unstable"
+                    "`impl Trait` in type aliases is unstable"
                 );
             }
             ast::ImplItemKind::Type(_) => {
diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs
index a5085c5f879..176bcf1959a 100644
--- a/src/libsyntax/mut_visit.rs
+++ b/src/libsyntax/mut_visit.rs
@@ -851,7 +851,7 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) {
             vis.visit_ty(ty);
             vis.visit_generics(generics);
         }
-        ItemKind::Existential(bounds, generics) => {
+        ItemKind::OpaqueTy(bounds, generics) => {
             visit_bounds(bounds, vis);
             vis.visit_generics(generics);
         }
@@ -934,7 +934,7 @@ pub fn noop_flat_map_impl_item<T: MutVisitor>(mut item: ImplItem, visitor: &mut
             visitor.visit_block(body);
         }
         ImplItemKind::Type(ty) => visitor.visit_ty(ty),
-        ImplItemKind::Existential(bounds) => visit_bounds(bounds, visitor),
+        ImplItemKind::OpaqueTy(bounds) => visit_bounds(bounds, visitor),
         ImplItemKind::Macro(mac) => visitor.visit_mac(mac),
     }
     visitor.visit_span(span);
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 8ca962a4419..eca1e218fca 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -62,12 +62,12 @@ use std::path::{self, Path, PathBuf};
 use std::slice;
 
 #[derive(Debug)]
-/// Whether the type alias or associated type is a concrete type or an existential type
+/// Whether the type alias or associated type is a concrete type or an opaque type
 pub enum AliasKind {
     /// Just a new name for the same type
     Weak(P<Ty>),
     /// Only trait impls of the type will be usable, not the actual type itself
-    Existential(GenericBounds),
+    OpaqueTy(GenericBounds),
 }
 
 bitflags::bitflags! {
@@ -4273,11 +4273,6 @@ impl<'a> Parser<'a> {
         self.token.is_keyword(kw::Crate) && self.look_ahead(1, |t| t != &token::ModSep)
     }
 
-    fn is_existential_type_decl(&self) -> bool {
-        self.token.is_keyword(kw::Existential) &&
-        self.is_keyword_ahead(1, &[kw::Type])
-    }
-
     fn is_auto_trait_item(&self) -> bool {
         // auto trait
         (self.token.is_keyword(kw::Auto) &&
@@ -4375,7 +4370,6 @@ impl<'a> Parser<'a> {
                   !self.token.is_qpath_start() &&
                   !self.is_union_item() &&
                   !self.is_crate_vis() &&
-                  !self.is_existential_type_decl() &&
                   !self.is_auto_trait_item() &&
                   !self.is_async_fn() {
             let path = self.parse_path(PathStyle::Expr)?;
@@ -5694,7 +5688,7 @@ impl<'a> Parser<'a> {
             let (name, alias, generics) = type_?;
             let kind = match alias {
                 AliasKind::Weak(typ) => ast::ImplItemKind::Type(typ),
-                AliasKind::Existential(bounds) => ast::ImplItemKind::Existential(bounds),
+                AliasKind::OpaqueTy(bounds) => ast::ImplItemKind::OpaqueTy(bounds),
             };
             (name, kind, generics)
         } else if self.is_const_item() {
@@ -6813,40 +6807,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<PResult<'a, (Ident, AliasKind, ast::Generics)>> {
         // 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)> {
+    /// Parses a type alias or opaque type.
+    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)
+            AliasKind::OpaqueTy(bounds)
         } else {
-            self.expect(&token::Eq)?;
             let ty = self.parse_ty()?;
             AliasKind::Weak(ty)
         };
@@ -7268,7 +7251,7 @@ impl<'a> Parser<'a> {
             // TYPE ITEM
             let item_ = match alias {
                 AliasKind::Weak(ty) => ItemKind::Ty(ty, generics),
-                AliasKind::Existential(bounds) => ItemKind::Existential(bounds, generics),
+                AliasKind::OpaqueTy(bounds) => ItemKind::OpaqueTy(bounds, generics),
             };
             let prev_span = self.prev_span;
             let item = self.mk_item(lo.to(prev_span),
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 07b1aef337f..e61e1113dca 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1221,9 +1221,10 @@ impl<'a> State<'a> {
                 self.s.word(";");
                 self.end(); // end the outer ibox
             }
-            ast::ItemKind::Existential(ref bounds, ref generics) => {
-                self.head(visibility_qualified(&item.vis, "existential type"));
+            ast::ItemKind::OpaqueTy(ref bounds, ref generics) => {
+                self.head(visibility_qualified(&item.vis, "type"));
                 self.print_ident(item.ident);
+                self.word_space("= impl");
                 self.print_generic_params(&generics.params);
                 self.end(); // end the inner ibox
 
@@ -1581,9 +1582,12 @@ impl<'a> State<'a> {
             ast::ImplItemKind::Type(ref ty) => {
                 self.print_associated_type(ii.ident, None, Some(ty));
             }
-            ast::ImplItemKind::Existential(ref bounds) => {
-                self.word_space("existential");
-                self.print_associated_type(ii.ident, Some(bounds), None);
+            ast::ImplItemKind::OpaqueTy(ref bounds) => {
+                self.word_space("type");
+                self.print_ident(ii.ident);
+                self.word_space("= impl");
+                self.print_type_bounds(":", bounds);
+                self.s.word(";");
             }
             ast::ImplItemKind::Macro(ref mac) => {
                 self.print_mac(mac);
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 5fee8ed81ab..67226c2177f 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -259,7 +259,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
             visitor.visit_ty(typ);
             visitor.visit_generics(generics)
         }
-        ItemKind::Existential(ref bounds, ref generics) => {
+        ItemKind::OpaqueTy(ref bounds, ref generics) => {
             walk_list!(visitor, visit_param_bound, bounds);
             visitor.visit_generics(generics)
         }
@@ -619,7 +619,7 @@ pub fn walk_impl_item<'a, V: Visitor<'a>>(visitor: &mut V, impl_item: &'a ImplIt
         ImplItemKind::Type(ref ty) => {
             visitor.visit_ty(ty);
         }
-        ImplItemKind::Existential(ref bounds) => {
+        ImplItemKind::OpaqueTy(ref bounds) => {
             walk_list!(visitor, visit_param_bound, bounds);
         }
         ImplItemKind::Macro(ref mac) => {