about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorFlavio Percoco <flaper87@gmail.com>2015-01-22 22:14:52 +0100
committerFlavio Percoco <flaper87@gmail.com>2015-02-22 02:14:24 +0100
commit6a2f16e1365160d05a3d360f21756039d1bd3254 (patch)
treebe3c95808ab82fa1b60406feb76d72f78f9113cd /src/libsyntax
parent2b01a37ec38db9301239f0c0abcf3c695055b0ff (diff)
downloadrust-6a2f16e1365160d05a3d360f21756039d1bd3254.tar.gz
rust-6a2f16e1365160d05a3d360f21756039d1bd3254.zip
Add support for default trait impls in libsyntax
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs7
-rw-r--r--src/libsyntax/ast_map/mod.rs1
-rw-r--r--src/libsyntax/ast_util.rs8
-rw-r--r--src/libsyntax/ext/deriving/generic/mod.rs2
-rw-r--r--src/libsyntax/fold.rs5
-rw-r--r--src/libsyntax/parse/parser.rs41
-rw-r--r--src/libsyntax/print/pprust.rs12
-rw-r--r--src/libsyntax/visit.rs3
8 files changed, 60 insertions, 19 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 140e21b5d04..d57b23b8b1b 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -1641,6 +1641,10 @@ pub enum Item_ {
               Generics,
               TyParamBounds,
               Vec<TraitItem>),
+
+    // Default trait implementations
+    // `impl Trait for ..`
+    ItemDefTrait(Unsafety, TraitRef),
     ItemImpl(Unsafety,
              ImplPolarity,
              Generics,
@@ -1666,7 +1670,8 @@ impl Item_ {
             ItemStruct(..) => "struct",
             ItemTrait(..) => "trait",
             ItemMac(..) |
-            ItemImpl(..) => "item"
+            ItemImpl(..) |
+            ItemDefTrait(..) => "item"
         }
     }
 }
diff --git a/src/libsyntax/ast_map/mod.rs b/src/libsyntax/ast_map/mod.rs
index ba08f61b557..7903a3a1bfc 100644
--- a/src/libsyntax/ast_map/mod.rs
+++ b/src/libsyntax/ast_map/mod.rs
@@ -1044,6 +1044,7 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
                 ItemStruct(..) => "struct",
                 ItemTrait(..) => "trait",
                 ItemImpl(..) => "impl",
