about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorTyler Mandry <tmandry@gmail.com>2019-11-15 14:44:47 +0100
committerGitHub <noreply@github.com>2019-11-15 14:44:47 +0100
commitc5bb2ec0dd1f6f38117ec0e7e22c077a4b74dc09 (patch)
tree2804bcc92024c0ad0d0a1fa39fd820630286b75c /src/libsyntax
parentce36ab2b064c2aa716084d79717c64cc04bb6532 (diff)
parent03cf0d737f075aa8839dd7cc5b1047910ec00ddf (diff)
downloadrust-c5bb2ec0dd1f6f38117ec0e7e22c077a4b74dc09.tar.gz
rust-c5bb2ec0dd1f6f38117ec0e7e22c077a4b74dc09.zip
Rollup merge of #66197 - Centril:transparent-ast, r=varkor
Push `ast::{ItemKind, ImplItemKind}::OpaqueTy` hack down into lowering

We currently have a hack in the form of `ast::{ItemKind, ImplItemKind}::OpaqueTy` which is constructed literally when you write `type Alias = impl Trait;` but not e.g. `type Alias = Vec<impl Trait>;`. Per https://github.com/rust-lang/rfcs/pull/2515, this needs to change to allow `impl Trait` in nested positions.  This PR achieves this change for the syntactic aspect but not the semantic one, which will require changes in lowering and def collection. In the interim, `TyKind::opaque_top_hack` is introduced to avoid knock-on changes in lowering, collection, and resolve. These hacks can then be removed and fixed one by one until the desired semantics are supported.

r? @varkor
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs15
-rw-r--r--src/libsyntax/feature_gate/check.rs46
-rw-r--r--src/libsyntax/mut_visit.rs5
-rw-r--r--src/libsyntax/print/pprust.rs20
-rw-r--r--src/libsyntax/visit.rs7
5 files changed, 35 insertions, 58 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 13bf6752ba2..d358efbe543 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -1579,7 +1579,6 @@ pub enum ImplItemKind {
     Const(P<Ty>, P<Expr>),
     Method(FnSig, P<Block>),
     TyAlias(P<Ty>),
-    OpaqueTy(GenericBounds),
     Macro(Mac),
 }
 
@@ -1816,6 +1815,15 @@ impl TyKind {
             false
         }
     }
+
+    /// HACK(type_alias_impl_trait, Centril): A temporary crutch used
+    /// in lowering to avoid making larger changes there and beyond.
+    pub fn opaque_top_hack(&self) -> Option<&GenericBounds> {
+        match self {
+            Self::ImplTrait(_, bounds) => Some(bounds),
+            _ => None,
+        }
+    }
 }
 
 /// Syntax used to declare a trait object.
@@ -2483,10 +2491,6 @@ pub enum ItemKind {
     ///
     /// E.g., `type Foo = Bar<u8>;`.
     TyAlias(P<Ty>, Generics),
-    /// An opaque `impl Trait` type alias.
-    ///
-    /// E.g., `type Foo = impl Bar + Boo;`.
-    OpaqueTy(GenericBounds, Generics),
     /// An enum definition (`enum`).
     ///
     /// E.g., `enum Foo<A, B> { C<A>, D<B> }`.
@@ -2540,7 +2544,6 @@ impl ItemKind {
             ItemKind::ForeignMod(..) => "foreign module",
             ItemKind::GlobalAsm(..) => "global asm",
             ItemKind::TyAlias(..) => "type alias",
-            ItemKind::OpaqueTy(..) => "opaque type",
             ItemKind::Enum(..) => "enum",
             ItemKind::Struct(..) => "struct",
             ItemKind::Union(..) => "union",
diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs
index d95dac9bf52..bd836eee42a 100644
--- a/src/libsyntax/feature_gate/check.rs
+++ b/src/libsyntax/feature_gate/check.rs
@@ -321,6 +321,27 @@ impl<'a> PostExpansionVisitor<'a> {
             );
         }
     }
+
+    /// Feature gate `impl Trait` inside `type Alias = $type_expr;`.
+    fn check_impl_trait(&self, ty: &ast::Ty) {
+        struct ImplTraitVisitor<'a> {
+            vis: &'a PostExpansionVisitor<'a>,
+        }
+        impl Visitor<'_> for ImplTraitVisitor<'_> {
+            fn visit_ty(&mut self, ty: &ast::Ty) {
+                if let ast::TyKind::ImplTrait(..) = ty.kind {
+                    gate_feature_post!(
+                        &self.vis,
+                        type_alias_impl_trait,
+                        ty.span,
+                        "`impl Trait` in type aliases is unstable"
+                    );
+                }
+                visit::walk_ty(self, ty);
+            }
+        }
+        ImplTraitVisitor { vis: self }.visit_ty(ty);
+    }
 }
 
 impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
