From 369f7fa169d9f97ac8185105201182781076a90d Mon Sep 17 00:00:00 2001
From: Ben Blum <bblum@andrew.cmu.edu>
Date: Wed, 14 Aug 2013 18:13:16 -0400
Subject: [PATCH 01/10] Prevent Send, Freeze, and Sized from being manually
 implemented. Close #8517.

---
 src/librustc/middle/lang_items.rs             |  6 ++++++
 src/librustc/middle/ty.rs                     |  6 ++++++
 src/librustc/middle/typeck/collect.rs         |  7 +++++++
 .../cant-implement-builtin-kinds.rs           | 19 +++++++++++++++++++
 4 files changed, 38 insertions(+)
 create mode 100644 src/test/compile-fail/cant-implement-builtin-kinds.rs

diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index 9b11301a9c4..8dd5ee20585 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -158,6 +158,12 @@ impl LanguageItems {
         }
     }
 
+    pub fn is_builtin_kind(&self, id: def_id) -> bool {
+        Some(id) == self.freeze_trait() ||
+        Some(id) == self.send_trait() ||
+        Some(id) == self.sized_trait()
+    }
+
     pub fn freeze_trait(&self) -> Option<def_id> {
         self.items[FreezeTraitLangItem as uint]
     }
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 685699f7819..56c3616d671 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -3725,6 +3725,12 @@ pub fn impl_trait_ref(cx: ctxt, id: ast::def_id) -> Option<@TraitRef> {
     return ret;
 }
 
+pub fn trait_ref_is_builtin_kind(tcx: ctxt, tr: &ast::trait_ref) -> bool {
+    let def = tcx.def_map.find(&tr.ref_id).expect("no def-map entry for trait");
+    let def_id = ast_util::def_id_of_def(*def);
+    tcx.lang_items.is_builtin_kind(def_id)
+}
+
 pub fn ty_to_def_id(ty: t) -> Option<ast::def_id> {
     match get(ty).sty {
       ty_trait(id, _, _, _, _) | ty_struct(id, _) | ty_enum(id, _) => Some(id),
diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs
index 7678a12b78a..2f6728891ff 100644
--- a/src/librustc/middle/typeck/collect.rs
+++ b/src/librustc/middle/typeck/collect.rs
@@ -869,6 +869,13 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::item) {
                                   &i_ty_generics, generics,
                                   parent_visibility);
         for t in opt_trait_ref.iter() {
+            // Prevent the builtin kind traits from being manually implemented.
+            if ty::trait_ref_is_builtin_kind(ccx.tcx, t) {
+                ccx.tcx.sess.span_err(it.span,
+                    "cannot provide an explicit implementation \
+                     for a builtin kind");
+            }
+
             check_methods_against_trait(ccx, generics, rp, selfty, t, cms);
         }
       }
diff --git a/src/test/compile-fail/cant-implement-builtin-kinds.rs b/src/test/compile-fail/cant-implement-builtin-kinds.rs
new file mode 100644
index 00000000000..c35ca098372
--- /dev/null
+++ b/src/test/compile-fail/cant-implement-builtin-kinds.rs
@@ -0,0 +1,19 @@
+// 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> Freeze for X<T> { } //~ ERROR cannot provide an explicit implementation for a builtin kind
+
+fn main() { }

From 69322d941032202b7d5308dbe16e31b62c752cd2 Mon Sep 17 00:00:00 2001
From: Ben Blum <bblum@andrew.cmu.edu>
Date: Fri, 16 Aug 2013 16:57:42 -0400
Subject: [PATCH 02/10] Allow traits to use builtin kinds as supertraits for
 #7083.

---
 src/librustc/metadata/decoder.rs      | 20 +++++++-
 src/librustc/metadata/encoder.rs      |  3 ++
 src/librustc/middle/kind.rs           | 74 +++++++++++++--------------
 src/librustc/middle/lang_items.rs     | 15 ++++--
 src/librustc/middle/ty.rs             | 20 ++++++--
 src/librustc/middle/typeck/astconv.rs | 28 +---------
 src/librustc/middle/typeck/collect.rs | 49 +++++++++++-------
 7 files changed, 118 insertions(+), 91 deletions(-)

diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index 81a2e863bde..9eb09806bc0 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -375,9 +375,21 @@ pub fn get_trait_def(cdata: cmd,
     let tp_defs = item_ty_param_defs(item_doc, tcx, cdata,
                                      tag_items_data_item_ty_param_bounds);
     let rp = item_ty_region_param(item_doc);
+    let mut bounds = ty::EmptyBuiltinBounds();
+    // Collect the builtin bounds from the encoded supertraits.
+    // FIXME(#8559): They should be encoded directly.
+    do reader::tagged_docs(item_doc, tag_item_super_trait_ref) |trait_doc| {
+        // NB. Bypasses real supertraits. See get_supertraits() if you wanted them.
+        let trait_ref = doc_trait_ref(trait_doc, tcx, cdata);
+        do tcx.lang_items.to_builtin_kind(trait_ref.def_id).map_move |bound| {
+            bounds.add(bound);
+        };
+        true
+    };
     ty::TraitDef {
         generics: ty::Generics {type_param_defs: tp_defs,
                                 region_param: rp},
+        bounds: bounds,
         trait_ref: @item_trait_ref(item_doc, tcx, cdata)
     }
 }
@@ -929,7 +941,13 @@ pub fn get_supertraits(cdata: cmd, id: ast::NodeId, tcx: ty::ctxt)
     let mut results = ~[];
     let item_doc = lookup_item(id, cdata.data);
     do reader::tagged_docs(item_doc, tag_item_super_trait_ref) |trait_doc| {
-        results.push(@doc_trait_ref(trait_doc, tcx, cdata));
+        // NB. Only reads the ones that *aren't* builtin-bounds. See also
+        // get_trait_def() for collecting the builtin bounds.
+        // FIXME(#8559): The builtin bounds shouldn't be encoded in the first place.
+        let trait_ref = doc_trait_ref(trait_doc, tcx, cdata);
+        if tcx.lang_items.to_builtin_kind(trait_ref.def_id).is_none() {
+            results.push(@trait_ref);
+        }
         true
     };
     return results;
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index 4a3704dc3aa..6a999a0c266 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -1076,6 +1076,9 @@ fn encode_info_for_item(ecx: &EncodeContext,
             ebml_w.end_tag();
         }
         encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