+                ItemDefTrait(..) => "default impl",
                 ItemMac(..) => "macro"
             };
             format!("{} {}{}", item_str, path_str, id_str)
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index f660296fcd7..f1228c1d363 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -252,8 +252,12 @@ pub fn name_to_dummy_lifetime(name: Name) -> Lifetime {
 /// hint of where they came from, (previously they would all just be
 /// listed as `__extensions__::method_name::hash`, with no indication
 /// of the type).
-pub fn impl_pretty_name(trait_ref: &Option<TraitRef>, ty: &Ty) -> Ident {
-    let mut pretty = pprust::ty_to_string(ty);
+pub fn impl_pretty_name(trait_ref: &Option<TraitRef>, ty: Option<&Ty>) -> Ident {
+    let mut pretty = match ty {
+        Some(t) => pprust::ty_to_string(t),
+        None => String::from_str("..")
+    };
+
     match *trait_ref {
         Some(ref trait_ref) => {
             pretty.push('.');
diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs
index b912ed34ae0..df6b73b4c97 100644
--- a/src/libsyntax/ext/deriving/generic/mod.rs
+++ b/src/libsyntax/ext/deriving/generic/mod.rs
@@ -498,7 +498,7 @@ impl<'a> TraitDef<'a> {
         // Just mark it now since we know that it'll end up used downstream
         attr::mark_used(&attr);
         let opt_trait_ref = Some(trait_ref);
-        let ident = ast_util::impl_pretty_name(&opt_trait_ref, &*self_type);
+        let ident = ast_util::impl_pretty_name(&opt_trait_ref, Some(&*self_type));
         let mut a = vec![attr];
         a.extend(self.attributes.iter().cloned());
         cx.item(
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 1fb0642d24f..31e5a876374 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -999,6 +999,9 @@ pub fn noop_fold_item_underscore<T: Folder>(i: Item_, folder: &mut T) -> Item_ {
             let struct_def = folder.fold_struct_def(struct_def);
             ItemStruct(struct_def, folder.fold_generics(generics))
         }
+        ItemDefTrait(unsafety, ref trait_ref) => {
+            ItemDefTrait(unsafety, folder.fold_trait_ref((*trait_ref).clone()))
+        }
         ItemImpl(unsafety, polarity, generics, ifce, ty, impl_items) => {
             let new_impl_items = impl_items.into_iter().flat_map(|item| {
                 folder.fold_impl_item(item).into_iter()
@@ -1150,7 +1153,7 @@ pub fn noop_fold_item_simple<T: Folder>(Item {id, ident, attrs, node, vis, span}
     let ident = match node {
         // The node may have changed, recompute the "pretty" impl name.
         ItemImpl(_, _, _, ref maybe_trait, ref ty, _) => {
-            ast_util::impl_pretty_name(maybe_trait, &**ty)
+            ast_util::impl_pretty_name(maybe_trait, Some(&**ty))
         }
         _ => ident
     };
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 370201e5382..55c4afc36a5 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -31,7 +31,7 @@ use ast::{ExprVec, ExprWhile, ExprWhileLet, ExprForLoop, Field, FnDecl};
 use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod, FunctionRetTy};
 use ast::{Ident, Inherited, ImplItem, Item, Item_, ItemStatic};
 use ast::{ItemEnum, ItemFn, ItemForeignMod, ItemImpl, ItemConst};
-use ast::{ItemMac, ItemMod, ItemStruct, ItemTrait, ItemTy};
+use ast::{ItemMac, ItemMod, ItemStruct, ItemTrait, ItemTy, ItemDefTrait};
 use ast::{ItemExternCrate, ItemUse};
 use ast::{LifetimeDef, Lit, Lit_};
 use ast::{LitBool, LitChar, LitByte, LitBinary};
@@ -4783,10 +4783,13 @@ impl<'a> Parser<'a> {
         (impl_items, inner_attrs)
     }
 
-    /// Parses two variants (with the region/type params always optional):
+    /// Parses items implementations variants
     ///    impl<T> Foo { ... }
-    ///    impl<T> ToString for ~[T] { ... }
+    ///    impl<T> ToString for &'static T { ... }
+    ///    impl Send for .. {}
     fn parse_item_impl(&mut self, unsafety: ast::Unsafety) -> ItemInfo {
+        let impl_span = self.span;
+
         // First, parse type parameters if necessary.
         let mut generics = self.parse_generics();
 
@@ -4807,7 +4810,7 @@ impl<'a> Parser<'a> {
         // Parse traits, if necessary.
         let opt_trait = if could_be_trait && self.eat_keyword(keywords::For) {
             // New-style trait. Reinterpret the type as a trait.
-            let opt_trait_ref = match ty.node {
+            match ty.node {
                 TyPath(ref path, node_id) => {
                     Some(TraitRef {
                         path: (*path).clone(),
@@ -4818,10 +4821,7 @@ impl<'a> Parser<'a> {
                     self.span_err(ty.span, "not a trait");
                     None
                 }
-            };
-
-            ty = self.parse_ty_sum();
-            opt_trait_ref
+            }
         } else {
             match polarity {
                 ast::ImplPolarity::Negative => {
@@ -4834,14 +4834,27 @@ impl<'a> Parser<'a> {
             None
         };
 
-        self.parse_where_clause(&mut generics);
-        let (impl_items, attrs) = self.parse_impl_items();
+        if self.eat(&token::DotDot) {
+            if generics.is_parameterized() {
+                self.span_err(impl_span, "default trait implementations are not \
+                                          allowed to have genercis");
+            }
 
-        let ident = ast_util::impl_pretty_name(&opt_trait, &*ty);
+            self.expect(&token::OpenDelim(token::Brace));
+            self.expect(&token::CloseDelim(token::Brace));
+            (ast_util::impl_pretty_name(&opt_trait, None),
+             ItemDefTrait(unsafety, opt_trait.unwrap()), None)
+        } else {
+            if opt_trait.is_some() {
+                ty = self.parse_ty_sum();
+            }
+            self.parse_where_clause(&mut generics);
+            let (impl_items, attrs) = self.parse_impl_items();
 
-        (ident,
-         ItemImpl(unsafety, polarity, generics, opt_trait, ty, impl_items),
-         Some(attrs))
+            (ast_util::impl_pretty_name(&opt_trait, Some(&*ty)),
+             ItemImpl(unsafety, polarity, generics, opt_trait, ty, impl_items),
+             Some(attrs))
+        }
     }
 
     /// Parse a::B<String,i32>
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index f26578e7401..d5b17b5798b 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -926,6 +926,18 @@ impl<'a> State<'a> {
                 try!(self.print_struct(&**struct_def, generics, item.ident, item.span));
             }
 
+            ast::ItemDefTrait(unsafety, ref trait_ref) => {
+                try!(self.head(""));
+                try!(self.print_visibility(item.vis));
+                try!(self.print_unsafety(unsafety));
+                try!(self.word_nbsp("impl"));
+                try!(self.print_trait_ref(trait_ref));
+                try!(space(&mut self.s));
+                try!(self.word_space("for"));
+                try!(self.word_space(".."));
+                try!(self.bopen());
+                try!(self.bclose(item.span));
+            }
             ast::ItemImpl(unsafety,
                           polarity,
                           ref generics,
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 21cb62b0a0c..9654e7a005b 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -282,6 +282,9 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
             visitor.visit_generics(type_parameters);
             walk_enum_def(visitor, enum_definition, type_parameters)
         }
+        ItemDefTrait(_, ref trait_ref) => {
+            visitor.visit_trait_ref(trait_ref)
+        }
         ItemImpl(_, _,
                  ref type_parameters,
                  ref trait_reference,