@@ -455,14 +476,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
                 gate_feature_post!(&self, decl_macro, i.span, msg);
             }
 
-            ast::ItemKind::OpaqueTy(..) => {
-                gate_feature_post!(
-                    &self,
-                    type_alias_impl_trait,
-                    i.span,
-                    "`impl Trait` in type aliases is unstable"
-                );
-            }
+            ast::ItemKind::TyAlias(ref ty, ..) => self.check_impl_trait(&ty),
 
             _ => {}
         }
@@ -636,9 +650,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
                 }
             }
             ast::TraitItemKind::Type(_, ref default) => {
-                // We use three if statements instead of something like match guards so that all
-                // of these errors can be emitted if all cases apply.
-                if default.is_some() {
+                if let Some(ty) = default {
+                    self.check_impl_trait(ty);
                     gate_feature_post!(&self, associated_type_defaults, ti.span,
                                        "associated type defaults are unstable");
                 }
@@ -663,15 +676,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
                                        "C-variadic functions are unstable");
                 }
             }
-            ast::ImplItemKind::OpaqueTy(..) => {
-                gate_feature_post!(
-                    &self,
-                    type_alias_impl_trait,
-                    ii.span,
-                    "`impl Trait` in type aliases is unstable"
-                );
-            }
-            ast::ImplItemKind::TyAlias(_) => {
+            ast::ImplItemKind::TyAlias(ref ty) => {
+                self.check_impl_trait(ty);
                 self.check_gat(&ii.generics, ii.span);
             }
             _ => {}
diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs
index 376323a83ea..f4ef993edb9 100644
--- a/src/libsyntax/mut_visit.rs
+++ b/src/libsyntax/mut_visit.rs
@@ -887,10 +887,6 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) {
             vis.visit_ty(ty);
             vis.visit_generics(generics);
         }
-        ItemKind::OpaqueTy(bounds, generics) => {
-            visit_bounds(bounds, vis);
-            vis.visit_generics(generics);
-        }
         ItemKind::Enum(EnumDef { variants }, generics) => {
             variants.flat_map_in_place(|variant| vis.flat_map_variant(variant));
             vis.visit_generics(generics);
@@ -970,7 +966,6 @@ pub fn noop_flat_map_impl_item<T: MutVisitor>(mut item: ImplItem, visitor: &mut
             visitor.visit_block(body);
         }
         ImplItemKind::TyAlias(ty) => visitor.visit_ty(ty),
-        ImplItemKind::OpaqueTy(bounds) => visit_bounds(bounds, visitor),
         ImplItemKind::Macro(mac) => visitor.visit_mac(mac),
     }
     visitor.visit_span(span);
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index f154b7bde98..ef65a744e83 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1255,19 +1255,6 @@ impl<'a> State<'a> {
                 self.s.word(";");
                 self.end(); // end the outer ibox
             }
-            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
-
-                self.print_where_clause(&generics.where_clause);
-                self.s.space();
-                self.print_type_bounds(":", bounds);
-                self.s.word(";");
-                self.end(); // end the outer ibox
-            }
             ast::ItemKind::Enum(ref enum_definition, ref params) => {
                 self.print_enum_def(
                     enum_definition,
@@ -1620,13 +1607,6 @@ impl<'a> State<'a> {
             ast::ImplItemKind::TyAlias(ref ty) => {
                 self.print_associated_type(ii.ident, None, Some(ty));
             }
-            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);
                 match mac.delim {
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index ea2dc357e6e..2597ffd750d 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -263,10 +263,6 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
             visitor.visit_ty(typ);
             visitor.visit_generics(generics)
         }
-        ItemKind::OpaqueTy(ref bounds, ref generics) => {
-            walk_list!(visitor, visit_param_bound, bounds);
-            visitor.visit_generics(generics)
-        }
         ItemKind::Enum(ref enum_definition, ref generics) => {
             visitor.visit_generics(generics);
             visitor.visit_enum_def(enum_definition, generics, item.id, item.span)
@@ -628,9 +624,6 @@ pub fn walk_impl_item<'a, V: Visitor<'a>>(visitor: &mut V, impl_item: &'a ImplIt
         ImplItemKind::TyAlias(ref ty) => {
             visitor.visit_ty(ty);
         }
-        ImplItemKind::OpaqueTy(ref bounds) => {
-            walk_list!(visitor, visit_param_bound, bounds);
-        }
         ImplItemKind::Macro(ref mac) => {
             visitor.visit_mac(mac);
         }