summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorleonardo.yvens <leoyvens@gmail.com>2017-10-12 09:51:31 -0300
committerleonardo.yvens <leoyvens@gmail.com>2017-11-03 16:13:20 -0200
commit1f4b63089927f05d2171f2b3197d74ff26e42387 (patch)
tree6bcb85457d9083864757f91f407546a3ec863f59 /src/libsyntax
parent06506bb751ae952b67d76a2ebe21edb8ec96acb9 (diff)
downloadrust-1f4b63089927f05d2171f2b3197d74ff26e42387.tar.gz
rust-1f4b63089927f05d2171f2b3197d74ff26e42387.zip
add `auto` keyword, parse `auto trait`, lower to HIR
Adds an `IsAuto` field to `ItemTrait` which flags if the trait was
declared as an `auto trait`.

Auto traits cannot have generics nor super traits.
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs11
-rw-r--r--src/libsyntax/fold.rs3
-rw-r--r--src/libsyntax/parse/parser.rs46
-rw-r--r--src/libsyntax/print/pprust.rs10
-rw-r--r--src/libsyntax/visit.rs2
5 files changed, 65 insertions, 7 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 9fdbdd6ade9..99dff4edaad 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -1581,6 +1581,13 @@ impl FnDecl {
     }
 }
 
+/// Is the trait definition an auto trait?
+#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+pub enum IsAuto {
+    Yes,
+    No
+}
+
 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum Unsafety {
     Unsafe,
@@ -1942,8 +1949,8 @@ pub enum ItemKind {
     Union(VariantData, Generics),
     /// A Trait declaration (`trait` or `pub trait`).
     ///
-    /// E.g. `trait Foo { .. }` or `trait Foo<T> { .. }`
-    Trait(Unsafety, Generics, TyParamBounds, Vec<TraitItem>),
+    /// E.g. `trait Foo { .. }`, `trait Foo<T> { .. }` or `auto trait Foo {}`
+    Trait(IsAuto, Unsafety, Generics, TyParamBounds, Vec<TraitItem>),
     /// Auto trait implementation.
     ///
     /// E.g. `impl Trait for .. {}` or `impl<T> Trait<T> for .. {}`
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 69e67462b76..cc63bffec48 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -926,7 +926,8 @@ pub fn noop_fold_item_kind<T: Folder>(i: ItemKind, folder: &mut T) -> ItemKind {
             folder.fold_ty(ty),
             impl_items.move_flat_map(|item| folder.fold_impl_item(item)),
         ),
-        ItemKind::Trait(unsafety, generics, bounds, items) => ItemKind::Trait(
+        ItemKind::Trait(is_auto, unsafety, generics, bounds, items) => ItemKind::Trait(
+            is_auto,
             unsafety,
             folder.fold_generics(generics),
             folder.fold_bounds(bounds),
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index fa6a3b669fa..c94fcf461c7 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -16,12 +16,13 @@ use ast::{Mod, Arg, Arm, Attribute, BindingMode, TraitItemKind};
 use ast::Block;
 use ast::{BlockCheckMode, CaptureBy};
 use ast::{Constness, Crate};
+use ast::Generics;
 use ast::Defaultness;
 use ast::EnumDef;
 use ast::{Expr, ExprKind, RangeLimits};
 use ast::{Field, FnDecl};
 use ast::{ForeignItem, ForeignItemKind, FunctionRetTy};
-use ast::{Ident, ImplItem, Item, ItemKind};
+use ast::{Ident, ImplItem, IsAuto, Item, ItemKind};
 use ast::{Lifetime, LifetimeDef, Lit, LitKind, UintTy};
 use ast::Local;
 use ast::MacStmtStyle;
@@ -5078,7 +5079,17 @@ impl<'a> Parser<'a> {
                 }
             }
         }
-        Ok((ident, ItemKind::Trait(unsafety, tps, bounds, trait_items), None))
+        Ok((ident, ItemKind::Trait(IsAuto::No, unsafety, tps, bounds, trait_items), None))
+    }
+
+    fn parse_item_auto_trait(&mut self, unsafety: Unsafety) -> PResult<'a, ItemInfo> {
+        let ident = self.parse_ident()?;
+        self.expect(&token::OpenDelim(token::Brace))?;
+        self.expect(&token::CloseDelim(token::Brace))?;
+        // Auto traits cannot have generics, super traits nor contain items.
+        Ok((ident,
+            ItemKind::Trait(IsAuto::Yes, unsafety, Generics::default(), Vec::new(), Vec::new()),
+            None))
     }
 
     /// Parses items implementations variants
