about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-02-24 02:22:44 +0000
committerbors <bors@rust-lang.org>2015-02-24 02:22:44 +0000
commit2890508d97af287a136ac50ffa13a1c0a3e32e4e (patch)
treed4cba9bfc722d5fb7d44c74dfebde016c45130aa /src/libsyntax
parentc4fe7d6aea022330efb8d1b470cac030a859f8f5 (diff)
parent3dcc631dee7b2f4be3443b4bbc1dd916436d60ca (diff)
downloadrust-2890508d97af287a136ac50ffa13a1c0a3e32e4e.tar.gz
rust-2890508d97af287a136ac50ffa13a1c0a3e32e4e.zip
Auto merge of #21689 - FlaPer87:oibit-send-and-friends, r=nikomatsakis
This is one more step towards completing #13231

This series of commits add support for default trait implementations. The changes in this PR don't break existing code and they are expected to preserve the existing behavior in the compiler as far as built-in bounds checks go.

The PR adds negative implementations of `Send`/`Sync` for some types and it removes the special cases for `Send`/`Sync` during the trait obligations checks. That is, it now fully relies on the traits check rather than lang items.

Once this patch lands and a new snapshot is created, it'll be possible to add default impls for `Send` and `Sync` and remove entirely the use of `BuiltinBound::{BoundSend,BoundSync}` for positive implementations as well.

This PR also removes the restriction on negative implementations. That is, it is now possible to add negative implementations for traits other than `Send`/`Sync`
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..effaac52716 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 ..`
+    ItemDefaultImpl(Unsafety, TraitRef),
     ItemImpl(Unsafety,
              ImplPolarity,
              Generics,
@@ -1666,7 +1670,8 @@ impl Item_ {
             ItemStruct(..) => "struct",
             ItemTrait(..) => "trait",
             ItemMac(..) |
-            ItemImpl(..) => "item"
+            ItemImpl(..) |
+            ItemDefaultImpl(..) => "item"
         }
     }
 }
diff --git a/src/libsyntax/ast_map/mod.rs b/src/libsyntax/ast_map/mod.rs
index ba08f61b557..c33158193ce 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",
+                ItemDefaultImpl(..) => "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 36bd8d39a83..a36d3a155b8 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..dae830583c4 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))
         }
+        ItemDefaultImpl(unsafety, ref trait_ref) => {
+            ItemDefaultImpl(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 7977574b02b..fec33eddb91 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, ItemDefaultImpl};
 use ast::{ItemExternCrate, ItemUse};
 use ast::{LifetimeDef, Lit, Lit_};
 use ast::{LitBool, LitChar, LitByte, LitBinary};
@@ -4787,10 +4787,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();
 
@@ -4811,7 +4814,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(),
@@ -4822,10 +4825,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 => {
@@ -4838,14 +4838,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),
+             ItemDefaultImpl(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 92e7f4d2870..869dad867eb 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::ItemDefaultImpl(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..412bf0fa22a 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)
         }
+        ItemDefaultImpl(_, ref trait_ref) => {
+            visitor.visit_trait_ref(trait_ref)
+        }
         ItemImpl(_, _,
                  ref type_parameters,
                  ref trait_reference,