From 961ee0a1e0b90f542c718359c7ee2c3567e7c50f Mon Sep 17 00:00:00 2001
From: Nick Cameron <ncameron@mozilla.com>
Date: Wed, 22 Oct 2014 09:08:07 +1300
Subject: [PATCH] Allow impls for traits as a concrete type

---
 src/librustc/middle/resolve.rs                 | 11 ++++++++---
 src/librustc/middle/traits/select.rs           |  4 ++--
 src/librustc/middle/typeck/coherence/mod.rs    |  4 ++--
 src/librustc/middle/typeck/coherence/orphan.rs |  3 ++-
 4 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index c297bdc6ca2..03f1c33cce1 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -627,7 +627,10 @@ impl NameBindings {
                      sp: Span) {
         // Merges the module with the existing type def or creates a new one.
         let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
-        let module_ = Rc::new(Module::new(parent_link, def_id, kind, external,
+        let module_ = Rc::new(Module::new(parent_link,
+                                          def_id,
+                                          kind,
+                                          external,
                                           is_public));
         let type_def = self.type_def.borrow().clone();
         match type_def {
@@ -1372,6 +1375,8 @@ impl<'a> Resolver<'a> {
                 // Create the module and add all methods.
                 match ty.node {
                     TyPath(ref path, _, _) if path.segments.len() == 1 => {
+                        // FIXME(18446) we should distinguish between the name of
+                        // a trait and the name of an impl of that trait.
                         let mod_name = path.segments.last().unwrap().identifier.name;
 
                         let parent_opt = parent.module().children.borrow()
@@ -1380,8 +1385,8 @@ impl<'a> Resolver<'a> {
                             // It already exists
                             Some(ref child) if child.get_module_if_available()
                                                 .is_some() &&
-                                           child.get_module().kind.get() ==
-                                                ImplModuleKind => {
+                                           (child.get_module().kind.get() == ImplModuleKind ||
+                                            child.get_module().kind.get() == TraitModuleKind) => {
                                 ModuleReducedGraphParent(child.get_module())
                             }
                             Some(ref child) if child.get_module_if_available()
diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs
index f8c1c37452b..9ac47a23472 100644
--- a/src/librustc/middle/traits/select.rs
+++ b/src/librustc/middle/traits/select.rs
@@ -514,7 +514,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         // and `Rc<Baz>`. (Note that it is not a *coherence violation*
         // to have impls for both `Bar` and `Baz`, despite this
         // ambiguity).  In this case, we report an error, listing all
-        // the applicable impls.  The use can explicitly "up-coerce"
+        // the applicable impls.  The user can explicitly "up-coerce"
         // to the type they want.
         //
         // Note that this coercion step only considers actual impls
@@ -1931,7 +1931,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
     fn all_impls(&self, trait_def_id: ast::DefId) -> Vec<ast::DefId> {
         /*!
-         * Returns se tof all impls for a given trait.
+         * Returns set of all impls for a given trait.
          */
 
         ty::populate_implementations_for_trait_if_necessary(self.tcx(),
diff --git a/src/librustc/middle/typeck/coherence/mod.rs b/src/librustc/middle/typeck/coherence/mod.rs
index a569053507c..ac18f53de04 100644
--- a/src/librustc/middle/typeck/coherence/mod.rs
+++ b/src/librustc/middle/typeck/coherence/mod.rs
@@ -207,8 +207,8 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
         let impl_items = self.create_impl_from_item(item);
 
         for associated_trait in associated_traits.iter() {
-            let trait_ref = ty::node_id_to_trait_ref(
-                self.crate_context.tcx, associated_trait.ref_id);
+            let trait_ref = ty::node_id_to_trait_ref(self.crate_context.tcx,
+                                                     associated_trait.ref_id);
             debug!("(checking implementation) adding impl for trait '{}', item '{}'",
                    trait_ref.repr(self.crate_context.tcx),
                    token::get_ident(item.ident));
diff --git a/src/librustc/middle/typeck/coherence/orphan.rs b/src/librustc/middle/typeck/coherence/orphan.rs
index e7139e1229b..3c4ad347361 100644
--- a/src/librustc/middle/typeck/coherence/orphan.rs
+++ b/src/librustc/middle/typeck/coherence/orphan.rs
@@ -41,7 +41,8 @@ impl<'cx, 'tcx,'v> visit::Visitor<'v> for OrphanChecker<'cx, 'tcx> {
                 let self_ty = ty::lookup_item_type(self.tcx, def_id).ty;
                 match ty::get(self_ty).sty {
                     ty::ty_enum(def_id, _) |
-                    ty::ty_struct(def_id, _) => {
+                    ty::ty_struct(def_id, _) |
+                    ty::ty_trait(box ty::TyTrait{ def_id, ..}) => {
                         if def_id.krate != ast::LOCAL_CRATE {
                             span_err!(self.tcx.sess, item.span, E0116,
                                       "cannot associate methods with a type outside the \