@@ -6127,6 +6138,37 @@ impl<'a> Parser<'a> {
                                     maybe_append(attrs, extra_attrs));
             return Ok(Some(item));
         }
+        if self.eat_keyword(keywords::Auto) {
+            self.expect_keyword(keywords::Trait)?;
+            // AUTO TRAIT ITEM
+            let (ident,
+                 item_,
+                 extra_attrs) = self.parse_item_auto_trait(ast::Unsafety::Normal)?;
+            let prev_span = self.prev_span;
+            let item = self.mk_item(lo.to(prev_span),
+                                    ident,
+                                    item_,
+                                    visibility,
+                                    maybe_append(attrs, extra_attrs));
+            return Ok(Some(item));
+        }
+        if self.check_keyword(keywords::Unsafe) &&
+            self.look_ahead(1, |t| t.is_keyword(keywords::Auto)) {
+            self.expect_keyword(keywords::Unsafe)?;
+            self.expect_keyword(keywords::Auto)?;
+            self.expect_keyword(keywords::Trait)?;
+            // UNSAFE AUTO TRAIT ITEM
+            let (ident,
+                 item_,
+                 extra_attrs) = self.parse_item_auto_trait(ast::Unsafety::Unsafe)?;
+            let prev_span = self.prev_span;
+            let item = self.mk_item(lo.to(prev_span),
+                                    ident,
+                                    item_,
+                                    visibility,
+                                    maybe_append(attrs, extra_attrs));
+            return Ok(Some(item));
+        }
         if self.eat_keyword(keywords::Struct) {
             // STRUCT ITEM
             let (ident, item_, extra_attrs) = self.parse_item_struct()?;
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 487e158bfc3..1fbc632f8e5 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1338,9 +1338,10 @@ impl<'a> State<'a> {
                 }
                 self.bclose(item.span)?;
             }
-            ast::ItemKind::Trait(unsafety, ref generics, ref bounds, ref trait_items) => {
+            ast::ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref trait_items) => {
                 self.head("")?;
                 self.print_visibility(&item.vis)?;
+                self.print_is_auto(is_auto)?;
                 self.print_unsafety(unsafety)?;
                 self.word_nbsp("trait")?;
                 self.print_ident(item.ident)?;
@@ -3123,6 +3124,13 @@ impl<'a> State<'a> {
             ast::Unsafety::Unsafe => self.word_nbsp("unsafe"),
         }
     }
+
+    pub fn print_is_auto(&mut self, s: ast::IsAuto) -> io::Result<()> {
+        match s {
+            ast::IsAuto::Yes => self.word_nbsp("auto"),
+            ast::IsAuto::No => Ok(()),
+        }
+    }
 }
 
 fn repeat(s: &str, n: usize) -> String { iter::repeat(s).take(n).collect() }
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 6c63cd42d4d..c2e90f0bb13 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -300,7 +300,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
             visitor.visit_variant_data(struct_definition, item.ident,
                                      generics, item.id, item.span);
         }
-        ItemKind::Trait(_, ref generics, ref bounds, ref methods) => {
+        ItemKind::Trait(.., ref generics, ref bounds, ref methods) => {
             visitor.visit_generics(generics);
             walk_list!(visitor, visit_ty_param_bound, bounds);
             walk_list!(visitor, visit_trait_item, methods);