+        // FIXME(#8559): This should use the tcx's supertrait cache instead of
+        // reading the AST's list, because the former has already filtered out
+        // the builtin-kinds-as-supertraits. See corresponding fixme in decoder.
         for ast_trait_ref in super_traits.iter() {
             let trait_ref = ty::node_id_to_trait_ref(ecx.tcx, ast_trait_ref.ref_id);
             encode_trait_ref(ebml_w, ecx, trait_ref, tag_item_super_trait_ref);
diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs
index 6d7d8112991..edea267d226 100644
--- a/src/librustc/middle/kind.rs
+++ b/src/librustc/middle/kind.rs
@@ -50,8 +50,6 @@ use syntax::visit::Visitor;
 // primitives in the stdlib are explicitly annotated to only take sendable
 // types.
 
-pub static try_adding: &'static str = "Try adding a move";
-
 #[deriving(Clone)]
 pub struct Context {
     tcx: ty::ctxt,
@@ -77,9 +75,6 @@ impl Visitor<Context> for KindAnalysisVisitor {
     fn visit_item(&mut self, i:@item, e:Context) {
         check_item(self, i, e);
     }
-    fn visit_block(&mut self, b:&Block, e:Context) {
-        check_block(self, b, e);
-    }
 }
 
 pub fn check_crate(tcx: ty::ctxt,
@@ -125,46 +120,47 @@ fn check_struct_safe_for_destructor(cx: Context,
     }
 }
 
-fn check_block(visitor: &mut KindAnalysisVisitor,
-               block: &Block,
-               cx: Context) {
-    visit::walk_block(visitor, block, cx);
+fn check_impl_of_trait(cx: Context, it: @item, trait_ref: &trait_ref, self_type: &Ty) {
+    let ast_trait_def = cx.tcx.def_map.find(&trait_ref.ref_id)
+                            .expect("trait ref not in def map!");
+    let trait_def_id = ast_util::def_id_of_def(*ast_trait_def);
+    let trait_def = cx.tcx.trait_defs.find(&trait_def_id)
+                        .expect("trait def not in trait-defs map!");
+
+    // If this trait has builtin-kind supertraits, meet them.
+    let self_ty: ty::t = ty::node_id_to_type(cx.tcx, it.id);
+    error!("checking impl with self type %?", ty::get(self_ty).sty);
+    do check_builtin_bounds(cx, self_ty, trait_def.bounds) |missing| {
+        cx.tcx.sess.span_err(self_type.span,
+            fmt!("the type `%s', which does not fulfill `%s`, cannot implement this \
+                  trait", ty_to_str(cx.tcx, self_ty), missing.user_string(cx.tcx)));
+        cx.tcx.sess.span_note(self_type.span,
+            fmt!("types implementing this trait must fulfill `%s`",
+                 trait_def.bounds.user_string(cx.tcx)));
+    }
+
+    // If this is a destructor, check kinds.
+    if cx.tcx.lang_items.drop_trait() == Some(trait_def_id) {
+        match self_type.node {
+            ty_path(_, ref bounds, path_node_id) => {
+                assert!(bounds.is_none());
+                let struct_def = cx.tcx.def_map.get_copy(&path_node_id);
+                let struct_did = ast_util::def_id_of_def(struct_def);
+                check_struct_safe_for_destructor(cx, self_type.span, struct_did);
+            }
+            _ => {
+                cx.tcx.sess.span_bug(self_type.span,
+                    "the self type for the Drop trait impl is not a path");
+            }
+        }
+    }
 }
 
 fn check_item(visitor: &mut KindAnalysisVisitor, item: @item, cx: Context) {
-    // If this is a destructor, check kinds.
     if !attr::contains_name(item.attrs, "unsafe_destructor") {
         match item.node {
             item_impl(_, Some(ref trait_ref), ref self_type, _) => {
-                match cx.tcx.def_map.find(&trait_ref.ref_id) {
-                    None => cx.tcx.sess.bug("trait ref not in def map!"),
-                    Some(&trait_def) => {
-                        let trait_def_id = ast_util::def_id_of_def(trait_def);
-                        if cx.tcx.lang_items.drop_trait() == Some(trait_def_id) {
-                            // Yes, it's a destructor.
-                            match self_type.node {
-                                ty_path(_, ref bounds, path_node_id) => {
-                                    assert!(bounds.is_none());
-                                    let struct_def = cx.tcx.def_map.get_copy(
-                                        &path_node_id);
-                                    let struct_did =
-                                        ast_util::def_id_of_def(struct_def);
-                                    check_struct_safe_for_destructor(
-                                        cx,
-                                        self_type.span,
-                                        struct_did);
-                                }
-                                _ => {
-                                    cx.tcx.sess.span_bug(self_type.span,
-                                                         "the self type for \
-                                                          the Drop trait \
-                                                          impl is not a \
-                                                          path");
-                                }
-                            }
-                        }
-                    }
-                }
+                check_impl_of_trait(cx, item, trait_ref, self_type);
             }
             _ => {}
         }
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index 8dd5ee20585..47e2937ca8a 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -23,6 +23,7 @@
 use driver::session::Session;
 use metadata::csearch::each_lang_item;
 use metadata::cstore::iter_crate_data;
+use middle::ty::{BuiltinBound, BoundFreeze, BoundSend, BoundSized};
 use syntax::ast::{Crate, def_id, MetaItem};
 use syntax::ast_util::local_def;
 use syntax::attr::AttrMetaMethods;
@@ -158,10 +159,16 @@ impl LanguageItems {
         }
     }
 
-    pub fn is_builtin_kind(&self, id: def_id) -> bool {
-        Some(id) == self.freeze_trait() ||
-        Some(id) == self.send_trait() ||
-        Some(id) == self.sized_trait()
+    pub fn to_builtin_kind(&self, id: def_id) -> Option<BuiltinBound> {
+        if Some(id) == self.freeze_trait() {
+            Some(BoundFreeze)
+        } else if Some(id) == self.send_trait() {
+            Some(BoundSend)
+        } else if Some(id) == self.sized_trait() {
+            Some(BoundSized)
+        } else {
+            None
+        }
     }
 
     pub fn freeze_trait(&self) -> Option<def_id> {
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 56c3616d671..757f05c208b 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -863,6 +863,7 @@ pub struct ty_param_bounds_and_ty {
 /// As `ty_param_bounds_and_ty` but for a trait ref.
 pub struct TraitDef {
     generics: Generics,
+    bounds: BuiltinBounds,
     trait_ref: @ty::TraitRef,
 }
 
@@ -3725,10 +3726,23 @@ pub fn impl_trait_ref(cx: ctxt, id: ast::def_id) -> Option<@TraitRef> {
     return ret;
 }
 
-pub fn trait_ref_is_builtin_kind(tcx: ctxt, tr: &ast::trait_ref) -> bool {
+pub fn trait_ref_to_def_id(tcx: ctxt, tr: &ast::trait_ref) -> ast::def_id {
     let def = tcx.def_map.find(&tr.ref_id).expect("no def-map entry for trait");
-    let def_id = ast_util::def_id_of_def(*def);
-    tcx.lang_items.is_builtin_kind(def_id)
+    ast_util::def_id_of_def(*def)
+}
+
+pub fn try_add_builtin_trait(tcx: ctxt,
+                             trait_def_id: ast::def_id,
+                             builtin_bounds: &mut BuiltinBounds) -> bool {
+    //! Checks whether `trait_ref` refers to one of the builtin
+    //! traits, like `Send`, and adds the corresponding
+    //! bound to the set `builtin_bounds` if so. Returns true if `trait_ref`
+    //! is a builtin trait.
+
+    match tcx.lang_items.to_builtin_kind(trait_def_id) {
+        Some(bound) => { builtin_bounds.add(bound); true }
+        None => false
+    }
 }
 
 pub fn ty_to_def_id(ty: t) -> Option<ast::def_id> {
diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs
index c666e98c9c1..db76d75a5a5 100644
--- a/src/librustc/middle/typeck/astconv.rs
+++ b/src/librustc/middle/typeck/astconv.rs
@@ -773,9 +773,8 @@ fn conv_builtin_bounds(tcx: ty::ctxt, ast_bounds: &Option<OptVec<ast::TyParamBou
                     ast::TraitTyParamBound(ref b) => {
                         match lookup_def_tcx(tcx, b.path.span, b.ref_id) {
                             ast::def_trait(trait_did) => {
-                                if try_add_builtin_trait(tcx,
-                                                         trait_did,
-                                                         &mut builtin_bounds) {
+                                if ty::try_add_builtin_trait(tcx, trait_did,
+                                                             &mut builtin_bounds) {
                                     loop; // success
                                 }
                             }
@@ -807,26 +806,3 @@ fn conv_builtin_bounds(tcx: ty::ctxt, ast_bounds: &Option<OptVec<ast::TyParamBou
         (&None, ty::RegionTraitStore(*)) => ty::EmptyBuiltinBounds(),
     }
 }
-
-pub fn try_add_builtin_trait(tcx: ty::ctxt,
-                             trait_def_id: ast::def_id,
-                             builtin_bounds: &mut ty::BuiltinBounds) -> bool {
-    //! Checks whether `trait_ref` refers to one of the builtin
-    //! traits, like `Send`, and adds the corresponding
-    //! bound to the set `builtin_bounds` if so. Returns true if `trait_ref`
-    //! is a builtin trait.
-
-    let li = &tcx.lang_items;
-    if Some(trait_def_id) == li.send_trait() {
-        builtin_bounds.add(ty::BoundSend);
-        true
-    } else if Some(trait_def_id) == li.freeze_trait() {
-        builtin_bounds.add(ty::BoundFreeze);
-        true
-    } else if Some(trait_def_id) == li.sized_trait() {
-        builtin_bounds.add(ty::BoundSized);
-        true
-    } else {
-        false
-    }
-}
diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs
index 2f6728891ff..a22879654e8 100644
--- a/src/librustc/middle/typeck/collect.rs
+++ b/src/librustc/middle/typeck/collect.rs
@@ -398,28 +398,39 @@ pub fn ensure_supertraits(ccx: &CrateCtxt,
                           sp: codemap::span,
                           rp: Option<ty::region_variance>,
                           ast_trait_refs: &[ast::trait_ref],
-                          generics: &ast::Generics)
+                          generics: &ast::Generics) -> ty::BuiltinBounds
 {
     let tcx = ccx.tcx;
-    if tcx.supertraits.contains_key(&local_def(id)) { return; }
+
+    // Called only the first time trait_def_of_item is called.
+    // Supertraits are ensured at the same time.
+    assert!(!tcx.supertraits.contains_key(&local_def(id)));
 
     let self_ty = ty::mk_self(ccx.tcx, local_def(id));
     let mut ty_trait_refs: ~[@ty::TraitRef] = ~[];
+    let mut bounds = ty::EmptyBuiltinBounds();
     for ast_trait_ref in ast_trait_refs.iter() {
+        let trait_def_id = ty::trait_ref_to_def_id(ccx.tcx, ast_trait_ref);
+        // FIXME(#8559): Need to instantiate the trait_ref whether or not it's a
+        // builtin trait, so that the trait's node id appears in the tcx trait_ref
+        // map. This is only needed for metadata; see the similar fixme in encoder.rs.
         let trait_ref = instantiate_trait_ref(ccx, ast_trait_ref, rp,
                                               generics, self_ty);
+        if !ty::try_add_builtin_trait(ccx.tcx, trait_def_id, &mut bounds) {
 
-        // FIXME(#5527) Could have same trait multiple times
-        if ty_trait_refs.iter().any(|other_trait| other_trait.def_id == trait_ref.def_id) {
-            // This means a trait inherited from the same supertrait more
-            // than once.
-            tcx.sess.span_err(sp, "Duplicate supertrait in trait declaration");
-            break;
-        } else {
-            ty_trait_refs.push(trait_ref);
+            // FIXME(#5527) Could have same trait multiple times
+            if ty_trait_refs.iter().any(|other_trait| other_trait.def_id == trait_ref.def_id) {
+                // This means a trait inherited from the same supertrait more
+                // than once.
+                tcx.sess.span_err(sp, "Duplicate supertrait in trait declaration");
+                break;
+            } else {
+                ty_trait_refs.push(trait_ref);
+            }
         }
     }
     tcx.supertraits.insert(local_def(id), @ty_trait_refs);
+    bounds
 }
 
 /**
@@ -870,8 +881,9 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::item) {
                                   parent_visibility);
         for t in opt_trait_ref.iter() {
             // Prevent the builtin kind traits from being manually implemented.
-            if ty::trait_ref_is_builtin_kind(ccx.tcx, t) {
-                ccx.tcx.sess.span_err(it.span,
+            let trait_def_id = ty::trait_ref_to_def_id(tcx, t);
+            if tcx.lang_items.to_builtin_kind(trait_def_id).is_some() {
+                tcx.sess.span_err(it.span,
                     "cannot provide an explicit implementation \
                      for a builtin kind");
             }
@@ -879,11 +891,9 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::item) {
             check_methods_against_trait(ccx, generics, rp, selfty, t, cms);
         }
       }
-      ast::item_trait(ref generics, ref supertraits, ref trait_methods) => {
-          let trait_def = trait_def_of_item(ccx, it);
-          tcx.trait_defs.insert(local_def(it.id), trait_def);
+      ast::item_trait(ref generics, _, ref trait_methods) => {
+          let _trait_def = trait_def_of_item(ccx, it);
           ensure_trait_methods(ccx, it.id);
-          ensure_supertraits(ccx, it.id, it.span, rp, *supertraits, generics);
 
           let (_, provided_methods) =
               split_trait_methods(*trait_methods);
@@ -1039,13 +1049,16 @@ pub fn trait_def_of_item(ccx: &CrateCtxt, it: &ast::item) -> @ty::TraitDef {
     }
     let rp = tcx.region_paramd_items.find(&it.id).map_move(|x| *x);
     match it.node {
-        ast::item_trait(ref generics, _, _) => {
+        ast::item_trait(ref generics, ref supertraits, _) => {
             let self_ty = ty::mk_self(tcx, def_id);
             let (ty_generics, substs) = mk_item_substs(ccx, generics, rp,
                                                        Some(self_ty));
+            let bounds = ensure_supertraits(ccx, it.id, it.span, rp,
+                                            *supertraits, generics);
             let trait_ref = @ty::TraitRef {def_id: def_id,
                                            substs: substs};
             let trait_def = @ty::TraitDef {generics: ty_generics,
+                                           bounds: bounds,
                                            trait_ref: trait_ref};
             tcx.trait_defs.insert(def_id, trait_def);
             return trait_def;
@@ -1225,7 +1238,7 @@ pub fn ty_generics(ccx: &CrateCtxt,
                 TraitTyParamBound(ref b) => {
                     let ty = ty::mk_param(ccx.tcx, param_ty.idx, param_ty.def_id);
                     let trait_ref = instantiate_trait_ref(ccx, b, rp, generics, ty);
-                    if !astconv::try_add_builtin_trait(
+                    if !ty::try_add_builtin_trait(
                         ccx.tcx, trait_ref.def_id,
                         &mut param_bounds.builtin_bounds)
                     {

From 4ca2e55adbf0cfbc34d8b1e7de773045d36cce2e Mon Sep 17 00:00:00 2001
From: Ben Blum <bblum@andrew.cmu.edu>
Date: Fri, 16 Aug 2013 18:21:02 -0400
Subject: [PATCH 03/10] Add tests for #7083.

---
 .../auxiliary/trait_superkinds_in_metadata.rs | 14 ++++++++++++
 .../builtin-superkinds-double-superkind.rs    | 19 ++++++++++++++++
 .../builtin-superkinds-in-metadata.rs         | 22 +++++++++++++++++++
 .../compile-fail/builtin-superkinds-simple.rs | 19 ++++++++++++++++
 .../builtin-superkinds-typaram-not-send.rs    | 15 +++++++++++++
 .../builtin-superkinds-in-metadata.rs         | 22 +++++++++++++++++++
 .../builtin-superkinds-shadow-typaram.rs      | 17 ++++++++++++++
 .../run-pass/builtin-superkinds-simple.rs     | 15 +++++++++++++
 .../run-pass/builtin-superkinds-typaram.rs    | 15 +++++++++++++
 9 files changed, 158 insertions(+)
 create mode 100644 src/test/auxiliary/trait_superkinds_in_metadata.rs
 create mode 100644 src/test/compile-fail/builtin-superkinds-double-superkind.rs
 create mode 100644 src/test/compile-fail/builtin-superkinds-in-metadata.rs
 create mode 100644 src/test/compile-fail/builtin-superkinds-simple.rs
 create mode 100644 src/test/compile-fail/builtin-superkinds-typaram-not-send.rs
 create mode 100644 src/test/run-pass/builtin-superkinds-in-metadata.rs
 create mode 100644 src/test/run-pass/builtin-superkinds-shadow-typaram.rs
 create mode 100644 src/test/run-pass/builtin-superkinds-simple.rs
 create mode 100644 src/test/run-pass/builtin-superkinds-typaram.rs

diff --git a/src/test/auxiliary/trait_superkinds_in_metadata.rs b/src/test/auxiliary/trait_superkinds_in_metadata.rs
new file mode 100644
index 00000000000..02d2a6b8af4
--- /dev/null
+++ b/src/test/auxiliary/trait_superkinds_in_metadata.rs
@@ -0,0 +1,14 @@
+// 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.
+
+#[crate_type="lib"];
+
+pub trait Bar : Freeze { }
+pub trait Foo : Bar + Send { }
diff --git a/src/test/compile-fail/builtin-superkinds-double-superkind.rs b/src/test/compile-fail/builtin-superkinds-double-superkind.rs
new file mode 100644
index 00000000000..c5dbcd9bb23
--- /dev/null
+++ b/src/test/compile-fail/builtin-superkinds-double-superkind.rs
@@ -0,0 +1,19 @@
+// 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.
+
+trait Foo : Send+Freeze { }
+
+impl <T: Freeze> Foo for (T,) { } //~ ERROR cannot implement this trait
+
+impl <T: Send> Foo for (T,T) { } //~ ERROR cannot implement this trait
+
+impl <T: Send+Freeze> Foo for (T,T,T) { } // (ok)
+
+fn main() { }
diff --git a/src/test/compile-fail/builtin-superkinds-in-metadata.rs b/src/test/compile-fail/builtin-superkinds-in-metadata.rs
new file mode 100644
index 00000000000..3fa7c5a28ba
--- /dev/null
+++ b/src/test/compile-fail/builtin-superkinds-in-metadata.rs
@@ -0,0 +1,22 @@
+// 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.
+
+// aux-build:trait_superkinds_in_metadata.rs
+
+extern mod trait_superkinds_in_metadata;
+use trait_superkinds_in_metadata::{Foo, Bar};
+
+struct X<T>(T);
+
+impl <T:Freeze> Bar for X<T> { }
+
+impl <T:Freeze> Foo for X<T> { } //~ ERROR cannot implement this trait
+
+fn main() { }
diff --git a/src/test/compile-fail/builtin-superkinds-simple.rs b/src/test/compile-fail/builtin-superkinds-simple.rs
new file mode 100644
index 00000000000..472bef715e9
--- /dev/null
+++ b/src/test/compile-fail/builtin-superkinds-simple.rs
@@ -0,0 +1,19 @@
+// 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.
+
+trait Foo : Send { }
+
+impl <'self> Foo for &'self mut () { } //~ ERROR cannot implement this trait
+
+trait Bar : Freeze { }
+
+impl <'self> Bar for &'self mut () { } //~ ERROR cannot implement this trait
+
+fn main() { }
diff --git a/src/test/compile-fail/builtin-superkinds-typaram-not-send.rs b/src/test/compile-fail/builtin-superkinds-typaram-not-send.rs
new file mode 100644
index 00000000000..ec10ba09104
--- /dev/null
+++ b/src/test/compile-fail/builtin-superkinds-typaram-not-send.rs
@@ -0,0 +1,15 @@
+// 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.
+
+trait Foo : Send { }
+
+impl <T: Freeze> Foo for T { } //~ ERROR cannot implement this trait
+
+fn main() { }
diff --git a/src/test/run-pass/builtin-superkinds-in-metadata.rs b/src/test/run-pass/builtin-superkinds-in-metadata.rs
new file mode 100644
index 00000000000..fc445058c04
--- /dev/null
+++ b/src/test/run-pass/builtin-superkinds-in-metadata.rs
@@ -0,0 +1,22 @@
+// 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.
+
+// aux-build:trait_superkinds_in_metadata.rs
+
+extern mod trait_superkinds_in_metadata;
+use trait_superkinds_in_metadata::{Foo, Bar};
+
+struct X<T>(T);
+
+impl <T:Freeze> Bar for X<T> { }
+
+impl <T:Freeze+Send> Foo for X<T> { }
+
+fn main() { }
diff --git a/src/test/run-pass/builtin-superkinds-shadow-typaram.rs b/src/test/run-pass/builtin-superkinds-shadow-typaram.rs
new file mode 100644
index 00000000000..193efb06d39
--- /dev/null
+++ b/src/test/run-pass/builtin-superkinds-shadow-typaram.rs
@@ -0,0 +1,17 @@
+// 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.
+
+trait Foo : Send { }
+
+struct X<T>(());
+
+impl <T> Foo for X<T> { }
+
+fn main() { }
diff --git a/src/test/run-pass/builtin-superkinds-simple.rs b/src/test/run-pass/builtin-superkinds-simple.rs
new file mode 100644
index 00000000000..5ecac6a0f7a
--- /dev/null
+++ b/src/test/run-pass/builtin-superkinds-simple.rs
@@ -0,0 +1,15 @@
+// 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.
+
+trait Foo : Send { }
+
+impl Foo for int { }
+
+fn main() { }
diff --git a/src/test/run-pass/builtin-superkinds-typaram.rs b/src/test/run-pass/builtin-superkinds-typaram.rs
new file mode 100644
index 00000000000..eda04a780ee
--- /dev/null
+++ b/src/test/run-pass/builtin-superkinds-typaram.rs
@@ -0,0 +1,15 @@
+// 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.
+
+trait Foo : Send { }
+
+impl <T: Send> Foo for T { }
+
+fn main() { }

From 3c3bfb4c3c5f89a6c4f48b7ad8b9f71de792be04 Mon Sep 17 00:00:00 2001
From: Ben Blum <bblum@andrew.cmu.edu>
Date: Mon, 19 Aug 2013 16:50:23 -0400
Subject: [PATCH 04/10] Add more capabilities to typarams bounded by traits
 with super-builtin-kinds. Close #7083.

---
 src/librustc/middle/ty.rs | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 757f05c208b..3672bfeec86 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -2322,7 +2322,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
         let _i = indenter();
 
         let mut tc = TC_ALL;
-        for bound in type_param_def.bounds.builtin_bounds.iter() {
+        do each_inherited_builtin_bound(cx, type_param_def.bounds) |bound| {
             debug!("tc = %s, bound = %?", tc.to_str(), bound);
             tc = tc - match bound {
                 BoundStatic => TypeContents::nonstatic(cx),
@@ -2335,6 +2335,23 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
 
         debug!("result = %s", tc.to_str());
         return tc;
+
+        // Iterates over all builtin bounds on the type parameter def, including
+        // those inherited from traits with builtin-kind-supertraits.
+        fn each_inherited_builtin_bound(cx: ctxt, bounds: &ParamBounds,
+                                        f: &fn(BuiltinBound)) {
+            for bound in bounds.builtin_bounds.iter() {
+                f(bound);
+            }
+
+            do each_bound_trait_and_supertraits(cx, bounds.trait_bounds) |trait_ref| {
+                let trait_def = lookup_trait_def(cx, trait_ref.def_id);
+                for bound in trait_def.bounds.iter() {
+                    f(bound);
+                }
+                true
+            };
+        }
     }
 }
 

From 95089d37930267931c375fea5f10d0322fde771e Mon Sep 17 00:00:00 2001
From: Ben Blum <bblum@andrew.cmu.edu>
Date: Mon, 19 Aug 2013 16:54:58 -0400
Subject: [PATCH 05/10] Add tests for super-builtin-kind capabilities (#7083)

---
 ...ltin-superkinds-capabilities-transitive.rs | 25 ++++++++++++++++
 .../builtin-superkinds-capabilities-xc.rs     | 30 +++++++++++++++++++
 .../builtin-superkinds-capabilities.rs        | 23 ++++++++++++++
 3 files changed, 78 insertions(+)
 create mode 100644 src/test/run-pass/builtin-superkinds-capabilities-transitive.rs
 create mode 100644 src/test/run-pass/builtin-superkinds-capabilities-xc.rs
 create mode 100644 src/test/run-pass/builtin-superkinds-capabilities.rs

diff --git a/src/test/run-pass/builtin-superkinds-capabilities-transitive.rs b/src/test/run-pass/builtin-superkinds-capabilities-transitive.rs
new file mode 100644
index 00000000000..8b9cd057457
--- /dev/null
+++ b/src/test/run-pass/builtin-superkinds-capabilities-transitive.rs
@@ -0,0 +1,25 @@
+// 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.
+
+trait Bar : Send { }
+trait Foo : Bar { }
+
+impl <T: Send> Foo for T { }
+impl <T: Send> Bar for T { }
+
+fn foo<T: Foo>(val: T, chan: std::comm::Chan<T>) {
+    chan.send(val);
+}
+
+fn main() {
+    let (p,c) = std::comm::stream();
+    foo(31337, c);
+    assert!(p.recv() == 31337);
+}
diff --git a/src/test/run-pass/builtin-superkinds-capabilities-xc.rs b/src/test/run-pass/builtin-superkinds-capabilities-xc.rs
new file mode 100644
index 00000000000..85012896253
--- /dev/null
+++ b/src/test/run-pass/builtin-superkinds-capabilities-xc.rs
@@ -0,0 +1,30 @@
+// 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.
+
+// aux-build:trait_superkinds_in_metadata.rs
+
+extern mod trait_superkinds_in_metadata;
+use trait_superkinds_in_metadata::{Foo, Bar};
+
+#[deriving(Eq)]
+struct X<T>(T);
+
+impl <T: Freeze> Bar for X<T> { }
+impl <T: Freeze+Send> Foo for X<T> { }
+
+fn foo<T: Foo>(val: T, chan: std::comm::Chan<T>) {
+    chan.send(val);
+}
+
+fn main() {
+    let (p,c) = std::comm::stream();
+    foo(X(31337), c);
+    assert!(p.recv() == X(31337));
+}
diff --git a/src/test/run-pass/builtin-superkinds-capabilities.rs b/src/test/run-pass/builtin-superkinds-capabilities.rs
new file mode 100644
index 00000000000..639c78bd657
--- /dev/null
+++ b/src/test/run-pass/builtin-superkinds-capabilities.rs
@@ -0,0 +1,23 @@
+// 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.
+
+trait Foo : Send { }
+
+impl <T: Send> Foo for T { }
+
+fn foo<T: Foo>(val: T, chan: std::comm::Chan<T>) {
+    chan.send(val);
+}
+
+fn main() {
+    let (p,c) = std::comm::stream();
+    foo(31337, c);
+    assert!(p.recv() == 31337);
+}

From 4fd404f2ca1b3a246872521a606d749ae5a11258 Mon Sep 17 00:00:00 2001
From: Ben Blum <bblum@andrew.cmu.edu>
Date: Mon, 19 Aug 2013 17:15:25 -0400
Subject: [PATCH 06/10] Fixup style of test cases for #7083

---
 src/test/auxiliary/trait_superkinds_in_metadata.rs    |  7 +++++--
 .../builtin-superkinds-double-superkind.rs            |  3 +++
 .../compile-fail/builtin-superkinds-in-metadata.rs    |  9 ++++++---
 src/test/compile-fail/builtin-superkinds-simple.rs    |  3 +++
 .../builtin-superkinds-typaram-not-send.rs            |  2 ++
 .../builtin-superkinds-capabilities-transitive.rs     |  6 ++++++
 .../run-pass/builtin-superkinds-capabilities-xc.rs    | 11 +++++++----
 src/test/run-pass/builtin-superkinds-capabilities.rs  |  4 ++++
 src/test/run-pass/builtin-superkinds-in-metadata.rs   |  8 +++++---
 ...param.rs => builtin-superkinds-phantom-typaram.rs} |  4 ++++
 src/test/run-pass/builtin-superkinds-simple.rs        |  2 ++
 src/test/run-pass/builtin-superkinds-typaram.rs       |  3 +++
 12 files changed, 50 insertions(+), 12 deletions(-)
 rename src/test/run-pass/{builtin-superkinds-shadow-typaram.rs => builtin-superkinds-phantom-typaram.rs} (74%)

diff --git a/src/test/auxiliary/trait_superkinds_in_metadata.rs b/src/test/auxiliary/trait_superkinds_in_metadata.rs
index 02d2a6b8af4..dfb0c0310ec 100644
--- a/src/test/auxiliary/trait_superkinds_in_metadata.rs
+++ b/src/test/auxiliary/trait_superkinds_in_metadata.rs
@@ -8,7 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// Test library crate for cross-crate usages of traits inheriting
+// from the builtin kinds. Mostly tests metadata correctness.
+
 #[crate_type="lib"];
 
-pub trait Bar : Freeze { }
-pub trait Foo : Bar + Send { }
+pub trait RequiresFreeze : Freeze { }
+pub trait RequiresRequiresFreezeAndSend : RequiresFreeze + Send { }
diff --git a/src/test/compile-fail/builtin-superkinds-double-superkind.rs b/src/test/compile-fail/builtin-superkinds-double-superkind.rs
index c5dbcd9bb23..15fa0b66433 100644
--- a/src/test/compile-fail/builtin-superkinds-double-superkind.rs
+++ b/src/test/compile-fail/builtin-superkinds-double-superkind.rs
@@ -8,6 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// Test for traits that inherit from multiple builtin kinds at once,
+// testing that all such kinds must be present on implementing types.
+
 trait Foo : Send+Freeze { }
 
 impl <T: Freeze> Foo for (T,) { } //~ ERROR cannot implement this trait
diff --git a/src/test/compile-fail/builtin-superkinds-in-metadata.rs b/src/test/compile-fail/builtin-superkinds-in-metadata.rs
index 3fa7c5a28ba..a52a3765889 100644
--- a/src/test/compile-fail/builtin-superkinds-in-metadata.rs
+++ b/src/test/compile-fail/builtin-superkinds-in-metadata.rs
@@ -10,13 +10,16 @@
 
 // aux-build:trait_superkinds_in_metadata.rs
 
+// Test for traits inheriting from the builtin kinds cross-crate.
+// Mostly tests correctness of metadata.
+
 extern mod trait_superkinds_in_metadata;
-use trait_superkinds_in_metadata::{Foo, Bar};
+use trait_superkinds_in_metadata::{RequiresRequiresFreezeAndSend, RequiresFreeze};
 
 struct X<T>(T);
 
-impl <T:Freeze> Bar for X<T> { }
+impl <T:Freeze> RequiresFreeze for X<T> { }
 
-impl <T:Freeze> Foo for X<T> { } //~ ERROR cannot implement this trait
+impl <T:Freeze> RequiresRequiresFreezeAndSend for X<T> { } //~ ERROR cannot implement this trait
 
 fn main() { }
diff --git a/src/test/compile-fail/builtin-superkinds-simple.rs b/src/test/compile-fail/builtin-superkinds-simple.rs
index 472bef715e9..c1011f1368a 100644
--- a/src/test/compile-fail/builtin-superkinds-simple.rs
+++ b/src/test/compile-fail/builtin-superkinds-simple.rs
@@ -8,6 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// Basic test for traits inheriting from the builtin kinds, checking
+// the type contents of the implementing type (that's not a typaram).
+
 trait Foo : Send { }
 
 impl <'self> Foo for &'self mut () { } //~ ERROR cannot implement this trait
diff --git a/src/test/compile-fail/builtin-superkinds-typaram-not-send.rs b/src/test/compile-fail/builtin-superkinds-typaram-not-send.rs
index ec10ba09104..2a3d3c7df61 100644
--- a/src/test/compile-fail/builtin-superkinds-typaram-not-send.rs
+++ b/src/test/compile-fail/builtin-superkinds-typaram-not-send.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// Basic test for traits inheriting from the builtin kinds.
+
 trait Foo : Send { }
 
 impl <T: Freeze> Foo for T { } //~ ERROR cannot implement this trait
diff --git a/src/test/run-pass/builtin-superkinds-capabilities-transitive.rs b/src/test/run-pass/builtin-superkinds-capabilities-transitive.rs
index 8b9cd057457..ab5e58285d4 100644
--- a/src/test/run-pass/builtin-superkinds-capabilities-transitive.rs
+++ b/src/test/run-pass/builtin-superkinds-capabilities-transitive.rs
@@ -8,6 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// Tests "transitivity" of super-builtin-kinds on traits. Here, if
+// we have a Foo, we know we have a Bar, and if we have a Bar, we
+// know we have a Send. So if we have a Foo we should know we have
+// a Send. Basically this just makes sure rustc is using
+// each_bound_trait_and_supertraits in type_contents correctly.
+
 trait Bar : Send { }
 trait Foo : Bar { }
 
diff --git a/src/test/run-pass/builtin-superkinds-capabilities-xc.rs b/src/test/run-pass/builtin-superkinds-capabilities-xc.rs
index 85012896253..1e24c121f5a 100644
--- a/src/test/run-pass/builtin-superkinds-capabilities-xc.rs
+++ b/src/test/run-pass/builtin-superkinds-capabilities-xc.rs
@@ -10,16 +10,19 @@
 
 // aux-build:trait_superkinds_in_metadata.rs
 
+// Tests "capabilities" granted by traits with super-builtin-kinds,
+// even when using them cross-crate.
+
 extern mod trait_superkinds_in_metadata;
-use trait_superkinds_in_metadata::{Foo, Bar};
+use trait_superkinds_in_metadata::{RequiresRequiresFreezeAndSend, RequiresFreeze};
 
 #[deriving(Eq)]
 struct X<T>(T);
 
-impl <T: Freeze> Bar for X<T> { }
-impl <T: Freeze+Send> Foo for X<T> { }
+impl <T: Freeze> RequiresFreeze for X<T> { }
+impl <T: Freeze+Send> RequiresRequiresFreezeAndSend for X<T> { }
 
-fn foo<T: Foo>(val: T, chan: std::comm::Chan<T>) {
+fn foo<T: RequiresRequiresFreezeAndSend>(val: T, chan: std::comm::Chan<T>) {
     chan.send(val);
 }
 
diff --git a/src/test/run-pass/builtin-superkinds-capabilities.rs b/src/test/run-pass/builtin-superkinds-capabilities.rs
index 639c78bd657..ebbb3d38694 100644
--- a/src/test/run-pass/builtin-superkinds-capabilities.rs
+++ b/src/test/run-pass/builtin-superkinds-capabilities.rs
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// Tests "capabilities" granted by traits that inherit from super-
+// builtin-kinds, e.g., if a trait requires Send to implement, then
+// at usage site of that trait, we know we have the Send capability.
+
 trait Foo : Send { }
 
 impl <T: Send> Foo for T { }
diff --git a/src/test/run-pass/builtin-superkinds-in-metadata.rs b/src/test/run-pass/builtin-superkinds-in-metadata.rs
index fc445058c04..9f68976a4a4 100644
--- a/src/test/run-pass/builtin-superkinds-in-metadata.rs
+++ b/src/test/run-pass/builtin-superkinds-in-metadata.rs
@@ -10,13 +10,15 @@
 
 // aux-build:trait_superkinds_in_metadata.rs
 
+// Tests (correct) usage of trait super-builtin-kinds cross-crate.
+
 extern mod trait_superkinds_in_metadata;
-use trait_superkinds_in_metadata::{Foo, Bar};
+use trait_superkinds_in_metadata::{RequiresRequiresFreezeAndSend, RequiresFreeze};
 
 struct X<T>(T);
 
-impl <T:Freeze> Bar for X<T> { }
+impl <T:Freeze> RequiresFreeze for X<T> { }
 
-impl <T:Freeze+Send> Foo for X<T> { }
+impl <T:Freeze+Send> RequiresRequiresFreezeAndSend for X<T> { }
 
 fn main() { }
diff --git a/src/test/run-pass/builtin-superkinds-shadow-typaram.rs b/src/test/run-pass/builtin-superkinds-phantom-typaram.rs
similarity index 74%
rename from src/test/run-pass/builtin-superkinds-shadow-typaram.rs
rename to src/test/run-pass/builtin-superkinds-phantom-typaram.rs
index 193efb06d39..b6e58bfbf3d 100644
--- a/src/test/run-pass/builtin-superkinds-shadow-typaram.rs
+++ b/src/test/run-pass/builtin-superkinds-phantom-typaram.rs
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// Tests that even when a type paramenter doesn't implement a required
+// super-builtin-kind of a trait, if the type parameter is never used,
+// the type can implement the trait anyway.
+
 trait Foo : Send { }
 
 struct X<T>(());
diff --git a/src/test/run-pass/builtin-superkinds-simple.rs b/src/test/run-pass/builtin-superkinds-simple.rs
index 5ecac6a0f7a..61a22d97498 100644
--- a/src/test/run-pass/builtin-superkinds-simple.rs
+++ b/src/test/run-pass/builtin-superkinds-simple.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// Simple test case of implementing a trait with super-builtin-kinds.
+
 trait Foo : Send { }
 
 impl Foo for int { }
diff --git a/src/test/run-pass/builtin-superkinds-typaram.rs b/src/test/run-pass/builtin-superkinds-typaram.rs
index eda04a780ee..7dfd1e0629f 100644
--- a/src/test/run-pass/builtin-superkinds-typaram.rs
+++ b/src/test/run-pass/builtin-superkinds-typaram.rs
@@ -8,6 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// Tests correct implementation of traits with super-builtin-kinds
+// using a bounded type parameter.
+
 trait Foo : Send { }
 
 impl <T: Send> Foo for T { }

From cdbdfe88a5e95428055f0c630bd3346a78436486 Mon Sep 17 00:00:00 2001
From: Ben Blum <bblum@andrew.cmu.edu>
Date: Tue, 20 Aug 2013 15:44:19 -0400
Subject: [PATCH 07/10] Allow the Self type to benefit from
 builtin-kinds-as-supertraits (#7083).

---
 src/librustc/middle/ty.rs | 34 +++++++++++++++++-----------------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 3672bfeec86..4e0f76fe198 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -2161,17 +2161,19 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
                 // def-id.
                 assert_eq!(p.def_id.crate, ast::LOCAL_CRATE);
 
-                type_param_def_to_contents(
-                    cx, cx.ty_param_defs.get(&p.def_id.node))
+                let tp_def = cx.ty_param_defs.get(&p.def_id.node);
+                kind_bounds_to_contents(cx, &tp_def.bounds.builtin_bounds,
+                                        tp_def.bounds.trait_bounds)
             }
 
-            ty_self(_) => {
-                // Currently, self is not bounded, so we must assume the
-                // worst.  But in the future we should examine the super
-                // traits.
-                //
+            ty_self(def_id) => {
                 // FIXME(#4678)---self should just be a ty param
-                TC_ALL
+
+                // Self may be bounded if the associated trait has builtin kinds
+                // for supertraits. If so we can use those bounds.
+                let trait_def = lookup_trait_def(cx, def_id);
+                let traits = [trait_def.trait_ref];
+                kind_bounds_to_contents(cx, &trait_def.bounds, traits)
             }
 
             ty_infer(_) => {
@@ -2315,14 +2317,12 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
         st + mt + bt
     }
 
-    fn type_param_def_to_contents(cx: ctxt,
-                                  type_param_def: &TypeParameterDef) -> TypeContents
-    {
-        debug!("type_param_def_to_contents(%s)", type_param_def.repr(cx));
+    fn kind_bounds_to_contents(cx: ctxt, bounds: &BuiltinBounds, traits: &[@TraitRef])
+            -> TypeContents {
         let _i = indenter();
 
         let mut tc = TC_ALL;
-        do each_inherited_builtin_bound(cx, type_param_def.bounds) |bound| {
+        do each_inherited_builtin_bound(cx, bounds, traits) |bound| {
             debug!("tc = %s, bound = %?", tc.to_str(), bound);
             tc = tc - match bound {
                 BoundStatic => TypeContents::nonstatic(cx),
@@ -2338,13 +2338,13 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
 
         // Iterates over all builtin bounds on the type parameter def, including
         // those inherited from traits with builtin-kind-supertraits.
-        fn each_inherited_builtin_bound(cx: ctxt, bounds: &ParamBounds,
-                                        f: &fn(BuiltinBound)) {
-            for bound in bounds.builtin_bounds.iter() {
+        fn each_inherited_builtin_bound(cx: ctxt, bounds: &BuiltinBounds,
+                                        traits: &[@TraitRef], f: &fn(BuiltinBound)) {
+            for bound in bounds.iter() {
                 f(bound);
             }
 
-            do each_bound_trait_and_supertraits(cx, bounds.trait_bounds) |trait_ref| {
+            do each_bound_trait_and_supertraits(cx, traits) |trait_ref| {
                 let trait_def = lookup_trait_def(cx, trait_ref.def_id);
                 for bound in trait_def.bounds.iter() {
                     f(bound);

From 5796e9e49ccf155772b8f829f458c304da1742fb Mon Sep 17 00:00:00 2001
From: Ben Blum <bblum@andrew.cmu.edu>
Date: Tue, 20 Aug 2013 15:46:48 -0400
Subject: [PATCH 08/10] Add tests for self type using builtin kinds. (#7083)

---
 .../builtin-superkinds-self-type.rs           | 26 +++++++++++++++++++
 .../run-pass/builtin-superkinds-self-type.rs  | 26 +++++++++++++++++++
 2 files changed, 52 insertions(+)
 create mode 100644 src/test/compile-fail/builtin-superkinds-self-type.rs
 create mode 100644 src/test/run-pass/builtin-superkinds-self-type.rs

diff --git a/src/test/compile-fail/builtin-superkinds-self-type.rs b/src/test/compile-fail/builtin-superkinds-self-type.rs
new file mode 100644
index 00000000000..75690edeb01
--- /dev/null
+++ b/src/test/compile-fail/builtin-superkinds-self-type.rs
@@ -0,0 +1,26 @@
+// 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.
+
+// Tests (negatively) the ability for the Self type in default methods
+// to use capabilities granted by builtin kinds as supertraits.
+
+trait Foo : Freeze {
+    fn foo(self, chan: std::comm::Chan<Self>) {
+        chan.send(self); //~ ERROR does not fulfill `Send`
+    }
+}
+
+impl <T: Freeze> Foo for T { }
+
+fn main() {
+    let (p,c) = std::comm::stream();
+    1193182.foo(c);
+    assert!(p.recv() == 1193182);
+}
diff --git a/src/test/run-pass/builtin-superkinds-self-type.rs b/src/test/run-pass/builtin-superkinds-self-type.rs
new file mode 100644
index 00000000000..da7f0fb5de9
--- /dev/null
+++ b/src/test/run-pass/builtin-superkinds-self-type.rs
@@ -0,0 +1,26 @@
+// 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.
+
+// Tests the ability for the Self type in default methods to use
+// capabilities granted by builtin kinds as supertraits.
+
+trait Foo : Send {
+    fn foo(self, chan: std::comm::Chan<Self>) {
+        chan.send(self);
+    }
+}
+
+impl <T: Send> Foo for T { }
+
+fn main() {
+    let (p,c) = std::comm::stream();
+    1193182.foo(c);
+    assert!(p.recv() == 1193182);
+}

From 22ad36d75b18bb6b37d88fd5559c6873e50dd4c6 Mon Sep 17 00:00:00 2001
From: Ben Blum <bblum@andrew.cmu.edu>
Date: Wed, 21 Aug 2013 15:52:31 -0400
Subject: [PATCH 09/10] oops, xfail-fast the cross-crate superkind tests

---
 src/test/compile-fail/builtin-superkinds-in-metadata.rs | 2 ++
 src/test/run-pass/builtin-superkinds-capabilities-xc.rs | 2 ++
 src/test/run-pass/builtin-superkinds-in-metadata.rs     | 2 ++
 3 files changed, 6 insertions(+)

diff --git a/src/test/compile-fail/builtin-superkinds-in-metadata.rs b/src/test/compile-fail/builtin-superkinds-in-metadata.rs
index a52a3765889..fe35bf47196 100644
--- a/src/test/compile-fail/builtin-superkinds-in-metadata.rs
+++ b/src/test/compile-fail/builtin-superkinds-in-metadata.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// xfail-fast
+
 // aux-build:trait_superkinds_in_metadata.rs
 
 // Test for traits inheriting from the builtin kinds cross-crate.
diff --git a/src/test/run-pass/builtin-superkinds-capabilities-xc.rs b/src/test/run-pass/builtin-superkinds-capabilities-xc.rs
index 1e24c121f5a..6e722d4d538 100644
--- a/src/test/run-pass/builtin-superkinds-capabilities-xc.rs
+++ b/src/test/run-pass/builtin-superkinds-capabilities-xc.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// xfail-fast
+
 // aux-build:trait_superkinds_in_metadata.rs
 
 // Tests "capabilities" granted by traits with super-builtin-kinds,
diff --git a/src/test/run-pass/builtin-superkinds-in-metadata.rs b/src/test/run-pass/builtin-superkinds-in-metadata.rs
index 9f68976a4a4..e2fc6cc335f 100644
--- a/src/test/run-pass/builtin-superkinds-in-metadata.rs
+++ b/src/test/run-pass/builtin-superkinds-in-metadata.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// xfail-fast
+
 // aux-build:trait_superkinds_in_metadata.rs
 
 // Tests (correct) usage of trait super-builtin-kinds cross-crate.

From b795fab046ca1b218785bee5ec5af7326ef9fc85 Mon Sep 17 00:00:00 2001
From: Ben Blum <bblum@andrew.cmu.edu>
Date: Wed, 21 Aug 2013 20:33:56 -0400
Subject: [PATCH 10/10] oops v2, apparently writing std::comm::stream() doesn't
 work on check-fast; fix this

---
 src/test/compile-fail/builtin-superkinds-self-type.rs       | 6 ++++--
 .../run-pass/builtin-superkinds-capabilities-transitive.rs  | 6 ++++--
 src/test/run-pass/builtin-superkinds-capabilities-xc.rs     | 5 +++--
 src/test/run-pass/builtin-superkinds-capabilities.rs        | 6 ++++--
 src/test/run-pass/builtin-superkinds-self-type.rs           | 6 ++++--
 5 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/src/test/compile-fail/builtin-superkinds-self-type.rs b/src/test/compile-fail/builtin-superkinds-self-type.rs
index 75690edeb01..d7ee3aae4d5 100644
--- a/src/test/compile-fail/builtin-superkinds-self-type.rs
+++ b/src/test/compile-fail/builtin-superkinds-self-type.rs
@@ -11,8 +11,10 @@
 // Tests (negatively) the ability for the Self type in default methods
 // to use capabilities granted by builtin kinds as supertraits.
 
+use std::comm;
+
 trait Foo : Freeze {
-    fn foo(self, chan: std::comm::Chan<Self>) {
+    fn foo(self, chan: comm::Chan<Self>) {
         chan.send(self); //~ ERROR does not fulfill `Send`
     }
 }
@@ -20,7 +22,7 @@ trait Foo : Freeze {
 impl <T: Freeze> Foo for T { }
 
 fn main() {
-    let (p,c) = std::comm::stream();
+    let (p,c) = comm::stream();
     1193182.foo(c);
     assert!(p.recv() == 1193182);
 }
diff --git a/src/test/run-pass/builtin-superkinds-capabilities-transitive.rs b/src/test/run-pass/builtin-superkinds-capabilities-transitive.rs
index ab5e58285d4..74a218ac469 100644
--- a/src/test/run-pass/builtin-superkinds-capabilities-transitive.rs
+++ b/src/test/run-pass/builtin-superkinds-capabilities-transitive.rs
@@ -14,18 +14,20 @@
 // a Send. Basically this just makes sure rustc is using
 // each_bound_trait_and_supertraits in type_contents correctly.
 
+use std::comm;
+
 trait Bar : Send { }
 trait Foo : Bar { }
 
 impl <T: Send> Foo for T { }
 impl <T: Send> Bar for T { }
 
-fn foo<T: Foo>(val: T, chan: std::comm::Chan<T>) {
+fn foo<T: Foo>(val: T, chan: comm::Chan<T>) {
     chan.send(val);
 }
 
 fn main() {
-    let (p,c) = std::comm::stream();
+    let (p,c) = comm::stream();
     foo(31337, c);
     assert!(p.recv() == 31337);
 }
diff --git a/src/test/run-pass/builtin-superkinds-capabilities-xc.rs b/src/test/run-pass/builtin-superkinds-capabilities-xc.rs
index 6e722d4d538..ea61b91e3b9 100644
--- a/src/test/run-pass/builtin-superkinds-capabilities-xc.rs
+++ b/src/test/run-pass/builtin-superkinds-capabilities-xc.rs
@@ -17,6 +17,7 @@
 
 extern mod trait_superkinds_in_metadata;
 use trait_superkinds_in_metadata::{RequiresRequiresFreezeAndSend, RequiresFreeze};
+use std::comm;
 
 #[deriving(Eq)]
 struct X<T>(T);
@@ -24,12 +25,12 @@ struct X<T>(T);
 impl <T: Freeze> RequiresFreeze for X<T> { }
 impl <T: Freeze+Send> RequiresRequiresFreezeAndSend for X<T> { }
 
-fn foo<T: RequiresRequiresFreezeAndSend>(val: T, chan: std::comm::Chan<T>) {
+fn foo<T: RequiresRequiresFreezeAndSend>(val: T, chan: comm::Chan<T>) {
     chan.send(val);
 }
 
 fn main() {
-    let (p,c) = std::comm::stream();
+    let (p,c) = comm::stream();
     foo(X(31337), c);
     assert!(p.recv() == X(31337));
 }
diff --git a/src/test/run-pass/builtin-superkinds-capabilities.rs b/src/test/run-pass/builtin-superkinds-capabilities.rs
index ebbb3d38694..c2d2129b1c1 100644
--- a/src/test/run-pass/builtin-superkinds-capabilities.rs
+++ b/src/test/run-pass/builtin-superkinds-capabilities.rs
@@ -12,16 +12,18 @@
 // builtin-kinds, e.g., if a trait requires Send to implement, then
 // at usage site of that trait, we know we have the Send capability.
 
+use std::comm;
+
 trait Foo : Send { }
 
 impl <T: Send> Foo for T { }
 
-fn foo<T: Foo>(val: T, chan: std::comm::Chan<T>) {
+fn foo<T: Foo>(val: T, chan: comm::Chan<T>) {
     chan.send(val);
 }
 
 fn main() {
-    let (p,c) = std::comm::stream();
+    let (p,c) = comm::stream();
     foo(31337, c);
     assert!(p.recv() == 31337);
 }
diff --git a/src/test/run-pass/builtin-superkinds-self-type.rs b/src/test/run-pass/builtin-superkinds-self-type.rs
index da7f0fb5de9..2285c471c91 100644
--- a/src/test/run-pass/builtin-superkinds-self-type.rs
+++ b/src/test/run-pass/builtin-superkinds-self-type.rs
@@ -11,8 +11,10 @@
 // Tests the ability for the Self type in default methods to use
 // capabilities granted by builtin kinds as supertraits.
 
+use std::comm;
+
 trait Foo : Send {
-    fn foo(self, chan: std::comm::Chan<Self>) {
+    fn foo(self, chan: comm::Chan<Self>) {
         chan.send(self);
     }
 }
@@ -20,7 +22,7 @@ trait Foo : Send {
 impl <T: Send> Foo for T { }
 
 fn main() {
-    let (p,c) = std::comm::stream();
+    let (p,c) = comm::stream();
     1193182.foo(c);
     assert!(p.recv() == 1193182);
 }