diff options
| author | leonardo.yvens <leoyvens@gmail.com> | 2017-10-12 09:51:31 -0300 |
|---|---|---|
| committer | leonardo.yvens <leoyvens@gmail.com> | 2017-11-03 16:13:20 -0200 |
| commit | 1f4b63089927f05d2171f2b3197d74ff26e42387 (patch) | |
| tree | 6bcb85457d9083864757f91f407546a3ec863f59 /src/libsyntax | |
| parent | 06506bb751ae952b67d76a2ebe21edb8ec96acb9 (diff) | |
| download | rust-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.rs | 11 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 46 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 10 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 2 |
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); |
