about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-05-03 08:06:49 -0700
committerbors <bors@rust-lang.org>2014-05-03 08:06:49 -0700
commit757f106bcc771e10073bfcfa5331ad2bd5f1fe21 (patch)
tree682524424989f2a93dd11bb655b58a88bbc0950b /src
parent529b19f37bfcb39bf8f8709497c10c9fbd8dc5d5 (diff)
parentc39271e99cadcc580583bb29bce6e8475db15b0a (diff)
downloadrust-757f106bcc771e10073bfcfa5331ad2bd5f1fe21.tar.gz
rust-757f106bcc771e10073bfcfa5331ad2bd5f1fe21.zip
auto merge of #13868 : FlaPer87/rust/opt-in-phase1, r=alexcrichton
This is a first patch towards an opt-in built-in trait world. This patch removes the restriction on built-in traits and allows such traits to be derived.

[RFC#3]

cc #13231

@nikomatsakis r?
Diffstat (limited to 'src')
-rw-r--r--src/librustc/middle/typeck/collect.rs9
-rw-r--r--src/libsyntax/ext/deriving/bounds.rs46
-rw-r--r--src/libsyntax/ext/deriving/mod.rs5
-rw-r--r--src/test/compile-fail/cant-implement-builtin-kinds.rs19
-rw-r--r--src/test/compile-fail/deriving-bounds.rs17
-rw-r--r--src/test/run-pass/deriving-bounds.rs16
6 files changed, 85 insertions, 27 deletions
diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs
index 9c49512d4dc..c87776ba893 100644
--- a/src/librustc/middle/typeck/collect.rs
+++ b/src/librustc/middle/typeck/collect.rs
@@ -631,14 +631,7 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::Item) {
                             parent_visibility);
 
             for trait_ref in opt_trait_ref.iter() {
-                let trait_ref = instantiate_trait_ref(ccx, trait_ref, selfty);
-
-                // Prevent the builtin kind traits from being manually implemented.
-                if tcx.lang_items.to_builtin_kind(trait_ref.def_id).is_some() {
-                    tcx.sess.span_err(it.span,
-                        "cannot provide an explicit implementation \
-                         for a builtin kind");
-                }
+                instantiate_trait_ref(ccx, trait_ref, selfty);
             }
         },
         ast::ItemTrait(ref generics, _, _, ref trait_methods) => {
diff --git a/src/libsyntax/ext/deriving/bounds.rs b/src/libsyntax/ext/deriving/bounds.rs
new file mode 100644
index 00000000000..b5b2667f892
--- /dev/null
+++ b/src/libsyntax/ext/deriving/bounds.rs
@@ -0,0 +1,46 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use ast::{MetaItem, MetaWord, Item};
+use codemap::Span;
+use ext::base::ExtCtxt;
+use ext::deriving::generic::*;
+
+pub fn expand_deriving_bound(cx: &mut ExtCtxt,
+                             span: Span,
+                             mitem: @MetaItem,
+                             item: @Item,
+                             push: |@Item|) {
+
+    let name = match mitem.node {
+        MetaWord(ref tname) => {
+            match tname.get() {
+                "Copy" => "Copy",
+                "Send" => "Send",
+                "Share" => "Share",
+                ref tname => cx.span_bug(span,
+                                         format!("expected built-in trait name but found {}",
+                                                 *tname))
+            }
+        },
+        _ => return cx.span_err(span, "unexpected value in deriving, expected a trait")
+    };
+
+    let trait_def = TraitDef {
+        span: span,
+        attributes: Vec::new(),
+        path: Path::new(vec!("std", "kinds", name)),
+        additional_bounds: Vec::new(),
+        generics: LifetimeBounds::empty(),
+        methods: vec!()
+    };
+
+    trait_def.expand(cx, mitem, item, push)
+}
diff --git a/src/libsyntax/ext/deriving/mod.rs b/src/libsyntax/ext/deriving/mod.rs
index 5a980cb9de9..1187e83308b 100644
--- a/src/libsyntax/ext/deriving/mod.rs
+++ b/src/libsyntax/ext/deriving/mod.rs
@@ -22,6 +22,7 @@ use ast::{Item, MetaItem, MetaList, MetaNameValue, MetaWord};
 use ext::base::ExtCtxt;
 use codemap::Span;
 
+pub mod bounds;
 pub mod clone;
 pub mod encodable;
 pub mod decodable;
@@ -90,6 +91,10 @@ pub fn expand_meta_deriving(cx: &mut ExtCtxt,
 
                             "FromPrimitive" => expand!(primitive::expand_deriving_from_primitive),
 
+                            "Send" => expand!(bounds::expand_deriving_bound),
+                            "Share" => expand!(bounds::expand_deriving_bound),
+                            "Copy" => expand!(bounds::expand_deriving_bound),
+
                             ref tname => {
                                 cx.span_err(titem.span, format!("unknown \
                                     `deriving` trait: `{}`", *tname));
diff --git a/src/test/compile-fail/cant-implement-builtin-kinds.rs b/src/test/compile-fail/cant-implement-builtin-kinds.rs
deleted file mode 100644
index 6bedac6d12d..00000000000
--- a/src/test/compile-fail/cant-implement-builtin-kinds.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// See issue #8517 for why this should be illegal.
-
-struct X<T>(T);
-
-impl <T> Send for X<T> { } //~ ERROR cannot provide an explicit implementation for a builtin kind
-impl <T> Sized for X<T> { } //~ ERROR cannot provide an explicit implementation for a builtin kind
-impl <T> Share for X<T> { } //~ ERROR cannot provide an explicit implementation for a builtin kind
-
-fn main() { }
diff --git a/src/test/compile-fail/deriving-bounds.rs b/src/test/compile-fail/deriving-bounds.rs
new file mode 100644
index 00000000000..9d9f5527366
--- /dev/null
+++ b/src/test/compile-fail/deriving-bounds.rs
@@ -0,0 +1,17 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//NOTE: Remove in the next snapshot
+#[cfg(not(stage0))]
+#[deriving(Share(Bad),Send,Copy)]
+//~^ ERROR unexpected value in deriving, expected a trait
+struct Test;
+
+pub fn main() {}
diff --git a/src/test/run-pass/deriving-bounds.rs b/src/test/run-pass/deriving-bounds.rs
new file mode 100644
index 00000000000..a3951584702
--- /dev/null
+++ b/src/test/run-pass/deriving-bounds.rs
@@ -0,0 +1,16 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//NOTE: Remove in the next snapshot
+#[cfg(not(stage0))]
+#[deriving(Share,Send,Copy)]
+struct Test;
+
+pub fn main() {}